src/server/daemon/conf.c

changeset 14
b8bf95b39952
parent 13
1fdbf4170ef4
child 15
cff9c4101dd7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/conf.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,455 @@
+/*
+ * 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/sstring.h"
+
+#include "httplistener.h"
+#include "conf.h"
+#include "func.h"
+
+#include "vserver.h"
+#include "../util/pblock.h"
+
+VirtualServer *default_vs;
+
+void load_init_conf(char *file) {
+    printf("load_init_conf\n");
+
+    pool_handle_t *pool = pool_create();
+
+    FILE *in = fopen("conf/init.conf", "r");
+    if(in == NULL) {
+        fprintf(stderr, "Cannot open conf/init.conf\n");
+        return;
+    }
+
+    char buf[512];
+    buf[0] = 0;
+    int  len = 512;
+
+    while(!feof(in)) {
+        fgets(buf, len, in);
+
+        if(*buf == 0) {
+            continue;
+        }
+
+        char *ptr;
+        if((ptr = strrchr(buf, '\n'))) {
+            ptr[0] = 0;
+        }
+        
+        sstr_t line = string_trim(sstr(buf));
+        if(line.length > 0) {
+            sstr_t type;
+            directive *d = parse_directive(pool, line, &type);
+            if(sstrcmp(type, sstr("Init"))) {
+                d->func->func(d->param, NULL, NULL);
+            }
+        }
+    }
+}
+
+void load_server_conf(char *file) {
+    printf("load_server_conf\n");
+    
+    ListenerConfig *conf = malloc(sizeof(ListenerConfig));
+    conf->port = 9090;
+    conf->nacceptors = 1;
+    conf->name = "default";
+
+    http_listener_new(conf);
+
+    // virtual server
+    default_vs = vs_new();
+    // load obj.conf
+    default_vs->objects = load_obj_conf("conf/obj.conf");
+    default_vs->default_obj_name = "default";
+
+    // begin objset test
+    /*
+    httpd_objset *objset = default_vs->objset;
+    for(int i=0;i<objset->pos;i++) {
+        httpd_object *obj = objset->obj[i];
+        printf("<object [%s]>\n", obj->name);
+        for(int j=0;j<obj->nd;j++) {
+            dtable *dt;
+            switch(j) {
+                case NSAPIAuthTrans: {
+                    printf("  Get AuthTrans Directives\n");
+                    dt = object_get_dtable(obj, NSAPIAuthTrans);
+                    break;
+                }
+                case NSAPINameTrans: {
+                    printf("  Get NameTrans Directives\n");
+                    dt = object_get_dtable(obj, NSAPINameTrans);
+                    break;
+                }
+                case NSAPIPathCheck: {
+                    printf("  Get PathCheck Directives\n");
+                    dt = object_get_dtable(obj, NSAPIPathCheck);
+                    break;
+                }
+                case NSAPIService: {
+                    printf("  Get Service Directives\n");
+                    dt = object_get_dtable(obj, NSAPIService);
+                    break;
+                }
+                default: {
+                    printf("j: %d\n", j);
+                    dt = object_get_dtable(obj, j);
+                    break;
+                }
+            }
+            if(dt != NULL) {
+                printf("  dtable[%d].length = %d\n", dt, dt->ndir);
+            } else {
+                continue;
+            }
+            for(int k=0;k<dt->ndir;k++) {
+                directive *d = dt->directive[k];
+                if(d == NULL) {
+                    printf("d is null\n");
+                } else {
+                    printf("    Directive[%d].name = %s\n", d, d->func->name);
+                }
+            }
+        }
+    }
+    */
+    // end objset test
+}
+
+VirtualServer* conf_get_default_vs() {
+    return default_vs;
+}
+
+HTTPObjectConfig* load_obj_conf(char *file) {
+    printf("load_obj_conf\n");
+
+    /* create object config */
+    ObjectConfParser parser;
+    HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1);
+    conf->pool = pool_create();   
+    parser.conf = conf;
+
+    FILE *in = fopen("conf/obj.conf", "r");
+    if(in == NULL) {
+        fprintf(stderr, "Cannot open conf/obj.conf\n");
+        return NULL;
+    }
+
+    char buf[512];
+    int  len = 512;
+
+    while(!feof(in)) {
+        fgets(buf, len, in);
+
+        if(*buf == 0) {
+            continue;
+        }
+
+        char *ptr;
+        if((ptr = strrchr(buf, '\n'))) {
+            ptr[0] = 0;
+        }
+
+        sstr_t line = string_trim(sstr(buf));
+        if(line.length > 0) {
+            obj_conf_parse_line(&parser, line);
+        }
+    }
+
+    
+
+    return conf;
+}
+
+void obj_conf_parse_line(ObjectConfParser *parser, sstr_t line) {
+    //printf("{%s}[%d]\n", line.ptr, line.length);
+    if(line.ptr[0] == '#') {
+        return;
+    }
+
+    if(line.length < 3) {
+        // to short for everything
+        fprintf(stderr, "obj.conf: line to short \"%s\"\n", line.ptr);
+        return;
+    }
+
+    // TODO: ersetzen
+    if(line.ptr[0] == '<') {
+        if(line.ptr[1] == '/') {
+            // end tag
+            if(line.ptr[2] == 'O' && parser->obj != NULL) {
+                // end of Object
+                httpobjconf_add_object(parser->conf, parser->obj);
+                parser->obj = NULL;
+                return;
+            }
+        } else {
+            // new tag
+            httpd_object *obj = parse_new_object_tag(line);
+            parser->obj = obj;
+        }
+    } else {
+        // directive
+        sstr_t dtype;
+        directive *d = parse_directive(parser->conf->pool, line, &dtype);
+        int dt = get_directive_type_from_string(dtype);
+        object_add_directive(parser->obj, d, dt);
+    }
+}
+
+
+/* utils */
+
+sstr_t string_trim(sstr_t string) {
+    sstr_t newstr = string;
+    int nsoff = 0;
+    int l = 1;
+    for(int i=0;i<string.length;i++) {
+        char c = string.ptr[i];
+        if(l) {
+            /* leading whitespace */
+            if(c > 32) {
+                l = 0;
+                nsoff = i;
+                newstr.ptr = &string.ptr[i];
+                newstr.length = string.length - nsoff;
+            }
+        } else {
+            /* trailing whitespace */
+            if(c > 32) {
+                newstr.length = (i - nsoff) + 1;
+            }
+        }
+    }
+    return newstr;
+}
+
+httpd_object* parse_new_object_tag(sstr_t line) {
+    int i = 0;
+    int b = 0;
+    sstr_t name;
+    sstr_t value;
+
+    char *obj_name = NULL;
+    char *obj_ppath = NULL;
+    
+    for(;i<line.length;i++) {
+        if(line.ptr[i] < 33) {
+            b = 1;
+        } else if(b == 1) {
+            break;
+        }
+    }
+    if(!b || line.ptr[i] < 33) {
+        printf("1\n");
+        return NULL;
+    }
+    b = 0;
+    
+    /* parse name=value params */
+    for(;i<line.length;i++) {
+        if(line.ptr[i] == '>') {
+            break;
+        }
+        
+        /* get name */
+        name.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            if(line.ptr[i] == '=') {
+                b = 1;
+                i++;
+                break;
+            }
+        }
+        if(!b) {
+            printf("2\n");
+            return NULL;
+        }
+        name.length = line.ptr + i - name.ptr - 1;
+
+        if(line.ptr[i] == '\"') {
+            i++; // TODO: Bug wenn end of line - wird nicht erkannt!
+        }
+        value.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            char c = line.ptr[i];
+            if(c < 33 || c == '\"' || c == '>') {
+                b = 1;
+                break;
+            }
+        }
+        if(!b) {
+            printf("3\n");
+            return NULL;
+        }
+        value.length = line.ptr + i - value.ptr;
+
+        if(sstrcmp(name, sstrn("name", 4)) == 0) {
+            obj_name = sstrdub(value).ptr;
+        } else if (sstrcmp(name, sstrn("ppath", 5)) == 0) {
+            obj_ppath = sstrdub(value).ptr;
+        }
+
+        /*
+        printf("name: [%d]{", name.length);
+        fwrite(name.ptr, 1, name.length, stdout);
+        printf("}\n");
+        printf("value: [%d]{", value.length);
+        fwrite(value.ptr, 1, value.length, stdout);
+        printf("}\n");
+        */
+
+        char c = line.ptr[i];
+        if(c == '>') {
+            break;
+        } else {
+            i++;
+        }
+    }
+
+    if(obj_name != NULL || obj_ppath != NULL) {
+        httpd_object *o = object_new(obj_name);
+        o->path = obj_ppath;
+        return o;
+    }
+
+    return NULL;
+}
+
+directive* parse_directive(pool_handle_t *pool, sstr_t line, sstr_t *type) {
+    int i = 0;
+    int b = 0;
+
+    sstr_t directive_type = line;
+    
+    directive *directive = malloc(sizeof(directive));
+    directive->cond = NULL;
+    directive->param = pblock_create_pool(pool, 8);
+
+    for(;i<line.length;i++) {
+        if(line.ptr[i] < 33) {
+            b = 1;
+            directive_type.length = i;
+            if(directive_type.length <= 0) {
+                fprintf(stderr, "parse error: cannot parse directive\n");
+                return NULL;
+            }
+        } else if(b == 1) {
+            break;
+        }
+    }
+    
+    /* parse name=value params */
+    sstr_t name;
+    sstr_t value;
+    for(;i<line.length;i++) {
+        /* get name */
+        name.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            if(line.ptr[i] == '=') {
+                b = 1;
+                i++;
+                break;
+            }
+        }
+        if(!b) {
+            printf("2\n");
+            return NULL;
+        }
+        name.length = line.ptr + i - name.ptr - 1;
+
+        if(line.ptr[i] == '\"') {
+            i++; // TODO: Bug wenn end of line - wird nicht erkannt!
+        }
+        value.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            char c = line.ptr[i];
+            if(c < 33 || c == '\"') {
+                b = 1;
+                break;
+            }
+        }
+        if(!b) {
+            printf("3\n");
+            return NULL;
+        }
+        value.length = line.ptr + i - value.ptr;
+
+        name = string_trim(name);
+        value = string_trim(value);
+
+        /* insert name and value into directive pblock */
+        pblock_nvlinsert(
+                name.ptr,
+                name.length,
+                value.ptr,
+                value.length,
+                directive->param);
+    }
+
+    /* get function */
+    char *func_name = pblock_findval("fn", directive->param);
+    directive->func = get_function(func_name);
+
+    *type = directive_type;
+    return directive;
+}
+
+int get_directive_type_from_string(sstr_t type) {
+    /* get nsapi function type */
+    int dt = -1;
+    if(sstrcmp(type, sstr("AuthTrans")) == 0) {
+        dt = 0;
+    } else if(sstrcmp(type, sstr("NameTrans")) == 0) {
+        dt = 1;
+    } else if(sstrcmp(type, sstr("PathCheck")) == 0) {
+        dt = 2;
+    } else if(sstrcmp(type, sstr("ObjectType")) == 0) {
+        dt = 3;
+    } else if(sstrcmp(type, sstr("Service")) == 0) {
+        dt = 4;
+    } else if(sstrcmp(type, sstr("AddLog")) == 0) {
+        dt = 5;
+    }
+    return dt;
+}

mercurial