diff --git a/src/conf.c b/src/conf.c index a311021e..4a708923 100644 --- a/src/conf.c +++ b/src/conf.c @@ -48,6 +48,8 @@ #include "ll.h" #include "daapd.h" #include "os.h" +#include "webserver.h" +#include "xml-rpc.h" /** Globals */ //static int ecode; @@ -84,6 +86,7 @@ static int _conf_makedir(char *path, char *user); static int _conf_existdir(char *path); static int _conf_split(char *s, char *delimiters, char ***argvp); static void _conf_dispose_split(char **argv); +static int _conf_xml_dump(XMLSTRUCT *pxml,LL *pll,int sublevel,char *parent); static CONF_ELEMENTS conf_elements[] = { { 1, 0, CONF_T_STRING,"general","runas" }, @@ -1209,3 +1212,85 @@ void conf_dispose_array(char **argv) { index++; } } + +/* FIXME: this belongs in xml-rpc, but need config enumerating fns */ + +/** + * dump the config to xml + * + * @param pwsc web connection to dump to + * @returns TRUE on success, FALSE otherwise + */ +int conf_xml_dump(WS_CONNINFO *pwsc) { + XMLSTRUCT *pxml; + int retval; + + if(!conf_main_file) { + return FALSE; /* CONF_E_NOCONF */ + } + + pxml = xml_init(pwsc,1); + xml_push(pxml,"config"); + + _conf_lock(); + + retval = _conf_xml_dump(pxml,conf_main,0,NULL); + + _conf_unlock(); + + xml_pop(pxml); + xml_deinit(pxml); + + return retval; +} + +/** + * do the actual work of dumping the config file + * + * @param pwsc web connection we are writing the config file to + * @param pll list we are dumping k/v pairs for + * @param sublevel whether this is the root, or a subkey + * @returns TRUE on success, FALSE otherwise + */ +int _conf_xml_dump(XMLSTRUCT *pxml, LL *pll, int sublevel, char *parent) { + LL_ITEM *pli; + LL_ITEM *plitemp; + + if(!pll) + return TRUE; + + /* write all the solo keys, first! */ + pli = pll->itemlist.next; + while(pli) { + switch(pli->type) { + case LL_TYPE_LL: + if(sublevel) { + /* must be multivalued */ + plitemp = NULL; + xml_push(pxml,"array"); + while((plitemp = ll_get_next(pli->value.as_ll,plitemp))) { + xml_output(pxml,pli->key,"%s",plitemp->value.as_string); + } + xml_pop(pxml); + } else { + xml_push(pxml,pli->key); + if(!_conf_xml_dump(pxml, pli->value.as_ll, 1, pli->key)) + return FALSE; + xml_pop(pxml); + } + break; + + case LL_TYPE_INT: + xml_output(pxml,pli->key,"%d",pli->value.as_int); + break; + + case LL_TYPE_STRING: + xml_output(pxml,pli->key,"%s",pli->value.as_string); + break; + } + + pli = pli->next; + } + + return TRUE; +} diff --git a/src/conf.h b/src/conf.h index 5ab32321..d3c43600 100644 --- a/src/conf.h +++ b/src/conf.h @@ -48,4 +48,9 @@ extern int conf_write(void); extern char *conf_implode(char *section, char *key, char *delimiter); extern int conf_get_array(char *section, char *key, char ***argvp); extern void conf_dispose_array(char **argv); + +/* FIXME: get enum functions and move to xml-rpc */ +#include "webserver.h" +extern int conf_xml_dump(WS_CONNINFO *pwsc); + #endif /* _CONFIG_H_ */ diff --git a/src/xml-rpc.c b/src/xml-rpc.c index 1f7919c9..7c07ebb4 100644 --- a/src/xml-rpc.c +++ b/src/xml-rpc.c @@ -15,12 +15,14 @@ #include #include "configfile.h" +#include "conf.h" #include "db-generic.h" #include "daapd.h" #include "err.h" #include "mp3-scanner.h" #include "rend.h" #include "webserver.h" +#include "xml-rpc.h" /* typedefs */ typedef struct tag_xmlstack { @@ -28,22 +30,16 @@ typedef struct tag_xmlstack { struct tag_xmlstack *next; } XMLSTACK; -typedef struct tag_xmlstruct { +struct tag_xmlstruct { WS_CONNINFO *pwsc; int stack_level; XMLSTACK stack; -} XMLSTRUCT; +}; /* Forwards */ void xml_get_stats(WS_CONNINFO *pwsc); char *xml_entity_encode(char *original); -XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header); -void xml_push(XMLSTRUCT *pxml, char *term); -void xml_pop(XMLSTRUCT *pxml); -void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...); -void xml_deinit(XMLSTRUCT *pxml); - /** * create an xml response structure, a helper struct for * building xml responses. @@ -183,6 +179,11 @@ void xml_handle(WS_CONNINFO *pwsc) { return; } + if(strcasecmp(method,"config") == 0) { + conf_xml_dump(pwsc); + return; + } + ws_returnerror(pwsc,500,"Invalid method"); return; } diff --git a/src/xml-rpc.h b/src/xml-rpc.h index 0b2b46eb..9d75d3a9 100644 --- a/src/xml-rpc.h +++ b/src/xml-rpc.h @@ -9,4 +9,14 @@ extern void xml_handle(WS_CONNINFO *pwsc); +struct tag_xmlstruct; +typedef struct tag_xmlstruct XMLSTRUCT; + +extern XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header); +extern void xml_push(XMLSTRUCT *pxml, char *term); +extern void xml_pop(XMLSTRUCT *pxml); +extern void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...); +extern void xml_deinit(XMLSTRUCT *pxml); + + #endif /* _XMLRPC_H_ */