libidav/config.c

changeset 60
ee4e4742391e
parent 49
2f71f4ee247a
child 62
dbde5e038ea9
--- a/libidav/config.c	Wed Oct 23 21:46:43 2024 +0200
+++ b/libidav/config.c	Sun Oct 27 18:24:37 2024 +0100
@@ -79,7 +79,7 @@
 static int load_secretstore(DavConfig *config, xmlNode *node);
 
 
-int dav_cfg_string_set_value(DavConfig *config, CfgString *str, xmlNode *node) {
+int dav_cfg_string_set_node_value(DavConfig *config, CfgString *str, xmlNode *node) {
     str->node = node;
     char *value = util_xml_get_text(node);
     if(value) {
@@ -91,12 +91,111 @@
     }
 }
 
-void dav_cfg_bool_set_value(DavConfig *config, CfgBool *cbool, xmlNode *node) {
+void dav_cfg_bool_set_node_value(DavConfig *config, CfgBool *cbool, xmlNode *node) {
     cbool->node = node;
     char *value = util_xml_get_text(node);
     cbool->value = util_getboolean(value);
 }
 
+static void set_xml_content(xmlNode *node, const char *content) {
+    xmlNode *child = node->children;
+    while(child) {
+        xmlNode *next = child->next;
+        xmlUnlinkNode(child);
+        xmlFreeNode(child);
+        child = next;
+    }
+    
+    if(content) {
+        xmlChar *encoded = xmlEncodeSpecialChars(node->doc, (const xmlChar*)content);
+        if(encoded) {
+            xmlNodeSetContent(node, encoded);
+            xmlFree(encoded);
+        }
+    }
+}
+
+void dav_cfg_string_set_value(DavConfig *config, CfgString *str, xmlNode *parent, cxstring new_value, const char *nodename) {
+    if(str->value.ptr) {
+        cxFree(config->mp->allocator, str->value.ptr);
+    }
+    if(new_value.ptr) {
+        str->value = cx_strdup_a(config->mp->allocator, new_value);
+    } else {
+        str->value = cx_mutstrn(NULL, 0);
+    }
+    
+    if(!str->node) {
+        str->node = xmlNewNode(NULL, (const xmlChar*) nodename);
+        xmlAddChild(parent, str->node);
+    }
+    set_xml_content(str->node, new_value.ptr);
+}
+
+void dav_cfg_bool_set_value(DavConfig *config, CfgBool *cbool, xmlNode *parent, DavBool new_value, const char *nodename) {
+    const char *content = new_value ? "true" : "false";
+    cbool->value = new_value;
+    if(!cbool->node) {
+        cbool->node = xmlNewNode(NULL, (const xmlChar*) nodename);
+        xmlAddChild(parent, cbool->node);
+    }
+    set_xml_content(cbool->node, content);
+}
+
+void dav_cfg_int_set_value(DavConfig *config, CfgInt *cint, xmlNode *parent, int64_t new_value, const char *nodename) {
+    char content[32];
+    snprintf(content, 32, "%" PRId64, new_value);
+    cint->value = new_value;
+    if(!cint->node) {
+        cint->node = xmlNewNode(NULL, (const xmlChar*) nodename);
+        xmlAddChild(parent, cint->node);
+    }
+    set_xml_content(cint->node, content);
+}
+
+void dav_cfg_uint_set_value(DavConfig *config, CfgUInt *cint, xmlNode *parent, uint64_t new_value, const char *nodename) {
+    char content[32];
+    snprintf(content, 32, "%" PRIu64, new_value);
+    cint->value = new_value;
+    if(!cint->node) {
+        cint->node = xmlNewNode(NULL, (const xmlChar*) nodename);
+        xmlAddChild(parent, cint->node);
+    }
+    set_xml_content(cint->node, content);
+}
+
+void dav_cfg_string_remove(CfgString *str) {
+    if(str->node) {
+        xmlUnlinkNode(str->node);
+        xmlFreeNode(str->node);
+        str->node = NULL;
+    }
+}
+
+void dav_cfg_bool_remove(CfgBool *cbool) {
+    if(cbool->node) {
+        xmlUnlinkNode(cbool->node);
+        xmlFreeNode(cbool->node);
+        cbool->node = NULL;
+    }
+}
+
+void dav_cfg_int_remove(CfgInt *cint) {
+    if(cint->node) {
+        xmlUnlinkNode(cint->node);
+        xmlFreeNode(cint->node);
+        cint->node = NULL;
+    }
+}
+
+void dav_cfg_uint_remove(CfgUInt *cint) {
+    if(cint->node) {
+        xmlUnlinkNode(cint->node);
+        xmlFreeNode(cint->node);
+        cint->node = NULL;
+    }
+}
+
 
 DavConfig* dav_config_new(xmlDoc *doc) {
     CxMempool *cfg_mp = cxMempoolCreate(128, NULL);
@@ -212,55 +311,37 @@
     }
     
     if(xstreq(key, "name")) {
-        dav_cfg_string_set_value(config, &repo->name, node);
+        dav_cfg_string_set_node_value(config, &repo->name, node);
     } else if(xstreq(key, "url")) {
-        dav_cfg_string_set_value(config, &repo->url, node);
+        dav_cfg_string_set_node_value(config, &repo->url, node);
     } else if(xstreq(key, "user")) {
-        dav_cfg_string_set_value(config, &repo->user, node);
+        dav_cfg_string_set_node_value(config, &repo->user, node);
     } else if(xstreq(key, "password")) {
-        dav_cfg_string_set_value(config, &repo->password, node);
+        dav_cfg_string_set_node_value(config, &repo->password, node);
     } else if(xstreq(key, "stored-user")) {
-        dav_cfg_string_set_value(config, &repo->stored_user, node);
+        dav_cfg_string_set_node_value(config, &repo->stored_user, node);
     } else if(xstreq(key, "default-key")) {
-        dav_cfg_string_set_value(config, &repo->default_key, node);
+        dav_cfg_string_set_node_value(config, &repo->default_key, node);
     } else if(xstreq(key, "full-encryption")) {
-        dav_cfg_bool_set_value(config, &repo->full_encryption, node);
+        dav_cfg_bool_set_node_value(config, &repo->full_encryption, node);
     } else if(xstreq(key, "content-encryption")) {
-        dav_cfg_bool_set_value(config, &repo->content_encryption, node);
+        dav_cfg_bool_set_node_value(config, &repo->content_encryption, node);
     } else if(xstreq(key, "decrypt-content")) {
-        dav_cfg_bool_set_value(config, &repo->decrypt_content, node);
+        dav_cfg_bool_set_node_value(config, &repo->decrypt_content, node);
     } else if(xstreq(key, "decrypt-name")) {
-        dav_cfg_bool_set_value(config, &repo->decrypt_name, node);
+        dav_cfg_bool_set_node_value(config, &repo->decrypt_name, node);
     } else if(xstreq(key, "cert")) {
-        dav_cfg_string_set_value(config, &repo->cert, node);
+        dav_cfg_string_set_node_value(config, &repo->cert, node);
     } else if(xstreq(key, "verification")) {
-        dav_cfg_bool_set_value(config, &repo->verification, node);
+        dav_cfg_bool_set_node_value(config, &repo->verification, node);
     } else if(xstreq(key, "ssl-version")) {
         repo->ssl_version.node = node;
-        if(xstrEQ(value, "TLSv1")) {
-            repo->ssl_version.value = CURL_SSLVERSION_TLSv1;
-        } else if(xstrEQ(value, "SSLv2")) {
-            repo->ssl_version.value = CURL_SSLVERSION_SSLv2;
-        } else if(xstrEQ(value, "SSLv3")) {
-            repo->ssl_version.value = CURL_SSLVERSION_SSLv3;
-        }
-#if LIBCURL_VERSION_MAJOR * 1000 + LIBCURL_VERSION_MINOR >= 7034
-        else if(xstrEQ(value, "TLSv1.0")) {
-            repo->ssl_version.value = CURL_SSLVERSION_TLSv1_0;
-        } else if(xstrEQ(value, "TLSv1.1")) {
-            repo->ssl_version.value = CURL_SSLVERSION_TLSv1_1;
-        } else if(xstrEQ(value, "TLSv1.2")) {
-            repo->ssl_version.value = CURL_SSLVERSION_TLSv1_2;
-        }
-#endif
-#if LIBCURL_VERSION_MAJOR * 1000 + LIBCURL_VERSION_MINOR >= 7052
-        else if(xstrEQ(value, "TLSv1.3")) {
-            repo->ssl_version.value = CURL_SSLVERSION_TLSv1_3;
-        }
-#endif
-        else {
+        int ssl_version = dav_str2ssl_version((const char*)value);
+        if(ssl_version == -1) {
             print_warning(lineno, "unknown ssl version: %s\n", value);
             repo->ssl_version.value = CURL_SSLVERSION_DEFAULT;
+        } else {
+            repo->ssl_version.value = ssl_version;
         }
     } else if(xstreq(key, "authmethods")) {
         repo->authmethods.node = node;
@@ -295,6 +376,31 @@
     return 0;
 }
 
+int dav_str2ssl_version(const char *value) {
+    if(xstrEQ(value, "TLSv1")) {
+        return CURL_SSLVERSION_TLSv1;
+    } else if(xstrEQ(value, "SSLv2")) {
+        return CURL_SSLVERSION_SSLv2;
+    } else if(xstrEQ(value, "SSLv3")) {
+        return CURL_SSLVERSION_SSLv3;
+    }
+#if LIBCURL_VERSION_MAJOR * 1000 + LIBCURL_VERSION_MINOR >= 7034
+    else if(xstrEQ(value, "TLSv1.0")) {
+        return CURL_SSLVERSION_TLSv1_0;
+    } else if(xstrEQ(value, "TLSv1.1")) {
+        return CURL_SSLVERSION_TLSv1_1;
+    } else if(xstrEQ(value, "TLSv1.2")) {
+        return CURL_SSLVERSION_TLSv1_2;
+    }
+#endif
+#if LIBCURL_VERSION_MAJOR * 1000 + LIBCURL_VERSION_MINOR >= 7052
+    else if(xstrEQ(value, "TLSv1.3")) {
+        return CURL_SSLVERSION_TLSv1_3;
+    }
+#endif
+    return -1;
+}
+
 static int load_repository(
         DavConfig *config,
         DavCfgRepository **list_begin,
@@ -520,9 +626,9 @@
     while(node) {
         if(node->type == XML_ELEMENT_NODE) {
             if(xstreq(node->name, "name")) {
-                dav_cfg_string_set_value(config, &key->name, node);
+                dav_cfg_string_set_node_value(config, &key->name, node);
             } else if(xstreq(node->name, "file")) {
-                dav_cfg_string_set_value(config, &key->file, node);
+                dav_cfg_string_set_node_value(config, &key->file, node);
             } else if(xstreq(node->name, "type")) {
                 const char *value = util_xml_get_text(node);
                 key->type_node = node;
@@ -613,13 +719,13 @@
         if(node->type == XML_ELEMENT_NODE) {
             int reportmissingvalue = 0;
             if(xstreq(node->name, "url")) {
-                reportmissingvalue = dav_cfg_string_set_value(config, &proxy->url, node);
+                reportmissingvalue = dav_cfg_string_set_node_value(config, &proxy->url, node);
             } else if(xstreq(node->name, "user")) {
-                reportmissingvalue = dav_cfg_string_set_value(config, &proxy->user, node);
+                reportmissingvalue = dav_cfg_string_set_node_value(config, &proxy->user, node);
             } else if(xstreq(node->name, "password")) {
-                reportmissingvalue = dav_cfg_string_set_value(config, &proxy->password, node);
+                reportmissingvalue = dav_cfg_string_set_node_value(config, &proxy->password, node);
             } else if(xstreq(node->name, "no")) {
-                reportmissingvalue = dav_cfg_string_set_value(config, &proxy->noproxy, node);
+                reportmissingvalue = dav_cfg_string_set_node_value(config, &proxy->noproxy, node);
             } else {
                 proxy->unknown_elements++;
             }
@@ -724,9 +830,9 @@
     while(node) {
         if(node->type == XML_ELEMENT_NODE) {
             if(xstreq(node->name, "unlock-command")) {
-                dav_cfg_string_set_value(config, &config->secretstore->unlock_cmd, node);
+                dav_cfg_string_set_node_value(config, &config->secretstore->unlock_cmd, node);
             } else if(xstreq(node->name, "lock-command")) {
-                dav_cfg_string_set_value(config, &config->secretstore->lock_cmd, node);
+                dav_cfg_string_set_node_value(config, &config->secretstore->lock_cmd, node);
             }
         }
         node = node->next;

mercurial