# HG changeset patch # User Mike Becker # Date 1479472760 -3600 # Node ID d7c4ba50b7d8422bc0515591e8b4b71b1ed71a64 # Parent 1d2be1b31e707b0f0b4a1076089d062639278313 implements xmlErrorFunc for dav sync + adds line numbers to error reporting in both config checkers diff -r 1d2be1b31e70 -r d7c4ba50b7d8 dav/config.c --- a/dav/config.c Mon Nov 14 19:02:40 2016 +0100 +++ b/dav/config.c Fri Nov 18 13:39:20 2016 +0100 @@ -41,13 +41,17 @@ #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) #define xstrEQ(a,b) !xmlStrcasecmp(BAD_CAST a, BAD_CAST b) -#define print_error(...) \ +#define print_error(lineno, ...) \ do {\ - fprintf(stderr, "Error (config.xml): " __VA_ARGS__); \ + fprintf(stderr, "Error (config.xml line %u): ", lineno); \ + fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "Abort.\n"); \ } while(0); -#define print_warning(...) \ - fprintf(stderr, "Warning (config.xml): " __VA_ARGS__); +#define print_warning(lineno, ...) \ + do {\ + fprintf(stderr, "Warning (config.xml line %u): ", lineno); \ + fprintf(stderr, __VA_ARGS__); \ + } while(0); #ifdef _WIN32 #define ENV_HOME getenv("USERPROFILE") @@ -182,45 +186,17 @@ return repo; } -int load_repository(xmlNode *reponode) { - Repository *repo = repository_new(); - { - xmlNode *node = reponode->children; - int ret = 0; - while(node && !ret) { - if(node->type == XML_ELEMENT_NODE) { - char *name = (char*)node->name; - char *value = util_xml_get_text(node); - ret = repo_add_config(repo, name, value); - } - node = node->next; - } - if(ret) { - free(repo); - return 1; - } - } - - if(!repo->name) { - print_error("missing name for repository.\n"); - return 1; - } - if(!repo->url) { - print_error("missing url for repository '%s'.\n", repo->name); - return 1; - } - - ucx_map_cstr_put(repos, repo->name, repo); - return 0; -} +static int repo_add_config(Repository *repo, const xmlNode* node) { + unsigned short lineno = node->line; + char *key = (char*)node->name; + char *value = util_xml_get_text(node); -int repo_add_config(Repository *repo, char *key, char *value) { /* every key needs a value */ if(!value) { /* TODO: maybe this should only be reported, if the key is valid * But this makes the code very ugly. */ - print_error("missing value for config element: %s\n", key); + print_error(lineno, "missing value for config element: %s\n", key); return 1; } @@ -279,7 +255,7 @@ #endif #endif else { - print_warning("unknown ssl version: %s\n", value); + print_warning(lineno, "unknown ssl version: %s\n", value); } } else if(xstreq(key, "authmethods")) { repo->authmethods = CURLAUTH_NONE; @@ -300,19 +276,51 @@ } else if(xstrEQ(value, "none")) { /* skip */ } else { - print_warning("unknown authentication method: %s\n", value); + print_warning(lineno, + "unknown authentication method: %s\n", value); } meth = strtok(NULL, delims); } free(meths); } else { - print_error("unkown repository config element: %s\n", key); + print_error(lineno, "unkown repository config element: %s\n", key); return 1; } return 0; } -int load_proxy(DavProxy *proxy, xmlNode *proxynode, int type) { +int load_repository(const xmlNode *reponode) { + Repository *repo = repository_new(); + { + xmlNode *node = reponode->children; + int ret = 0; + while(node && !ret) { + if(node->type == XML_ELEMENT_NODE) { + ret = repo_add_config(repo, node); + } + node = node->next; + } + if(ret) { + free(repo); + return 1; + } + } + + if(!repo->name) { + print_error(reponode->line, "missing name for repository.\n"); + return 1; + } + if(!repo->url) { + print_error(reponode->line, + "missing url for repository '%s'.\n", repo->name); + return 1; + } + + ucx_map_cstr_put(repos, repo->name, repo); + return 0; +} + +int load_proxy(DavProxy *proxy, const xmlNode *proxynode, int type) { const char *stype; if(type == HTTPS_PROXY) { stype = "https"; @@ -321,7 +329,8 @@ } if(!proxy) { - print_error("no memory reserved for %s proxy.\n", stype); + // no xml error - so report this directly via fprintf + fprintf(stderr, "no memory reserved for %s proxy.\n", stype); return 1; } @@ -348,13 +357,14 @@ proxy->no_proxy = strdup(value); } } else { - print_error("invalid element for proxy config: %s\n", - node->name); + print_error(node->line, + "invalid element for proxy config: %s\n", node->name); ret = 1; } if (reportmissingvalue) { - print_error("missing value for proxy configuration " - "element '%s'.\n", node->name); + print_error(node->line, + "missing value for proxy configuration element: %s\n", + node->name); ret = 1; } } @@ -362,14 +372,14 @@ } if(!ret && !proxy->url) { - print_error("missing url for %s proxy.\n", stype); + print_error(proxynode->line, "missing url for %s proxy.\n", stype); return 1; } return ret; } -int load_key(xmlNode *keynode) { +int load_key(const xmlNode *keynode) { xmlNode *node = keynode->children; Key *key = calloc(1, sizeof(Key)); key->type = KEY_AES256; @@ -389,7 +399,8 @@ key->data = key_data.ptr; key->length = key_data.length; } else { - print_error("cannot get key from file: %s\n", value); + print_error(node->line, + "cannot get key from file: %s\n", value); error = 1; } } else if(xstreq(node->name, "type")) { @@ -398,7 +409,7 @@ } else if(!strcmp(value, "aes256")) { key->type = KEY_AES256; } else { - print_error("unknown key type %s\n", value); + print_error(node->line, "unknown key type %s\n", value); error = 1; } } @@ -417,7 +428,7 @@ expected_length = 32; } if(key->length < expected_length) { - print_error("key %s is too small (%zu < %zu)\n", + print_error(keynode->line, "key %s is too small (%zu < %zu)\n", key->name, key->length, expected_length); diff -r 1d2be1b31e70 -r d7c4ba50b7d8 dav/config.h --- a/dav/config.h Mon Nov 14 19:02:40 2016 +0100 +++ b/dav/config.h Fri Nov 18 13:39:20 2016 +0100 @@ -69,15 +69,14 @@ int load_config(DavContext *ctx); void free_config(void); -int load_repository(xmlNode *reponode); -int load_key(xmlNode *keynode); -int load_proxy(DavProxy*, xmlNode *proxynode, int type); +int load_repository(const xmlNode *reponode); +int load_key(const xmlNode *keynode); +int load_proxy(DavProxy*, const xmlNode *proxynode, int type); sstr_t load_key_file(char *filename); Repository* repository_new(void); Repository* get_repository(sstr_t name); -int repo_add_config(Repository *repo, char *key, char *value); int get_repository_flags(Repository *repo); DavSession *repository_session(Repository *repo); Key* get_key(char *name); diff -r 1d2be1b31e70 -r d7c4ba50b7d8 dav/scfg.c --- a/dav/scfg.c Mon Nov 14 19:02:40 2016 +0100 +++ b/dav/scfg.c Fri Nov 18 13:39:20 2016 +0100 @@ -39,13 +39,17 @@ #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) -#define print_error(...) \ +#define print_error(lineno, ...) \ do {\ - fprintf(stderr, "Error (sync.xml): " __VA_ARGS__); \ + fprintf(stderr, "Error (sync.xml line %u): ", lineno); \ + fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "Abort.\n"); \ } while(0); -#define print_warning(...) \ - fprintf(stderr, "Warning (sync.xml): " __VA_ARGS__); +#define print_warning(lineno, ...) \ + do {\ + fprintf(stderr, "Warning (sync.xml line %u): ", lineno); \ + fprintf(stderr, __VA_ARGS__); \ + } while(0); #ifdef _WIN32 #define ENV_HOME getenv("USERPROFILE") @@ -106,7 +110,8 @@ if(xstreq(node->name, "directory")) { ret = scfg_load_directory(node); } else { - print_error("unknown config element: %s\n", node->name); + print_error(node->line, + "unknown config element: %s\n", node->name); ret = 1; } } @@ -118,17 +123,20 @@ return ret; } -static UcxList* add_regex_pattern(UcxList *list, char *value) { +static UcxList* add_regex_pattern(UcxList *list, char *value, + unsigned short xmlline) { regex_t *regex = malloc(sizeof(regex_t)); if (regcomp(regex, value, REG_EXTENDED|REG_NOSUB)) { - fprintf(stderr, "Invalid regular expression (%s) ... skipped\n", value); + print_warning(xmlline, + "Invalid regular expression (%s) ... skipped\n", value); return list; } else { return ucx_list_append(list, regex); } } -static int scfg_load_filter(xmlNode *node, UcxList **include, UcxList **exclude) { +static int scfg_load_filter(xmlNode *node, + UcxList **include, UcxList **exclude) { node = node->children; while(node) { @@ -136,18 +144,20 @@ char *value = util_xml_get_text(node); if(xstreq(node->name, "include")) { if(value) { - *include = add_regex_pattern(*include, value); + *include = add_regex_pattern(*include, value, node->line); } } else if(xstreq(node->name, "exclude")) { if(value) { - *exclude = add_regex_pattern(*exclude, value); + *exclude = add_regex_pattern(*exclude, value, node->line); } } else { - print_error("unknown filter config element: %s\n", node->name); + print_error(node->line, + "unknown filter config element: %s\n", node->name); return 1; } if(!value) { - print_error("missing value for filter: %s\n", node->name); + print_error(node->line, + "missing value for filter: %s\n", node->name); return 1; } } @@ -172,6 +182,7 @@ bool lockpull = false; bool lockpush = false; + unsigned short parentlineno = node->line; node = node->children; while(node) { if(node->type == XML_ELEMENT_NODE) { @@ -181,7 +192,8 @@ /* TODO: maybe this should only be reported, if the key is valid * But this makes the code very ugly. */ - print_error("missing value for directory element: %s\n", + print_error(node->line, + "missing value for directory element: %s\n", node->name); return 1; } @@ -206,7 +218,7 @@ if(util_strtoint(value, &i) && i >= 0) { max_retry = (int)i; } else { - print_warning("unsigned integer value " + print_warning(node->line, "unsigned integer value " "expected in element\n"); } } else if(xstreq(node->name, "backup-on-pull")) { @@ -216,8 +228,8 @@ } else if(xstreq(node->name, "lock-push")) { lockpush = util_getboolean(value); } else { - print_error("unknown directory config element: %s\n", - node->name); + print_error(node->line, + "unknown directory config element: %s\n", node->name); return 1; } } @@ -225,19 +237,22 @@ } if(!name) { - print_error("missing name element for directory\n"); + print_error(parentlineno, "missing name element for directory\n"); return 1; } if(!path) { - print_error("missing path element for directory %s\n", name); + print_error(parentlineno, + "missing path element for directory %s\n", name); return 1; } if(!repository) { - print_error("missing repository element for directory %s\n", name); + print_error(parentlineno, + "missing repository element for directory %s\n", name); return 1; } if(!database) { - print_error("missing database element for directory %s\n", name); + print_error(parentlineno, + "missing database element for directory %s\n", name); return 1; } diff -r 1d2be1b31e70 -r d7c4ba50b7d8 dav/sync.c --- a/dav/sync.c Mon Nov 14 19:02:40 2016 +0100 +++ b/dav/sync.c Fri Nov 18 13:39:20 2016 +0100 @@ -55,7 +55,10 @@ static DavContext *ctx; static void xmlerrorfnc(void * c, const char * msg, ... ) { - // nothing + va_list ap; + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); } int main(int argc, char **argv) { diff -r 1d2be1b31e70 -r d7c4ba50b7d8 libidav/utils.c --- a/libidav/utils.c Mon Nov 14 19:02:40 2016 +0100 +++ b/libidav/utils.c Fri Nov 18 13:39:20 2016 +0100 @@ -448,7 +448,7 @@ } -char* util_xml_get_text(xmlNode *elm) { +char* util_xml_get_text(const xmlNode *elm) { xmlNode *node = elm->children; while(node) { if(node->type == XML_TEXT_NODE) { diff -r 1d2be1b31e70 -r d7c4ba50b7d8 libidav/utils.h --- a/libidav/utils.h Mon Nov 14 19:02:40 2016 +0100 +++ b/libidav/utils.h Fri Nov 18 13:39:20 2016 +0100 @@ -74,7 +74,7 @@ int util_getboolean(char *v); int util_strtoint(char *str, int64_t *value); -char* util_xml_get_text(xmlNode *elm); +char* util_xml_get_text(const xmlNode *elm); char* util_base64decode(char *in); char* util_base64decode_len(char *in, int *outlen);