preparation for admin interface

Fri, 28 Jun 2013 14:52:35 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 28 Jun 2013 14:52:35 +0200
changeset 81
d25825f37967
parent 80
0de4a90979e1
child 82
740cfd9dd443

preparation for admin interface

src/server/admin/admin.c file | annotate | diff | comparison | revisions
src/server/admin/admin.h file | annotate | diff | comparison | revisions
src/server/admin/admindex.c file | annotate | diff | comparison | revisions
src/server/admin/adminui.h file | annotate | diff | comparison | revisions
src/server/admin/objs.mk file | annotate | diff | comparison | revisions
src/server/admin/template.h file | annotate | diff | comparison | revisions
src/server/admin/webui.c file | annotate | diff | comparison | revisions
src/server/admin/webui.h file | annotate | diff | comparison | revisions
src/server/config/initconf.c file | annotate | diff | comparison | revisions
src/server/config/serverconf.c file | annotate | diff | comparison | revisions
src/server/config/serverconf.h file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/public/nsapi.h file | annotate | diff | comparison | revisions
src/server/util/util.c file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/admin/admin.c	Fri Jun 28 14:52:35 2013 +0200
@@ -0,0 +1,158 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 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 <unistd.h>
+
+#include "admin.h"
+#include "../util/pblock.h"
+
+#include "../config/conf.h"
+#include "../config/serverconf.h"
+#include "../config/objconf.h"
+
+static Page *root_page;
+
+int admin_init(pblock *pb, Session *sn, Request *rq) {
+    printf("admin-init\n");
+    pool_handle_t *pool = pool_create();
+    root_page = admin_page_create(pool, NULL, admin_root);
+    
+    Page *ls_page = admin_page_create(pool, "listener", adm_listener);
+    admin_add_page(root_page, ls_page);
+    Page *cfgls_page = admin_page_create(pool, NULL, adm_cfglistener);
+    admin_add_page(ls_page, cfgls_page);
+    
+    Page *auth_page = admin_page_create(pool, "auth", adm_auth);
+    admin_add_page(root_page, auth_page);
+    
+    return REQ_PROCEED;
+}
+
+int admin_service(pblock *pb, Session *sn, Request *rq) {
+    pblock_removekey(pb_key_content_type, rq->srvhdrs);
+    pblock_nvinsert("content-type", "text/plain", rq->srvhdrs);
+    protocol_status(sn, rq, 200, NULL);
+    http_start_response(sn, rq);
+    
+    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+    uri++;
+    uri = strchr(uri, '/');
+    size_t uri_len = strlen(uri);
+    // start with second character to skip leading '/'
+    int s = 0;
+    int i = 1;
+    Page *page = root_page;
+    for(;i<=uri_len;i++) {
+        char c = uri[i];
+        if(c == '/' || c == '\0') {
+            if(i-s > 1) {
+                // we have the path element name
+                char *name = uri+s+1;
+                size_t name_len = i-s-1;
+                
+                // get matching admin page
+                Page *child = page->children;
+                page = NULL;
+                while(child) {
+                    if(child->name) {
+                        if(!strncmp(child->name, name, name_len)) {
+                            page = child;
+                            break;
+                        }
+                    } else {
+                        page = child;
+                        break;
+                    }
+                    child = child->next;
+                }
+                
+                if(!page) {
+                    break;
+                }
+                
+                s = i;
+            }
+        }
+    }
+    
+    // service admin page
+    if(page) {
+        page->service(page, NULL);
+    } else {
+        net_printf(sn->csd, "page not found\n");
+    }
+    
+    return REQ_PROCEED;
+}
+
+int admin_root(Page *page, AdminRequest *rq) {
+    return REQ_PROCEED;
+}
+
+int adm_listener(Page *page, AdminRequest *rq) {
+    printf("adm_listener\n");
+    return REQ_PROCEED;
+}
+
+int adm_cfglistener(Page *page, AdminRequest *rq) {
+    printf("adm_cfglistener\n");
+    return REQ_PROCEED;
+}
+
+int adm_auth(Page *page, AdminRequest *rq) {
+    printf("adm_auth\n");
+    return REQ_PROCEED;
+}
+
+
+// public admin API
+
+Page* admin_page_create(pool_handle_t *pool, char *name, admin_service_f f) {
+    Page *p = pool_malloc(pool, sizeof(Page));
+    ZERO(p, sizeof(Page));
+    if(name) {
+        p->name = pool_strdup(pool, name);
+    }
+    p->service = f;
+    return p;
+}
+
+void admin_add_page(Page *parent, Page *child) {
+    child->parent = parent;
+    Page *ch = parent->children;
+    if(ch) {
+        while(ch->next) {
+            ch = ch->next;
+        }
+        ch->next = child;
+    } else {
+        parent->children = child;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/admin/admin.h	Fri Jun 28 14:52:35 2013 +0200
@@ -0,0 +1,102 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 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.
+ */
+
+#ifndef ADMIN_H
+#define	ADMIN_H
+
+#include "../public/nsapi.h"
+#include "webui.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct admin_page    Page;
+typedef struct admin_request AdminRequest;
+typedef int (*admin_service_f)(Page *, AdminRequest *);
+
+struct admin_page {
+    /*
+     * The name of the page is an element of the admin page path. The path is
+     * used to map urls to admin pages. If the name is NULL, every name is
+     * mapped to this page.
+     */
+    char *name;
+    
+    /*
+     * Parent page
+     */
+    Page *parent;
+    
+    /*
+     * 
+     */
+    Page *next;
+    
+    /*
+     * Pointer to the first child
+     */
+    Page *children;
+    
+    /*
+     * int service(Page *page, AdminRequest *rq)
+     * 
+     * Service handler function for the page
+     */
+    int (*service)(Page *page, AdminRequest *rq);
+    
+    /*
+     * custom user data
+     */
+    void *data;
+};
+
+struct admin_request {
+    Session *sn;
+    Request *rq;
+    char    *name;
+};
+
+int admin_init(pblock *pb, Session *sn, Request *rq);
+int admin_service(pblock *pb, Session *sn, Request *rq);
+
+int admin_root(Page *page, AdminRequest *rq);
+int adm_listener(Page *page, AdminRequest *rq);
+int adm_cfglistener(Page *page, AdminRequest *rq);
+int adm_auth(Page *page, AdminRequest *rq);
+
+Page* admin_page_create(pool_handle_t *pool, char *name, admin_service_f f);
+void admin_add_page(Page *parent, Page *child);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* ADMIN_H */
+
--- a/src/server/admin/admindex.c	Wed Jun 26 17:14:45 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2013 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 "template.h"
-
-CSP_SERVICE_FUNC_RETURN adm_index(CSP_SERVICE_FUNC_ARGS) {
-    CSP_FUNCTION_START
-
-    csp_start_response();
-
-csp_write("<html>\n\t<head>\n\t\t<title>Webserver Administration</title>\n\t</head",64);
-csp_write(">\n\t<body>\n\t<h1>Webserver</h1>\n\t<body>\n</html>\n",46);
-
-    CSP_FUNCTION_END
-}
-
--- a/src/server/admin/adminui.h	Wed Jun 26 17:14:45 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/* 
- * File:   adminui.h
- * Author: olaf
- *
- * Created on 18. Februar 2012, 17:23
- */
-
-#ifndef ADMINUI_H
-#define	ADMINUI_H
-
-#include "../public/nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-int adm_index(pblock *pb, Session *sn, Request *rq);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* ADMINUI_H */
-
--- a/src/server/admin/objs.mk	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/admin/objs.mk	Fri Jun 28 14:52:35 2013 +0200
@@ -30,7 +30,8 @@
 
 ADMIN_OBJPRE = $(OBJ_DIR)$(ADMIN_SRC_DIR)
 
-ADMINOBJ = admindex.o
+ADMINOBJ = admin.o
+ADMINOBJ += webui.o
 
 ADMINOBJS = $(ADMINOBJ:%=$(ADMIN_OBJPRE)%)
 ADMINSOURCE = $(ADMINOBJ:%.o=admin/%.c)
--- a/src/server/admin/template.h	Wed Jun 26 17:14:45 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2013 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"
-
-#define CSP_SERVICE_FUNC_RETURN  int
-#define CSP_SERVICE_FUNC_ARGS    pblock *pb, Session *sn, Request *rq
-#define CSP_SERVICE_CALL_ARGS    pb, sn, rq
-
-#define CSP_FUNCTION_START // nothing
-#define CSP_FUNCTION_END   return REQ_PROCEED;
-
-
-#define csp_add_header(n,v) pblock_nvinsert(n, v, rq->rq->srvhdrs)
-#define csp_start_response() http_start_response(sn, rq)
-#define csp_write(str,len) net_write(sn->csd, str, len)
-
-#define csp_printf(...) net_printf(sn, __VA_ARGS__)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/admin/webui.c	Fri Jun 28 14:52:35 2013 +0200
@@ -0,0 +1,54 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 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 "admin.h"
+
+WebUI *webui_begin(Session *sn, Request *rq) {
+    WebUI *ui = pool_malloc(sn->pool, sizeof(WebUI));
+    ui->sn = sn;
+    ui->rq = rq;
+    
+    net_printf(sn->csd, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n");
+    net_printf(sn->csd, "    \"http://www.w3.org/TR/html4/loose.dtd\">\n");
+    net_printf(sn->csd, "<html><head><title>Admin Console</title></head><body>\n");
+    
+    net_printf(sn->csd, "<h1>Webserver Administration</h1><hr>\n");
+    
+    return ui;
+}
+
+void webui_end(WebUI *ui) {
+    net_printf(ui->sn->csd, "</body></html>\n");
+}
+
+void webui_page_title(WebUI *ui, char *title) {
+    net_printf(ui->sn->csd, "<h2>%s</h2>\n<hr>\n", title);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/admin/webui.h	Fri Jun 28 14:52:35 2013 +0200
@@ -0,0 +1,54 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 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.
+ */
+
+#ifndef WEBUI_H
+#define	WEBUI_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct WebUI {
+    Session *sn;
+    Request *rq;
+} WebUI;
+
+WebUI *webui_begin(Session *sn, Request *rq);
+void webui_end(WebUI *ui);
+
+void webui_page_title(WebUI *ui, char *title);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* WEBUI_H */
+
--- a/src/server/config/initconf.c	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/config/initconf.c	Fri Jun 28 14:52:35 2013 +0200
@@ -46,10 +46,9 @@
     int r = cfg_parse_basic_file((ConfigParser*)conf, in);
     cfg_dlist_destr(conf->parser.mp, conf->directives);
     if(r != 0) {
-        // TODO: free
+        free_init_config(conf);
         return NULL;
     }
-    
     fclose(in);
 
     return conf;
--- a/src/server/config/serverconf.c	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/config/serverconf.c	Fri Jun 28 14:52:35 2013 +0200
@@ -114,3 +114,52 @@
     }
     return 0;
 }
+
+
+UcxList* srvcfg_get_listeners(ServerConfig *cfg, UcxMempool *mp, int *error) {
+    mp = mp ? mp : cfg->parser.mp;
+    
+    UcxList *list = ucx_map_sstr_get(cfg->objects, sstrn("Listener", 8));
+    UcxList *lslist = NULL;
+    UCX_FOREACH(UcxList*, list, elm) {
+        ServerConfigObject *ls = elm->data;
+        sstr_t name = cfg_directivelist_get_str(ls->directives, sstr("Name"));
+        sstr_t port = cfg_directivelist_get_str(ls->directives, sstr("Port"));
+        sstr_t vs = cfg_directivelist_get_str(
+                ls->directives,
+                sstr("DefaultVS"));
+        sstr_t threadpool = cfg_directivelist_get_str(
+                ls->directives,
+                sstr("Threadpool"));
+        
+        CfgListener *listener = ucx_mempool_calloc(mp, 1, sizeof(CfgListener));
+        // threadpool is optional, all other configs must be set
+        if(!name.ptr || !port.ptr || !vs.ptr) {
+            // TODO: log error
+            *error = 1;
+            listener->cfg_correct = 0;
+        } else {
+            listener->cfg_correct = 1;
+        }
+        
+        if(name.ptr) {
+            listener->name = sstrdup_mp(mp, name);
+        }
+        if(port.ptr) {
+            // don't expect that port is null terminated, sstrdup it to be sure
+            sstr_t portdp = sstrdup(port);
+            listener->port = atoi(portdp.ptr);
+            free(portdp.ptr);
+        }
+        if(vs.ptr) {
+            listener->vs = sstrdup_mp(mp, vs);
+        }
+        if(threadpool.ptr) {
+            listener->threadpool = sstrdup_mp(mp, threadpool);
+        }
+        
+        lslist = cfg_list_append(mp, lslist, listener);
+    }
+    
+    return lslist;
+}
--- a/src/server/config/serverconf.h	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/config/serverconf.h	Fri Jun 28 14:52:35 2013 +0200
@@ -51,13 +51,68 @@
     ServerConfigObject *obj;
 } ServerConfig;
 
+// server.conf objects
+
+typedef struct _cfg_listener {
+    ServerConfigObject   *cfgobj;
+    sstr_t               name;
+    sstr_t               vs;
+    sstr_t               threadpool;
+    sstr_t               address;
+    int                  port;
+    int                  nacceptors;
+    int                  cfg_correct;
+} CfgListener;
+
+typedef struct _cfg_keyfile_authdb {
+    sstr_t file;
+} CfgKeyfileAuthDB;
+
+typedef struct _cfg_ldap_authdb {
+    sstr_t host;
+    int    port;
+    sstr_t basedn;
+    sstr_t binddn;
+    sstr_t bindpw;
+} CfgLDAPAuthDB;
+
+union authdb {
+    CfgKeyfileAuthDB keyfile;
+    CfgLDAPAuthDB    ldap;
+};
+
+enum authdb_type {
+    AUTHDB_TYPE_KEYFILE,
+    AUTHDB_TYPE_LDAP
+};
+
+typedef struct _cfg_authdb {
+    sstr_t           name;
+    enum authdb_type type;
+    union authdb     cfg;
+    int              cfg_correct;
+} CfgAuthDB;
+
+
+/*
+ * Loads and parses a server configuration file. The function only structures
+ * the file content to configuration objects with directives. The semantics
+ * of the objects and directives can be extracted with the srvcfg_* funcsions.
+ */
 ServerConfig *load_server_config(char *file);
 
+/*
+ * frees the ServerConfig object
+ */
 void free_server_config(ServerConfig *conf);
 
+// private - parses a server.conf line
 int serverconf_parse(void *p, ConfigLine *begin, ConfigLine *end, sstr_t line);
 
 
+UcxList* srvcfg_get_listeners(ServerConfig *cfg, UcxMempool *mp, int *error);
+
+
 #ifdef	__cplusplus
 }
 #endif
--- a/src/server/daemon/httplistener.c	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/daemon/httplistener.c	Fri Jun 28 14:52:35 2013 +0200
@@ -90,6 +90,7 @@
     newls->port = fl->port;
     newls->server_socket = fl->server_socket;
     newls->running = 1;
+    newls->threadpool = NULL;
     newls->ref = 2; // 1 reference is fl->next
     
     newls->session_handler = fl->session_handler; // TODO
@@ -144,6 +145,7 @@
     listener->cfg = conf->cfg;
     listener->name = conf->name;
     listener->default_vs.vs_name = conf->vs.ptr;
+    listener->threadpool = NULL;
     if(conf->threadpool.ptr != NULL) {
         listener->threadpool = get_threadpool(conf->threadpool);
     }
--- a/src/server/daemon/ws-fn.c	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/daemon/ws-fn.c	Fri Jun 28 14:52:35 2013 +0200
@@ -38,7 +38,7 @@
 #include "../safs/addlog.h"
 #include "../webdav/webdav.h"
 
-#include "../admin/adminui.h"
+#include "../admin/admin.h"
 
 struct FuncStruct webserver_funcs[] = {
     { "init-test", init_test, NULL, 0 },
@@ -53,7 +53,8 @@
     { "webdav-init", webdav_init, NULL, 0},
     { "webdav-setcollection", webdav_setcollection, NULL, 0},
     { "webdav-service", webdav_service, NULL, 0},
-    { "admin-index", adm_index, NULL, 0},
+    { "admin-init", admin_init, NULL, 0},
+    { "admin-service", admin_service, NULL, 0},
     { "auth-basic", auth_basic, NULL, 0 },
     { "auth-db", auth_db, NULL, 0 },
     { "require-auth", require_auth, NULL, 0},
--- a/src/server/public/nsapi.h	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/public/nsapi.h	Fri Jun 28 14:52:35 2013 +0200
@@ -1389,6 +1389,8 @@
 
 NSAPI_PUBLIC int util_errno2status(int errno_value); // new
 #define util_errno2status util_errno2status
+NSAPI_PUBLIC pblock* util_parse_param(pool_handle_t *pool, char *query);
+#define util_parse_param util_parse_param
 
 
 // threadpool
--- a/src/server/util/util.c	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/util/util.c	Fri Jun 28 14:52:35 2013 +0200
@@ -255,6 +255,87 @@
 // TODO: asprintf
 
 
+
+/* -------------------------- util_uri_unescape --------------------------- */
+
+NSAPI_PUBLIC void util_uri_unescape(char *s)
+{
+    char *t, *u;
+
+    for(t = s, u = s; *t; ++t, ++u) {
+        if((*t == '%') && t[1] && t[2]) {
+            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A')+10 : (t[1] - '0'))*16) +
+                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A')+10 : (t[2] - '0'));
+            t += 2;
+        }
+        else
+            if(u != t)
+                *u = *t;
+    }
+    *u = *t;
+}
+
+/*
+ * Same as util_uri_unescape, but returns success/failure
+ */
+NSAPI_PUBLIC int util_uri_unescape_strict(char *s)
+{
+    char *t, *u, t1, t2;
+    int rv = 1;
+
+    for(t = s, u = s; *t; ++t, ++u) {
+        if (*t == '%') {
+            t1 = t[1] & 0xdf; /* [a-f] -> [A-F] */
+            if ((t1 < 'A' || t1 > 'F') && (t[1] < '0' || t[1] > '9'))
+                rv = 0;
+
+            t2 = t[2] & 0xdf; /* [a-f] -> [A-F] */
+            if ((t2 < 'A' || t2 > 'F') && (t[2] < '0' || t[2] > '9'))
+                rv = 0;
+
+            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A')+10 : (t[1] - '0'))*16) +
+                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A')+10 : (t[2] - '0'));
+            t += 2;
+        }
+        else if (u != t)
+            *u = *t;
+    }
+    *u = *t;
+
+    return rv;
+}
+
+
+NSAPI_PUBLIC int
+util_uri_unescape_plus (const char *src, char *trg, int len)
+{
+    const char *t = src;
+    char *u = trg == NULL ? (char *)src : trg;
+    int	rlen = 0;
+
+    if (len == -1)
+        len = strlen (src);
+
+    for( ; len && *t; ++t, ++u, len--, rlen++)
+    {
+        if((*t == '%') && t[1] && t[2])
+        {
+            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A') + 10 : (t[1] - '0')) * 16) +
+                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A') + 10 : (t[2] - '0'));
+            t  += 2;
+            len-= 2;
+        }
+        else
+            if (*t == '+')
+                *u = ' ';
+            else
+                *u = *t;
+    }
+    *u = 0;
+    return rlen;
+}
+
+
 NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def) {
     if(v[0] == 'T' || v[0] == 't') {
         return 1;
@@ -379,32 +460,7 @@
     return 500;
 }
 
-NSAPI_PUBLIC int util_uri_unescape_strict(char *s)
-{
-    char *t, *u, t1, t2;
-    int rv = 1;
 
-    for(t = s, u = s; *t; ++t, ++u) {
-        if (*t == '%') {
-            t1 = t[1] & 0xdf; /* [a-f] -> [A-F] */
-            if ((t1 < 'A' || t1 > 'F') && (t[1] < '0' || t[1] > '9'))
-                rv = 0;
-
-            t2 = t[2] & 0xdf; /* [a-f] -> [A-F] */
-            if ((t2 < 'A' || t2 > 'F') && (t[2] < '0' || t[2] > '9'))
-                rv = 0;
-
-            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A')+10 : (t[1] - '0'))*16) +
-                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A')+10 : (t[2] - '0'));
-            t += 2;
-        }
-        else if (u != t)
-            *u = *t;
-    }
-    *u = *t;
-
-    return rv;
-}
 
 NSAPI_PUBLIC
 sstr_t util_path_append(pool_handle_t *pool, char *path, char *ch) {
@@ -453,3 +509,62 @@
     }
     return path;
 }
+
+
+// new - code in parts from params.cpp
+NSAPI_PUBLIC pblock* util_parse_param(pool_handle_t *pool, char *query) {
+    pblock *pb = pblock_create_pool(pool, 32);
+    if(!pb) {
+        return NULL;
+    }
+    if(!query || !(*query)) {
+        return pb;
+    }
+    
+    int loopFlag = 1;
+    int nl = 0;	// size of the name substring
+    int vl = 0;	// size of the value substring
+    int state = 0;
+    const char *np = query;
+    const char *vp = NULL;
+    
+    while (loopFlag) {
+        char delim = *query++;
+        switch (delim) {
+            case '&':
+            case '\0': {
+                if(!delim) {
+                    loopFlag = 0;
+                }
+                
+                state = 0;
+                
+                if(nl > 0) {
+                    util_uri_unescape_plus(np, NULL, nl);
+                    util_uri_unescape_plus(vp, NULL, vl);
+                    pblock_nvlinsert(np, nl, vp, vl, pb);
+                }
+                
+                nl = 0;
+                vl = 0;
+                vp = NULL;
+                np = query;
+                break;
+            }
+            case '=': {
+                state = 1;
+                vp = query;
+                break;
+            }
+            default: {
+                if(state) {
+                    vl++;
+                } else {
+                    nl++;
+                }
+            }
+        } /* switch */
+    } /* while */
+
+    return pb;
+}

mercurial