From 3d27be7405da0b2de2e5efbfeef322e5376d2fb0 Mon Sep 17 00:00:00 2001 From: Ron Pedde Date: Wed, 8 Feb 2006 23:02:43 +0000 Subject: [PATCH] More incremental config changes --- src/{config.c => conf.c} | 102 ++++++++++++++++++++++++++++++++++----- src/{config.h => conf.h} | 9 ++-- src/config-driver.c | 15 ++++-- src/config.mk | 4 +- src/ll.c | 64 +++++++++++++++++++++--- src/ll.h | 4 +- 6 files changed, 169 insertions(+), 29 deletions(-) rename src/{config.c => conf.c} (52%) rename src/{config.h => conf.h} (87%) diff --git a/src/config.c b/src/conf.c similarity index 52% rename from src/config.c rename to src/conf.c index 845ae3e1..f5641c8d 100644 --- a/src/config.c +++ b/src/conf.c @@ -32,18 +32,75 @@ #include +#include "conf.h" #include "err.h" #include "ll.h" #include "daapd.h" /** Globals */ -int ecode; -LL_HANDLE config_main=NULL; +static int ecode; +static LL_HANDLE config_main=NULL; #define CONFIG_LINEBUFFER 128 +#define CONF_T_INT 0 +#define CONF_T_STRING 1 + +/** Forwards */ +static int _ll_verify(LL_HANDLE pll); + + + +typedef struct _CONF_ELEMENTS { + int required; + int deprecated; + int type; + char *section; + char *term; +} CONF_ELEMENTS; + +static CONF_ELEMENTS conf_elements[] = { + { 1, 0, CONF_T_STRING,"general","runas" }, + { 1, 0, CONF_T_STRING,"general","web_root" }, + { 1, 0, CONF_T_INT,"general","port" }, + { 1, 0, CONF_T_STRING,"general","admin_pw" }, + { 1, 0, CONF_T_STRING,"general","mp3_dir" }, + { 0, 1, CONF_T_STRING,"general","db_dir" }, + { 0, 0, CONF_T_STRING,"general","db_type" }, + { 0, 0, CONF_T_STRING,"general","db_parms" }, + { 0, 0, CONF_T_INT,"general","debuglevel" }, + { 1, 0, CONF_T_STRING,"general","servername" }, + { 0, 0, CONF_T_INT,"general","rescan_interval" }, + { 0, 0, CONF_T_INT,"general","always_scan" }, + { 0, 1, CONF_T_INT,"general","latin1_tags" }, + { 0, 0, CONF_T_INT,"general","process_m3u" }, + { 0, 0, CONF_T_INT,"general","scan_type" }, + { 0, 1, CONF_T_INT,"general","compress" }, + { 0, 0, CONF_T_STRING,"general","playlist" }, + { 0, 0, CONF_T_STRING,"general","extensions" }, + { 0, 0, CONF_T_STRING,"general","interface" }, + { 0, 0, CONF_T_STRING,"general","ssc_codectypes" }, + { 0, 0, CONF_T_STRING,"general","ssc_prog" }, + { 0, 0, CONF_T_STRING,"general","password" }, + { 0, 0, CONF_T_STRING,"general","compdirs" }, + { 0, 0, CONF_T_STRING,"general","logfile" } +}; + /** - * read a configfile into a bag + * check a tree and make sure it doesn't have any obviously bad + * configuration information + * + * @param pll tree to check + */ +int _ll_verify(LL_HANDLE pll) { + + + return LL_E_SUCCESS; +} + + +/** + * read a configfile into a tree * * @param file file to read * @returns TRUE if successful, FALSE otherwise @@ -51,26 +108,30 @@ LL_HANDLE config_main=NULL; int config_read(char *file) { FILE *fin; int err; - LL_HANDLE pllnew, plltemp; + LL_HANDLE pllnew, plltemp, pllcurrent; char linebuffer[CONFIG_LINEBUFFER+1]; char *comment, *term, *value, *delim; int compat_mode=1; + int line=0; fin=fopen(file,"r"); if(!fin) { - return CONFIG_E_FOPEN; + return CONF_E_FOPEN; } if((err=ll_create(&pllnew)) != LL_E_SUCCESS) { DPRINTF(E_LOG,L_CONF,"Error creating linked list: %d\n",err); fclose(fin); - return CONFIG_E_UNKNOWN; + return CONF_E_UNKNOWN; } + pllcurrent=NULL; + /* got what will be the root of the config tree, now start walking through * the input file, populating the tree */ while(fgets(linebuffer,CONFIG_LINEBUFFER,fin)) { + line++; linebuffer[CONFIG_LINEBUFFER] = '\0'; comment=strchr(linebuffer,'#'); @@ -90,17 +151,18 @@ int config_read(char *file) { if(!value) { ll_destroy(pllnew); fclose(fin); - return CONFIG_E_BADHEADER; + return CONF_E_BADHEADER; } *value = '\0'; if((err = ll_create(&plltemp)) != LL_E_SUCCESS) { ll_destroy(pllnew); fclose(fin); - return CONFIG_E_UNKNOWN; + return CONF_E_UNKNOWN; } ll_add_ll(pllnew,term,plltemp); + pllcurrent = plltemp; } else { /* k/v pair */ term=&linebuffer[0]; @@ -121,7 +183,23 @@ int config_read(char *file) { while(strlen(value) && (strchr("\t ",*value))) value++; - ll_add_string(pllnew,term,value); + if(!pllcurrent) { + /* we are definately in compat mode -- add a general section */ + if((err=ll_create(&plltemp)) != LL_E_SUCCESS) { + DPRINTF(E_LOG,L_CONF,"Error creating linked list: %d\n",err); + ll_destroy(pllnew); + fclose(fin); + return CONF_E_UNKNOWN; + } + ll_add_ll(pllnew,"general",plltemp); + pllcurrent = plltemp; + } + ll_add_string(pllcurrent,term,value); + } + if(((term) && (strlen(term))) && (!value)) { + DPRINTF(E_LOG,L_CONF,"Error in config file on line %d\n",line); + ll_destroy(pllnew); + return CONF_E_PARSE; } } } @@ -129,16 +207,18 @@ int config_read(char *file) { fclose(fin); /* Sanity check */ + _ll_verify(pllnew); + ll_dump(pllnew); ll_destroy(pllnew); - return CONFIG_E_SUCCESS; + return CONF_E_SUCCESS; } int config_close(void) { if(config_main) ll_destroy(config_main); - return CONFIG_E_SUCCESS; + return CONF_E_SUCCESS; } diff --git a/src/config.h b/src/conf.h similarity index 87% rename from src/config.h rename to src/conf.h index 455f8a57..79878e02 100644 --- a/src/config.h +++ b/src/conf.h @@ -22,10 +22,11 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -#define CONFIG_E_SUCCESS 0 -#define CONFIG_E_FOPEN 1 -#define CONFIG_E_UNKNOWN 2 -#define CONFIG_E_BADHEADER 3 +#define CONF_E_SUCCESS 0 +#define CONF_E_FOPEN 1 +#define CONF_E_UNKNOWN 2 +#define CONF_E_BADHEADER 3 +#define CONF_E_PARSE 4 extern int config_read(char *file); diff --git a/src/config-driver.c b/src/config-driver.c index 95e1ba87..690fab7c 100644 --- a/src/config-driver.c +++ b/src/config-driver.c @@ -4,13 +4,20 @@ #include -#include "config.h" +#include "conf.h" +#include "err.h" int main(int argc, char *argv[]) { - if(config_read(argv[1]) != CONFIG_E_SUCCESS) { - printf("Read config!\n"); + int err; + + err_debuglevel = 9; + + printf("Reading %s\n",argv[1]); + + if((err=config_read(argv[1])) != CONF_E_SUCCESS) { + printf("Error reading config: %d\n",err); } else { - printf("Error reading config\n"); + printf("Read config!\n"); } config_close(); } diff --git a/src/config.mk b/src/config.mk index b8b48699..8d414c87 100644 --- a/src/config.mk +++ b/src/config.mk @@ -2,8 +2,8 @@ CC=gcc CFLAGS := $(CFLAGS) -g -DHAVE_CONFIG_H -I. -I.. LDFLAGS := $(LDFLAGS) -TARGET = config -OBJECTS=config-driver.o config.o ll.o +TARGET = conf +OBJECTS=config-driver.o conf.o ll.o err.o $(TARGET): $(OBJECTS) $(CC) -o $(TARGET) $(LDFLAGS) $(OBJECTS) diff --git a/src/ll.c b/src/ll.c index 945e6cd3..5afc0e1d 100644 --- a/src/ll.c +++ b/src/ll.c @@ -34,6 +34,7 @@ /** Internal functions */ int _ll_add_item(LL *pl, char *key, void *vpval, int ival, int type); +void _ll_dump(LL *pl, int depth); /** * create a ll @@ -47,6 +48,9 @@ int ll_create(LL **ppl) { return LL_E_MALLOC; memset(*ppl,0x0,sizeof(struct _LL)); + + /* set default flags */ + (*ppl)->flags = LL_FLAG_NODUPS | LL_FLAG_INHERIT; return LL_E_SUCCESS; } @@ -88,7 +92,7 @@ int ll_destroy(LL *pl) { * thin wrapper for _ll_add_item */ int ll_add_string(LL *pl, char *key, char *cval) { - return _ll_add_item(pl,cval,key,0,LL_TYPE_STRING); + return _ll_add_item(pl,key,cval,0,LL_TYPE_STRING); } /** @@ -102,7 +106,15 @@ int ll_add_int(LL *pl, char *key, int ival) { * thin wrapper for _ll_add_item */ int ll_add_ll(LL *pl, char *key, LL *pnew) { - return _ll_add_item(pl,key,(void*)pnew,0,LL_TYPE_LL); + int result; + + result = _ll_add_item(pl,key,(void*)pnew,0,LL_TYPE_LL); + if(result == LL_E_SUCCESS) { + if(pl->flags & LL_FLAG_INHERIT) { + pnew->flags = pl->flags; + } + } + return result; } /** @@ -111,6 +123,11 @@ int ll_add_ll(LL *pl, char *key, LL *pnew) { int _ll_add_item(LL *pl, char *key, void* vpval, int ival, int type) { LL_ITEM *pli; + if(pl->flags & LL_FLAG_NODUPS) { + if(ll_fetch_item(pl,key)) + return LL_E_DUP; + } + pli=(LL_ITEM *)malloc(sizeof(LL_ITEM)); if(!pli) { return LL_E_MALLOC; @@ -138,7 +155,11 @@ int _ll_add_item(LL *pl, char *key, void* vpval, int ival, int type) { pl->itemlist.next = pli; } else { pli->next = NULL; - pl->tailptr->next = pli; + if(pl->tailptr) { + pl->tailptr->next = pli; + } else { + pl->itemlist.next = pli; + } pl->tailptr = pli; } @@ -160,10 +181,11 @@ LL_ITEM *ll_fetch_item(LL *pl, char *key) { current = pl->itemlist.next; while(current) { if(pl->flags & LL_FLAG_HONORCASE) { - if(!strcasecmp(current->key,key)) - break; if(!strcmp(current->key,key)) - break; + return current; + } else { + if(!strcasecmp(current->key,key)) + return current; } current = current->next; } @@ -198,7 +220,35 @@ int ll_get_flags(LL *pl, unsigned int *flags) { * * @parm pl linked list to dump */ -extern void ll_dump(LL *pl) { +void ll_dump(LL *pl) { + _ll_dump(pl,0); } +/** + * Internal support function for dumping linked list that + * carries depth. + * + * @param pl linked list to dump + * @param depth depth of list + */ + +void _ll_dump(LL *pl, int depth) { + LL_ITEM *pli; + pli = pl->itemlist.next; + while(pli) { + switch(pli->type) { + case LL_TYPE_INT: + printf("%*s%s (int): %d\n",depth*2,"",pli->key,pli->value.as_int); + break; + case LL_TYPE_STRING: + printf("%*s%s (string): %s\n",depth*2,"",pli->key,pli->value.as_string); + break; + case LL_TYPE_LL: + printf("%*s%s (list)\n",depth*2,"",pli->key); + _ll_dump(pli->value.as_ll,depth+1); + break; + } + pli = pli->next; + } +} diff --git a/src/ll.h b/src/ll.h index 319303cb..10b8a7d2 100644 --- a/src/ll.h +++ b/src/ll.h @@ -30,10 +30,12 @@ #define LL_E_SUCCESS 0 #define LL_E_MALLOC 1 #define LL_E_NOKEY 2 +#define LL_E_DUP 3 #define LL_FLAG_HONORCASE 1 /** Make keys case sensitive */ #define LL_FLAG_HEADINSERT 2 /** Insert at head, rather than tail */ - +#define LL_FLAG_NODUPS 4 /** Do not allow duplicates */ +#define LL_FLAG_INHERIT 8 /** Set child flags based on parent flags */ typedef struct _LLITEM { int type;