/*
    ldapdiff
    Copyright (C) 2000-2006 Thomas.Reith@rhoen.de

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <lber.h>
#include <ldap.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "ldapdiff.h"

void ldifread(struct s_ldif **sldif,char *filename)
{
 FILE          *f;
 char           line[MAXATTRLEN];
 char           folderline[MAXATTRLEN];
 char          *pline;
 char          *pstrip;
 char          *var = NULL;
 char          *val = NULL;
 size_t         val_len;
 teattrtype     val_type;
 struct s_ldif *psldif;
 int            clines = 0;
 int            centrs = 0;
 int            cattrs = 0;
 int            cempty = 0;
 int            cerrs  = 0;
 int            evalid = 0;

 if(filename != NULL){
  if((f = fopen(filename,"r")) == NULL){
   ldiflog(LOG0,"fopen() of %s failed: file: %s, line: %d",filename,__FILE__,__LINE__);
   exit(EXITLDERROR);
  }
 }
 else{
  f = stdin;
 }

 if(strcmp(ldifgetgconf(CONFICONV),"yes") == 0){
  ldificonvopen();
 }

 psldif = *sldif;
 while(fgets(line,sizeof(line),f) != NULL){
  clines++;

  pline = LDDUP(line);
  /* 
  rfc2849: '#', are valid for comment in the first column only 
  */
  /* strip comment */
  if(*pline == '#'){
    *pline = '\0';
  }
  /* strip \n */
  if((pstrip = strchr(pline,'\n')) != NULL){
   *pstrip = '\0';
  }
  /* strip \r\n */
  if((pstrip = strstr(pline,"\r\n")) != NULL){
   *pstrip = '\0';
  }

  if(strlen(pline) != 0){

   for(;;){
    char nextch = getc(f);

    ungetc(nextch, f);
    if(nextch != ' ' && nextch != '\t'){
     break;
    }
    if(fgets(folderline,sizeof(folderline),f) == NULL){
     break;
    }
    if((pstrip = strchr(folderline,'\n')) != NULL){
     *pstrip = '\0';
    }
    /* strip \r\n */
    if((pstrip = strstr(folderline,"\r\n")) != NULL){
     *pstrip = '\0';
    }
    clines++;
    if(strlen(line) + strlen(folderline+1) > MAXATTRLEN){
     ldiflog(LOG0,"error: attribute size too big: file:%s line:%d",__FILE__,__LINE__);
     exit(EXITLDERROR);
    }
    pline = realloc(pline,strlen(pline)+1 + strlen(folderline));
    strcat(pline,folderline+1);
   }

   if(ldifparse(pline,&var,&val,&val_len,&val_type) == -1){
    ldiflog(LOG0,"read: parse error in line %d: [%s]",clines,pline);
    exit(EXITLDERROR);
   }

   if(val_type == ATTREMPTY){
    ldiflog(LOG2,"read: warning, empty attribute ignored in line %d:",clines);
    cempty++;
   }
   else{
    if(strcasecmp(var,DNNAME) == 0){
     char *nval;

     nval = ldifnormalizedn(val);
     if(ldifcheckbase(nval) != 0){
      ldiflog(LOG0,"read: warning: unknown basedn ignored %d:",clines);
      ldiflog(LOG0,"read: [%s]",pline);
      cerrs++;
      evalid = 0;
     }
     else{
      centrs++;
      psldif = ldifadd(sldif,var,nval);
      evalid = 1;
     }
     free(nval);
    }
    else{
     if(evalid == 1){
      cattrs++;
      ldifaddentry(psldif,var,val,val_len,val_type);
     }
     else{
      ldiflog(LOG0,"fread: warning, unexpected attribute in line %d:",clines);
      ldiflog(LOG0,"read: [%s]",pline);
      cerrs++;
     }
    }
    /* we don't need var and val anymore*/
    free(var);
    free(val);
   }
  }
  free(pline);
 }

 if(strcmp(ldifgetgconf(CONFICONV),"yes") == 0){
  ldificonvclose();
 }

 ldiflog(LOG1,"read:   %10d lines      processed",clines);
 ldiflog(LOG1,"read:   %10d entries    processed",centrs);
 ldiflog(LOG1,"read:   %10d attributes processed",cattrs);
 ldiflog(LOG1,"read:   %10d empty attr processed",cempty);
 ldiflog(LOG1,"read:   %10d errors     proceesed",cerrs);

 if(filename != NULL){
  fclose(f);
 }
}


syntax highlighted by Code2HTML, v. 0.9.1