00001
00002
00003
00004
00005
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 }