configfile.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002  secwatch - Copyright (C) 2006 Nic Stevens -- See COPYING for license details
00003 ------------------------------------------------------------------------------
00004  configfile.c - load configuration data from specified file and provide
00005  functions to return config vars in various formats.
00006 -----------------------------------------------------------------------------*/
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <errno.h>
00011 #include <syslog.h>
00012 #include "log.h"
00013 #include "strutil.h"
00014 #include "module.h"
00015 #define CONFIG_DECL
00016 #include "configfile.h"
00017 
00023 int confVarInt(char *name, int *eptr) {
00024      int i;
00025      *eptr = 0;
00026      for(i = 0; config[i].name != NULL; i++) {
00027           if(strcmp(config[i].name,name) == 0) {
00028                if(config[i].type != ci_integer) {
00029                     *eptr = EINVAL;
00030                     return -1;
00031                }
00032                return config[i].val.i;
00033           }
00034      }
00035      *eptr = ENOENT;
00036      return -1;
00037 }
00043 int confVarBool(char *name, int *eptr) {
00044      int i;
00045      *eptr = 0;
00046      for(i = 0; config[i].name != NULL; i++) {
00047           if(strcmp(config[i].name,name) == 0) {
00048                if(config[i].type != ci_boolean) {
00049                     *eptr = EINVAL;
00050                     return -1;
00051                }
00052                return config[i].val.i;
00053           }
00054      }
00055      *eptr = ENOENT;
00056      return -1;
00057 }
00063 int confVarSyslog(char *name, int *eptr) {
00064      int i;
00065      *eptr = 0;
00066      for(i = 0; config[i].name != NULL; i++) {
00067           if(strcmp(config[i].name,name) == 0) {
00068                if(config[i].type == ci_logpri || config[i].type == ci_logfac) 
00069                     return config[i].val.i;
00070                *eptr = EINVAL;
00071                return -1;
00072           }
00073      }
00074      *eptr = ENOENT;
00075      return -1;
00076 }
00081 char * confVarText(char *name, int *eptr) {
00082      int i;
00083      *eptr = 0;
00084      for(i = 0; config[i].name != NULL; i++) {
00085           if(strcmp(config[i].name,name) == 0) {
00086                if(config[i].type != ci_text) {
00087                     *eptr = EINVAL;
00088                     return NULL;
00089                }
00090                return config[i].val.s;
00091           }
00092      }
00093      *eptr = ENOENT;
00094      return NULL;
00095 }
00100 char * confVarPath(char *name, int *eptr) {
00101      int i;
00102      *eptr = 0;
00103      for(i = 0; config[i].name != NULL; i++) {
00104           if(strcmp(config[i].name,name) == 0) {
00105                if(config[i].type != ci_pathname) {
00106                     *eptr = EINVAL;
00107                     return NULL;
00108                }
00109                return config[i].val.s;
00110           }
00111      }
00112      *eptr = ENOENT;
00113      return NULL;
00114 }
00119 char ** confVarFlist(char *name, int *eptr) {
00120      int i;
00121      *eptr = 0;
00122      for(i = 0; config[i].name != NULL; i++) {
00123           if(strcmp(config[i].name,name) == 0) {
00124                if(config[i].type != ci_flist) {
00125                     *eptr = EINVAL;
00126                     return NULL;
00127                }
00128                return config[i].val.a;
00129           }
00130      }
00131      *eptr = ENOENT;
00132      return NULL;
00133 }
00139 char *fixupPathName(char *val, char  *path) {
00140      size_t sz;
00141      char *tb, *tb1 = "", *tb2 = "/", tmp[2049];
00142 
00143      if(*val == '/')
00144           return val;
00145 
00146      if(path[strlen(path)-1] != '/')
00147           tb = tb2;
00148      else
00149           tb = tb1;
00150 
00151      sprintf(tmp,"%s%s%s",path,tb,val);
00152      sz = strlen(tmp)+5;
00153      if((val = realloc(val,sz)) == NULL)
00154           return NULL;
00155      strcpy(val,tmp);
00156      return val;
00157 }
00162 int getBooleanValue(char *s, int *v) {
00163      LOCAL char * bools[2][3] = {{"false","off","no"},{"true","on","yes"}};
00164      int i, j;
00165      *v = -1;
00166      for(i = 0; i < 2; i++) { 
00167           for(j = 0; j < 3; j++) {
00168                if(strcasecmp(s,bools[i][j]) == 0) {
00169                     *v = i;
00170                     return 0;
00171                }
00172           }
00173      }
00174      return -1;
00175 }
00180 LOCAL cfgitem_t *  _configTabEntry(char *name) {
00181      int i;
00182      for (i = 0; config[i].name != NULL; i++) {
00183           if(strcmp(config[i].name,name) == 0) {
00184                return &config[i];
00185           }
00186      }
00187      errno = ENOENT;
00188      return NULL;
00189 }
00194 int readConfig(char *file, char *ebuf, size_t ebsiz) {
00195      char buf[1024], _name[1024], _val[1024], *name, *val;
00196      char cbuf[1024];
00197      char *p, *ep, *p1;
00198      int i, line = 0;
00199      cfgitem_t *c;
00200      FILE *f;
00201      
00202      if((f = fopen(file,"r")) == NULL) {
00203           snprintf(ebuf,ebsiz,"%s(%d) Cannot open config file \"%s\": %m",file,line,file);
00204           return -1;
00205      }
00206      while((p = fgets(buf,sizeof(buf)-1,f)) != NULL) {
00207           line++;
00208           if(*p == '#') continue;
00209           if((p = strchr(buf,'#')) != NULL)
00210                *p = '\0';
00211           if((p = strchr(buf,'=')) == NULL)
00212                continue;
00213           *p++  = '\0';
00214           strcpy(_name,buf);
00215           strcpy(_val,p);
00216           name = trim(_name);
00217           val = trim(_val);
00218           if(strcmp(name,"loadmodule") == 0) {
00219                if(loadModule(val,cbuf,sizeof(cbuf))) {
00220                     snprintf(ebuf,ebsiz,"%s(%d): Error loading module: %s",file,line,cbuf);
00221                     return -1;
00222                }
00223                printf("module %s loaded\n",val);
00224                continue;
00225           }
00226           if((c = _configTabEntry(name)) == NULL) {
00227                snprintf(ebuf,ebsiz,"%s(%d): invalid configuration item %s",file,line,name);
00228                fclose(f);
00229                return -1;
00230           }
00231           switch(c->type) {
00232           case ci_pathname:
00233                if((c->val.s = strdup(val)) == NULL) {
00234                     snprintf(ebuf,ebsiz,"%s(%d): Could not alloc space for %s: %m",file,line,name);
00235                     fclose(f);
00236                     return -1;
00237                }
00238                break;
00239           case ci_integer:
00240                c->val.i = atoi(val);
00241                break;
00242           case ci_boolean:
00243                if(getBooleanValue(val,&c->val.i)) {
00244                     snprintf(ebuf,ebsiz,"%s(%d): Cannot evaluate boolen from %s",file,line,val);
00245                     return -1;
00246                }
00247                break;
00248           case ci_text:
00249                if((c->val.s = strdup(val)) == NULL) {
00250                     snprintf(ebuf,ebsiz,"%s(%d): Could not alloc space for %s: %m",file,line,name);
00251                     fclose(f);
00252                     return -1;
00253                }
00254                break;
00255           case ci_logpri:
00256                if((c->val.i = sysLogPri(val)) == -1) {
00257                     snprintf(ebuf,ebsiz,"%s(%d): Cannot parse log priority from \"%s\"\n",file,line,val);
00258                     return -1;
00259                }
00260                break;
00261           case ci_logfac:
00262                if((c->val.i = sysLogFac(val)) == -1) {
00263                     snprintf(ebuf,ebsiz,"%s(%d): Cannot parse log facility from \"%s\"\n",file,line,val);
00264                     return -1;
00265                }
00266                break;
00267           case ci_flist:
00268                if((c->val.a = split(",",trim(val))) == NULL) {
00269                     snprintf(ebuf,ebsiz,"%s(%d): Cannot split flist \"%s\": %m",file,line,name);
00270                     return -1;
00271                }
00272                break;
00273           }
00274      }
00275      fclose(f);
00276      return 0;
00277 }
00278 
00279 void dumpConfig() {
00280      int i, j;
00281      char *types[] = {"ci_pathname","ci_integer","ci_boolean","ci_logpri","ci_logfac","ci_text","ci_flist"};
00282      printf(">> Configuration Dump <<\n");
00283      for(i = 0; config[i].name != NULL; i++) {
00284           printf("%-15.15s\t%-15.15s\t",
00285                  config[i].name,types[config[i].type]);
00286           switch(config[i].type) {
00287           case ci_pathname:
00288           case ci_text:
00289                printf("%s",(config[i].val.s) ? config[i].val.s : "null");
00290                break;
00291           case ci_logfac:
00292                printf("%s",sysLogFacId(config[i].val.i));
00293                break;
00294           case ci_logpri:
00295                printf("%s",sysLogPriId(config[i].val.i));
00296                break;
00297           case ci_integer:
00298                printf("%d",config[i].val.i);
00299                break;
00300           case ci_boolean:
00301                printf("%s",(config[i].val.i) ? "true" : "false");
00302                break;
00303           case ci_flist:
00304                for(j = 0; config[i].val.a[j] != NULL; j++) {
00305                     if(config[i].val.a[j+1] == NULL)
00306                          printf("%s",config[i].val.a[j]);
00307                     else
00308                          printf("%s,",config[i].val.a[j]);
00309                }
00310                break;
00311           default:
00312                printf("unknown type %d\n",config[i].type);
00313                break;
00314           }
00315           printf("\n");
00316      }
00317 }

Generated on Tue Oct 31 10:17:23 2006 for secwatch by  doxygen 1.4.6