Sun, 26 Feb 2012 19:51:14 +0100
Minimal webdav support
/* * 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; return 0; } 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; // TODO: beyond array bounds write /* 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; }