merge srvctrl into default branch

Mon, 06 Mar 2017 17:32:26 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 06 Mar 2017 17:32:26 +0100
changeset 179
ef6827505bd2
parent 174
8f2a834d1d68 (current diff)
parent 178
4760f7f1b197 (diff)
child 180
98462e878ca7

merge srvctrl into default branch

src/server/Makefile file | annotate | diff | comparison | revisions
src/server/daemon/webserver.c file | annotate | diff | comparison | revisions
src/server/util/system.c file | annotate | diff | comparison | revisions
--- a/make/install.mk	Fri Feb 24 11:17:53 2017 +0100
+++ b/make/install.mk	Mon Mar 06 17:32:26 2017 +0100
@@ -46,7 +46,9 @@
 	sed s:%%WS_HOST%%:$(HOST):g ../templates/config/server.template > $(INSTALL_DIR)/config/server.conf
 	@echo "copy binaries"
 	cp ../build/bin/webservd$(APP_EXT) $(INSTALL_DIR)/bin/
+	cp ../build/bin/wstool$(APP_EXT) $(INSTALL_DIR)/bin/
 	cp ../build/lib/libucx$(LIB_EXT) $(INSTALL_DIR)/lib/
+	cp ../build/lib/libwscfg$(LIB_EXT) $(INSTALL_DIR)/lib/
 	@echo "copy includes"
 	cp ../src/server/public/nsapi.h $(INSTALL_DIR)/include/nsapi.h
 	cp ../src/server/public/auth.h $(INSTALL_DIR)/include/auth.h
--- a/src/Makefile	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/Makefile	Mon Mar 06 17:32:26 2017 +0100
@@ -28,11 +28,17 @@
 
 BUILD_ROOT = ../
 
-all: _ucx _server
+all: ucx server tools
 	
 
-_ucx:
+ucx: .FORCE
 	cd ucx; $(MAKE) 
 
-_server:
+server: ucx .FORCE
 	cd server; $(MAKE) 
+
+tools: server .FORCE
+	cd tools; $(MAKE)
+
+.FORCE:
+	
\ No newline at end of file
--- a/src/server/Makefile	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/Makefile	Mon Mar 06 17:32:26 2017 +0100
@@ -33,7 +33,9 @@
 
 MAIN_TARGET = $(BUILD_ROOT)/build/bin/webservd
 
-all: preparation $(MAIN_TARGET) $(PLUGINS)
+LIB_WSCFG = $(BUILD_ROOT)/build/lib/libwscfg$(LIB_EXT)
+
+all: preparation $(MAIN_TARGET) $(LIB_WSCFG) $(PLUGINS)
 
 include util/objs.mk
 include safs/objs.mk
@@ -65,6 +67,9 @@
 $(MAIN_TARGET): $(MAINOBJS)
 	$(CXX) -o $(MAIN_TARGET) $(MAINOBJS) -L$(BUILD_ROOT)/build/lib $(LDFLAGS)
 
+$(LIB_WSCFG): $(CONFOBJS)
+	$(CC) $(SHLIB_LDFLAGS) -o $@ $(CONFOBJS)
+
 
 ../../build/server/ucx/%.o: %.c
 	$(CC) -o $@ -c $(CFLAGS) $<
--- a/src/server/config/Makefile	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/config/Makefile	Mon Mar 06 17:32:26 2017 +0100
@@ -27,8 +27,5 @@
 #
 
 $(CONF_OBJPRE)%.o: config/%.c
-	$(CC) -o $@ -c $(CFLAGS) $<
+	$(CC) -o $@ -c $(CFLAGS) $(SHLIB_CFLAGS) $<
 
-$(CONF_OBJPRE)%.o: config/%.cpp
-	$(CXX) -o $@ -c $(CFLAGS) $<
-	
--- a/src/server/daemon/log.c	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/daemon/log.c	Mon Mar 06 17:32:26 2017 +0100
@@ -36,6 +36,7 @@
 #include <unistd.h>
 #include <aio.h>
 #include <time.h>
+#include <pthread.h>
 
 #include "log.h"
 #include "../util/strbuf.h"
@@ -43,12 +44,17 @@
 #include "../util/atomic.h"
 
 #include <ucx/map.h>
+#include <ucx/list.h>
 
 static int is_initialized = 0;
 
 static int log_file_fd;
 static int log_level = 0;
 
+static uint32_t log_dup_count = 0;
+static UcxList *log_dup_list = NULL;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
 WSBool main_is_daemon(void);
 
 /*
@@ -84,7 +90,8 @@
     "failure",
     "catastrophe",
     "info",
-    "verbose"
+    "verbose",
+    "debug"
 };
 
 static int can_log[] = {
@@ -94,7 +101,8 @@
     1, // failure
     1, // catastrophe
     1, // info
-    0  // verbose
+    0, // verbose
+    0  // debug
 };
 
 int init_log_file(LogConfig *cfg) {
@@ -114,10 +122,11 @@
         can_log[LOG_INFORM] = 0;
     } else if(!strcmp(cfg->level, "WARNING")) {
         can_log[LOG_INFORM] = 0;
-    } else if(!strcmp(cfg->level, "INFO")) {
-        
     } else if(!strcmp(cfg->level, "VERBOSE")) {
         can_log[LOG_VERBOSE] = 1;
+    } else if(!strcmp(cfg->level, "DEBUG")) {
+        can_log[LOG_VERBOSE] = 1;
+        can_log[LOG_DEBUG] = 1;
     }
     
     if(cfg->log_stdout) {
@@ -178,6 +187,21 @@
     if(!main_is_daemon()) {
         writev(STDOUT_FILENO, io, 2);
     }
+    
+    if(log_dup_count > 0) {
+        char *msg = malloc(len + 1);
+        memcpy(msg, str, len);
+        msg[len] = '\n';
+        
+        pthread_mutex_lock(&mutex);
+        UCX_FOREACH(elm, log_dup_list) {
+            LogDup *dup = elm->data;
+            dup->write(dup->cookie, msg, len + 1);
+        }        
+        pthread_mutex_unlock(&mutex);
+        
+        free(msg);
+    }
 }
 
 sstr_t log_get_prefix(int level) {
@@ -211,6 +235,27 @@
     return d;
 }
 
+void log_add_logdup(LogDup *dup) {
+    pthread_mutex_lock(&mutex);  
+    log_dup_list = ucx_list_append(log_dup_list, dup);
+    ws_atomic_inc32(&log_dup_count);   
+    pthread_mutex_unlock(&mutex);
+}
+
+void log_remove_logdup(LogDup *ldup) {
+    pthread_mutex_lock(&mutex);
+    UcxList *elm = log_dup_list;
+    while(elm) {
+        if(elm->data == ldup) {
+            log_dup_list = ucx_list_remove(log_dup_list, elm);
+            ws_atomic_dec32(&log_dup_count);
+            break;
+        }
+        elm = elm->next;
+    }
+    pthread_mutex_unlock(&mutex);
+}
+
 
 /*
  * log api functions
@@ -225,10 +270,10 @@
 }
 
 int log_ereport_v(int degree, const char *format, va_list args) { 
-    if(degree > 6) {
+    if(degree < 0 || degree > 7) {
         return 0;
     }
-    if(degree > 0 && !can_log[degree]) {
+    if(!can_log[degree]) {
         return 0;
     }
     
--- a/src/server/daemon/log.h	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/daemon/log.h	Mon Mar 06 17:32:26 2017 +0100
@@ -31,6 +31,7 @@
 
 #include "../public/nsapi.h"
 #include <ucx/string.h>
+#include <ucx/utils.h>
 
 #include <inttypes.h>
 
@@ -56,6 +57,11 @@
     LogFile  *log;
 } AccessLog;
 
+typedef void (*log_writefunc)(void *cookie, char *msg, size_t length);
+typedef struct {
+    log_writefunc write;
+    void *cookie;
+} LogDup;
 // server logging
 int init_log_file(LogConfig *cfg);
 
@@ -65,6 +71,8 @@
 
 sstr_t log_get_prefix(int level);
 
+void log_add_logdup(LogDup *dup);
+void log_remove_logdup(LogDup *dup);
 
 // access logging
 LogFile* get_access_log_file(sstr_t file);
--- a/src/server/daemon/main.c	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/daemon/main.c	Mon Mar 06 17:32:26 2017 +0100
@@ -39,10 +39,13 @@
 #include "../util/plist.h"
 #include "../util/date.h"
 
+#include "../../ucx/string.h"
+
 #include "webserver.h"
 #include "log.h"
 #include "httprequest.h"
 #include "httplistener.h"
+#include "srvctrl.h"
 
 #include "configmanager.h"
 
@@ -81,7 +84,7 @@
  */
 void sig_term(int sig) {
     webserver_shutdown();
-    exit(EXIT_SUCCESS);
+    //exit(EXIT_SUCCESS);
 }
 
 void* log_pipe_thread(void *data) {
@@ -164,17 +167,22 @@
     int status;
     status = webserver_init();
     if(status != 0) {
-        log_ereport(LOG_FAILURE, "Cannot initialize server.");
+        log_ereport(LOG_FAILURE, "cannot initialize server.");
         return EXIT_FAILURE;
     }
 
     status = webserver_run();
     if(status != 0) {
-        log_ereport(LOG_FAILURE, "Cannot run server.");
+        log_ereport(LOG_FAILURE, "cannot run server.");
         return EXIT_FAILURE;
     }
-     
+    
+    if(srvctrl_wait()) {
+        return EXIT_FAILURE;
+    }
+    
     /* TODO: join threads (or not?) */
+/*
     while(1) {
         if(is_daemon) {
             fflush(stdout);
@@ -185,6 +193,7 @@
             break;
         }
     }
+*/
 
     return EXIT_SUCCESS;
 }
--- a/src/server/daemon/objs.mk	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/daemon/objs.mk	Mon Mar 06 17:32:26 2017 +0100
@@ -44,6 +44,7 @@
 DAEMONOBJ += sessionhandler.o
 DAEMONOBJ += vserver.o
 DAEMONOBJ += webserver.o
+DAEMONOBJ += srvctrl.o
 DAEMONOBJ += ws-fn.o
 DAEMONOBJ += configmanager.o
 DAEMONOBJ += log.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/srvctrl.c	Mon Mar 06 17:32:26 2017 +0100
@@ -0,0 +1,220 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2017 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 <sys/socket.h>
+#include <sys/un.h>
+
+#include "log.h"
+#include "webserver.h"
+
+#include "../util/systhr.h"
+
+#include "../../ucx/utils.h"
+#include "../../ucx/buffer.h"
+
+#include "srvctrl.h"
+
+#define SRVCTRL_THREAD_STACKSIZE 8192
+
+static int srvctrl;
+static sstr_t srvctrl_path;
+
+static WSBool srv_shutdown;
+
+int srvctrl_init(ServerConfiguration *cfg) {
+    // create srvctrl unix domain socket
+    // this socket is used for stop, reconfigure and other operations
+    srvctrl_path = ucx_sprintf("%s/private/srvctrl.sock", cfg->tmp.ptr);
+    struct sockaddr_un addr;
+    if(srvctrl_path.length > sizeof(addr.sun_path)-1) {
+        log_ereport(
+                LOG_CATASTROPHE,
+                "path '%s' too long for unix domain socket",
+                srvctrl_path.ptr);
+        return -1;
+    }
+    
+    // make sure there is no old srvctrl socket file
+    // otherweise bind would fail
+    if(unlink(srvctrl_path.ptr)) {
+        if(errno != ENOENT) {
+            log_ereport(
+                    LOG_CATASTROPHE,
+                    "cannot unlink old srvctrl socket '%s': %s",
+                    srvctrl_path.ptr,
+                    strerror(errno));
+            return -1;
+        }
+    }
+
+    ZERO(&addr, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    memcpy(addr.sun_path, srvctrl_path.ptr, srvctrl_path.length);
+    
+    srvctrl = socket(AF_UNIX, SOCK_STREAM, 0);
+    if(srvctrl == -1) {
+        log_ereport(
+                LOG_CATASTROPHE,
+                "Cannot create server control socket: %s",
+                strerror(errno));
+        return -1;
+    }
+    if(bind(srvctrl, (struct sockaddr*)&addr, sizeof(addr))) {
+        log_ereport(
+                LOG_CATASTROPHE,
+                "srvctrl socket bind failed: %s",
+                strerror(errno));
+        return -1;
+    }
+    
+    return 0;
+}
+
+int srvctrl_wait() {
+    listen(srvctrl, 8);
+    
+    for(;;) {
+        int fd = accept(srvctrl, NULL, 0);
+        if(fd < 0) {
+            if(srv_shutdown) break;
+            log_ereport(
+                    LOG_FAILURE,
+                    "srvctrl: accept failed: %s",
+                    strerror(errno));
+            break;
+        }
+        
+        SrvCtrlClient *client = srvctrl_create_client(fd);
+        SYS_THREAD t = systhread_start(
+                SYSTHREAD_DEFAULT_PRIORITY,
+                SRVCTRL_THREAD_STACKSIZE,
+                (thrstartfunc)srvctrl_thread,
+                client);
+        systhread_detach(t);
+        
+    }
+    
+    close(srvctrl);
+    unlink(srvctrl_path.ptr);
+    free(srvctrl_path.ptr);
+    
+    return 0;
+}
+
+void srvctrl_shutdown() {
+    srv_shutdown = TRUE;
+    shutdown(srvctrl, SHUT_RDWR);
+}
+
+SrvCtrlClient* srvctrl_create_client(int fd) {
+    SrvCtrlClient *client = malloc(sizeof(SrvCtrlClient));
+    ZERO(client, sizeof(SrvCtrlClient));
+    client->fd = fd;      
+    return client;
+}
+
+void* srvctrl_thread(SrvCtrlClient *client) {
+    LogDup log;
+    log.write = (log_writefunc)srvctrl_log;
+    log.cookie = client;
+    log_add_logdup(&log);
+    
+    char buf[64];
+    UcxBuffer *line = ucx_buffer_new(NULL, 32, UCX_BUFFER_AUTOEXTEND);
+    
+    ssize_t r;
+    WSBool br = FALSE;
+    while((r = read(client->fd, buf, 64)) > 0) {
+        for(int i=0;i<r;i++) {
+            char c = buf[i];
+            if(c == '\n') {
+                sstr_t ln = sstrn(line->space, line->pos);
+                if(srvctrl_handle_cmd(client, ln)) {
+                    br = TRUE;
+                    break;
+                }
+            } else {
+                ucx_buffer_putc(line, c);
+            }
+        }
+        if(br) {
+            break;
+        }
+    }
+    log_remove_logdup(&log);
+    
+    ucx_buffer_free(line);
+    close(client->fd);
+    free(client);
+    return NULL;
+}
+
+int srvctrl_handle_cmd(SrvCtrlClient *client, sstr_t cmd) {
+    if(!sstrcmp(cmd, S("reconfig"))) {
+        log_ereport(LOG_INFORM, "reconfigure server");
+        if(webserver_reconfig()) {
+            log_ereport(LOG_FAILURE, "cannot reload config");
+        } else {
+            log_ereport(LOG_INFORM, "reconfig: success");
+        }
+    } else if(!sstrcmp(cmd, S("shutdown"))) {
+        webserver_shutdown();
+    } else if(!sstrcmp(cmd, S("stat"))) {
+        // TODO: implement
+    } else if(!sstrcmp(cmd, S("log"))) {
+        return 0;
+    } else {
+        log_ereport(
+                LOG_FAILURE,
+                "unknown srvctrl command: %.*s",
+                (int)cmd.length,
+                cmd.ptr);
+    }
+    return 1;
+}
+
+void srvctrl_log(SrvCtrlClient *client, char *msg, size_t len) {
+    char msgheader[4];
+    msgheader[0] = SRV_MSG_LOG;
+    uint16_t msglen = len;
+    memcpy(&msgheader[1], &msglen, 2);
+    write(client->fd, msgheader, 3);
+    
+    size_t pos = 0;
+    ssize_t w = 0;
+    while(pos < len) {
+        w = write(client->fd, msg + pos, len - pos);
+        if(w <= 0) {
+            break;
+        }
+        pos += w;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/srvctrl.h	Mon Mar 06 17:32:26 2017 +0100
@@ -0,0 +1,67 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2017 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 SRVCTRL_H
+#define SRVCTRL_H
+
+#include "../public/nsapi.h"
+
+#include "../../ucx/string.h"
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SRV_MSG_RESPONSE 0
+#define SRV_MSG_LOG      1
+    
+typedef struct {
+    int fd;
+} SrvCtrlClient;
+    
+int srvctrl_init(ServerConfiguration *cfg);
+
+int srvctrl_wait();
+
+void srvctrl_shutdown();
+
+SrvCtrlClient* srvctrl_create_client(int fd);
+
+void* srvctrl_thread(SrvCtrlClient *client);
+int srvctrl_handle_cmd(SrvCtrlClient *client, sstr_t cmd);
+void srvctrl_log(SrvCtrlClient *client, char *msg, size_t len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRVCTRL_H */
+
--- a/src/server/daemon/webserver.c	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/daemon/webserver.c	Mon Mar 06 17:32:26 2017 +0100
@@ -48,6 +48,8 @@
 #include "../util/io.h"
 #include "../util/util.h"
 
+#include "../../ucx/utils.h"
+
 #include "../safs/common.h"
 
 #include "func.h"
@@ -57,6 +59,7 @@
 #include "webserver.h"
 #include "log.h"
 #include "auth.h"
+#include "srvctrl.h"
 
 extern struct FuncStruct webserver_funcs[];
 
@@ -91,20 +94,6 @@
     // init caches
     auth_cache_init();
     
-    // create tmp dir and pid file
-    char *mkdir_cmd = NULL;
-    asprintf(&mkdir_cmd, "mkdir -p %s", cfg->tmp.ptr);
-    system(mkdir_cmd);
-    free(mkdir_cmd);
-
-    char *pid_file_path = NULL;
-    asprintf(&pid_file_path, "%s/pid", cfg->tmp.ptr);
-    FILE *pidfile = fopen(pid_file_path, "w"); // TODO: check error
-    pid_t pid = getpid();
-    fprintf(pidfile, "%d", pid);
-    fclose(pidfile);
-    free(pid_file_path);
-    
     // init SAFs
     common_saf_init();
     
@@ -168,6 +157,50 @@
                     "server must be started as root to change uid");
     }
     
+    // create tmp dir and pid file
+    char *mkdir_cmd = NULL;
+    asprintf(&mkdir_cmd, "mkdir -p %s", cfg->tmp.ptr);
+    system(mkdir_cmd);
+    free(mkdir_cmd);
+
+    char *pid_file_path = NULL;
+    asprintf(&pid_file_path, "%s/pid", cfg->tmp.ptr);
+    FILE *pidfile = fopen(pid_file_path, "w"); // TODO: check error
+    pid_t pid = getpid();
+    fprintf(pidfile, "%d", pid);
+    fclose(pidfile);
+    free(pid_file_path);
+    
+    // create unix domain socket for server control
+    sstr_t tmp_priv = ucx_sprintf("%s/private", cfg->tmp.ptr);
+    // TODO: remove existing private dir
+    if(mkdir(tmp_priv.ptr, S_IRWXU)) {
+        if(errno == EEXIST) {
+            if(chmod(tmp_priv.ptr, S_IRWXU)) {
+                log_ereport(
+                        LOG_CATASTROPHE,
+                        "cannot change permissions of tmp dir %s:",
+                        tmp_priv.ptr,
+                        strerror(errno));
+                return 0;
+            }
+        } else {
+            log_ereport(
+                    LOG_CATASTROPHE,
+                    "cannot create tmp dir %s:",
+                    tmp_priv.ptr,
+                    strerror(errno));
+            return -1;
+        }
+    }
+    
+    
+    // create srvctrl unix domain socket
+    // this socket is used for stop, reconfigure and other operations
+    if(srvctrl_init(cfg)) {
+        return -1;
+    }    
+    
     //endpwent(); // TODO: close or not?
     //free(pwbuf); // TODO: ?
     
@@ -190,6 +223,8 @@
 void webserver_shutdown() {
     log_ereport(LOG_INFORM, "webserver shutdown");
     
+    srvctrl_shutdown();
+    
     // execute restart callbacks
     RestartCallback *re = atrestart;
     while(re) {
@@ -198,6 +233,16 @@
     }
 }
 
+int webserver_reconfig() {
+    if(cfgmgr_load_config(NULL) != 0) {
+        return -1;
+    }
+    // start newly created listeners
+    start_all_listener();
+    
+    return 0;
+}
+
 void webserver_atrestart(void (*fn)(void *), void *data) {
     RestartCallback *cb = malloc(sizeof(RestartCallback));
     cb->func = fn;
--- a/src/server/daemon/webserver.h	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/daemon/webserver.h	Mon Mar 06 17:32:26 2017 +0100
@@ -45,6 +45,7 @@
 int webserver_init();
 int webserver_run();
 void webserver_shutdown();
+int webserver_reconfig();
 
 void webserver_atrestart(void (*fn)(void *), void *data);
 
--- a/src/server/plugins/java/Makefile	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/plugins/java/Makefile	Mon Mar 06 17:32:26 2017 +0100
@@ -60,7 +60,7 @@
 	$(CC) -o $(NSAPI_JNI_LIB) $(JNI_OBJS) $(LDFLAGS)
 
 $(JAVA_WSRT): $(JAVASRC)
-	ant -Dbuild.compiler=javac1.7 compile jar
+	ant compile jar
 
 
 ../../../../build/server/plugins/java/%.o: %.c
--- a/src/server/public/nsapi.h	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/public/nsapi.h	Mon Mar 06 17:32:26 2017 +0100
@@ -176,6 +176,9 @@
  */
 #define LOG_VERBOSE 6
 
+// new
+#define LOG_DEBUG 7
+
 /*
  * The time format to use in the error log
  */
--- a/src/server/util/system.c	Fri Feb 24 11:17:53 2017 +0100
+++ b/src/server/util/system.c	Mon Mar 06 17:32:26 2017 +0100
@@ -401,4 +401,4 @@
 #endif
 }
 
-*/
\ No newline at end of file
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tools/Makefile	Mon Mar 06 17:32:26 2017 +0100
@@ -0,0 +1,51 @@
+#
+# 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.
+#
+
+BUILD_ROOT = ../..
+
+include $(BUILD_ROOT)/config.mk
+
+CFLAGS += -I..
+LDFLAGS += -L../../build/lib -lucx -lwscfg
+
+# list of source files
+WSTOOL_SRC = wstool.c
+WSTOOL_SRC += srvctrlsocket.c
+
+WSTOOL_OBJ = $(WSTOOL_SRC:%.c=$(BUILD_ROOT)/build/tools/%$(OBJ_EXT))
+
+all: $(BUILD_ROOT)/build/tools $(BUILD_ROOT)/build/bin/wstool
+
+$(BUILD_ROOT)/build/bin/wstool: $(BUILD_ROOT)/build/tools $(WSTOOL_OBJ)
+	$(CC) -o $@ $(WSTOOL_OBJ) $(LDFLAGS)
+
+$(BUILD_ROOT)/build/tools/%$(OBJ_EXT): %.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+$(BUILD_ROOT)/build/tools:
+	mkdir -p $(BUILD_ROOT)/build/tools
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tools/srvctrlsocket.c	Mon Mar 06 17:32:26 2017 +0100
@@ -0,0 +1,112 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2017 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 "srvctrlsocket.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+SrvConnection* srvctrl_connet(char *socketfile) {
+    if(!socketfile) {
+        fprintf(stderr, "srvctrl_connect: no socketfile\n");
+        return NULL;
+    }
+    size_t len = strlen(socketfile);
+    if(len == 0) {
+        fprintf(stderr, "srvctrl_connect: invalid socket path\n");
+        return NULL;
+    }
+    if(len > 100) {
+        fprintf(stderr, "srvctrl_connect: socket path too long\n");
+        return NULL;
+    }
+    
+    int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if(fd == -1) {
+        perror("srvctrl_connect: cannot create socket");
+        return NULL;
+    }
+    
+    struct sockaddr_un addr;
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    memcpy(addr.sun_path, socketfile, len);
+    
+    if(connect(fd, (struct sockaddr*)&addr, sizeof(addr))) {
+        perror("srvctrl_connect");
+        close(fd);
+        return NULL;
+    }
+    
+    FILE *stream = fdopen(fd, "r+");
+    if(!stream) {
+        close(fd);
+        return NULL;
+    }
+    
+    SrvConnection *conn = calloc(1, sizeof(SrvConnection));
+    conn->socket = fd;
+    conn->stream = stream;
+    
+    return conn;
+}
+
+void srvctrl_close(SrvConnection *conn) {
+    fclose(conn->stream);
+    free(conn);
+}
+
+int srvctrl_readmsg(SrvConnection *conn, SrvMsg *msg) {
+    int type = 0;
+    uint16_t length;
+    
+    type = fgetc(conn->stream);
+    if(type == EOF) {
+        return 1;
+    }
+    
+    if(fread(&length, 1, 2, conn->stream) != 2) {
+        return -1;
+    }
+    
+    msg->type = type;
+    msg->length = length;
+    msg->message = malloc(length);
+    
+    size_t r = fread(msg->message, 1, length, conn->stream);
+    if(r != length) {
+        free(msg->message);
+        return -1;
+    }
+    
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tools/srvctrlsocket.h	Mon Mar 06 17:32:26 2017 +0100
@@ -0,0 +1,75 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2017 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 SRVCTRLSOCKET_H
+#define SRVCTRLSOCKET_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SrvConnection {
+    int  socket;
+    FILE *stream;
+} SrvConnection;
+
+typedef struct SrvMsg {
+    /*
+     * message type
+     * 0: cmd response
+     * 1: log message
+     */
+    int type;
+    
+    /*
+     * message data
+     */
+    char *message;
+    
+    /*
+     * message length
+     */
+    size_t length;
+} SrvMsg;
+
+SrvConnection* srvctrl_connet(char *socketfile);
+
+void srvctrl_close(SrvConnection *conn);
+
+int srvctrl_readmsg(SrvConnection *conn, SrvMsg *msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRVCTRLSOCKET_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tools/wstool.c	Mon Mar 06 17:32:26 2017 +0100
@@ -0,0 +1,123 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2017 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 "wstool.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../server/config/serverconf.h"
+
+#include "srvctrlsocket.h"
+
+static void print_info(char *cmd) {
+    fprintf(stderr, "usage:\n");
+    fprintf(stderr, "%s -t <srvconfigfile>\n", cmd);
+    fprintf(stderr, "%s -s <socketpath> <command>\n", cmd);
+    fprintf(stderr, "Commands: reconfig, shutdown, stat, log\n");
+}
+
+int main(int argc, char **argv) {
+    if(argc > 2) {
+        if(!strcmp(argv[1], "-t")) {
+            return tool_get_tmpdir(argv[2]);
+        } else if(!strcmp(argv[1], "-s")) {
+            if(argc != 4) {
+                print_info(argv[0]);
+                return -2;
+            }
+            return tool_srvctrl(argv[2], argv[3]);
+        }
+    }
+    
+    print_info(argv[0]);
+    return -2;
+}
+
+int tool_get_tmpdir(char *configfile) {
+    ServerConfig *serverconf = load_server_config(configfile);
+    UcxList *list = ucx_map_sstr_get(serverconf->objects, sstrn("Runtime", 7));
+    if(!list) {
+        fprintf(stderr, "Error: No Runtime element in %s\n", configfile);
+        return -1;
+    }
+    if(ucx_list_size(list) != 1) {
+        fprintf(stderr, "Error: Multiple Runtime elements in %s\n", configfile);
+        return -1;
+    }
+    ServerConfigObject *runtime = list->data;
+    sstr_t tmp = cfg_directivelist_get_str(runtime->directives, sstr("Temp"));
+    if(!tmp.ptr) {
+        fprintf(stderr, "Error: No Temp directive in Runtime Object\n");
+        return -1;
+    }
+    
+    printf("%.*s\n", (int)tmp.length, tmp.ptr);
+    
+    return 0;
+}
+
+int tool_srvctrl(char *socketfile, char *cmd) {
+    SrvConnection *srv = srvctrl_connet(socketfile);
+    if(!srv) {
+        return -1;
+    }
+    
+    fprintf(srv->stream, "%s\n", cmd);
+    fflush(srv->stream);
+    
+    SrvMsg msg;
+    while(!srvctrl_readmsg(srv, &msg)) {
+        if(msg.type == 0) {
+            fprintf(stdout, "%.*s", (int)msg.length, msg.message);
+            fflush(stdout);
+        } else if(msg.type == 1) {
+            fprintf(stderr, "%.*s", (int)msg.length, msg.message);
+            fflush(stderr);
+        }
+    }
+    
+    srvctrl_close(srv);
+    
+    return 0;
+}
+
+
+
+int log_ereport(int degree, const char *format, ...) {
+    va_list args;
+    va_start(args, format);
+    int ret = log_ereport_v(degree, format, args);
+    va_end(args);
+    return ret;
+}
+
+int log_ereport_v(int degree, const char *format, va_list args) { 
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tools/wstool.h	Mon Mar 06 17:32:26 2017 +0100
@@ -0,0 +1,50 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2017 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 WSTOOL_H
+#define WSTOOL_H
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int tool_get_tmpdir(char *configfile);
+
+int tool_srvctrl(char *socketfile, char *cmd);
+
+int log_ereport(int degree, const char *format, ...);
+int log_ereport_v(int degree, const char *format, va_list args);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WSTOOL_H */
+
--- a/templates/bin/reconfig.template	Fri Feb 24 11:17:53 2017 +0100
+++ b/templates/bin/reconfig.template	Mon Mar 06 17:32:26 2017 +0100
@@ -1,6 +1,57 @@
 #!/bin/sh
 
-PID=`cat /tmp/webserver-rw6pgl8b/pid`
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2017 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.
+#
 
-kill -USR1 $PID
+WS_INSTALL_DIR=%%WS_INSTALL_DIR%%
+
+cd $WS_INSTALL_DIR
+
+WS_TMP_DIR=`bin/wstool -t config/server.conf`
+if [ $? -ne 0 ]; then
+	exit 1
+fi
 
+WS_PID=`cat $WS_TMP_DIR/pid 2> /dev/null`
+if [ $? -ne 0 ]; then
+	echo "cannot get server pid"
+	exit 1
+fi
+if [ -z $WS_PID ]; then
+	echo "cannot get server pid"
+	exit 1
+fi
+
+kill -0 $WS_PID 2> /dev/null
+if [ $? -ne 0 ]; then
+	echo "server not running"
+	exit 1
+fi
+
+bin/wstool -s $WS_TMP_DIR/private/srvctrl.sock reconfig
+
--- a/templates/bin/startserv.template	Fri Feb 24 11:17:53 2017 +0100
+++ b/templates/bin/startserv.template	Mon Mar 06 17:32:26 2017 +0100
@@ -3,7 +3,7 @@
 #
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 #
-# Copyright 2011 Olaf Wintermann. All rights reserved.
+# Copyright 2017 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:
--- a/templates/bin/stopserv.template	Fri Feb 24 11:17:53 2017 +0100
+++ b/templates/bin/stopserv.template	Mon Mar 06 17:32:26 2017 +0100
@@ -1,6 +1,56 @@
 #!/bin/sh
 
-PID=`cat /tmp/webserver-rw6pgl8b/pid`
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2017 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.
+#
 
-kill -TERM $PID
+WS_INSTALL_DIR=%%WS_INSTALL_DIR%%
+
+cd $WS_INSTALL_DIR
+
+WS_TMP_DIR=`bin/wstool -t config/server.conf`
+if [ $? -ne 0 ]; then
+	exit 1
+fi
 
+WS_PID=`cat $WS_TMP_DIR/pid 2> /dev/null`
+if [ $? -ne 0 ]; then
+	echo "cannot get server pid"
+	exit 1
+fi
+if [ -z $WS_PID ]; then
+	echo "cannot get server pid"
+	exit 1
+fi
+
+kill -0 $WS_PID 2> /dev/null
+if [ $? -ne 0 ]; then
+	echo "server not running"
+	exit 1
+fi
+
+bin/wstool -s $WS_TMP_DIR/private/srvctrl.sock shutdown

mercurial