2 * Sherlock Library -- Reading configuration files
4 * (c) 2001 Robert Spalek <robert@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
18 #include "lib/chartype.h"
19 #include "lib/fastbuf.h"
20 #include "lib/pools.h"
27 static struct cfitem *cfsection;
28 static struct mempool *cfpool;
30 byte *cfdeffile = DEFAULT_CONFIG;
32 static void CONSTRUCTOR
35 cfpool = mp_new(4096);
41 return mp_alloc(cfpool, size);
48 byte *k = cfg_malloc(l + 1);
53 void cf_register(struct cfitem *items)
55 if(items[0].type!=CT_SECTION && items[0].type!=CT_INCOMPLETE_SECTION)
56 die("cf_register: Invalid section type");
57 items[0].var=cfsection;
61 int cf_item_count(void)
63 struct cfitem *sect, *item;
65 for (sect = cfsection; sect; sect = sect->var)
66 for (item = sect+1; item->type; item++)
71 struct cfitem *cf_get_item(byte *sect, byte *name)
73 struct cfitem *item, *section;
76 while(item && strcasecmp(item->name,sect))
78 if(!item) /* unknown section */
82 for(item++; item->type && strcasecmp(item->name,name); item++);
83 if (!item->type && section->type == CT_INCOMPLETE_SECTION)
86 return item; /* item->type == 0 if not found */
89 byte *cf_set_item(byte *sect, byte *name, byte *value)
95 return "Empty section name";
96 item=cf_get_item(sect,name);
97 if(!item) /* ignore unknown section */
105 msg="Missing number";
107 *((uns *) item->var) = strtoul(value, &end, 0);
109 msg = "Invalid number";
114 *((byte **) item->var) = cfg_stralloc(value);
117 msg = ((ci_func) item->var)(item, cfg_stralloc(value));
120 msg = "Unknown keyword";
127 static int cf_subread(byte *filename,int level)
131 byte def_section[BUFFER];
135 if(level>=MAX_LEVEL){
136 log(L_ERROR,"Too many (%d) nested files when reading %s",level,filename);
140 fd=open(filename,O_RDONLY, 0666);
142 log(L_ERROR,"Cannot open configuration file %s: %m",filename);
153 if(!bgets(b,buf,BUFFER))
158 while(c>buf && Cspace(c[-1]))
161 while(*c && Cspace(*c))
167 strcpy(def_section,c+1);
168 c=strchr(def_section,']');
172 msg="Garbage after ]";
181 byte *sect,*name,*value;
184 while(*c && !Cspace(*c))
186 while(*c && Cspace(*c))
190 if(!strcasecmp(name,"include")){
191 if(!cf_subread(value,level+1)){
192 msg="Included from here";
205 msg=cf_set_item(sect,name,value);
211 } /* for every line */
214 log(L_ERROR,"%s, line %d: %s",filename,line,msg);
219 void cf_read(byte *filename)
221 if(!cf_subread(filename,0))
222 die("Reading config file %s failed",filename);
226 int cf_getopt(int argc,char * const argv[],
227 const char *shortopts,const struct option *longopts,
233 res=getopt_long(argc,argv,shortopts,longopts,longindex);
235 byte *sect,*name,*value;
242 msg="Missing argument";
259 msg=cf_set_item(sect,name,value);
262 die("Invalid command line argument %s.%s=%s: %s",sect,name,value,msg);
267 /* unhandled option or end of options */