--- a/dav/config.c Sun Apr 16 14:12:24 2023 +0200 +++ b/dav/config.c Fri Apr 21 21:25:32 2023 +0200 @@ -30,7 +30,7 @@ #include <stdlib.h> #include <string.h> #include <sys/types.h> -#include <ucx/map.h> +#include <cx/hash_map.h> #include <errno.h> #include <libxml/tree.h> @@ -61,8 +61,8 @@ #define ENV_HOME getenv("HOME") #endif /* _WIN32 */ -static UcxMap *repos; -static UcxMap *keys; +static CxMap *repos; +static CxMap *keys; static PwdStore *pstore; @@ -104,8 +104,8 @@ int load_config(DavContext *ctx) { context = ctx; // TODO: free the config somewhere - repos = ucx_map_new(16); - keys = ucx_map_new(16); + repos = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); + keys = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 16); char *pwfile = util_concat_path(ENV_HOME, ".dav/secrets.crypt"); pstore = pwdstore_open(pwfile); @@ -164,10 +164,9 @@ void free_config(void) { if(repos) { - UcxMapIterator i = ucx_map_iterator(repos); - UcxKey k; + CxIterator i = cxMapIteratorValues(repos); Repository *repo; - UCX_MAP_FOREACH(k, repo, i) { + cx_foreach(Repository*, repo, i) { if(repo->default_key) { free(repo->default_key); } @@ -188,10 +187,10 @@ } free(repo); } - ucx_map_free(repos); + cxMapDestroy(repos); } if(keys) { - ucx_map_free(keys); + cxMapDestroy(keys); } } @@ -348,7 +347,7 @@ return 1; } - ucx_map_cstr_put(repos, repo->name, repo); + cxMapPut(repos, cx_hash_key_str(repo->name), repo); return 0; } @@ -426,7 +425,7 @@ key->name = strdup(value); } else if(xstreq(node->name, "file")) { // load key file - sstr_t key_data = load_key_file(value); + cxmutstr key_data = load_key_file(value); if(key_data.length > 0) { key->data = key_data.ptr; key->length = key_data.length; @@ -469,7 +468,7 @@ // add key to context if(!error) { - ucx_map_cstr_put(keys, key->name, key); + cxMapPut(keys, cx_hash_key_str(key->name), key); dav_context_add_key(context, key); } } @@ -486,8 +485,8 @@ } } -sstr_t load_key_file(char *filename) { - sstr_t k; +cxmutstr load_key_file(const char *filename) { + cxmutstr k; k.ptr = NULL; k.length = 0; @@ -597,11 +596,11 @@ return error; } -Repository* get_repository(sstr_t name) { +Repository* get_repository(cxstring name) { if(!name.ptr) { return NULL; } - return ucx_map_sstr_get(repos, name); + return cxMapGet(repos, cx_hash_key(name.ptr, name.length)); } int get_repository_flags(Repository *repo) { @@ -628,11 +627,11 @@ } -Key* get_key(char *name) { +Key* get_key(const char *name) { if(!name) { return NULL; } - return ucx_map_cstr_get(keys, name); + return cxMapGet(keys, cx_hash_key_str(name)); } int add_repository(Repository *repo) { @@ -753,17 +752,17 @@ xmlNodePtr prev = matchedRepoNode->prev; xmlNodePtr next = matchedRepoNode->next; if(prev && prev->type == XML_TEXT_NODE) { - sstr_t content = sstr((char*)prev->content); - sstr_t lf = sstrrchr(content, '\n'); + cxstring content = cx_str((char*)prev->content); + cxstring lf = cx_strrchr(content, '\n'); if(lf.length > 0) { - *lf.ptr = '\0'; - char* newcontent = sstrdup(content).ptr; + content.length = lf.ptr - content.ptr; + char* newcontent = cx_strdup(content).ptr; xmlNodeSetContent(prev, (xmlChar*)newcontent); free(newcontent); } } if(next && next->type == XML_TEXT_NODE) { - sstr_t lf = sstrchr(sstr((char*)next->content), '\n'); + cxstring lf = cx_strchr(cx_str((char*)next->content), '\n'); if(lf.length > 0) { char* newcontent = malloc(lf.length); memcpy(newcontent, lf.ptr+1, lf.length-1); @@ -785,22 +784,16 @@ } int list_repositories(void) { - UcxMapIterator i = ucx_map_iterator(repos); + CxIterator i = cxMapIteratorValues(repos); Repository *repo; - UCX_MAP_FOREACH(key, repo, i) { + cx_foreach(Repository *, repo, i) { printf("%s\n", repo->name); } return 0; } -UcxList* get_repositories(void) { - UcxList *list = NULL; - UcxMapIterator i = ucx_map_iterator(repos); - Repository *repo; - UCX_MAP_FOREACH(key, repo, i) { - list = ucx_list_append(list, repo); - } - return list; +CxIterator get_repositories(void) { + return cxMapIteratorValues(repos); } PwdStore* get_pwdstore(void) { @@ -821,29 +814,29 @@ -Repository* url2repo_s(sstr_t url, char **path) { +Repository* url2repo_s(cxstring url, char **path) { *path = NULL; int s; - if(sstrprefix(url, SC("http://"))) { + if(cx_strprefix(url, CX_STR("http://"))) { s = 7; - } else if(sstrprefix(url, SC("https://"))) { + } else if(cx_strprefix(url, CX_STR("https://"))) { s = 8; } else { s = 1; } // split URL into repository and path - sstr_t r = sstrsubs(url, s); - sstr_t p = sstrchr(r, '/'); - r = sstrsubsl(url, 0, url.length-p.length); + cxstring r = cx_strsubs(url, s); + cxstring p = cx_strchr(r, '/'); + r = cx_strsubsl(url, 0, url.length-p.length); if(p.length == 0) { - p = sstrn("/", 1); + p = cx_strn("/", 1); } Repository *repo = get_repository(r); if(repo) { - *path = sstrdup(p).ptr; + *path = cx_strdup(p).ptr; } else { // TODO: who is responsible for freeing this repository? // how can the callee know, if he has to call free()? @@ -853,17 +846,17 @@ repo->verification = true; repo->authmethods = CURLAUTH_BASIC; if(url.ptr[url.length-1] == '/') { - repo->url = sstrdup(url).ptr; + repo->url = cx_strdup(url).ptr; *path = strdup("/"); - } else if (sstrchr(url, '/').length > 0) { + } else if (cx_strchr(url, '/').length > 0) { // TODO: fix the following workaround after // fixing the inconsistent behavior of util_url_*() repo->url = util_url_base_s(url); - sstr_t truncated = sstrdup(url); + cxmutstr truncated = cx_strdup(url); *path = strdup(util_url_path(truncated.ptr)); free(truncated.ptr); } else { - repo->url = sstrdup(url).ptr; + repo->url = cx_strdup(url).ptr; *path = strdup("/"); } } @@ -871,8 +864,8 @@ return repo; } -Repository* url2repo(char *url, char **path) { - return url2repo_s(sstr(url), path); +Repository* url2repo(const char *url, char **path) { + return url2repo_s(cx_str(url), path); } static int decrypt_secrets(CmdArgs *a, PwdStore *secrets) { @@ -882,7 +875,7 @@ char *ps_password = NULL; if(secrets->unlock_cmd && strlen(secrets->unlock_cmd) > 0) { - UcxBuffer *cmd_out = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND); + CxBuffer *cmd_out = cxBufferCreate(NULL, 128, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); if(!util_exec_command(secrets->unlock_cmd, cmd_out)) { // command successful, get first line from output without newline // and use that as password for the secretstore @@ -899,7 +892,7 @@ ps_password[len] = 0; } } - ucx_buffer_free(cmd_out); + cxBufferFree(cmd_out); } if(!ps_password) { @@ -977,47 +970,48 @@ * The list secrets->location contains urls or repo names as * location strings. We need a list, that contains only urls */ - UcxList *locations = NULL; - UCX_FOREACH(elm, secrets->locations) { - PwdIndexEntry *e = elm->data; - - UCX_FOREACH(loc, e->locations) { + CxList *locations = cxLinkedListCreate(cxDefaultAllocator, (cx_compare_func)cmp_url_cred_entry, CX_STORE_POINTERS); + locations->simple_destructor = (cx_destructor_func)free_cred_location; + CxIterator i = cxListIterator(secrets->locations); + cx_foreach(PwdIndexEntry*, e, i) { + CxIterator entry_iter = cxListIterator(e->locations); + cx_foreach(char *, loc, entry_iter) { char *path; - Repository *r = url2repo(loc->data, &path); + Repository *r = url2repo(loc, &path); CredLocation *urlentry = calloc(1, sizeof(CredLocation)); urlentry->id = e->id; urlentry->location = util_concat_path(r->url, path); - locations = ucx_list_append(locations, urlentry); + cxListAdd(locations, urlentry); } } // the list must be sorted - locations = ucx_list_sort(locations, (cmp_func)cmp_url_cred_entry, NULL); + cxListSort(locations); // create full request url string and remove protocol prefix - sstr_t req_url_proto = sstr(util_concat_path(repo->url, path)); - sstr_t req_url = req_url_proto; - if(sstrprefix(req_url, S("http://"))) { - req_url = sstrsubs(req_url, 7); - } else if(sstrprefix(req_url, S("https://"))) { - req_url = sstrsubs(req_url, 8); + cxmutstr req_url_proto = cx_mutstr(util_concat_path(repo->url, path)); + cxstring req_url = cx_strcast(req_url_proto); + if(cx_strprefix(req_url, CX_STR("http://"))) { + req_url = cx_strsubs(req_url, 7); + } else if(cx_strprefix(req_url, CX_STR("https://"))) { + req_url = cx_strsubs(req_url, 8); } // iterate over sorted locations and check if a location is a prefix // of the requested url char *id = NULL; int ret = 0; - UCX_FOREACH(elm, locations) { - CredLocation *cred = elm->data; - sstr_t cred_url = sstr(cred->location); + i = cxListIterator(locations); + cx_foreach(CredLocation*, cred, i) { + cxstring cred_url = cx_str(cred->location); // remove protocol prefix - if(sstrprefix(cred_url, S("http://"))) { - cred_url = sstrsubs(cred_url, 7); - } else if(sstrprefix(cred_url, S("https://"))) { - cred_url = sstrsubs(cred_url, 8); + if(cx_strprefix(cred_url, CX_STR("http://"))) { + cred_url = cx_strsubs(cred_url, 7); + } else if(cx_strprefix(cred_url, CX_STR("https://"))) { + cred_url = cx_strsubs(cred_url, 8); } - if(sstrprefix(req_url, cred_url)) { + if(cx_strprefix(req_url, cred_url)) { id = cred->id; break; } @@ -1035,8 +1029,7 @@ } free(req_url_proto.ptr); - ucx_list_free_content(locations, (ucx_destructor)free_cred_location); - ucx_list_free(locations); + cxListDestroy(locations); return ret; }