src/server/daemon/config.c

changeset 415
d938228c382e
parent 409
62aad4d94d5d
child 418
b7dcc9c4f270
--- a/src/server/daemon/config.c	Wed Nov 02 19:19:01 2022 +0100
+++ b/src/server/daemon/config.c	Sun Nov 06 15:53:32 2022 +0100
@@ -37,8 +37,11 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 
-#include <ucx/string.h>
-#include <ucx/utils.h>
+#include <cx/string.h>
+#include <cx/utils.h>
+#include <cx/hash_map.h>
+#include <cx/linked_list.h>
+#include <cx/compare.h>
 
 #include "httplistener.h"
 #include "config.h"
@@ -54,13 +57,13 @@
 #include "../util/pblock.h"
 #include "../util/util.h"
 #include "../util/atomic.h"
-#include "ucx/buffer.h"
+#include "cx/buffer.h"
 
 pool_handle_t *init_pool;
 
 char* cfg_config_file_path(const char *file) {
-    sstr_t base = ST("config/");
-    sstr_t path = sstrcat(2, base, scstr(file));
+    cxstring base = CX_STR("config/");
+    cxmutstr path = cx_strcat(2, base, cx_str(file));
     return path.ptr;
 }
 
@@ -72,24 +75,23 @@
         log_ereport(LOG_FAILURE, "Cannot load init.conf");
         return 1;
     }
-    UcxAllocator *mp = cfg->parser.mp;
+    CxAllocator *mp = cfg->parser.mp;
 
     init_pool = pool_create(); // one pool for one Configuration
-    UcxList *dirs = cfg->directives;
+    ConfigDirectiveList *dirs = cfg->directives;
     while(dirs != NULL) {
-        ConfigDirective *dir = dirs->data;
+        ConfigDirective *dir = dirs->directive;
 
         /* create NSAPI directive */
         directive *d = malloc(sizeof(directive));
         d->param = pblock_create_pool(init_pool, 8);
-        UcxList *param = cfg_param_list(dir->value, mp);
+        ConfigParam *param = cfg_param_list(dir->value, mp);
         while(param != NULL) {
-            ConfigParam *p = param->data;
             pblock_nvlinsert(
-                    p->name.ptr,
-                    p->name.length,
-                    p->value.ptr,
-                    p->value.length,
+                    param->name.ptr,
+                    param->name.length,
+                    param->value.ptr,
+                    param->value.length,
                     d->param);
             
             param = param->next;
@@ -148,15 +150,15 @@
     serverconfig->ref = 1;
     serverconfig->pool = pool;
     
-    UcxAllocator allocator = util_pool_allocator(serverconfig->pool);
-    serverconfig->a = pool_malloc(pool, sizeof(UcxAllocator));
-    *serverconfig->a = allocator;
+    CxAllocator *allocator = pool_allocator(serverconfig->pool);
+    serverconfig->a = allocator;
     
-    serverconfig->listeners = NULL;
-    serverconfig->host_vs = ucx_map_new_a(serverconfig->a, 16);
-    serverconfig->authdbs = ucx_map_new_a(serverconfig->a, 16);
-    serverconfig->resources = ucx_map_new_a(serverconfig->a, 16);
-    serverconfig->dav = ucx_map_new_a(serverconfig->a, 16);
+    serverconfig->listeners = cxPointerLinkedListCreate(serverconfig->a, cx_cmp_ptr);
+    serverconfig->logfiles = cxPointerLinkedListCreate(serverconfig->a, cx_cmp_ptr);
+    serverconfig->host_vs = cxHashMapCreate(serverconfig->a, 16);
+    serverconfig->authdbs = cxHashMapCreate(serverconfig->a, 16);
+    serverconfig->resources = cxHashMapCreate(serverconfig->a, 16);
+    serverconfig->dav = cxHashMapCreate(serverconfig->a, 16);
     
     // STAGE 1 load_server_conf:
     // At stage 1 we load the file and get the Runtime infos for changing
@@ -168,25 +170,26 @@
     // Listener (dependencies: Threadpool, EventHandler)
     
     // load Runtime config
-    UcxList *list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Runtime"));
-    UCX_FOREACH(elm, list) {
-        ConfigNode *runtimeobj = elm->data;
+    CxList *list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("Runtime"));
+    CxIterator iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, runtimeobj, iter) {
         if(cfg_handle_runtime(serverconfig, runtimeobj)) {
             // error
             return NULL;
         }
     }
-    ucx_list_free(list);
+    cxListDestroy(list);
     
     // load threadpool config
     log_ereport(LOG_DEBUG, "apply config: Threadpool");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Threadpool"));
-    UCX_FOREACH(elm, list) {
-        if(cfg_handle_threadpool(serverconfig, elm->data)) {
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("Threadpool"));
+    iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, elm, iter) {
+        if(cfg_handle_threadpool(serverconfig, elm)) {
             return NULL;
         }
     }
-    ucx_list_free(list);
+    cxListDestroy(list);
     // check thread pool config
     if(check_thread_pool_cfg() != 0) {
         /* critical error */
@@ -195,9 +198,10 @@
     
     // load eventhandler config
     log_ereport(LOG_DEBUG, "apply config: EventHandler");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("EventHandler"));
-    UCX_FOREACH(elm, list) {
-        if(cfg_handle_eventhandler(serverconfig, elm->data)) {
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("EventHandler"));
+    iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, elm, iter) {
+        if(cfg_handle_eventhandler(serverconfig, elm)) {
             // error            
             return NULL;
         }
@@ -207,18 +211,18 @@
         /* critical error */
         return NULL;
     }
-    ucx_list_free(list);
+    cxListDestroy(list);
     
     // load Listener config
     log_ereport(LOG_DEBUG, "apply config: Listener");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Listener"));
-    UCX_FOREACH(elm, list) {
-        ConfigNode *scfgobj = elm->data;
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("Listener"));
+    iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, scfgobj, iter) {
         if(cfg_handle_listener(serverconfig, scfgobj)) {
             return NULL;
         }
     }
-    ucx_list_free(list);
+    cxListDestroy(list);
     
     // we return here, to let the webserver use the runtime info to
     // change the uid if needed
@@ -242,95 +246,92 @@
      */
     
     // init logfile first
-    UcxList *list;
+    CxList *list;
     
     log_ereport(LOG_DEBUG, "apply config: LogFile");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("LogFile"));
-    if(list) {
-        ConfigNode *logobj = list->data;
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("LogFile"));
+    CxIterator iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, logobj, iter) {
         if(!logobj) {
             // error
-            return NULL; // TODO: fix memory leak
+            cxListDestroy(list);
+            return NULL;
         }
         
         int ret = cfg_handle_logfile(serverconfig, logobj);
         if(ret != 0) {
             // cannot initialize log file
-            return NULL; // TODO: fix memory leak
+            cxListDestroy(list);
+            return NULL;
         }
-    } else {
-        // horrible error
-        return NULL;
     }
-    ucx_list_free(list);
+    cxListDestroy(list);
     
     log_ereport(LOG_DEBUG, "apply config: AccessLog");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("AccessLog"));
-    UCX_FOREACH(elm, list) {
-        ConfigNode *scfgobj = elm->data;
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("AccessLog"));
+    iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, scfgobj, iter) {
         if(cfg_handle_accesslog(serverconfig, scfgobj)) {
             return NULL;
         }
     }
-    ucx_list_free(list);
+    cxListDestroy(list);
     
     log_ereport(LOG_DEBUG, "apply config: AuthDB");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("AuthDB"));
-    UCX_FOREACH(elm, list) {
-        ConfigNode *scfgobj = elm->data;
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("AuthDB"));
+    iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, scfgobj, iter) {
         if(cfg_handle_authdb(serverconfig, scfgobj)) {
             return NULL;
         }
     }
-    ucx_list_free(list);
+    cxListDestroy(list);
     
     log_ereport(LOG_DEBUG, "apply config: VirtualServer");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("VirtualServer"));
-    UCX_FOREACH(elm, list) {
-        ConfigNode *scfgobj = elm->data;
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("VirtualServer"));
+    iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, scfgobj, iter) {
         if(cfg_handle_vs(serverconfig, scfgobj)) {
             return NULL;
         }
     }
-    ucx_list_free(list);
+    cxListDestroy(list);
     
     log_ereport(LOG_DEBUG, "apply config: ResourcePool");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("ResourcePool"));
-    UCX_FOREACH(elm, list) {
-        ConfigNode *scfgobj = elm->data;
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("ResourcePool"));
+    iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, scfgobj, iter) {
         if(cfg_handle_resourcepool(serverconfig, scfgobj)) {
             return NULL;
         }
     }
+    cxListDestroy(list);
     
     log_ereport(LOG_DEBUG, "apply config: Dav");
-    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, SC("Dav"));
-    UCX_FOREACH(elm, list) {
-        ConfigNode *scfgobj = elm->data;
+    list = serverconfig_get_node_list(serverconf->root, CONFIG_NODE_OBJECT, cx_str("Dav"));
+    iter = cxListIterator(list, 0);
+    cx_foreach(ConfigNode *, scfgobj, iter) {
         if(cfg_handle_dav(serverconfig, scfgobj)) {
             return NULL;
         }
     }
+    cxListDestroy(list);
 
     // set VirtualServer for all listeners
-    UcxList *ls = serverconfig->listeners;
-    while(ls) {
-        HttpListener *listener = ls->data;
-
-        sstr_t vsname = sstr(listener->default_vs.vs_name);
+    CxList *ls = serverconfig->listeners;
+    iter = cxListIterator(ls, 0);
+    cx_foreach(HttpListener *, listener, iter) {
+        cxstring vsname = cx_str(listener->default_vs.vs_name);
 
         // search for VirtualServer
         //int b = 0;
-        UcxMapIterator iter = ucx_map_iterator(serverconfig->host_vs);
-        VirtualServer *vs;
-        UCX_MAP_FOREACH(key, vs, iter) {
-            if(!sstrcmp(vsname, vs->name)) {
+        CxIterator map_iter = cxMapIteratorValues(serverconfig->host_vs);
+        cx_foreach(VirtualServer *, vs, map_iter) {
+            if(!cx_strcmp(vsname, (cxstring){vs->name.ptr, vs->name.length})) {
                 listener->default_vs.vs = vs;
                 break;
             }
         }
-
-        ls = ls->next;
     }
     
     serverconfig_free(serverconf);
@@ -355,13 +356,13 @@
 }
 
 int cfg_handle_runtime(ServerConfiguration *cfg, ConfigNode *obj) { 
-    scstr_t user = serverconfig_directive_value(obj, SC("User"));
+    cxstring user = serverconfig_directive_value(obj, cx_str("User"));
     if(user.ptr) {
-        cfg->user = sstrdup_a(cfg->a, user);
+        cfg->user = cx_strdup_a(cfg->a, user);
     }
-    scstr_t tmp = serverconfig_directive_value(obj, SC("Temp"));
+    cxstring tmp = serverconfig_directive_value(obj, cx_str("Temp"));
     if(tmp.ptr) {
-        cfg->tmp = sstrdup_a(cfg->a, tmp);
+        cfg->tmp = cx_strdup_a(cfg->a, tmp);
     } else {
         // TODO: do this check after all config loading is done
         log_ereport(LOG_MISCONFIG, "no temporary directory specified");
@@ -369,9 +370,9 @@
     }
     
     // mime file
-    scstr_t mf = serverconfig_directive_value(obj, SC("MimeFile"));  
-    scstr_t base = SC("config/"); 
-    sstr_t file = sstrcat(2, base, mf);
+    cxstring mf = serverconfig_directive_value(obj, cx_str("MimeFile"));  
+    cxstring base = cx_str("config/"); 
+    cxmutstr file = cx_strcat(2, base, mf);
     
     if(mime_conf_load(cfg, file)) {
         return -1;
@@ -382,8 +383,8 @@
 }
 
 int cfg_handle_logfile(ServerConfiguration *cfg, ConfigNode *obj) {
-    scstr_t file = serverconfig_directive_value(obj, SC("File"));
-    scstr_t lvl = serverconfig_directive_value(obj, SC("Level"));
+    cxstring file = serverconfig_directive_value(obj, cx_str("File"));
+    cxstring lvl = serverconfig_directive_value(obj, cx_str("Level"));
     
     int err = 0;
     if(file.ptr == NULL) {
@@ -418,11 +419,11 @@
     poolcfg.queue_size = 64;
     poolcfg.stack_size = 262144;
     
-    scstr_t name  = serverconfig_directive_value(obj, SC("Name"));
-    scstr_t min   = serverconfig_directive_value(obj, SC("MinThreads"));
-    scstr_t max   = serverconfig_directive_value(obj, SC("MaxThreads"));
-    scstr_t stack = serverconfig_directive_value(obj, SC("StackSize"));
-    scstr_t queue = serverconfig_directive_value(obj, SC("QueueSize"));
+    cxstring name  = serverconfig_directive_value(obj, cx_str("Name"));
+    cxstring min   = serverconfig_directive_value(obj, cx_str("MinThreads"));
+    cxstring max   = serverconfig_directive_value(obj, cx_str("MaxThreads"));
+    cxstring stack = serverconfig_directive_value(obj, cx_str("StackSize"));
+    cxstring queue = serverconfig_directive_value(obj, cx_str("QueueSize"));
     // TODO: Type
     
     if(name.length == 0) {
@@ -477,9 +478,9 @@
 int cfg_handle_eventhandler(ServerConfiguration *c, ConfigNode *obj) {
     EventHandlerConfig evcfg;
     
-    scstr_t name      = serverconfig_directive_value(obj, SC("Name"));
-    scstr_t threads   = serverconfig_directive_value(obj, SC("Threads"));
-    scstr_t isdefault = serverconfig_directive_value(obj, SC("Default"));
+    cxstring name      = serverconfig_directive_value(obj, cx_str("Name"));
+    cxstring threads   = serverconfig_directive_value(obj, cx_str("Threads"));
+    cxstring isdefault = serverconfig_directive_value(obj, cx_str("Default"));
     
     evcfg.name = name;
     
@@ -501,8 +502,8 @@
 }
 
 int cfg_handle_resourcepool(ServerConfiguration *cfg, ConfigNode *obj) {
-    scstr_t name = serverconfig_directive_value(obj, SC("Name"));
-    scstr_t type = serverconfig_directive_value(obj, SC("Type"));
+    cxstring name = serverconfig_directive_value(obj, cx_str("Name"));
+    cxstring type = serverconfig_directive_value(obj, cx_str("Type"));
     
     int ret = 0;
     if(resourcepool_new(cfg, type, name, obj)) {
@@ -515,11 +516,11 @@
 int cfg_handle_accesslog(ServerConfiguration *cfg, ConfigNode *obj) {
     // TODO: use a name to identify the log file
     
-    scstr_t file = serverconfig_directive_value(obj, SC("File"));
+    cxstring file = serverconfig_directive_value(obj, cx_str("File"));
     if(file.ptr == NULL) {
         return 0;
     }
-    sstr_t format;
+    cxmutstr format;
     format.ptr = NULL;
     format.length = 0;
     
@@ -530,10 +531,10 @@
         return 0;
     }
     AccessLog *log = pool_malloc(cfg->pool, sizeof(AccessLog));
-    log->file = sstrdup_a(cfg->a, file);
+    log->file = cx_strdup_a(cfg->a, file);
     log->format = format;
     log->log = log_file;
-    cfg->logfiles = ucx_list_append_a(cfg->a, cfg->logfiles, log);
+    cxListAdd(cfg->logfiles, log);
     
     if(!cfg->default_log) {
         cfg->default_log = log;
@@ -543,30 +544,30 @@
 }
 
 int cfg_handle_authdb(ServerConfiguration *cfg, ConfigNode *obj) {
-    scstr_t name = serverconfig_directive_value(obj, SC("Name"));
-    scstr_t type = serverconfig_directive_value(obj, SC("Type"));
+    cxstring name = serverconfig_directive_value(obj, cx_str("Name"));
+    cxstring type = serverconfig_directive_value(obj, cx_str("Type"));
     
     AuthDB *authdb = NULL;
     
-    if(!sstrcmp(type, sstr("ldap"))) {
+    if(!cx_strcmp(type, cx_str("ldap"))) {
         LDAPConfig conf;
         
-        scstr_t host = serverconfig_directive_value(obj, SC("Host"));
-        scstr_t port = serverconfig_directive_value( obj, SC("Port"));
-        scstr_t basedn = serverconfig_directive_value(obj, SC("BaseDN"));
-        scstr_t binddn = serverconfig_directive_value(obj, SC("BindDN"));
-        scstr_t basepw = serverconfig_directive_value(obj, SC("BindPW"));
+        cxstring host = serverconfig_directive_value(obj, cx_str("Host"));
+        cxstring port = serverconfig_directive_value( obj, cx_str("Port"));
+        cxstring basedn = serverconfig_directive_value(obj, cx_str("BaseDN"));
+        cxstring binddn = serverconfig_directive_value(obj, cx_str("BindDN"));
+        cxstring basepw = serverconfig_directive_value(obj, cx_str("BindPW"));
         
-        conf.hostname = sstrdup_a(cfg->a, host).ptr;
+        conf.hostname = cx_strdup_a(cfg->a, host).ptr;
         conf.port = atoi(port.ptr);
-        conf.basedn = sstrdup_a(cfg->a, basedn).ptr;
-        conf.binddn = sstrdup_a(cfg->a, binddn).ptr;
-        conf.bindpw = sstrdup_a(cfg->a, basepw).ptr;
+        conf.basedn = cx_strdup_a(cfg->a, basedn).ptr;
+        conf.binddn = cx_strdup_a(cfg->a, binddn).ptr;
+        conf.bindpw = cx_strdup_a(cfg->a, basepw).ptr;
         
         authdb = create_ldap_authdb(cfg, name.ptr, &conf);      
-    } else if(!sstrcmp(type, sstr("keyfile"))) {
+    } else if(!cx_strcmp(type, cx_str("keyfile"))) {
         // we only need the file parameter
-        scstr_t file = serverconfig_directive_value(obj, SC("File"));
+        cxstring file = serverconfig_directive_value(obj, cx_str("File"));
         if(file.length == 0) {
             log_ereport(
                     LOG_MISCONFIG,
@@ -579,7 +580,7 @@
     }
 
     if(authdb) {
-        if(ucx_map_sstr_put(cfg->authdbs, name, authdb)) {
+        if(cxMapPut(cfg->authdbs, cx_hash_key_bytes((const unsigned char*)name.ptr, name.length), authdb)) {
             return -1;
         }
     }
@@ -594,13 +595,13 @@
     lc.port = 8080;
     lc.nacceptors = 1;
     
-    scstr_t name = serverconfig_directive_value(obj, SC("Name"));
-    scstr_t port = serverconfig_directive_value(obj, SC("Port"));
-    scstr_t vs   = serverconfig_directive_value(obj, SC("DefaultVS"));
-    scstr_t thrp = serverconfig_directive_value(obj, SC("Threadpool"));
-    scstr_t blck = serverconfig_directive_value(obj, SC("BlockingIO"));
+    cxstring name = serverconfig_directive_value(obj, cx_str("Name"));
+    cxstring port = serverconfig_directive_value(obj, cx_str("Port"));
+    cxstring vs   = serverconfig_directive_value(obj, cx_str("DefaultVS"));
+    cxstring thrp = serverconfig_directive_value(obj, cx_str("Threadpool"));
+    cxstring blck = serverconfig_directive_value(obj, cx_str("BlockingIO"));
     
-    // TODO: use sstrdup_pool?
+    // TODO: use cx_strdup_pool?
     int64_t port_value;
     if(!util_strtoint(port.ptr, &port_value)) {
         log_ereport(LOG_MISCONFIG, "Listener: Invalid argument for parameter 'Port': '%s'", port.ptr);
@@ -611,19 +612,19 @@
         return 1;
     }
     
-    lc.name = sstrdup(name);
+    lc.name = cx_strdup(name);
     lc.port = port_value;
-    lc.vs = sstrdup(vs);
-    lc.threadpool = sstrdup(thrp);
+    lc.vs = cx_strdup(vs);
+    lc.threadpool = cx_strdup(thrp);
     
     lc.blockingio = util_getboolean_s(blck, WS_FALSE);
     
-    scstr_t ssl = serverconfig_directive_value(obj, SC("SSL"));
+    cxstring ssl = serverconfig_directive_value(obj, cx_str("SSL"));
     if(util_getboolean_s(ssl, WS_FALSE)) {
-        scstr_t cert        = serverconfig_directive_value(obj, SC("Cert"));
-        scstr_t privkey     = serverconfig_directive_value(obj, SC("Key"));
-        scstr_t chain       = serverconfig_directive_value(obj, SC("CertChain"));
-        scstr_t disableprot = serverconfig_directive_value(obj, SC("SSLDisableProtocol"));
+        cxstring cert        = serverconfig_directive_value(obj, cx_str("Cert"));
+        cxstring privkey     = serverconfig_directive_value(obj, cx_str("Key"));
+        cxstring chain       = serverconfig_directive_value(obj, cx_str("CertChain"));
+        cxstring disableprot = serverconfig_directive_value(obj, cx_str("SSLDisableProtocol"));
         
         WSBool config_ok = WS_TRUE;
         // TODO: log error
@@ -660,8 +661,8 @@
         return 1;
     }
     
-    listener->default_vs.vs_name = sstrdup_a(cfg->a, lc.vs).ptr;
-    cfg->listeners = ucx_list_append_a(cfg->a, cfg->listeners, listener); 
+    listener->default_vs.vs_name = cx_strdup_a(cfg->a, (cxstring){lc.vs.ptr, lc.vs.length}).ptr;
+    cxListAdd(cfg->listeners, listener);
     
     return 0;
 }
@@ -669,18 +670,17 @@
 int cfg_handle_vs(ServerConfiguration *cfg, ConfigNode *obj) {
     VirtualServer *vs = vs_new();
 
-    vs->name = sstrdup_a(cfg->a, serverconfig_directive_value(obj, SC("Name")));
-    vs->host = sstrdup_a(cfg->a, serverconfig_directive_value(obj, SC("Host")));
-    vs->document_root = sstrdup_a(cfg->a, serverconfig_directive_value(obj, SC("DocRoot")));
+    vs->name = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("Name")));
+    vs->host = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("Host")));
+    vs->document_root = cx_strdup_a(cfg->a, serverconfig_directive_value(obj, cx_str("DocRoot")));
     
-    scstr_t objfile = serverconfig_directive_value(obj, SC("ObjectFile"));
-    scstr_t aclfile = serverconfig_directive_value(obj, SC("ACLFile"));
+    cxstring objfile = serverconfig_directive_value(obj, cx_str("ObjectFile"));
+    cxstring aclfile = serverconfig_directive_value(obj, cx_str("ACLFile"));
     
     // load the object config file
-    sstr_t base = sstr("config/");
-    sstr_t file = sstrcat(2, base, objfile);
-    // sstrcat with allocator because we want to keep the string
-    file = sstrcat_a(cfg->a, 2, base, objfile);
+    cxstring base = cx_str("config/");
+    // cx_strcat with allocator because we want to keep the string
+    cxmutstr file = cx_strcat_a(cfg->a, 2, base, objfile);
 
     HTTPObjectConfig *httpobj = objconf_load(cfg, file);
     if(!httpobj) {
@@ -691,45 +691,44 @@
     
     
     // load acl config file
-    file = sstrcat(2, base, aclfile);
+    cxmutstr acl_filepath = cx_strcat(2, base, aclfile);
     
-    ACLData *acldata = acl_conf_load(cfg, file);
+    ACLData *acldata = acl_conf_load(cfg, acl_filepath.ptr);
+    free(acl_filepath.ptr);
     if(!acldata) {
         return -1;
     }
     vs->acls = acldata;
     
-    free(file.ptr);
-    
     
     // set the access log for the virtual server
     // TODO: don't always use the default
     vs->log = cfg->default_log;
 
-    ucx_map_sstr_put(cfg->host_vs, vs->host, vs);
+    cxMapPut(cfg->host_vs, cx_hash_key_bytes((unsigned const char*)vs->host.ptr, vs->host.length), vs);
     
     return 0;
 }
 
 int cfg_handle_dav(ServerConfiguration *cfg, ConfigNode *obj) {
-    UcxList *backends = NULL; // list of ConfigArg*
-    UcxAllocator a = util_pool_allocator(cfg->pool);
+    CxAllocator *a = pool_allocator(cfg->pool);
+    CxList *backends = cxPointerLinkedListCreate(a, cx_cmp_ptr); // list of ConfigParam*
     int init_error;
     
     // parse args
     char *uri = NULL;
     char *ppath = NULL;
     char *name = NULL;
-    UCX_FOREACH(elm, obj->args) {
-        ConfigArg *arg = elm->data;
+    for(ConfigParam *arg=obj->args;arg;arg=arg->next) {
+        cxstring arg_name = (cxstring){ arg->name.ptr, arg->name.length };
         if(arg->name.ptr == NULL) {
             // default: uri
             uri = arg->value.ptr;
-        } else if(!sstrcasecmp(arg->name, SC("uri"))) {
+        } else if(!cx_strcasecmp(arg_name, cx_str("uri"))) {
             uri = arg->value.ptr;
-        } else if(!sstrcasecmp(arg->name, SC("ppath"))) {
+        } else if(!cx_strcasecmp(arg_name, cx_str("ppath"))) {
             ppath = arg->value.ptr;
-        } else if(!sstrcasecmp(arg->name, SC("name"))) {
+        } else if(!cx_strcasecmp(arg_name, cx_str("name"))) {
             name = arg->value.ptr;
         }
     }
@@ -738,21 +737,20 @@
     }
     
     // get a list of all DavBackends
-    UCX_FOREACH(elm, obj->children) {
-        ConfigNode *node = elm->data;
-        if(!sstrcasecmp(node->name, SC("DavBackend"))) {
+    for(ConfigNode *node=obj->children_begin;node;node=node->next) {
+        cxstring node_name = cx_strn(node->name.ptr, node->name.length);
+        if(!cx_strcasecmp(node_name, cx_str("DavBackend"))) {
             if(node->type == CONFIG_NODE_DIRECTIVE) {
-                if(ucx_list_size(node->args) == 1) {
-                    ConfigArg *arg = node->args->data;
-                    backends = ucx_list_append(backends, arg);
+                if(CFG_NUM_PARAMS(node->args) == 1) {
+                    cxListAdd(backends, node->args);
                 } else {
                     log_ereport(LOG_MISCONFIG, "DavBackend must have only one value");
-                    ucx_list_free(backends);
+                    cxListDestroy(backends);
                     return 1;
                 }
             } else {
                 log_ereport(LOG_MISCONFIG, "DavBackend must be a directive");
-                ucx_list_free(backends);
+                cxListDestroy(backends);
                 return 1;
             }
         }
@@ -762,14 +760,14 @@
     WebdavRepository *repository = pool_malloc(cfg->pool, sizeof(WebdavRepository));
     repository->vfs = NULL;
     repository->vfsInitData = NULL;
-    repository->davBackends = NULL;
+    repository->davBackends = cxPointerLinkedListCreate(a, cx_cmp_ptr); // value type: WebdavBackendInitData*
     
     // initialize backends
-    UCX_FOREACH(elm, backends) {
+    CxIterator i = cxListIterator(backends, 0);
+    cx_foreach(ConfigParam *, backendArg, i) {
         // the DavBackend value should contain the dav class name
-        ConfigArg *backendArg = elm->data;
         
-        WebdavType *dav = webdav_get_type((scstr_t){backendArg->value.ptr, backendArg->value.length});
+        WebdavType *dav = webdav_get_type((cxstring){backendArg->value.ptr, backendArg->value.length});
         if(!dav) {
             log_ereport(LOG_MISCONFIG, "Unknown webdav backend type '%s'", backendArg->value.ptr);
             ret = 1;
@@ -794,13 +792,14 @@
         davInit->davType = dav;
         davInit->davInitData = init_data;
         
-        repository->davBackends = ucx_list_append_a(&a, repository->davBackends, davInit);
+        cxListAdd(repository->davBackends, davInit);
     }
+    cxListDestroy(backends);
     
     // initialize vfs
-    scstr_t vfs_class = serverconfig_directive_value(obj, SC("VFS"));
+    cxstring vfs_class = serverconfig_directive_value(obj, cx_str("VFS"));
     if(vfs_class.length > 0) {
-        VfsType *vfs = vfs_get_type((scstr_t){vfs_class.ptr, vfs_class.length});
+        VfsType *vfs = vfs_get_type((cxstring){vfs_class.ptr, vfs_class.length});
         if(vfs) {
             repository->vfs = vfs;
             repository->vfsInitData = vfs_init_backend(cfg, cfg->pool, vfs, obj, &init_error);
@@ -813,9 +812,9 @@
         }
     }
     
-    scstr_t object = serverconfig_directive_value(obj, SC("Object"));
+    cxstring object = serverconfig_directive_value(obj, cx_str("Object"));
     if(object.length > 0) {
-        repository->object = sstrdup_a(&a, object);
+        repository->object = cx_strdup_a(a, object);
         if(repository->object.length != object.length) {
             // OOM
             log_ereport(LOG_FAILURE, "Cannot create webdav repository: OOM");
@@ -825,7 +824,7 @@
     
     if(!ret) {
         if(name) {
-            ucx_map_cstr_put(cfg->dav, name, repository);
+            cxMapPut(cfg->dav, cx_hash_key_str(name), repository);
         } else {
             log_ereport(LOG_FAILURE, "TODO: location based dav repositories not implemented");
             ret = 1;
@@ -835,23 +834,22 @@
     return ret;    
 }
 
-static int convert_objconf(ServerConfiguration *scfg, ObjectConfig *cfg, HTTPObjectConfig *conf, sstr_t file) {
+static int convert_objconf(ServerConfiguration *scfg, ObjectConfig *cfg, HTTPObjectConfig *conf, cxmutstr file) {
     pool_handle_t *pool = conf->pool;
     
-    UcxList *objlist = cfg->objects;
+    CxList *objlist = cfg->objects;
+    CxIterator iter = cxListIterator(objlist, 0);
     int i = 0;
-    while(objlist != NULL) {
-        ConfigObject *cob = objlist->data;
-
+    cx_foreach(ConfigObject*, cob, iter) {
         // get name and ppath
         char *name = NULL;
         char *ppath = NULL;
         if(cob->name.length > 0) {
-            name = sstrdup_pool(pool, cob->name).ptr;
+            name = cx_strdup_pool(pool, cob->name).ptr;
             if(!name) return -1;
         }
         if(cob->ppath.length > 0) {
-            ppath = sstrdup_pool(pool, cob->ppath).ptr;
+            ppath = cx_strdup_pool(pool, cob->ppath).ptr;
             if(!ppath) return -1;
         }
 
@@ -864,14 +862,14 @@
 
         // add directives
         for(int j=0;j<NUM_NSAPI_TYPES-1;j++) {
-            UcxList *dirs = cob->directives[j];
+            ConfigDirectiveList *dirs = cob->directives[j];
             while(dirs != NULL) {
-                ConfigDirective *cfgdir = dirs->data;
+                ConfigDirective *cfgdir = dirs->directive;
 
                 directive *d = pool_malloc(pool, sizeof(directive));
                 if(!d) return -1;
                 if(cfgdir->condition) {
-                    sstr_t expr = cfgdir->condition->param_str;
+                    cxmutstr expr = cfgdir->condition->param_str;
                     d->cond = condition_from_str(pool, expr.ptr, expr.length);
                 } else {
                     d->cond = NULL;
@@ -879,14 +877,13 @@
                 d->param = pblock_create_pool(pool, 8);
 
                 // add params
-                UcxList *param = cfg_param_list(cfgdir->value, scfg->a);
+                ConfigParam *param = cfg_param_list(cfgdir->value, scfg->a);
                 while(param != NULL) {
-                    ConfigParam *p = param->data;
                     pblock_nvlinsert(
-                            p->name.ptr,
-                            p->name.length,
-                            p->value.ptr,
-                            p->value.length,
+                            param->name.ptr,
+                            param->name.length,
+                            param->value.ptr,
+                            param->value.length,
                             d->param);
                     param = param->next;
                 }
@@ -912,13 +909,12 @@
 
         // next
         i++;
-        objlist = objlist->next;
     }
     
     return 0;
 }
 
-HTTPObjectConfig* objconf_load(ServerConfiguration *scfg, sstr_t file) {
+HTTPObjectConfig* objconf_load(ServerConfiguration *scfg, cxmutstr file) {
     log_ereport(LOG_VERBOSE, "load_obj_conf");
     
     int ret = 0;
@@ -940,7 +936,7 @@
     // convert ObjectConfig to HTTPObjectConfig
 
     // add objects
-    conf->nobj = ucx_list_size(cfg->objects);
+    conf->nobj = cfg->objects->size;
     conf->objects = pool_calloc(pool, conf->nobj, sizeof(httpd_object*));
     if(conf->objects) {
         ret = convert_objconf(scfg, cfg, conf, file);
@@ -953,7 +949,7 @@
     return !ret ? conf : NULL;
 }
 
-int mime_conf_load(ServerConfiguration *cfg, sstr_t file) {
+int mime_conf_load(ServerConfiguration *cfg, cxmutstr file) {
     MimeConfig *mimecfg = load_mime_config(file.ptr);
     if(!mimecfg) {
         return -1;
@@ -962,20 +958,19 @@
     int ret = 0;
     
     // cleanup in case of errors is done by the allocator
-    MimeMap *mimemap = almalloc(cfg->a, sizeof(MimeMap));
-    UcxMap *map = ucx_map_new_a(cfg->a, (mimecfg->ntypes * 3) / 2);
+    MimeMap *mimemap = cxMalloc(cfg->a, sizeof(MimeMap));
+    CxMap *map = cxHashMapCreate(cfg->a, (mimecfg->ntypes * 3) / 2);
     
     if(mimemap && map) {
         mimemap->map = map;
         
         // add ext type pairs
-        UCX_FOREACH(md, mimecfg->directives) {
-            MimeDirective *d = md->data;
+        for(MimeDirective *d=mimecfg->directives_begin;d;d=d->next) {
             // add the type for each extension to the map
-            UCX_FOREACH(xl, d->exts) {
-                sstr_t ext = sstr(xl->data);
-                sstr_t value = sstrdup(d->type);
-                if(ucx_map_sstr_put(map, ext, value.ptr)) {
+            for(int i=0;i<d->nextensions;i++) {
+                cxstring ext = d->extensions[i];
+                cxmutstr value = cx_strdup(cx_strn(d->type.ptr, d->type.length));
+                if(cxMapPut(map, cx_hash_key_bytes((const unsigned char *)ext.ptr, ext.length), value.ptr)) {
                     log_ereport(LOG_CATASTROPHE, "OOM");
                     ret = -1;
                     break;
@@ -998,17 +993,21 @@
 
 
 
-ACLData* acl_conf_load(ServerConfiguration *cfg, sstr_t file) {
-    ACLFile *aclfile = load_acl_file(file.ptr);
+ACLData* acl_conf_load(ServerConfiguration *cfg, const char *file) {
+    ACLFile *aclfile = load_acl_file(file);
+    if(!aclfile) {
+        log_ereport(LOG_FAILURE, "Cannot load acl file %s", file);
+        return NULL;
+    }
     
     // TODO: malloc return checks
     
     ACLData *acldata = acl_data_new(cfg->a);
-    UCX_FOREACH(elm, aclfile->namedACLs) {
-        ACLConfig *ac = elm->data;
+    CxIterator iter = cxListIterator(aclfile->namedACLs, 0);
+    cx_foreach(ACLConfig *, ac, iter) {
         ACLList *acl = acl_config_convert(cfg, ac);
         log_ereport(LOG_VERBOSE, "add acl: %.*s", (int)ac->id.length, ac->id.ptr);
-        ucx_map_sstr_put(acldata->namedACLs, ac->id, acl);
+        cxMapPut(acldata->namedACLs, cx_hash_key(ac->id.ptr, ac->id.length), acl);
     }
     free_acl_file(aclfile);
     
@@ -1016,9 +1015,9 @@
 }
 
 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) {
-    UcxAllocator *a = cfg->a;
+    CxAllocator *a = cfg->a;
     
-    WSAcl *acllist = almalloc(cfg->a, sizeof(WSAcl));
+    WSAcl *acllist = cxMalloc(cfg->a, sizeof(WSAcl));
     acllist->acl.check = (acl_check_f)wsacl_check;
     acllist->acl.authdb = NULL;
     acllist->acl.authprompt = NULL;
@@ -1026,26 +1025,24 @@
     acllist->ace = NULL;
     acllist->ece = NULL;
     
-    if(acl->type.ptr && !sstrcmp(acl->type, sstr("fs"))) {
+    if(acl->type.ptr && !cx_strcmp(cx_strn(acl->type.ptr, acl->type.length), cx_str("fs"))) {
         acllist->acl.isextern = 1;
     }
     
-    size_t s = ucx_list_size(acl->entries);
+    size_t s = CFG_ACE_LIST_SIZE(acl->entries);
     WSAce **tmp_aces = calloc(s, sizeof(WSAce*));
     WSAce **tmp_eces = calloc(s, sizeof(WSAce*));
     int ai = 0;
     int ei = 0;
     
     // convert entries
-    UCX_FOREACH(elm, acl->entries) {
-        ACEConfig *acecfg = elm->data;
-        
+    for(ACEConfig *acecfg=acl->entries;acecfg;acecfg=acecfg->next) {
         // copy data
-        WSAce *ace = almalloc(a, sizeof(WSAce));
+        WSAce *ace = cxMalloc(a, sizeof(WSAce));
         ace->access_mask = acecfg->access_mask;
         ace->flags = acecfg->flags;
         ace->type = acecfg->type;
-        ace->who = sstrdup_a(a, acecfg->who).ptr;
+        ace->who = cx_strdup_a(a, cx_strcast(acecfg->who)).ptr;
         
         // add the entry to the correct array
         if(ace->type >= ACL_TYPE_AUDIT) {
@@ -1059,10 +1056,10 @@
     
     // create new entrie arrays with perfect fitting size
     if(ai > 0) {
-        acllist->ace = alcalloc(a, ai, sizeof(WSAce*));
+        acllist->ace = cxCalloc(a, ai, sizeof(WSAce*));
     }
     if(ei > 0) {
-        acllist->ece = alcalloc(a, ei, sizeof(WSAce*));
+        acllist->ece = cxCalloc(a, ei, sizeof(WSAce*));
     }
     memcpy(acllist->ace, tmp_aces, ai*sizeof(WSAce*));
     memcpy(acllist->ece, tmp_eces, ei*sizeof(WSAce*));
@@ -1074,14 +1071,14 @@
     
     // get authentication information
     if(acl->authparam) {
-        sstr_t authdb_str = cfg_param_get(acl->authparam, sstr("authdb"));
-        sstr_t prompt_str = cfg_param_get(acl->authparam, sstr("prompt"));
+        cxmutstr authdb_str = cfg_param_get(acl->authparam, cx_str("authdb"));
+        cxmutstr prompt_str = cfg_param_get(acl->authparam, cx_str("prompt"));
         
         if(authdb_str.ptr) {
-            AuthDB *authdb = ucx_map_sstr_get(cfg->authdbs, authdb_str);
+            AuthDB *authdb = cxMapGet(cfg->authdbs, cx_hash_key(authdb_str.ptr, authdb_str.length));
             acllist->acl.authdb = authdb;
             if(authdb && prompt_str.ptr) {
-                acllist->acl.authprompt = sstrdup_a(a, prompt_str).ptr;
+                acllist->acl.authprompt = cx_strdup_a(a, cx_strcast(prompt_str)).ptr;
             }
         }
     }
@@ -1089,7 +1086,7 @@
     return &acllist->acl;
 }
 
-AuthDB* keyfile_load(ServerConfiguration *cfg, scstr_t file) {
+AuthDB* keyfile_load(ServerConfiguration *cfg, cxstring file) {
     Keyfile *keyfile = keyfile_new(cfg->a);
     if(!keyfile) {
         return NULL;
@@ -1102,8 +1099,7 @@
     
     AuthDB *ret = &keyfile->authdb;
     
-    UCX_FOREACH(elm, conf->users) {
-        KeyfileEntry *user = elm->data;
+    for(KeyfileEntry *user=conf->users_begin;user;user=user->next) {
         if(keyfile_add_user(
                 keyfile,
                 user->name,
@@ -1124,10 +1120,9 @@
 
 pblock* config_obj2pblock(pool_handle_t *pool, ConfigNode *obj) {
     pblock *pb = pblock_create_pool(pool, 8);
-    UCX_FOREACH(elm, obj->children) {
-        ConfigNode *d = elm->data;
-        if(d->type == CONFIG_NODE_DIRECTIVE && d->name.length > 0 && ucx_list_size(d->args) == 1) {
-            ConfigArg *arg = d->args->data;
+    for(ConfigNode *d=obj->children_begin;d;d=d->next) {
+        if(d->type == CONFIG_NODE_DIRECTIVE && d->name.length > 0 && CFG_NUM_PARAMS(d->args) == 1) {
+            ConfigParam *arg = d->args;
             pblock_nvlinsert(d->name.ptr, d->name.length, arg->value.ptr, arg->value.length, pb);
         }
     }

mercurial