diff -r b4285fb0f582 -r 7842c7665cd0 libidav/config.c --- a/libidav/config.c Sun Oct 27 14:36:42 2024 +0100 +++ b/libidav/config.c Sun Oct 27 15:22:08 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,73 @@ } } -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_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; + } +} + DavConfig* dav_config_new(xmlDoc *doc) { CxMempool *cfg_mp = cxMempoolCreate(128, NULL); @@ -212,29 +273,29 @@ } 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")) { @@ -520,9 +581,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 +674,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 +785,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;