src/server/daemon/config.c

Mon, 13 Feb 2012 13:49:49 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 13 Feb 2012 13:49:49 +0100
changeset 21
627b09ee74e4
parent 20
7b235fa88008
child 25
5dee29c7c530
permissions
-rw-r--r--

New configuration loader

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2011 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "../public/nsapi.h"

#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/mman.h>

#include "../ucx/string.h"

#include "httplistener.h"
#include "config.h"
#include "func.h"
#include "configmanager.h"

#include "vserver.h"
#include "../util/pblock.h"

pool_handle_t *cfg_pool;

// TODO: Funktion für ConfigDirective -> directive
// TODO: Funktion für UcxList parameter list -> pblock

void load_init_conf(char *file) {
    printf("load_init_conf\n");

    InitConfig *cfg = load_init_config(file);
    if(cfg == NULL) {
        return;
    }

    cfg_pool = pool_create(); // one pool for one Configuration
    UcxDlist *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);
        UcxList *param = dir->param;
        while(param != NULL) {
            ConfigParam *p = param->data;
            pblock_nvlinsert(
                    p->name.ptr,
                    p->name.length,
                    p->value.ptr,
                    p->value.length,
                    d->param);
            
            param = param->next;
        }

        /* get function */
        char *func_name = pblock_findval("fn", d->param);
        d->func = get_function(func_name);
        if(d->func == NULL) {
            free(d);
            dirs = dirs->next;
            continue;
        }

        /* execute init directive */
        d->func->func(d->param, NULL, NULL);

        dirs = dirs->next;
    }
    
    free_init_config(cfg);
}

ServerConfiguration* load_server_conf(ServerConfiguration *old, char *file) {
    printf("load_server_conf\n");

    ServerConfig *serverconf = load_server_config(file);
    if(serverconf == NULL) {
        fprintf(stderr, "Cannot load server.conf\n");
    }
    ServerConfiguration *serverconfig = malloc(sizeof(ServerConfiguration));
    serverconfig->pool = pool_create();
    serverconfig->listeners = NULL;
    serverconfig->host_vs = ucx_map_new(16);
    // TODO: init serverconfig stuff

    /* convert ServerConfig to ServerConfiguration */
    for(int i=0;i<serverconf->objects->size;i++) {
        UcxMapElement *elm = &serverconf->objects->map[i];
        while(elm != NULL) {
            UcxList *list = elm->data;
            while(list != NULL) {
                ServerConfigObject *scfgobj = list->data;

                /* handle config object */
                int hr = 0;
                if(!sstrcmp(scfgobj->type, sstr("Runtime"))) {
                    hr = cfg_handle_runtime(serverconfig, scfgobj);
                } else if(!sstrcmp(scfgobj->type, sstr("LogFile"))) {
                    hr = cfg_handle_logfile(serverconfig, scfgobj);
                } else if(!sstrcmp(scfgobj->type, sstr("AuthDB"))) {
                    hr = cfg_handle_authdb(serverconfig, scfgobj);
                } else if(!sstrcmp(scfgobj->type, sstr("Listener"))) {
                    hr = cfg_handle_listener(serverconfig, scfgobj);
                } else if(!sstrcmp(scfgobj->type, sstr("VirtualServer"))) {
                    hr = cfg_handle_vs(serverconfig, scfgobj);
                }


                /* next object */
                list = list->next;
            }
            
            elm = elm->next;
        }
    }



    /* set VirtualServer for all listeners */
    UcxList *ls = serverconfig->listeners;
    while(ls) {
        HttpListener *listener = ls->data;

        sstr_t vsname = sstr(listener->default_vs.vs_name);

        /* search for VirtualServer */
        int b = 0;
        for(int i=0;i<serverconfig->host_vs->size;i++) {
            UcxMapElement *elm = &serverconfig->host_vs->map[i];
            while(elm != NULL && elm->data != NULL) {
                VirtualServer *vs = elm->data;

                if(!sstrcmp(vsname, vs->name)) {
                    b = 1;
                    listener->default_vs.vs = vs;
                    break;
                }

                elm = elm->next;
            }
            if(b) {
                break;
            }
        }

        ls = ls->next;
    }

    return serverconfig;
}


void init_server_config_parser() {
    
}

int cfg_handle_runtime(ServerConfiguration *cfg, ServerConfigObject *obj) {
    cfg->user = sstrdub(cfg_directivelist_get_str(
            obj->directives,
            sstr("User")));
    cfg->tmp = sstrdub(cfg_directivelist_get_str(
            obj->directives,
            sstr("Temp")));

    return 0;
}

int cfg_handle_logfile(ServerConfiguration *cfg, ServerConfigObject *obj) {
    /* TODO: log files */

    return 0;
}

int cfg_handle_authdb(ServerConfiguration *cfg, ServerConfigObject *obj) {
    /* TODO: authdb*/

    return 0;
}

int cfg_handle_listener(ServerConfiguration *cfg, ServerConfigObject *obj) {
    ListenerConfig lc;
    lc.port = 8080;
    lc.nacceptors = 1;

    lc.name = sstrdub(cfg_directivelist_get_str(
            obj->directives,
            sstr("Name")));
    lc.port = atoi(cfg_directivelist_get_str(
            obj->directives,
            sstr("Port")).ptr);
    lc.vs = sstrdub(cfg_directivelist_get_str(
            obj->directives,
            sstr("DefaultVS")));
    

    HttpListener *listener = http_listener_new(&lc);
    listener->default_vs.vs_name = lc.vs.ptr;
    cfg->listeners = ucx_list_append(cfg->listeners, listener); 

    return 0;
}

int cfg_handle_vs(ServerConfiguration *cfg, ServerConfigObject *obj) {
    VirtualServer *vs = vs_new();

    vs->name = sstrdub(cfg_directivelist_get_str(
            obj->directives,
            sstr("Name")));
    vs->host = sstrdub(cfg_directivelist_get_str(
            obj->directives,
            sstr("Host")));
    vs->document_root = sstrdub(cfg_directivelist_get_str(
            obj->directives,
            sstr("DocRoot")));
    sstr_t objfile = cfg_directivelist_get_str(
            obj->directives,
            sstr("ObjectFile"));
    sstr_t base = sstr("conf/");
    sstr_t file;
    file.length = base.length + objfile.length + 1;
    file.ptr = alloca(file.length);
    file.ptr[file.length] = 0;
    file = sstrncat(2, file, base, objfile);

    ConfigFile *f = cfgmgr_get_file(file);
    if(f == NULL) {
        f = malloc(sizeof(ConfigFile));
        f->file = sstrdub(file);
        f->reload = object_conf_reload;
        f->reload(f, cfg);
        cfgmgr_attach_file(f);
    }
    vs->objects = (HTTPObjectConfig*)f->data;

    ucx_map_sstr_put(cfg->host_vs, vs->host, vs);
    
    return 0;
}


int object_conf_reload(ConfigFile *file, ServerConfiguration *cfg) {
    file->data = load_obj_conf(file->file.ptr);
    struct stat s;
    if(stat(file->file.ptr, &s) != 0) {
        perror("object_conf_reload: stat");
        return -1;
    }
    file->last_modified = s.st_mtim.tv_sec;
}

HTTPObjectConfig* load_obj_conf(char *file) {
    printf("load_obj_conf\n");

    // new conf function test
    ObjectConfig *cfg = load_object_config(file);
    if(cfg == NULL) {
        return NULL;
    }

    /* create object config */
    HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1);
    conf->pool = pool_create();

    /* convert ObjectConfig to HTTPObjectConfig */

    /* add objects */
    conf->nobj = ucx_dlist_size(cfg->objects);
    conf->objects = calloc(1, sizeof(httpd_object*));
    
    UcxDlist *objlist = cfg->objects;
    int i = 0;
    while(objlist != NULL) {
        ConfigObject *cob = objlist->data;

        /* get name and ppath */
        char *name = NULL;
        char *ppath = NULL;
        if(cob->name.length > 0) {
            name = sstrdub(cob->name).ptr;
        }
        if(cob->ppath.length > 0) {
            ppath = sstrdub(cob->ppath).ptr;
        }

        /* create and add object */
        httpd_object *obj = object_new(name);
        obj->path = NULL;

        conf->objects[i] = obj;

        /* add directives */
        for(int i=0;i<6;i++) {
            UcxDlist *dirs = cob->directives[i];
            while(dirs != NULL) {
                ConfigDirective *cfgdir = dirs->data;

                directive *d = malloc(sizeof(directive));
                d->cond = NULL;
                d->param = pblock_create_pool(conf->pool, 8);

                /* add params */
                UcxList *param = cfgdir->param;
                while(param != NULL) {
                    ConfigParam *p = param->data;
                    pblock_nvlinsert(
                            p->name.ptr,
                            p->name.length,
                            p->value.ptr,
                            p->value.length,
                            d->param);
                    param = param->next;
                }

                /* get function */
                char *func_name = pblock_findval("fn", d->param);
                d->func = get_function(func_name);

                dirs = dirs->next;

                /* add function to dtable */
                object_add_directive(obj, d, cfgdir->type_num);
            }
        }

        /* next */
        i++;
        objlist = objlist->next;
    }

    free_object_config(cfg);

    return conf;
}

mercurial