implements xmlErrorFunc for dav sync + adds line numbers to error reporting in both config checkers

Fri, 18 Nov 2016 13:39:20 +0100

author
Mike Becker <universe@uap-core.de>
date
Fri, 18 Nov 2016 13:39:20 +0100
changeset 254
d7c4ba50b7d8
parent 253
1d2be1b31e70
child 255
bf19378aed58

implements xmlErrorFunc for dav sync + adds line numbers to error reporting in both config checkers

dav/config.c file | annotate | diff | comparison | revisions
dav/config.h file | annotate | diff | comparison | revisions
dav/scfg.c file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
libidav/utils.c file | annotate | diff | comparison | revisions
libidav/utils.h file | annotate | diff | comparison | revisions
--- 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);
--- 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);
--- 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 <max-retry> 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;
     }
     
--- 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) {
--- 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) {
--- 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);

mercurial