Tue, 01 Jan 2013 13:32:04 +0100
added Linux 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 <stdio.h> #include <stdlib.h> #include "../public/nsapi.h" #include "../ucx/string.h" #include "httplistener.h" #include "log.h" #include "configmanager.h" ServerConfiguration *current_config = NULL; time_t sc_last_modified = 0; UcxMap *config_files; void init_configuration_manager() { /* init parser */ init_server_config_parser(); config_files = ucx_map_new(16); } 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); } // copy functions static void* copy_listener(HttpListener *ls, ServerConfiguration *cfg) { /* * we reuse the old listener, but change the * ServerConfiguration and VirtualServer */ http_listener_ref(ls); // TODO: this is non atomar sstr_t vsname = ls->default_vs.vs->name; ls->default_vs.vs = ucx_map_sstr_get(cfg->host_vs, vsname); ls->cfg = cfg; return ls; } static void* copy_vs(void *vserver, void *pool) { VirtualServer *vs = vs_copy(vserver, pool); /* * this function is executed on configuration reload, so some * VS configs may be changed * * vs * objects */ ConfigFile *objectfile = cfgmgr_get_file(vs->objectfile); vs->objects = objectfile->data; return vs; } int cfgmgr_load_config() { int cfgreload = 0; /* check config files */ UcxMapIterator iter = ucx_map_iterator(config_files); ConfigFile *f; UCX_MAP_FOREACH(f, iter) { 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; } if(f->last_modified != s.st_mtim.tv_sec) { /* reload the file */ //printf("reload: %s\n", sstrdup(f->file).ptr); log_ereport( LOG_LEVEL_INFO, "reload configuration file: %s", f->file.ptr); f->reload(f, current_config); cfgreload = 1; } } struct stat s; if(stat("config/server.conf", &s) != 0) { perror("stat(\"config/server.conf\")"); return -1; } ServerConfiguration *config; if(sc_last_modified != s.st_mtim.tv_sec) { printf("cfgmgr load server.conf\n"); config = load_server_conf( current_config, "config/server.conf"); if(config == NULL) { fprintf(stderr, "Cannot load server.conf\n"); return -1; } sc_last_modified = s.st_mtim.tv_sec; } else if(cfgreload) { /* copy configuration */ printf("cfgmgr copy server.conf\n"); /* TODO: copy */ /* config = load_server_conf( current_config, "config/server.conf"); */ config = malloc(sizeof(ServerConfiguration)); config->ref = 1; config->pool = pool_create(); config->user = sstrdup_pool(config->pool, current_config->user); config->tmp = sstrdup_pool(config->pool, current_config->tmp); // copy configuration config->host_vs = ucx_map_clone( current_config->host_vs, copy_vs, config->pool); config->listeners = ucx_list_clone( current_config->listeners, (copy_func)copy_listener, config); // TODO: we need to get the mime map from the configfile data config->mimetypes = current_config->mimetypes; if(config == NULL) { fprintf(stderr, "Cannot load server.conf\n"); return -1; } } else { printf("no reconfig required!\n"); config = current_config; } current_config = config; return 0; } ServerConfiguration *cfgmgr_get_server_config() { return current_config; }