/* 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 #include #include #include #include #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); } }