dav/scfg.c

changeset 252
6b8e287269fc
parent 246
470f0c2e505e
child 253
1d2be1b31e70
--- a/dav/scfg.c	Mon Nov 07 19:32:17 2016 +0100
+++ b/dav/scfg.c	Fri Nov 11 15:03:19 2016 +0100
@@ -38,6 +38,15 @@
 
 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
 
+
+#define print_error(...) \
+    do {\
+        fprintf(stderr, "Error (sync.xml): " __VA_ARGS__); \
+        fprintf(stderr, "Abort.\n"); \
+    } while(0);
+#define print_warning(...) \
+    fprintf(stderr, "Warning (sync.xml): " __VA_ARGS__);
+
 #ifdef _WIN32
 #define ENV_HOME getenv("USERPROFILE")
 #else
@@ -71,7 +80,8 @@
         switch(errno) {
             case ENOENT: {
                 if(create_default_sync_config(file)) {
-                    return -1;
+                    /* this recursion is safe: ENOENT cannot occur again */
+                    return load_sync_config();
                 }
                 break;
             }
@@ -85,21 +95,20 @@
     
     xmlDoc *doc = xmlReadFile(file, NULL, 0);
     if(!doc) {
-        fprintf(stderr, "Broken configuration file\n");
+        fprintf(stderr, "Cannot load sync.xml\n");
         free(file);
         return -1;
     }
     
     int ret = 0;
     xmlNode *node = xmlDocGetRootElement(doc)->children;
-    while(node) {
+    while(node && !ret) {
         if(node->type == XML_ELEMENT_NODE) {
             if(xstreq(node->name, "directory")) {
-                if(scfg_load_directory(node)) {
-                    ret = 1;
-                    ucx_map_free(directories);
-                    break;
-                }
+                ret = scfg_load_directory(node);
+            } else {
+                print_error("unknown config element: %s\n", node->name);
+                ret = 1;
             }
         }
         node = node->next;
@@ -126,12 +135,21 @@
     while(node) {
         if(node->type == XML_ELEMENT_NODE) {
             char *value = util_xml_get_text(node);
-            if(!value) {
+            if(xstreq(node->name, "include")) {
+                if(value) {
+                    *include = add_regex_pattern(*include, value);
+                }
+            } else if(xstreq(node->name, "exclude")) {
+                if(value) {
+                    *exclude = add_regex_pattern(*exclude, value);
+                }
+            } else {
+                print_error("unknown filter config element: %s\n", node->name);
                 return 1;
-            } else if(xstreq(node->name, "include")) {
-                *include = add_regex_pattern(*include, value);
-            } else if(xstreq(node->name, "exclude")) {
-                *exclude = add_regex_pattern(*exclude, value);
+            }
+            if(!value) {
+                print_error("missing value for filter: %s\n", node->name);
+                return 1;
             }
         }
         
@@ -159,9 +177,16 @@
     while(node) {
         if(node->type == XML_ELEMENT_NODE) {
             char *value = util_xml_get_text(node);
+            /* every key needs a value */
             if(!value) {
-                // next
-            } else if(xstreq(node->name, "name")) {
+                /* 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",
+                        node->name);
+                return 1;
+            }
+            if(xstreq(node->name, "name")) {
                 name = value;
             } else if(xstreq(node->name, "path")) {
                 path = value;
@@ -173,7 +198,7 @@
                 repository = value;
             } else if(xstreq(node->name, "filter")) {
                 if(scfg_load_filter(node, &include, &exclude)) {
-                    return -1;
+                    return 1;
                 }
             } else if(xstreq(node->name, "database")) {
                 database = value;
@@ -182,8 +207,8 @@
                 if(util_strtoint(value, &i) && i >= 0) {
                     max_retry = (int)i;
                 } else {
-                    fprintf(stderr, "Warning: sync.xml: unsigned integer value "
-                                    "expected in <max-retry> element\n");
+                    print_warning("unsigned integer value "
+                            "expected in <max-retry> element\n");
                 }
             } else if(xstreq(node->name, "backup-on-pull")) {
                 backuppull = util_getboolean(value);
@@ -191,26 +216,30 @@
                 lockpull = util_getboolean(value);
             } else if(xstreq(node->name, "lock-push")) {
                 lockpush = util_getboolean(value);
+            } else {
+                print_error("unknown directory config element: %s\n",
+                        node->name);
+                return 1;
             }
         }
         node = node->next;
     }
     
     if(!name) {
-        fprintf(stderr, "Missing name element for directory\n");
-        return -1;
+        print_error("missing name element for directory\n");
+        return 1;
     }
     if(!path) {
-        fprintf(stderr, "Missing path element for directory\n");
-        return -1;
+        print_error("missing path element for directory %s\n", name);
+        return 1;
     }
     if(!repository) {
-        fprintf(stderr, "Missing repository element for directory\n");
-        return -1;
+        print_error("missing repository element for directory %s\n", name);
+        return 1;
     }
     if(!database) {
-        fprintf(stderr, "Missing database element for directory\n");
-        return -1;
+        print_error("missing database element for directory %s\n", name);
+        return 1;
     }
     
     SyncDirectory *dir = malloc(sizeof(SyncDirectory));
@@ -426,34 +455,36 @@
 
 
 void free_sync_config() {
-    UcxMapIterator i = ucx_map_iterator(directories);
-    SyncDirectory *dir;
-    UCX_MAP_FOREACH(elm, dir, i) {
-        free(dir->name);
-        free(dir->path);
-        free(dir->repository);
-        free(dir->database);
-        
-        if(dir->collection) {
-            free(dir->collection);
-        }
-        if(dir->trash) {
-            free(dir->trash);
+    if(directories) {
+        UcxMapIterator i = ucx_map_iterator(directories);
+        SyncDirectory *dir;
+        UCX_MAP_FOREACH(elm, dir, i) {
+            free(dir->name);
+            free(dir->path);
+            free(dir->repository);
+            free(dir->database);
+
+            if(dir->collection) {
+                free(dir->collection);
+            }
+            if(dir->trash) {
+                free(dir->trash);
+            }
+
+            UCX_FOREACH(elm, dir->include) {
+                regfree(elm->data);
+                free(elm->data);
+            }
+            ucx_list_free(dir->include);
+            UCX_FOREACH(elm, dir->exclude) {
+                regfree(elm->data);
+                free(elm->data);
+            }
+            ucx_list_free(dir->exclude);
+
+            free(dir);
         }
-        
-        UCX_FOREACH(elm, dir->include) {
-            regfree(elm->data);
-            free(elm->data);
-        }
-        ucx_list_free(dir->include);
-        UCX_FOREACH(elm, dir->exclude) {
-            regfree(elm->data);
-            free(elm->data);
-        }
-        ucx_list_free(dir->exclude);
-        
-        free(dir);
+
+        ucx_map_free(directories);
     }
-    
-    ucx_map_free(directories);
 }

mercurial