/*
    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 <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "ldapdiff.h"

static struct s_conf asdefconf[] = {
 {NULL, SECTIONGLOBAL,  CONFLDAPHOST,        "ldaphost",        NULL },
 {NULL, SECTIONGLOBAL,  CONFLDAPPORT,        "ldapport",        NULL },
 {NULL, SECTIONGLOBAL,  CONFROOTDN,          "rootdn",          NULL },
 {NULL, SECTIONGLOBAL,  CONFROOTPW,          "rootpw",          NULL },
 {NULL, SECTIONGLOBAL,  CONFMODFILE,         "modfile",         NULL },
 {NULL, SECTIONGLOBAL,  CONFADDFILE,         "addfile",         NULL },
 {NULL, SECTIONGLOBAL,  CONFONLINEUPDATE,    "onlineupdate",    NULL },
 {NULL, SECTIONGLOBAL,  CONFOFFLINEUPDATE,   "offlineupdate",   NULL },
 {NULL, SECTIONGLOBAL,  CONFONLINEERRFATAL,  "onlineerrfatal",  NULL },
 {NULL, SECTIONGLOBAL,  CONFICONV,           "iconv",           NULL },
 {NULL, SECTIONGLOBAL,  CONFLDIFCHARSET,     "ldifcharset",     NULL },
 {NULL, SECTIONGLOBAL,  CONFLDAPCHARSET,     "ldapcharset",     NULL },
 {NULL, SECTIONGLOBAL,  CONFSCHEMACHECK,     "schemacheck",     NULL },
 {NULL, SECTIONGLOBAL,  CONFSCHEMABASE,      "schemabase",      NULL },
 {NULL, SECTIONGLOBAL,  CONFSCHEMAFILTER,    "schemafilter",    NULL },
 {NULL, SECTIONGLOBAL,  CONFSCHEMAATTRIBUTE, "schemaattribute", NULL },
 {NULL, SECTIONPROFILE, CONFBASEDN,          "basedn",          NULL },
 {NULL, SECTIONPROFILE, CONFFILTER,          "filter",          NULL },
 {NULL, SECTIONPROFILE, CONFGROUP,           "group",           NULL },
 {NULL, SECTIONPROFILE, CONFIGNORE,          "ignore",          NULL },
 {NULL, SECTIONPROFILE, CONFIGNOREVAL,       "ignoreval",       NULL },
 {NULL, SECTIONPROFILE, CONFNOEQUALITY,      "noequality",      NULL },
 {NULL, SECTIONPROFILE, CONFMAPALIAS,        "mapalias",        NULL },
 {NULL, SECTIONPROFILE, CONFDELETEENTRY,     "deleteentry",     NULL },
 {NULL, SECTIONPROFILE, CONFDELETEATTRIBUTE, "deleteattribute", NULL },
 {NULL, SECTIONPROFILE, CONFMODIFYBYDELADD,  "modifybydeladd",  NULL },
 {NULL, SECTIONPROFILE, CONFADDENTRY,        "addentry",        NULL },
 {NULL, SECTIONNONE,    CONFNONE,            NULL,              NULL }
};

static struct s_conf *asconf[MAXCONFVAR];

static char *getconf(char *section,tevarid varid)
{
 int   count = 0;
 char *var   = "unknown";

 while(asconf[count] != NULL){
  if(strcmp(section,asconf[count]->section) == 0 && asconf[count]->varid == varid){
   return asconf[count]->val;
  }
  count++;
 }

 count=0;
 while(asdefconf[count].varid != CONFNONE){
  if(asdefconf[count].varid == varid){
   var = asdefconf[count].var;
  }
  count++;
 }

 ldiflog(LOG0,"error: requested variable [%s]:%s not found",section,var);
 exit(EXITLDERROR);

 return NULL;
}

char *ldifgetgconf(tevarid varid)
{
 return getconf(SECTGLOB,varid);
}

char *ldifgetpconf(tevarid varid)
{
 extern char *profile;
 return getconf(profile,varid);
}

static void confcheck(char *section)
{
 static struct s_conf *ascmpconf[MAXCONFVAR];
 int           count;
 int           cmpcount;
 int           found;
 tesectiontype sectiontype;

 count    = 0;
 cmpcount = 0;
 while(asconf[count] != NULL){
  if(strcmp(asconf[count]->section,section) == 0){
   ascmpconf[cmpcount] = asconf[count];
   cmpcount++;
  }
  count++;
 }
 ascmpconf[cmpcount] = NULL;

 sectiontype = SECTIONPROFILE;
 if(strcmp(section,SECTGLOB) == 0){
  sectiontype = SECTIONGLOBAL;
 }

 count    = 0;
 while(asdefconf[count].varid != CONFNONE){
  if(asdefconf[count].sectiontype == sectiontype){
   cmpcount = 0;
   found    = 0;
   while(ascmpconf[cmpcount] != NULL){
    if(strcmp(asdefconf[count].var,ascmpconf[cmpcount]->var) == 0){
     found++;
    }
    cmpcount++;
   }
   if(found == 0){
    ldiflog(LOG0,"config error: parameter [%s] %s missing",section,asdefconf[count].var);
    exit(EXITLDERROR);
   }
  }
  count++;
 }

 count    = 0;
 while(ascmpconf[count] != NULL){
  cmpcount = count + 1;
  while(ascmpconf[cmpcount] != NULL){
   if(strcmp(ascmpconf[count]->var,ascmpconf[cmpcount]->var) == 0 &&
      strcmp(ascmpconf[count]->section,ascmpconf[cmpcount]->section) == 0){
    ldiflog(LOG0,"config error: parameter [%s] %s already defined",ascmpconf[cmpcount]->section,ascmpconf[cmpcount]->var);
    exit(EXITLDERROR);
   }
   cmpcount++;
  }
  count++;
 }
}

void ldifinitconf(char* cfile)
{
 FILE *f;
 char  line[MAXATTRLEN];
 char  section[MAXATTRLEN];
 char  var[MAXATTRLEN];
 char  val[MAXATTRLEN];
 char *fname;
 int   count;
 int   confcount;
 int   found;
 int   clines  = 0;

 fname = LDALLOC(MAXATTRLEN,sizeof(char));

 /* intialize asconf array */
 for(confcount = 0;confcount < MAXCONFVAR;confcount++){
  asconf[confcount] = NULL;
 }

 if(cfile[0] != '/'){
  getcwd(fname,MAXATTRLEN);
  if(strlen(fname) + strlen("/") < MAXATTRLEN){
   strcat(fname,"/");
  }
  if(strlen(fname) + strlen(cfile) < MAXATTRLEN){
   strcat(fname,cfile);
  }
 }
 else{
  strncpy(fname,cfile,MAXATTRLEN - 1);
 }
 ldiflog(LOG2,"config: using config file: %s",fname);

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

 confcount  = 0;
 section[0] = 0;
 while(fgets(line,sizeof(line),f) != NULL){
  int ccount;

  clines++;

  /* strip '\n' '\r' and '#' */
  ccount = 0;
  while(line[ccount] != '\0'){
   if(line[ccount] == '\n' || line[ccount] == '\r' || line[ccount] == '#'){
    line[ccount] = '\0';
    break;
   }
   ccount++;
  }
  if(strlen(line) == 0){
   continue;
  }

  if(strchr(line,'[') != NULL && strchr(line,']') != NULL){
   int seclength;
   seclength = strchr(line,']') - strchr(line,'[') - 1;
   if(seclength > 0){

    if(strlen(section) != 0){
     confcheck(section);
    }

    memset(section,0,MAXATTRLEN * sizeof(char));
    strncpy(section,strchr(line,'[') + 1,seclength);
    ldiflog(LOG2,"config: processing section   [%s]",section);
    continue;
   }
  }

  if(ldifconfnormalize(line,var,val) == -1){
   ldiflog(LOG0,"config error: parse error in line %d: [%s]",clines,line);
   exit(EXITLDERROR);
  }

  if(strlen(section) != 0 && strlen(var) != 0 && strlen(val) != 0){
   count = 0;
   found = 0;
   while(asdefconf[count].varid != CONFNONE){
    if(strcmp(asdefconf[count].var,var) == 0){
     struct s_conf *psconf;

     psconf = LDALLOC(1,sizeof(struct s_conf));
     psconf->section     = LDDUP(section);
     psconf->sectiontype = asdefconf[count].sectiontype;
     psconf->varid       = asdefconf[count].varid;
     psconf->var         = LDDUP(var);
     psconf->val         = LDDUP(val);
     asconf[confcount]   = psconf;
     ldiflog(LOG2,"config: processing parameter [%s] %s: %s",section,var,val);
     confcount++;
     found = 1;
    }
    count++;
   }
   if(found == 0){
    ldiflog(LOG0,"config error: unknown parameter [%s] %s: %s",section,var,val);
    exit(EXITLDERROR);
   }
  }
 }
 /* the last section should be checked, too */
 if(strlen(section) != 0){
  confcheck(section);
 }
 
 fclose(f);
 free(fname);
}


syntax highlighted by Code2HTML, v. 0.9.1