X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fconf.c;h=50c3511a293d5a83ffd2f8a20c82c692426609dd;hb=e23b57dd8b0ac4da53451625be99ca1fa75caa48;hp=c2e5f1b4fa14dd3599b5c405d2cdeded05a95049;hpb=eb3d130d22a4235cbfc8fd547e4e303780149752;p=libucw.git diff --git a/lib/conf.c b/lib/conf.c index c2e5f1b4..50c3511a 100644 --- a/lib/conf.c +++ b/lib/conf.c @@ -1,8 +1,8 @@ /* - * Sherlock Library -- Reading of configuration files + * UCW Library -- Reading of configuration files * * (c) 2001 Robert Spalek - * (c) 2003 Martin Mares + * (c) 2003--2005 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -11,7 +11,7 @@ #include "lib/lib.h" #include "lib/chartype.h" #include "lib/fastbuf.h" -#include "lib/pools.h" +#include "lib/mempool.h" #include "lib/conf.h" @@ -28,6 +28,10 @@ static struct cfitem *cfsection; struct mempool *cfpool; +#ifndef DEFAULT_CONFIG +#define DEFAULT_CONFIG NULL +#endif + byte *cfdeffile = DEFAULT_CONFIG; static void CONSTRUCTOR @@ -42,13 +46,26 @@ cfg_malloc(uns size) return mp_alloc(cfpool, size); } +void * +cfg_malloc_zero(uns size) +{ + return mp_alloc_zero(cfpool, size); +} + byte * -cfg_stralloc(byte *s) +cfg_strdup(byte *s) { - uns l = strlen(s); - byte *k = cfg_malloc(l + 1); - strcpy(k, s); - return k; + return mp_strdup(cfpool, s); +} + +byte * +cfg_printf(char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + byte *res = mp_vprintf(cfpool, fmt, args); + va_end(args); + return res; } void cf_register(struct cfitem *items) @@ -94,7 +111,7 @@ struct unit { static const struct unit units[] = { { 'd', 86400, 1 }, - { 'h', 1440, 1 }, + { 'h', 3600, 1 }, { 'k', 1000, 1 }, { 'm', 1000000, 1 }, { 'g', 1000000000, 1 }, @@ -105,6 +122,7 @@ static const struct unit units[] = { { 0, 0, 0 } }; +#if 0 static const struct unit *cf_lookup_unit(byte *value, byte *end, char **msg) { if (end && *end) { @@ -201,6 +219,46 @@ byte *cf_parse_double(byte *value, double *varp) return msg; } +byte * +cf_parse_ip(byte **p, u32 *varp) +{ + while (Cspace(**p)) + (*p)++; + if (!**p) + return "Missing IP address"; + uns x = 0; + if (**p == '0' && *(*p + 1) | 32 == 'X') + { + errno = 0; + x = strtoul(*p + 2, (char **)p, 16); + if (errno == ERANGE || x > 0xffffffff) + goto error; + } + else + for (uns i = 0; i < 4; i++) + { + if (i) + { + while (Cspace(**p)) + (*p)++; + if (*(*p)++ != '.') + goto error; + } + while (Cspace(**p)) + (*p)++; + errno = 0; + uns y = strtoul(*p, (char **)p, 10); + if (errno == ERANGE || y > 255) + goto error; + x = (x << 8) + y; + } + *varp = x; + return NULL; +error: + return "Invalid IP address"; +} +#endif + byte *cf_set_item(byte *sect, byte *name, byte *value) { struct cfitem *item; @@ -217,10 +275,10 @@ byte *cf_set_item(byte *sect, byte *name, byte *value) msg = cf_parse_int(value, (uns *) item->var); break; case CT_STRING: - *((byte **) item->var) = cfg_stralloc(value); + *((byte **) item->var) = cfg_strdup(value); break; case CT_FUNCTION: - msg = ((ci_func) item->var)(item, cfg_stralloc(value)); + msg = ((ci_func) item->var)(item, cfg_strdup(value)); break; case CT_DOUBLE: msg = cf_parse_double(value, (double *) item->var); @@ -334,50 +392,63 @@ void cf_read(byte *filename) cfdeffile = NULL; } +static void cf_opt_S(void) +{ + byte *sect,*name,*value; + byte *c; + byte *msg=NULL; + byte arg[strlen(optarg)+1]; + + strcpy(arg, optarg); + name = arg; + c=strchr(name,'='); + if(!c){ + msg="Missing argument"; + sect=value=""; + }else{ + *c++=0; + value=c; + + c=strchr(name,'.'); + if(!c) + sect=""; + else{ + sect=name; + *c++=0; + name=c; + } + + if (cfdeffile) + cf_read(cfdeffile); + msg=cf_set_item(sect,name,value); + } + if(msg) + die("Invalid command line argument -S%s.%s=%s: %s",sect,name,value,msg); + +} + int cf_getopt(int argc,char * const argv[], const char *shortopts,const struct option *longopts, int *longindex) { int res; + static int other_options; do{ res=getopt_long(argc,argv,shortopts,longopts,longindex); + if(res == 'S' || res == 'C') { + if(other_options) + die("The -S and -C options must precede all other arguments"); + } if(res=='S'){ - byte *sect,*name,*value; - byte *c; - byte *msg=NULL; - - name=optarg; - c=strchr(name,'='); - if(!c){ - msg="Missing argument"; - sect=value=""; - }else{ - *c++=0; - value=c; - - c=strchr(name,'.'); - if(!c) - sect=""; - else{ - sect=name; - *c++=0; - name=c; - } - - if (cfdeffile) - cf_read(cfdeffile); - msg=cf_set_item(sect,name,value); - } - if(msg) - die("Invalid command line argument %s.%s=%s: %s",sect,name,value,msg); - + cf_opt_S(); }else if(res=='C'){ cf_read(optarg); }else{ /* unhandled option or end of options */ if(cfdeffile) cf_read(cfdeffile); + other_options++; return res; } }while(1);