refactor configuration loading mechanism config

Mon, 24 Aug 2020 12:50:16 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 24 Aug 2020 12:50:16 +0200
branch
config
changeset 255
b5d15a4a19f5
parent 254
4784c14aa639
child 256
19259b6c5cf7

refactor configuration loading mechanism

src/server/config/keyfile.c file | annotate | diff | comparison | revisions
src/server/config/keyfile.h file | annotate | diff | comparison | revisions
src/server/config/mimeconf.c file | annotate | diff | comparison | revisions
src/server/config/mimeconf.h file | annotate | diff | comparison | revisions
src/server/daemon/acldata.c file | annotate | diff | comparison | revisions
src/server/daemon/acldata.h file | annotate | diff | comparison | revisions
src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/config.h file | annotate | diff | comparison | revisions
src/server/daemon/configmanager.c file | annotate | diff | comparison | revisions
src/server/daemon/configmanager.h file | annotate | diff | comparison | revisions
src/server/daemon/keyfile_auth.c file | annotate | diff | comparison | revisions
src/server/daemon/keyfile_auth.h file | annotate | diff | comparison | revisions
src/server/daemon/vserver.c file | annotate | diff | comparison | revisions
src/server/daemon/vserver.h file | annotate | diff | comparison | revisions
--- a/src/server/config/keyfile.c	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/config/keyfile.c	Mon Aug 24 12:50:16 2020 +0200
@@ -31,7 +31,7 @@
 
 #include "keyfile.h"
 
-KeyfileConfig *load_keyfile_config(char *file) {
+KeyfileConfig *load_keyfile_config(const char *file) {
     FILE *in = fopen(file, "r");
     if(in == NULL) {
         return NULL;
@@ -39,7 +39,7 @@
     
     KeyfileConfig *conf = malloc(sizeof(KeyfileConfig));
     conf->parser.parse = keyfile_parse;
-    conf->file = file;
+    conf->file = strdup(file);
     conf->users = NULL;
 
     int r = cfg_parse_basic_file((ConfigParser*)conf, in);
--- a/src/server/config/keyfile.h	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/config/keyfile.h	Mon Aug 24 12:50:16 2020 +0200
@@ -50,7 +50,7 @@
     size_t               numgroups;
 } KeyfileEntry;
 
-KeyfileConfig *load_keyfile_config(char *file);
+KeyfileConfig *load_keyfile_config(const char *file);
 void free_keyfile_config(KeyfileConfig *conf);
 int keyfile_parse(void *p, ConfigLine *begin, ConfigLine *end, sstr_t line);
 
--- a/src/server/config/mimeconf.c	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/config/mimeconf.c	Mon Aug 24 12:50:16 2020 +0200
@@ -38,7 +38,7 @@
     void           *ptr;
 } ucx_regdestr;
 
-MimeConfig *load_mime_config(char *file) {
+MimeConfig *load_mime_config(const char *file) {
     FILE *in = fopen(file, "r");
     if(in == NULL) {
         return NULL;
@@ -46,7 +46,6 @@
     
     MimeConfig *conf = malloc(sizeof(MimeConfig));
     conf->parser.parse = mimeconf_parse;
-    conf->file = file;
     conf->directives = NULL;
     conf->ntypes = 0;
     int r = cfg_parse_basic_file((ConfigParser*)conf, in);
--- a/src/server/config/mimeconf.h	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/config/mimeconf.h	Mon Aug 24 12:50:16 2020 +0200
@@ -37,7 +37,6 @@
 
 typedef struct _mime_conf {
     ConfigParser parser;
-    char         *file;
     UcxList      *directives; // MimeDirective list
     int          ntypes;
 } MimeConfig;
@@ -47,7 +46,7 @@
     UcxList *exts; // char*
 } MimeDirective;
 
-MimeConfig *load_mime_config(char *file);
+MimeConfig *load_mime_config(const char *file);
 
 void free_mime_config(MimeConfig *conf);
 
--- a/src/server/daemon/acldata.c	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/acldata.c	Mon Aug 24 12:50:16 2020 +0200
@@ -32,39 +32,20 @@
 
 #include "acldata.h"
 
-ACLData* acl_data_new() {
-    ACLData *dat = malloc(sizeof(ACLData));
-    dat->ref = 1;
+ACLData* acl_data_new(UcxAllocator *a) {
+    ACLData *dat = almalloc(a, sizeof(ACLData));
+    if(!dat) {
+        return NULL;
+    }
     
-    dat->namedACLs = ucx_map_new(16);
+    dat->namedACLs = ucx_map_new_a(a, 16);
+    if(!dat->namedACLs) {
+        return NULL;
+    }
     
     return dat;
 }
 
-void acl_data_ref(ACLData *acldata) {
-    if(acldata) {
-        ws_atomic_inc32(&acldata->ref);
-    }
-}
-
-void acl_data_unref(ACLData *acldata) {
-    uint32_t ref = ws_atomic_dec32(&acldata->ref);
-    if(ref == 0) {
-        UcxMapIterator i = ucx_map_iterator(acldata->namedACLs);
-        WSAcl *acl;
-        UCX_MAP_FOREACH(key, acl, i) {
-            free(acl->ace);
-            free(acl->ece);
-            if(acl->acl.authprompt) {
-                free(acl->acl.authprompt);
-            }
-            free(acl);
-        }
-        ucx_map_free(acldata->namedACLs);
-        free(acldata);
-    }
-}
-
 ACLList* acl_get(ACLData *acldata, char *name) {
     ACLList *acl = ucx_map_cstr_get(acldata->namedACLs, name);
     return acl;
--- a/src/server/daemon/acldata.h	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/acldata.h	Mon Aug 24 12:50:16 2020 +0200
@@ -41,12 +41,9 @@
     
 typedef struct acl_data {
     UcxMap  *namedACLs;
-    uint32_t ref;
 } ACLData;
 
 ACLData* acl_data_new();
-void acl_data_ref(ACLData *acldata);
-void acl_data_unref(ACLData *acldata);
 
 ACLList* acl_get(ACLData *acldata, char *name);
 
--- a/src/server/daemon/config.c	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/config.c	Mon Aug 24 12:50:16 2020 +0200
@@ -55,10 +55,8 @@
 #include "../util/atomic.h"
 #include "ucx/buffer.h"
 
-pool_handle_t *cfg_pool;
+pool_handle_t *init_pool;
 
-// TODO: Funktion für ConfigDirective -> directive
-// TODO: Funktion für UcxList parameter list -> pblock
 
 int load_init_conf(char *file) {
     log_ereport(LOG_VERBOSE, "load_init_conf");
@@ -70,14 +68,14 @@
     }
     UcxAllocator *mp = cfg->parser.mp;
 
-    cfg_pool = pool_create(); // one pool for one Configuration
+    init_pool = pool_create(); // one pool for one Configuration
     UcxList *dirs = cfg->directives;
     while(dirs != NULL) {
         ConfigDirective *dir = dirs->data;
 
         /* create NSAPI directive */
         directive *d = malloc(sizeof(directive));
-        d->param = pblock_create_pool(cfg_pool, 8);
+        d->param = pblock_create_pool(init_pool, 8);
         UcxList *param = cfg_param_list(dir->value, mp);
         while(param != NULL) {
             ConfigParam *p = param->data;
@@ -127,19 +125,27 @@
     return 0;
 }
 
-ServerConfiguration* load_server_conf(ServerConfiguration *old, char *file) {
+ServerConfiguration* load_server_conf(char *file) {
     log_ereport(LOG_VERBOSE, "load_server_conf");
 
-    ServerConfig2 *serverconf = load_server_config(file);
-    if(serverconf == NULL) {
+    ServerConfig2 *serverconf2 = load_server_config(file);
+    if(serverconf2 == NULL) {
         log_ereport(LOG_FAILURE, "Cannot load server.conf");
     }
-    ServerConfiguration *serverconfig = calloc(1, sizeof(ServerConfiguration));
+    pool_handle_t *pool = pool_create();
+    
+    
+    ServerConfiguration *serverconfig = pool_calloc(pool, 1, sizeof(ServerConfiguration));
     serverconfig->ref = 1;
-    serverconfig->pool = pool_create();
+    serverconfig->pool = pool;
     serverconfig->listeners = NULL;
     serverconfig->host_vs = ucx_map_new(16);
     serverconfig->authdbs = ucx_map_new(16);
+    
+    UcxAllocator allocator = util_pool_allocator(serverconfig->pool);
+    serverconfig->a = pool_malloc(pool, sizeof(UcxAllocator));
+    *serverconfig->a = allocator;
+    
     // TODO: init serverconfig stuff
     
     
@@ -161,7 +167,7 @@
      */
     
     // init logfile first
-    UcxList *lfl = ucx_map_sstr_get(serverconf->objects, sstrn("LogFile", 7));
+    UcxList *lfl = ucx_map_sstr_get(serverconf2->objects, sstrn("LogFile", 7));
     if(lfl != NULL) {
         ServerConfigObject *logobj = lfl->data;
         if(logobj == NULL) {
@@ -179,7 +185,7 @@
         return NULL;
     }
      
-    UcxList *list = ucx_map_sstr_get(serverconf->objects, sstrn("Runtime", 7));
+    UcxList *list = ucx_map_sstr_get(serverconf2->objects, sstrn("Runtime", 7));
     UCX_FOREACH(elm, list) {
         ServerConfigObject *scfgobj = elm->data;
         if(cfg_handle_runtime(serverconfig, scfgobj)) {
@@ -188,7 +194,7 @@
         }
     }
     
-    list = ucx_map_sstr_get(serverconf->objects, sstrn("Threadpool", 10));
+    list = ucx_map_sstr_get(serverconf2->objects, sstrn("Threadpool", 10));
     UCX_FOREACH(elm, list) {
         if(cfg_handle_threadpool(serverconfig, elm->data)) {
             return NULL;
@@ -200,7 +206,7 @@
         return NULL;
     }
     
-    list = ucx_map_sstr_get(serverconf->objects, sstrn("EventHandler", 12));
+    list = ucx_map_sstr_get(serverconf2->objects, sstrn("EventHandler", 12));
     UCX_FOREACH(elm, list) {
         if(cfg_handle_eventhandler(
                 serverconfig, (ServerConfigObject*)elm->data)) {
@@ -214,7 +220,7 @@
         return NULL;
     }
     
-    list = ucx_map_sstr_get(serverconf->objects, sstrn("AccessLog", 9));
+    list = ucx_map_sstr_get(serverconf2->objects, sstrn("AccessLog", 9));
     UCX_FOREACH(elm, list) {
         ServerConfigObject *scfgobj = elm->data;
         if(cfg_handle_accesslog(serverconfig, scfgobj)) {
@@ -222,7 +228,7 @@
         }
     }
     
-    list = ucx_map_sstr_get(serverconf->objects, sstrn("AuthDB", 6));
+    list = ucx_map_sstr_get(serverconf2->objects, sstrn("AuthDB", 6));
     UCX_FOREACH(elm, list) {
         ServerConfigObject *scfgobj = elm->data;
         if(cfg_handle_authdb(serverconfig, scfgobj)) {
@@ -230,7 +236,7 @@
         }
     }
     
-    list = ucx_map_sstr_get(serverconf->objects, sstrn("Listener", 8));
+    list = ucx_map_sstr_get(serverconf2->objects, sstrn("Listener", 8));
     UCX_FOREACH(elm, list) {
         ServerConfigObject *scfgobj = elm->data;
         if(cfg_handle_listener(serverconfig, scfgobj)) {
@@ -238,7 +244,7 @@
         }
     }
     
-    list = ucx_map_sstr_get(serverconf->objects, sstrn("VirtualServer", 13));
+    list = ucx_map_sstr_get(serverconf2->objects, sstrn("VirtualServer", 13));
     UCX_FOREACH(elm, list) {
         ServerConfigObject *scfgobj = elm->data;
         if(cfg_handle_vs(serverconfig, scfgobj)) {
@@ -268,7 +274,7 @@
         ls = ls->next;
     }
     
-    free_server_config(serverconf);
+    free_server_config(serverconf2);
     return serverconfig;
 }
 
@@ -279,8 +285,7 @@
 void cfg_unref(ServerConfiguration *cfg) {
     uint32_t ref = ws_atomic_dec32(&cfg->ref);
     if(ref == 0) {
-        // TODO: free configuration
-        printf("free ServerConfiguration %"PRIxPTR"\n", (intptr_t)cfg);
+        pool_destroy(cfg->pool);
     }
 }
 
@@ -307,28 +312,10 @@
     sstr_t base = sstr("config/"); 
     sstr_t file = sstrcat(2, base, mf);
     
-    ConfigFile *f = cfgmgr_get_file(file);
-    if(f == NULL) {
-        f = malloc(sizeof(ConfigFile));
-        f->data = NULL;
-        f->file = sstrdup(file);
-        f->reload = mime_conf_reload;
-        f->last_modified = 0;
-        
-        // load the file content
-        //f->reload(f, cfg);
-        if(cfgmgr_reload_file(f, cfg, NULL)) {
-            free(f->file.ptr);
-            free(f);
-            
-            free(file.ptr);
-            return -1;
-        }
-        cfgmgr_attach_file(f);
+    if(mime_conf_load(cfg, file)) {
+        return -1;
     }
     
-    cfg->mimetypes = f->data;
-    
     free(file.ptr);
     return 0;
 }
@@ -472,6 +459,8 @@
     sstr_t name = cfg_directivelist_get_str(obj->directives, sstr("Name"));
     sstr_t type = cfg_directivelist_get_str(obj->directives, sstr("Type"));
     
+    AuthDB *authdb = NULL;
+    
     if(!sstrcmp(type, sstr("ldap"))) {
         LDAPConfig conf;
         
@@ -505,8 +494,7 @@
         
         name = sstrdup(name);
         
-        AuthDB *authdb = create_ldap_authdb(name.ptr, &conf);
-        ucx_map_sstr_put(cfg->authdbs, name, authdb);
+        authdb = create_ldap_authdb(name.ptr, &conf);
         
         // TODO: create_ldap_authdb should copy the strings
         /*
@@ -531,28 +519,15 @@
         }
         
         // load keyfile
-        ConfigFile *f = cfgmgr_get_file(file);
-        if(f == NULL) {
-            f = malloc(sizeof(ConfigFile));
-            f->data = NULL;
-            f->file = sstrdup(file);
-            f->reload = keyfile_reload;
-            f->last_modified = 0;
-            //f->reload(f, cfg);
-            if(cfgmgr_reload_file(f, cfg, NULL)) {
-                free(f->file.ptr);
-                free(f);
-                return -1;
-            }
-            cfgmgr_attach_file(f);
-        }
-        
-        // add keyfile authdb
-        Keyfile *keyfile = f->data;
-        keyfile->authdb.name = sstrdup(name).ptr;
-        ucx_map_sstr_put(cfg->authdbs, name, keyfile);
+        authdb = keyfile_load(cfg, file);
     }
 
+    if(authdb) {
+        if(ucx_map_sstr_put(cfg->authdbs, name, authdb)) {
+            return -1;
+        }
+    }
+    
     return 0;
 }
 
@@ -656,56 +631,31 @@
     // load the object config file
     sstr_t base = sstr("config/");
     sstr_t file = sstrcat(2, base, objfile);
-    file = sstrcat(2, base, objfile);
+    // sstrcat with allocator because we want to keep the string
+    file = sstrcat_a(cfg->a, 2, base, objfile);
 
-    // the file is managed by the configuration manager
-    ConfigFile *f = cfgmgr_get_file(file);
-    if(f == NULL) {
-        f = malloc(sizeof(ConfigFile));
-        f->data = NULL;
-        f->file = sstrdup(file);
-        f->reload = object_conf_reload;
-        f->last_modified = 0;
-        //f->reload(f, cfg);
-        if(cfgmgr_reload_file(f, cfg, NULL)) {
-            free(f->file.ptr);
-            free(f);
-            
-            free(file.ptr);
-            return -1;
-        }
-        cfgmgr_attach_file(f);
+    HTTPObjectConfig *httpobj = objconf_load(cfg, file);
+    if(!httpobj) {
+        return -1;
     }
-    vs->objectfile = sstrdup(file);
-    vs->objects = (HTTPObjectConfig*)f->data;
-    free(file.ptr);
+    vs->objectfile = file;
+    vs->objects = httpobj;
     
     
     // load acl config file
     file = sstrcat(2, base, aclfile);
     
-    ConfigFile *aclf = cfgmgr_get_file(file);
-    if(aclf == NULL) {
-        aclf = malloc(sizeof(ConfigFile));
-        aclf->data = NULL;
-        aclf->file = sstrdup(file);
-        aclf->reload = acl_conf_reload;
-        aclf->last_modified = 0;
-        //aclf->reload(aclf, cfg);
-        if(cfgmgr_reload_file(aclf, cfg, NULL)) {
-            free(aclf->file.ptr);
-            free(aclf);
-            
-            free(file.ptr);
-            return -1;
-        }
-        cfgmgr_attach_file(aclf);
+    ACLData *acldata = acl_conf_load(cfg, file);
+    if(!acldata) {
+        return -1;
     }
-    vs->acls = aclf->data;
+    vs->acls = acldata;
+    
     free(file.ptr);
     
+    
     // set the access log for the virtual server
-    // TODO: don't use always the default
+    // TODO: don't always use the default
     vs->log = cfg->default_log;
 
     ucx_map_sstr_put(cfg->host_vs, vs->host, vs);
@@ -714,53 +664,8 @@
 }
 
 
-int object_conf_reload(ConfigFile *file, ServerConfiguration *cfg) {
-    HTTPObjectConfig *old_conf = file->data;
-    file->data = load_obj_conf(file->file.ptr);
-    if(old_conf) {
-        object_conf_unref(old_conf);
-    }
-    if(file->data) {
-        return 0;
-    } else {
-        return 1;
-    }
-}
-
-void object_conf_ref(HTTPObjectConfig *conf) {
-    if(conf) {
-        ws_atomic_inc32(&conf->ref);
-    }
-}
-
-void object_conf_unref(HTTPObjectConfig *conf) {
-    uint32_t ref = ws_atomic_dec32(&conf->ref);
-    if(ref == 0) {
-        printf("free HTTPObjectConfig %"PRIxPTR"\n", (intptr_t)conf);
-        pool_destroy(conf->pool);
-    }
-}
-
-HTTPObjectConfig* load_obj_conf(char *file) {
-    log_ereport(LOG_VERBOSE, "load_obj_conf");
-
-    // new conf function test
-    ObjectConfig *cfg = load_object_config(file);
-    UcxAllocator *mp = cfg->parser.mp;
-    if(cfg == NULL) {
-        return NULL;
-    }
-
-    // create object config
-    pool_handle_t *pool = pool_create();
-    HTTPObjectConfig *conf = pool_calloc(pool, sizeof(HTTPObjectConfig), 1);
-    conf->pool = pool;
-
-    // convert ObjectConfig to HTTPObjectConfig
-
-    // add objects
-    conf->nobj = ucx_list_size(cfg->objects);
-    conf->objects = pool_calloc(pool, conf->nobj, sizeof(httpd_object*));
+static int convert_objconf(ServerConfiguration *scfg, ObjectConfig *cfg, HTTPObjectConfig *conf, sstr_t file) {
+    pool_handle_t *pool = conf->pool;
     
     UcxList *objlist = cfg->objects;
     int i = 0;
@@ -772,13 +677,16 @@
         char *ppath = NULL;
         if(cob->name.length > 0) {
             name = sstrdup_pool(pool, cob->name).ptr;
+            if(!name) return -1;
         }
         if(cob->ppath.length > 0) {
             ppath = sstrdup_pool(pool, cob->ppath).ptr;
+            if(!ppath) return -1;
         }
 
         // create and add object
         httpd_object *obj = object_new(pool, name);
+        if(!obj) return -1;
         obj->path = NULL;
 
         conf->objects[i] = obj;
@@ -788,8 +696,9 @@
             UcxList *dirs = cob->directives[j];
             while(dirs != NULL) {
                 ConfigDirective *cfgdir = dirs->data;
-                
+
                 directive *d = pool_malloc(pool, sizeof(directive));
+                if(!d) return -1;
                 if(cfgdir->condition) {
                     sstr_t expr = cfgdir->condition->param_str;
                     d->cond = condition_from_str(pool, expr.ptr, expr.length);
@@ -799,7 +708,7 @@
                 d->param = pblock_create_pool(pool, 8);
 
                 // add params
-                UcxList *param = cfg_param_list(cfgdir->value, mp);
+                UcxList *param = cfg_param_list(cfgdir->value, scfg->a);
                 while(param != NULL) {
                     ConfigParam *p = param->data;
                     pblock_nvlinsert(
@@ -814,13 +723,13 @@
                 // get function
                 char *func_name = pblock_findval("fn", d->param);
                 if(!func_name) {
-                    log_ereport(LOG_MISCONFIG, "%s: Missing fn parameter", file);
-                    return NULL;
+                    log_ereport(LOG_MISCONFIG, "%s: Missing fn parameter", file.ptr);
+                    return -1;
                 }
                 d->func = get_function(func_name);
                 if(!d->func) {
                     log_ereport(LOG_MISCONFIG, "func %s not found", func_name);
-                    return NULL;
+                    return -1;
                 }
 
                 dirs = dirs->next;
@@ -834,66 +743,94 @@
         i++;
         objlist = objlist->next;
     }
+    
+    return 0;
+}
+
+HTTPObjectConfig* objconf_load(ServerConfiguration *scfg, sstr_t file) {
+    log_ereport(LOG_VERBOSE, "load_obj_conf");
+    
+    int ret = 0;
+
+    // create object config
+    pool_handle_t *pool = scfg->pool;
+    HTTPObjectConfig *conf = pool_calloc(pool, sizeof(HTTPObjectConfig), 1);
+    if(!conf) {
+        return NULL;
+    }
+    conf->pool = pool;
+    
+    // load obj config file
+    ObjectConfig *cfg = load_object_config(file.ptr);
+    if(!cfg) {
+        return NULL;
+    }
+
+    // convert ObjectConfig to HTTPObjectConfig
+
+    // add objects
+    conf->nobj = ucx_list_size(cfg->objects);
+    conf->objects = pool_calloc(pool, conf->nobj, sizeof(httpd_object*));
+    if(conf->objects) {
+        ret = convert_objconf(scfg, cfg, conf, file);
+    } else {
+        ret = -1;
+    }
 
     free_object_config(cfg);
 
-    return conf;
+    return !ret ? conf : NULL;
 }
 
-int mime_conf_reload(ConfigFile *file, ServerConfiguration *cfg) {
-    MimeConfig *mimecfg = load_mime_config(file->file.ptr);
-    MimeMap *old_conf = file->data;
-    
-    MimeMap *mimemap = malloc(sizeof(MimeMap));
-    mimemap->ref = 1;
-    UcxMap *map = ucx_map_new((mimecfg->ntypes * 3) / 2);
-    mimemap->map = map;
-    
-    // add ext type pairs
-    UCX_FOREACH(md, mimecfg->directives) {
-        MimeDirective *d = md->data;
-        // 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);
-            ucx_map_sstr_put(map, ext, value.ptr);
-        }
+int mime_conf_load(ServerConfiguration *cfg, sstr_t file) {
+    MimeConfig *mimecfg = load_mime_config(file.ptr);
+    if(!mimecfg) {
+        return -1;
     }
     
-    file->data = mimemap;
+    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);
     
-    if(old_conf) {
-        mime_conf_unref(old_conf);
+    if(mimemap && map) {
+        mimemap->map = map;
+        
+        // add ext type pairs
+        UCX_FOREACH(md, mimecfg->directives) {
+            MimeDirective *d = md->data;
+            // 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)) {
+                    ret = -1;
+                    break;
+                }
+            }
+            if(ret) {
+                break;
+            }
+        }
+        
+        cfg->mimetypes = mimemap;
+    } else {
+        ret = -1;
     }
     
     free_mime_config(mimecfg);
-    return 0;
-}
-
-void mime_conf_ref(MimeMap *conf) {
-    if(conf) {
-        ws_atomic_inc32(&conf->ref);
-    }
+    return ret;
 }
 
-void mime_conf_unref(MimeMap *conf) {
-    uint32_t ref = ws_atomic_dec32(&conf->ref);
-    if(ref == 0) {
-        printf("free MimeConfig %"PRIxPTR"\n", (intptr_t)conf);
-        UcxMapIterator i = ucx_map_iterator(conf->map);
-        char *str;
-        UCX_MAP_FOREACH(key, str, i) {
-            free(str);
-        }
-        ucx_map_free(conf->map);
-        free(conf);
-    }
-}
+
 
-int acl_conf_reload(ConfigFile *file, ServerConfiguration *cfg) {
-    ACLFile *aclfile = load_acl_file(file->file.ptr);
+ACLData* acl_conf_load(ServerConfiguration *cfg, sstr_t file) {
+    ACLFile *aclfile = load_acl_file(file.ptr);
     
-    ACLData *acldata = acl_data_new();
+    // TODO: malloc return checks
+    
+    ACLData *acldata = acl_data_new(cfg->a);
     UCX_FOREACH(elm, aclfile->namedACLs) {
         ACLConfig *ac = elm->data;
         ACLList *acl = acl_config_convert(cfg, ac);
@@ -902,17 +839,13 @@
     }
     free_acl_file(aclfile);
     
-    ACLData *old_data = file->data;
-    file->data = acldata;
-    if(old_data) {
-        acl_data_unref(old_data);
-    }
-    
-    return 0;
+    return acldata;
 }
 
 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) {
-    WSAcl *acllist = malloc(sizeof(WSAcl));
+    UcxAllocator *a = cfg->a;
+    
+    WSAcl *acllist = almalloc(cfg->a, sizeof(WSAcl));
     acllist->acl.check = (acl_check_f)wsacl_check;
     acllist->acl.authdb = NULL;
     acllist->acl.authprompt = NULL;
@@ -925,8 +858,8 @@
     }
     
     size_t s = ucx_list_size(acl->entries);
-    WSAce **aces = calloc(s, sizeof(WSAce*));
-    WSAce **eces = calloc(s, sizeof(WSAce*));
+    WSAce **tmp_aces = calloc(s, sizeof(WSAce*));
+    WSAce **tmp_eces = calloc(s, sizeof(WSAce*));
     int ai = 0;
     int ei = 0;
     
@@ -935,36 +868,36 @@
         ACEConfig *acecfg = elm->data;
         
         // copy data
-        WSAce *ace = malloc(sizeof(WSAce));
+        WSAce *ace = almalloc(a, sizeof(WSAce));
         ace->access_mask = acecfg->access_mask;
         ace->flags = acecfg->flags;
         ace->type = acecfg->type;
-        ace->who = sstrdup(acecfg->who).ptr;
+        ace->who = sstrdup_a(a, acecfg->who).ptr;
         
         // add the entry to the correct array
         if(ace->type >= ACL_TYPE_AUDIT) {
-            eces[ei] = ace;
+            tmp_eces[ei] = ace;
             ei++;
         } else {
-            aces[ai] = ace;
+            tmp_aces[ai] = ace;
             ai++;
         }
     }
     
     // create new entrie arrays with perfect fitting size
     if(ai > 0) {
-        acllist->ace = calloc(ai, sizeof(WSAce*));
+        acllist->ace = alcalloc(a, ai, sizeof(WSAce*));
     }
     if(ei > 0) {
-        acllist->ece = calloc(ei, sizeof(WSAce*));
+        acllist->ece = alcalloc(a, ei, sizeof(WSAce*));
     }
-    memcpy(acllist->ace, aces, ai*sizeof(WSAce*));
-    memcpy(acllist->ece, eces, ei*sizeof(WSAce*));
+    memcpy(acllist->ace, tmp_aces, ai*sizeof(WSAce*));
+    memcpy(acllist->ece, tmp_eces, ei*sizeof(WSAce*));
     acllist->acenum = ai;
     acllist->ecenum = ei;
     
-    free(aces);
-    free(eces);
+    free(tmp_aces);
+    free(tmp_eces);
     
     // get authentication information
     if(acl->authparam) {
@@ -975,7 +908,7 @@
             AuthDB *authdb = ucx_map_sstr_get(cfg->authdbs, authdb_str);
             acllist->acl.authdb = authdb;
             if(authdb && prompt_str.ptr) {
-                acllist->acl.authprompt = sstrdup(prompt_str).ptr;
+                acllist->acl.authprompt = sstrdup_a(a, prompt_str).ptr;
             }
         }
     }
@@ -983,69 +916,35 @@
     return &acllist->acl;
 }
 
-int keyfile_reload(ConfigFile *file, ServerConfiguration *cfg) {
-    KeyfileConfig *conf = load_keyfile_config(file->file.ptr);
-    if(!conf) {
-        return 1;
+AuthDB* keyfile_load(ServerConfiguration *cfg, sstr_t file) {
+    Keyfile *keyfile = keyfile_new(cfg->a);
+    if(!keyfile) {
+        return NULL;
     }
     
-    Keyfile *keyfile = keyfile_new();
+    KeyfileConfig *conf = load_keyfile_config(file.ptr);
+    if(!conf) {
+        return NULL;
+    }
+    
+    AuthDB *ret = &keyfile->authdb;
     
     UCX_FOREACH(elm, conf->users) {
         KeyfileEntry *user = elm->data;
-        keyfile_add_user(
+        if(keyfile_add_user(
                 keyfile,
                 user->name,
                 user->hashtype,
                 user->hashdata,
                 user->groups,
-                user->numgroups);
+                user->numgroups))
+        {
+            ret = NULL;
+            break;
+        }
     }
     
     free_keyfile_config(conf);
     
-    Keyfile *old_data = file->data;
-    file->data = keyfile;
-    if(old_data) {
-        keyfile_unref(old_data);
-    }
-    
-    return 0;
+    return ret;
 }
-
-
-sstr_t cfg_load_file(sstr_t file) {
-    sstr_t r;
-    r.ptr = NULL;
-    r.length = 0;
-    
-    if(!file.ptr) {
-        return r;
-    }
-    
-    sstr_t f = sstrdup(file);
-    FILE *in = fopen(f.ptr, "r");
-    if(!in) {
-        return r;
-    }
-    
-    UcxBuffer *buf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
-    if(!buf) {
-        fclose(in);
-        return r;
-    }
-    
-    if(ucx_stream_copy(in, buf, (read_func)fread, (write_func)ucx_buffer_write) == 0) {
-        fclose(in);
-        ucx_buffer_free(buf);
-        return r;
-    }
-    
-    r.ptr = buf->space;
-    r.length = buf->pos;
-    
-    free(buf);
-    fclose(in);
-    
-    return r;
-}
--- a/src/server/daemon/config.h	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/config.h	Mon Aug 24 12:50:16 2020 +0200
@@ -57,6 +57,8 @@
     
 typedef struct _server_configuration {
     pool_handle_t   *pool;
+    UcxAllocator    *a;
+    
     UcxMap          *host_vs;   // map of all vservers. key is the host name
     UcxList         *listeners; // list of all listeners
     UcxList         *logfiles;
@@ -69,20 +71,8 @@
 } ServerConfiguration;
 
 
-typedef struct ConfigFile ConfigFile;
-
-typedef int(*cfg_reload_f)(ConfigFile*,ServerConfiguration*);
-
-struct ConfigFile {
-    sstr_t         file;
-    time_t         last_modified;
-    cfg_reload_f   reload;
-    void           *data;
-};
-
 struct mime_map {
     UcxMap   *map;
-    uint32_t ref;
 };
 
 int load_init_conf(char *file);
@@ -105,23 +95,18 @@
 
 int cfg_handle_vs(ServerConfiguration *cfg, ServerConfigObject *obj);
 
-ServerConfiguration* load_server_conf(ServerConfiguration *old, char *file);
+ServerConfiguration* load_server_conf(char *file);
 void cfg_ref(ServerConfiguration *cfg);
 void cfg_unref(ServerConfiguration *cfg);
 
+HTTPObjectConfig* objconf_load(ServerConfiguration *scfg, sstr_t file);
+int mime_conf_load(ServerConfiguration *cfg, sstr_t file);
 
-int object_conf_reload(ConfigFile *file, ServerConfiguration *cfg);
-void object_conf_ref(HTTPObjectConfig *conf);
-void object_conf_unref(HTTPObjectConfig *conf);
-HTTPObjectConfig* load_obj_conf(char *file);
-int mime_conf_reload(ConfigFile *file, ServerConfiguration *cfg);
-void mime_conf_ref(MimeMap *conf);
-void mime_conf_unref(MimeMap *conf);
-int acl_conf_reload(ConfigFile *file, ServerConfiguration *cfg);
+ACLData* acl_conf_load(ServerConfiguration *cfg, sstr_t file);
 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl);
-int keyfile_reload(ConfigFile *file, ServerConfiguration *cfg);
+AuthDB* keyfile_load(ServerConfiguration *cfg, sstr_t file);
 
-sstr_t cfg_load_file(sstr_t file);
+
 
 #ifdef	__cplusplus
 }
--- a/src/server/daemon/configmanager.c	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/configmanager.c	Mon Aug 24 12:50:16 2020 +0200
@@ -38,111 +38,39 @@
 #include "configmanager.h"
 
 static ServerConfiguration *current_config = NULL;
-static time_t sc_last_modified = 0;
 
-static UcxMap *config_files;
 
 static conf_global_vars_s global_vars;
 
 void init_configuration_manager() {
     /* init parser */
     init_server_config_parser();
-
-    config_files = ucx_map_new(16);
 }
 
 NSAPI_PUBLIC conf_global_vars_s* conf_getglobals() {
     return &global_vars;
 }
 
-void cfgmgr_attach_file(ConfigFile *cf) {
-    ucx_map_sstr_put(config_files, cf->file, cf);
-}
-
-ConfigFile* cfgmgr_get_file(sstr_t name) {
-    return ucx_map_sstr_get(config_files, name);
-}
-
-int cfgmgr_reload_file(ConfigFile *f, ServerConfiguration *conf, int *reload) {
-    struct stat s;
-    if(stat(f->file.ptr, &s) != 0) {
-        fprintf(
-                stderr,
-                "Error: Cannot get stat of file %s\n", f->file.ptr);
-        perror("cfgmgr_load_config: stat");
-        return -1;
-    }
+int cfgmgr_load_config(ServerConfiguration **set_cfg) {
+    ServerConfiguration *config = load_server_conf("config/server.conf");
     
-    //printf("1 time: %d - %d\n", f->last_modified, s.st_mtim.tv_sec);
-    if(f->last_modified != s.st_mtime) {
-        /* reload the file */
-        if(f->last_modified != 0) {
-            log_ereport(
-                    LOG_INFORM,
-                    "reload configuration file: %s",
-                    f->file.ptr);
-        }
-        if(f->reload(f, conf)) {
-            return -1;
-        }
-        f->last_modified = s.st_mtime;
-        if(reload) {
-            *reload = 1;
-        }
-    }
-    return 0;
-}
-
-int cfgmgr_load_config(ServerConfiguration **set_cfg) {
-    int cfgreload = 0;
-    
-    /* check config files */  
-    UcxMapIterator iter = ucx_map_iterator(config_files);
-    ConfigFile *f;
-    UCX_MAP_FOREACH(key, f, iter) {
-        if(cfgmgr_reload_file(f, current_config, &cfgreload) == -1) {
-            return -1;
-        }
-    }
-
-    struct stat s;
-    if(stat("config/server.conf", &s) != 0) {
-        perror("stat(\"config/server.conf\")");
+    if(!config) {
         return -1;
     }
-
-    ServerConfiguration *config;
-    if(cfgreload || !current_config || sc_last_modified != s.st_mtime) {
-        config = load_server_conf(
-            current_config,
-            "config/server.conf");
-
-        if(config == NULL) {
-            return -1;
-        }
-        
-        sc_last_modified = s.st_mtime;
-    } else {
-        log_ereport(LOG_VERBOSE, "no reconfig required");
-        config = current_config;
-    }
     
     if(set_cfg) {
          *set_cfg = config;
     }
-    ServerConfiguration *old_conf = NULL;
-    if(current_config != config) {
-        old_conf = current_config;
+    
+    if(current_config) {
+        cfg_unref(current_config);
     }
     current_config = config;
-    if(old_conf) {
-        cfg_unref(old_conf);
-    }
+    
     return 0;
 }
 
 ServerConfiguration *cfgmgr_get_server_config() {
-    //cfg_ref(current_config);
     return current_config;
 }
 
--- a/src/server/daemon/configmanager.h	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/configmanager.h	Mon Aug 24 12:50:16 2020 +0200
@@ -46,9 +46,6 @@
 
 void init_configuration_manager();
 
-void cfgmgr_attach_file(ConfigFile *cf);
-ConfigFile* cfgmgr_get_file(sstr_t name);
-int cfgmgr_reload_file(ConfigFile *f, ServerConfiguration *conf, int *reload);
 int cfgmgr_load_config(ServerConfiguration **cfg);
 
 ServerConfiguration* cfgmgr_get_server_config();
--- a/src/server/daemon/keyfile_auth.c	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/keyfile_auth.c	Mon Aug 24 12:50:16 2020 +0200
@@ -43,40 +43,18 @@
 
 #include "keyfile_auth.h"
 
-Keyfile* keyfile_new() {
-    Keyfile *keyfile = malloc(sizeof(Keyfile));
+Keyfile* keyfile_new(UcxAllocator *a) {
+    Keyfile *keyfile = alcalloc(a, 1, sizeof(Keyfile));
+    if(!keyfile) {
+        return NULL;
+    }
     keyfile->authdb.get_user = keyfile_get_user;
     keyfile->authdb.use_cache = 0;
-    keyfile->users = ucx_map_new(16);
-    keyfile->ref = 1;
+    keyfile->users = ucx_map_new_a(a, 16);
     return keyfile;
 }
 
-void keyfile_ref(Keyfile *keyfile) {
-    ws_atomic_inc32(&keyfile->ref);
-}
-
-void keyfile_unref(Keyfile *keyfile) {
-    uint32_t ref = ws_atomic_dec32(&keyfile->ref);
-    if(ref == 0) { 
-        UcxMapIterator i = ucx_map_iterator(keyfile->users);
-        KeyfileUser *user;
-        UCX_MAP_FOREACH(key, user, i) {
-            free(user->user.name);
-            free(user->hash);
-            for(int n=0;n<user->numgroups;n++) {
-                free(user->groups[n].ptr);
-            }
-            free(user->groups);
-        }
-        ucx_map_free(keyfile->users);
-        
-        free(keyfile->authdb.name);
-        free(keyfile);
-    }
-}
-
-void keyfile_add_user(
+int keyfile_add_user(
         Keyfile *keyfile,
         sstr_t name,
         enum KeyfileHashType hash_type,
@@ -84,14 +62,16 @@
         sstr_t *groups,
         size_t ngroups)
 {
+    UcxAllocator *a = keyfile->users->allocator;
+    
     if(hash.length < 12) {
         // hash too short
         // TODO: log
-        return;
+        return -1;
     }
     
-    KeyfileUser *user = malloc(sizeof(KeyfileUser));
-    user->user.name = sstrdup(name).ptr;
+    KeyfileUser *user = almalloc(a, sizeof(KeyfileUser));
+    user->user.name = sstrdup_a(a, name).ptr;
     user->user.uid = -1;
     user->user.gid = -1;
     user->user.verify_password = keyfile_user_verify_password;
@@ -99,16 +79,29 @@
     user->user.free = keyfile_user_free;
     
     user->hash_type = hash_type;
-    user->hash = malloc(hash.length + 1);
+    user->hash = almalloc(a, hash.length + 1);
+    
+    if(!user->user.name || !user->hash) {
+        return -1;
+    }
+    
     user->hashlen = util_base64decode(hash.ptr, hash.length, user->hash);
     
-    user->groups = calloc(ngroups, sizeof(sstr_t));
-    for(int i=0;i<ngroups;i++) {
-        user->groups[i] = sstrdup(groups[i]);
+    if(ngroups > 0) {
+        user->groups = alcalloc(a, ngroups, sizeof(sstr_t));
+        if(!user->groups) {
+            return -1;
+        }
+        for(int i=0;i<ngroups;i++) {
+            user->groups[i] = sstrdup(groups[i]);
+        }
+        
+    } else {
+        user->groups = NULL;
     }
     
     // add to keyfile
-    ucx_map_sstr_put(keyfile->users, name, user);
+    return ucx_map_sstr_put(keyfile->users, name, user);
 }
 
 // authdb functions
--- a/src/server/daemon/keyfile_auth.h	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/keyfile_auth.h	Mon Aug 24 12:50:16 2020 +0200
@@ -48,9 +48,8 @@
 };
 
 struct keyfile {
-    AuthDB   authdb;
-    UcxMap   *users;
-    uint32_t ref;
+    AuthDB       authdb;
+    UcxMap       *users;
 };
 
 struct keyfile_user {
@@ -62,11 +61,9 @@
     size_t               hashlen;
 };
 
-Keyfile* keyfile_new();
-void keyfile_ref(Keyfile *keyfile);
-void keyfile_unref(Keyfile *keyfile);
+Keyfile* keyfile_new(UcxAllocator *a);
 
-void keyfile_add_user(
+int keyfile_add_user(
         Keyfile *keyfile,
         sstr_t user,
         enum KeyfileHashType hash_type,
--- a/src/server/daemon/vserver.c	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/vserver.c	Mon Aug 24 12:50:16 2020 +0200
@@ -38,23 +38,6 @@
     return vs;
 }
 
-VirtualServer* vs_copy(VirtualServer *vs, pool_handle_t *pool) {
-    VirtualServer *newvs = malloc(sizeof(VirtualServer));
-    newvs->ref = 1;
-    newvs->document_root = sstrdup_pool(pool, vs->document_root);
-    newvs->host = sstrdup_pool(pool, vs->host);
-    newvs->name = sstrdup_pool(pool, vs->name);
-    newvs->objectfile = sstrdup_pool(pool, vs->objectfile);
-    newvs->acls = vs->acls;
-    acl_data_ref(newvs->acls);
-    newvs->log = vs->log; // TODO: ref
-    
-    newvs->objects = vs->objects;
-    
-    return newvs;
-}
-
-
 
 
 
--- a/src/server/daemon/vserver.h	Sun Aug 23 23:04:17 2020 +0200
+++ b/src/server/daemon/vserver.h	Mon Aug 24 12:50:16 2020 +0200
@@ -58,7 +58,6 @@
 };
 
 VirtualServer* vs_new();
-VirtualServer* vs_copy(VirtualServer *vs, pool_handle_t *pool);
 
 
 #ifdef	__cplusplus

mercurial