dav/config.c

changeset 252
6b8e287269fc
parent 247
3020d1b5e7bd
child 254
d7c4ba50b7d8
--- a/dav/config.c	Mon Nov 07 19:32:17 2016 +0100
+++ b/dav/config.c	Fri Nov 11 15:03:19 2016 +0100
@@ -35,11 +35,20 @@
 #include <libxml/tree.h>
 
 #include "config.h"
+#include "main.h"
 #include <libidav/utils.h>
 
 #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(...) \
+    do {\
+        fprintf(stderr, "Error (config.xml): " __VA_ARGS__); \
+        fprintf(stderr, "Abort.\n"); \
+    } while(0);
+#define print_warning(...) \
+    fprintf(stderr, "Warning (config.xml): " __VA_ARGS__);
+
 #ifdef _WIN32
 #define ENV_HOME getenv("USERPROFILE")
 #else
@@ -48,8 +57,6 @@
 
 static UcxMap *repos;
 static UcxMap *keys;
-static Proxy  *http_proxy;
-static Proxy  *https_proxy;
 
 int check_config_dir(void) {
     char *file = util_concat_path(ENV_HOME, ".dav");
@@ -73,15 +80,13 @@
     xmlFreeDoc(doc);
 }
 
-void load_config(DavContext *ctx) {
+int load_config(DavContext *ctx) {
     context = ctx;
     // TODO: free the config somewhere
     repos = ucx_map_new(16);
     keys = ucx_map_new(16);
-    http_proxy = calloc(1, sizeof(Proxy));
-    https_proxy = calloc(1, sizeof(Proxy));
     if(check_config_dir()) {
-        return;
+        return 1;
     }
     
     char *file = util_concat_path(ENV_HOME, ".dav/config.xml");
@@ -97,64 +102,72 @@
                 perror("Cannot load config.xml");
             }
         }
-        return;
+        return 1;
     }
     
     xmlDoc *doc = xmlReadFile(file, NULL, 0);
     free(file);
     if(!doc) {
         fprintf(stderr, "Cannot load config.xml\n");
-        return;
+        return 1;
     }
     
     xmlNode *xml_root = xmlDocGetRootElement(doc);
     xmlNode *node = xml_root->children;
-    while(node) {
+    int ret = 0;
+    while(node && !ret) {
         if(node->type == XML_ELEMENT_NODE) {
             if(xstreq(node->name, "repository")) {
-                load_repository(node);
+                ret = load_repository(node);
             } else if(xstreq(node->name, "key")) {
-                load_key(node);
+                ret = load_key(node);
             } else if (xstreq(node->name, "http-proxy")) {
-                load_proxy(node, HTTP_PROXY);
+                ret = load_proxy(ctx->http_proxy, node, HTTP_PROXY);
             } else if (xstreq(node->name, "https-proxy")) {
-                load_proxy(node, HTTPS_PROXY);
+                ret = load_proxy(ctx->https_proxy, node, HTTPS_PROXY);
+            } else {
+                fprintf(stderr, "Unknown config element: %s\n", node->name);
+                ret = 1;
             }
         }
         node = node->next;
     }
     
     xmlFreeDoc(doc);
+    return ret;
 }
 
 void free_config(void) {
-    UcxMapIterator i = ucx_map_iterator(repos);
-    UcxKey k;
-    Repository *repo;
-    UCX_MAP_FOREACH(k, repo, i) {
-        if(repo->default_key) {
-            free(repo->default_key);
-        }
-        if(repo->name) {
-            free(repo->name);
-        }
-        if(repo->password) {
-            free(repo->password);
+    if(repos) {
+        UcxMapIterator i = ucx_map_iterator(repos);
+        UcxKey k;
+        Repository *repo;
+        UCX_MAP_FOREACH(k, repo, i) {
+            if(repo->default_key) {
+                free(repo->default_key);
+            }
+            if(repo->name) {
+                free(repo->name);
+            }
+            if(repo->password) {
+                free(repo->password);
+            }
+            if(repo->url) {
+                free(repo->url);
+            }
+            if(repo->user) {
+                free(repo->user);
+            }
+            if(repo->cert) {
+                free(repo->cert);
+            }      
+            free(repo);
         }
-        if(repo->url) {
-            free(repo->url);
-        }
-        if(repo->user) {
-            free(repo->user);
-        }
-        if(repo->cert) {
-            free(repo->cert);
-        }      
-        free(repo);
+        ucx_map_free(repos);
     }
-    ucx_map_free(repos);
-    
-    ucx_map_free(keys);
+    if(keys) {
+        ucx_map_free(keys);
+    }
 }
 
 Repository* repository_new(void) {
@@ -169,45 +182,48 @@
     return repo;
 }
 
-void load_repository(xmlNode *reponode) {
-    xmlNode *node = reponode->children;
+int load_repository(xmlNode *reponode) {
     Repository *repo = repository_new();
-    while(node) {
-        if(node->type == XML_ELEMENT_NODE) {
-            char *name = (char*)node->name;
-            char *value = util_xml_get_text(node);
-            if(value) {
-                if(repo_add_config(repo, name, value)) {
-                    fprintf(
-                            stderr,
-                            "Unkown repository config element: %s\n",
-                            name);
-                }
+    {
+        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;
         }
-        node = node->next;
+        if(ret) {
+            free(repo);
+            return 1;
+        }
     }
     
     if(!repo->name) {
-        fprintf(
-                stderr,
-                "Cannot load config.xml: missing name for repository.\n");
-        fprintf(stderr, "Abort.\n");
-        exit(-1);
+        print_error("missing name for repository.\n");
+        return 1;
     }
     if(!repo->url) {
-        fprintf(
-                stderr,
-                "Cannot load config.xml: "
-                "missing url for repository '%s'.\n", repo->name);
-        fprintf(stderr, "Abort.\n");
-        exit(-1);
+        print_error("missing url for repository '%s'.\n", repo->name);
+        return 1;
     }
     
     ucx_map_cstr_put(repos, repo->name, repo);
+    return 0;
 }
 
-int repo_add_config(Repository *repo, char *key, char *value) {  
+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);
+        return 1;
+    }
+    
     if(xstreq(key, "name")) {
         repo->name = strdup(value);
     } else if(xstreq(key, "url")) {
@@ -263,7 +279,7 @@
 #endif
 #endif
         else {
-            fprintf(stderr, "Unknown ssl version: %s\n", value);
+            print_warning("unknown ssl version: %s\n", value);
         }
     } else if(xstreq(key, "authmethods")) {
         repo->authmethods = CURLAUTH_NONE;
@@ -284,56 +300,76 @@
             } else if(xstrEQ(value, "none")) {
                 /* skip */
             } else {
-                fprintf(stderr, "Unknown authentication method: %s\n", value);
+                print_warning("unknown authentication method: %s\n", value);
             }
             meth = strtok(NULL, delims);
         }
         free(meths);
     } else {
-        return -1;
+        print_error("unkown repository config element: %s\n", key);
+        return 1;
     }
     return 0;
 }
 
-void load_proxy(xmlNode *proxynode, int type) {
-    Proxy *proxy;
+int load_proxy(DavProxy *proxy, xmlNode *proxynode, int type) {
     const char *stype;
-    if (type == HTTPS_PROXY) {
-        proxy = https_proxy;
+    if(type == HTTPS_PROXY) {
         stype = "https";
-    } else if (type == HTTP_PROXY) {
-        proxy = http_proxy;
+    } else if(type == HTTP_PROXY) {
         stype = "http";
     }
     
+    if(!proxy) {
+        print_error("no memory reserved for %s proxy.\n", stype);
+        return 1;
+    }
+    
     xmlNode *node = proxynode->children;
-    while(node) {
+    int ret = 0;
+    while(node && !ret) {
         if(node->type == XML_ELEMENT_NODE) {
             char *value = util_xml_get_text(node);
-            if(!value) {
-                // next
-            } else if(xstreq(node->name, "url")) {
-                proxy->url = strdup(value);
+            int reportmissingvalue = 0;
+            if(xstreq(node->name, "url")) {
+                if(!(reportmissingvalue = !value)) {
+                    proxy->url = strdup(value);
+                }
             } else if(xstreq(node->name, "user")) {
-                proxy->user = strdup(value);
+                if(!(reportmissingvalue = !value)) {
+                    proxy->username = strdup(value);
+                }
             } else if(xstreq(node->name, "password")) {
-                proxy->password = util_base64decode(value);
+                if(!(reportmissingvalue = !value)) {
+                    proxy->password = util_base64decode(value);
+                }
             } else if(xstreq(node->name, "no")) {
-                proxy->no = strdup(value);
+                if(!(reportmissingvalue = !value)) {
+                    proxy->no_proxy = strdup(value);
+                }
+            } else {
+                print_error("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);
+                ret = 1;
             }
         }
         node = node->next;
     }
     
-    if(!proxy->url) {
-        fprintf(stderr,
-            "Cannot load config.xml: missing url for %s proxy.\n", stype);
-        fprintf(stderr, "Abort.\n");
-        exit(-1);
+    if(!ret && !proxy->url) {
+        print_error("missing url for %s proxy.\n", stype);
+        return 1;
     }
+    
+    return ret;
 }
 
-void load_key(xmlNode *keynode) {
+int load_key(xmlNode *keynode) {
     xmlNode *node = keynode->children;
     Key *key = calloc(1, sizeof(Key));
     key->type = KEY_AES256;
@@ -353,7 +389,7 @@
                     key->data = key_data.ptr;
                     key->length = key_data.length;
                 } else {
-                    fprintf(stderr, "Error: Cannot key from file: %s\n", value);
+                    print_error("cannot get key from file: %s\n", value);
                     error = 1;
                 }
             } else if(xstreq(node->name, "type")) {
@@ -362,7 +398,7 @@
                 } else if(!strcmp(value, "aes256")) {
                     key->type = KEY_AES256;
                 } else {
-                    fprintf(stderr, "Error: unknown key type %s\n", value);
+                    print_error("unknown key type %s\n", value);
                     error = 1;
                 }
             }
@@ -373,27 +409,19 @@
     
     if(!error && key->name) {
         error = 0;
+        size_t expected_length = 0;
         if(key->type == KEY_AES128) {
-            if(key->length < 16) {
-                fprintf(
-                        stderr,
-                        "Error: Key %s is too small (%zu < 16)\n",
-                        key->name,
-                        key->length);
-                error = 1;
-            }
-            key->length = 16;
+            expected_length = 16;
         }
         if(key->type == KEY_AES256) {
-            if(key->length < 32) {
-                fprintf(
-                        stderr,
-                        "Error: Key %s is too small (%zu < 32)\n",
-                        key->name,
-                        key->length);
-                error = 1;
-            }
-            key->length = 32;
+            expected_length = 32;
+        }
+        if(key->length < expected_length) {
+            print_error("key %s is too small (%zu < %zu)\n",
+                    key->name,
+                    key->length,
+                    expected_length);
+            error = 1;
         }
         
         // add key to context
@@ -409,6 +437,9 @@
             free(key->data);
         }
         free(key);
+        return 1;
+    } else {
+        return 0;
     }
 }
 
@@ -473,15 +504,6 @@
     return ucx_map_cstr_get(keys, name);
 }
 
-Proxy* get_http_proxy(void) {
-    return http_proxy;
-}
-
-Proxy* get_https_proxy(void) {
-    return https_proxy;
-}
-
-
 int add_repository(Repository *repo) {
     char *file = util_concat_path(ENV_HOME, ".dav/config.xml");
     xmlDoc *doc = xmlReadFile(file, NULL, 0);

mercurial