]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
windows work.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 11 Mar 2009 16:32:07 +0000 (16:32 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 11 Mar 2009 16:32:07 +0000 (16:32 +0000)
git-svn-id: file:///svn/unbound/trunk@1520 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/unbound.c
doc/Changelog
makedist.sh
util/log.c
winrc/service.conf
winrc/setup.nsi
winrc/win_svc.c
winrc/win_svc.h

index 14a3e45b74aca5e39d82ca08c3b3306452a380c0..19cd456daad9516a4d1fd62864b34c90fb543c03 100644 (file)
@@ -582,6 +582,7 @@ main(int argc, char* argv[])
        const char* winopt = NULL;
        int cmdline_verbose = 0;
        int debug_mode = 0;
+       int cmdline_cfg = 0;
 
 #ifdef HAVE_SBRK
        /* take debug snapshot of heap */
@@ -594,6 +595,7 @@ main(int argc, char* argv[])
                switch(c) {
                case 'c':
                        cfgfile = optarg;
+                       cmdline_cfg = 1;
                        break;
                case 'v':
                        cmdline_verbose ++;
@@ -617,7 +619,8 @@ main(int argc, char* argv[])
 
        if(winopt) {
 #ifdef UB_ON_WINDOWS
-               wsvc_command_option(winopt, cfgfile, cmdline_verbose);
+               wsvc_command_option(winopt, cfgfile, cmdline_verbose, 
+                       cmdline_cfg);
 #else
                fatal_exit("option not supported");
 #endif
index fa897e839a3bf97b2dc7e9e7cee464891ca39086..0038b5fa74c123f1807ee9ee7884dca4e52f9cd4 100644 (file)
@@ -3,6 +3,11 @@
        - winsock event handler tests if signals are really signalled.
        - install and service with log to file works on XP and Vista on 
          default install location.
+       - on windows logging to the Application logbook works (as a service).
+       - fix RUN_DIR on windows compile setting in makedist.
+       - windows registry has Software\Unbound\ConfigFile element.
+         If does not exist, the default is used. The -c switch overrides it.
+       - fix makedist version cleanup function.
 
 10 March 2009: Wouter
        - makedist -w strips out old rc.. and snapshot info from version.
index 80e9229b79f908f18df1ee61e19a4fbc48bff9ac..7d33d1a0367b2473556f527a4ac432d9077f712e 100755 (executable)
@@ -149,13 +149,14 @@ done
 if [ "$DOWIN" = "yes" ]; then
     version=`./configure --version | head -1 | awk '{ print $3 }'` \
        || error_cleanup "Cannot determine version number."
-    version=`echo $version | sed -e 's/rc.*$//' -e 's/_20.*$//'`
     if [ "$RC" != "no" -o "$SNAPSHOT" != "no" ]; then
        if [ "$RC" != "no" ]; then
-               version2=`echo $version | sed -e 's/rc.*//'`"rc$RC"
+               version2=`echo $version | sed -e 's/rc.*$//' -e 's/_20.*$//'`
+               version2=`echo $version2 | sed -e 's/rc.*//'`"rc$RC"
        fi
        if [ "$SNAPSHOT" != "no" ]; then
-               version2="${version}_`date +%Y%m%d`"
+               version2=`echo $version | sed -e 's/rc.*$//' -e 's/_20.*$//'`
+               version2="${version2}_`date +%Y%m%d`"
        fi
        replace_text "configure.ac" "AC_INIT(unbound, $version" "AC_INIT(unbound, $version2"
        version="$version2"
@@ -170,8 +171,7 @@ if [ "$DOWIN" = "yes" ]; then
     echo './configure --enable-debug --enable-static-exe "--with-conf-file=C:\Program Files\Unbound\service.conf" --with-run-dir="" --with-pidfile="" --with-chroot-dir="" '"$*"
     ./configure --enable-debug --enable-static-exe \
        "--with-conf-file=C:\Program Files\Unbound\service.conf" \
-       "--with-run-dir=C:\Program Files\Unbound" --with-pidfile="" \
-       --with-chroot-dir="" $* \
+       --with-run-dir="" --with-pidfile="" --with-chroot-dir="" $* \
        || error_cleanup "Could not configure"
     info "Calling make"
     make || error_cleanup "Could not make"
index 25e98fc51b9cc606850bf2d65414ab88a4cffd0e..0f6ef07dad3267b36d4d9c405714f6089f42f632 100644 (file)
@@ -54,6 +54,9 @@
 #  define LOG_INFO 6
 #  define LOG_DEBUG 7
 #endif
+#ifdef UB_ON_WINDOWS
+#  include "winrc/win_svc.h"
+#endif
 
 /* default verbosity */
 enum verbosity_value verbosity = 0;
@@ -65,7 +68,7 @@ static int key_created = 0;
 static ub_thread_key_t logkey;
 /** the identity of this executable/process */
 static const char* ident="unbound";
-#ifdef HAVE_SYSLOG_H
+#if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS)
 /** are we using syslog(3) to log to */
 static int logging_to_syslog = 0;
 #endif /* HAVE_SYSLOG_H */
@@ -83,7 +86,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
                ub_thread_key_create(&logkey, NULL);
        }
        if(logfile 
-#ifdef HAVE_SYSLOG_H
+#if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS)
        || logging_to_syslog
 #endif
        )
@@ -103,6 +106,14 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
                logging_to_syslog = 1;
                return;
        }
+#elif defined(UB_ON_WINDOWS)
+       if(logging_to_syslog) {
+               logging_to_syslog = 0;
+       }
+       if(use_syslog) {
+               logging_to_syslog = 1;
+               return;
+       }
 #endif /* HAVE_SYSLOG_H */
        if(!filename || !filename[0]) {
                logfile = stderr;
@@ -165,6 +176,32 @@ log_vmsg(int pri, const char* type,
                        (int)getpid(), tid?*tid:0, type, message);
                return;
        }
+#elif defined(UB_ON_WINDOWS)
+       if(logging_to_syslog) {
+               char m[32768];
+               HANDLE* s;
+               LPCTSTR str = m;
+               DWORD tp = MSG_GENERIC_ERR;
+               WORD wt = EVENTLOG_ERROR_TYPE;
+               if(strcmp(type, "info") == 0) {
+                       tp=MSG_GENERIC_INFO;
+                       wt=EVENTLOG_INFORMATION_TYPE;
+               } else if(strcmp(type, "warning") == 0) {
+                       tp=MSG_GENERIC_WARN;
+                       wt=EVENTLOG_WARNING_TYPE;
+               } else if(strcmp(type, "notice") == 0 
+                       || strcmp(type, "debug") == 0) {
+                       tp=MSG_GENERIC_SUCCESS;
+                       wt=EVENTLOG_SUCCESS;
+               }
+               snprintf(m, sizeof(m), "[unbound:%x] %s: %s", 
+                       tid?*tid:0, type, message);
+               s = RegisterEventSource(NULL, SERVICE_NAME);
+               if(!s) return;
+               ReportEvent(s, wt, 0, tp, NULL, 1, 0, &str, NULL);
+               DeregisterEventSource(s);
+               return;
+       }
 #endif /* HAVE_SYSLOG_H */
        if(!logfile) return;
        if(log_now)
index 8334adfb1f262c5ce0cbd38da5ade886abc6311b..4b6b49060dd3df93acc0c5601d3d3fe8c7374cad 100644 (file)
@@ -1,8 +1,13 @@
 # Unbound configuration file on windows.
 # See example.conf for more settings and syntax
 server:
-       # if you want to log to a file use
-       logfile: "unbound.log"
        # verbosity level 0-4 of logging
-       #verbosity: 1
+       verbosity: 0
+
+       # if you want to log to a file use
+       #logfile: "unbound.log"
+
+       # on Windows, this setting makes reports go into the Application log
+       # found in ControlPanels - System tasks - Logs 
+       #use-syslog: yes
 
index 7de5c72cb9e7d3ff12b5e8135214df2b5beefa15..baa3443b801ba169b50e5bd82e4d0b4eac917808 100644 (file)
@@ -112,7 +112,8 @@ section "-hidden.postinstall"
        ${EndIf}
 
        # store installation folder
-       WriteRegStr HKLM "Software\Unbound" "InstallLocation" $INSTDIR
+       WriteRegStr HKLM "Software\Unbound" "InstallLocation" "$INSTDIR"
+       WriteRegStr HKLM "Software\Unbound" "ConfigFile" "$INSTDIR\service.conf"
 
        # uninstaller
        WriteUninstaller "uninst.exe"
index 5a18f5478db919c3b6c4fc3ea54477c41d478a52..f04fc0fdfe63eaad7b1026205aa532b4ff870ff5 100644 (file)
 #include "util/netevent.h"
 #include "util/winsock_event.h"
 
-/** from gen_msg.h - success message record for windows message log */
-#define MSG_GENERIC_SUCCESS              ((DWORD)0x20010001L)
-/** from gen_msg.h - informational message record for windows message log */
-#define MSG_GENERIC_INFO                 ((DWORD)0x60010002L)
-/** from gen_msg.h - warning message record for windows message log */
-#define MSG_GENERIC_WARN                 ((DWORD)0xA0010003L)
-/** from gen_msg.h - error message record for windows message log */
-#define MSG_GENERIC_ERR                  ((DWORD)0xE0010004L)
-
 /** global service status */
 SERVICE_STATUS service_status;
 /** global service status handle */
@@ -70,7 +61,7 @@ WSAEVENT service_stop_event = NULL;
 /** event struct for stop callbacks */
 struct event service_stop_ev;
 /** config file to open. global communication to service_main() */
-const char* service_cfgfile = CONFIGFILE;
+char* service_cfgfile = CONFIGFILE;
 /** commandline verbosity. global communication to service_main() */
 int service_cmdline_verbose = 0;
 
@@ -80,7 +71,7 @@ int service_cmdline_verbose = 0;
  * @param exitcode: error code (when stopped)
  * @param wait: pending operation estimated time in milliseconds.
  */
-void report_status(DWORD state, DWORD exitcode, DWORD wait)
+static void report_status(DWORD state, DWORD exitcode, DWORD wait)
 {
        static DWORD checkpoint = 1;
        service_status.dwCurrentState = state;
@@ -145,6 +136,47 @@ reportev(const char* str)
        DeregisterEventSource(s);
 }
 
+/**
+ * Obtain registry string (if it exists).
+ * @param key: key string
+ * @param name: name of value to fetch.
+ * @return malloced string with the result or NULL if it did not
+ * exist on an error (logged) was encountered.
+ */
+static char*
+lookup_reg_str(const char* key, const char* name)
+{
+       HKEY hk = NULL;
+       DWORD type = 0;
+       BYTE buf[1024];
+       DWORD len = (DWORD)sizeof(buf);
+       LONG ret;
+       char* result = NULL;
+       ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hk);
+       if(ret == ERROR_FILE_NOT_FOUND)
+               return NULL; /* key does not exist */
+       else if(ret != ERROR_SUCCESS) {
+               reportev("RegOpenKeyEx failed");
+               return NULL;
+       }
+       ret = RegQueryValueEx(hk, (LPCTSTR)name, 0, &type, buf, &len);
+       if(RegCloseKey(hk))
+               reportev("RegCloseKey");
+       if(ret == ERROR_FILE_NOT_FOUND)
+               return NULL; /* name does not exist */
+       else if(ret != ERROR_SUCCESS) {
+               reportev("RegQueryValueEx failed");
+               return NULL;
+       }
+       if(type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ) {
+               buf[sizeof(buf)-1] = 0;
+               buf[sizeof(buf)-2] = 0; /* for multi_sz */
+               result = strdup(buf);
+               if(!result) reportev("out of memory");
+       }
+       return result;
+}
+
 /**
  * Init service. Keeps calling status pending to tell service control
  * manager that this process is not hanging.
@@ -157,9 +189,13 @@ service_init(struct daemon** d, struct config_file** c)
 {
        struct config_file* cfg = NULL;
        struct daemon* daemon = NULL;
-       const char* logfile= "C:\\unbound.log";
-       verbosity=4; service_cmdline_verbose=4;
-       log_init(logfile, 0, NULL); /* DEBUG logfile */
+
+       if(!service_cfgfile) {
+               char* newf = lookup_reg_str("Software\\Unbound", "ConfigFile");
+               if(newf) service_cfgfile = newf;
+               else    service_cfgfile = strdup(CONFIGFILE);
+               if(!service_cfgfile) fatal_exit("out of memory");
+       }
 
        /* create daemon */
        daemon = daemon_init();
@@ -191,7 +227,7 @@ service_init(struct daemon** d, struct config_file** c)
                } else
                        verbose(VERB_QUERY, "chdir to %s", cfg->directory);
        }
-       /* log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir); DEBUG*/
+       log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
        report_status(SERVICE_START_PENDING, NO_ERROR, 2400);
        verbose(VERB_QUERY, "winservice - apply cfg");
        daemon_apply_cfg(daemon, cfg);
@@ -222,8 +258,6 @@ service_main(DWORD ATTR_UNUSED(argc), LPTSTR* ATTR_UNUSED(argv))
        struct config_file* cfg = NULL;
        struct daemon* daemon = NULL;
 
-       reportev("Trying to report event");
-
        service_status_handle = RegisterServiceCtrlHandler(SERVICE_NAME, 
                (LPHANDLER_FUNCTION)hdlr);
        if(!service_status_handle) {
@@ -269,25 +303,29 @@ service_main(DWORD ATTR_UNUSED(argc), LPTSTR* ATTR_UNUSED(argv))
        config_delete(cfg);
        daemon_delete(daemon);
        (void)WSACloseEvent(service_stop_event);
+       free(service_cfgfile);
        verbose(VERB_QUERY, "winservice - full stop");
        report_status(SERVICE_STOPPED, NO_ERROR, 0);
 }
 
 /** start the service */
 static void 
-service_start(const char* cfgfile, int v)
+service_start(const char* cfgfile, int v, int c)
 {
        SERVICE_TABLE_ENTRY myservices[2] = {
                {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)service_main},
                {NULL, NULL} };
        verbosity=v;
-       if(1) {
-               /* DEBUG log to file */
+       if(verbosity >= VERB_QUERY) {
+               /* log to file about start sequence */
                fclose(fopen("C:\\unbound.log", "w"));
                log_init("C:\\unbound.log", 0, 0);
                verbose(VERB_QUERY, "open logfile");
-       }
-       service_cfgfile = cfgfile;
+       } else log_init(0, 1, 0); /* otherwise, use Application log */
+       if(c) {
+               service_cfgfile = strdup(cfgfile);
+               if(!service_cfgfile) fatal_exit("out of memory");
+       } else  service_cfgfile = NULL;
        service_cmdline_verbose = v;
        /* this call returns when service has stopped. */
        if(!StartServiceCtrlDispatcher(myservices)) {
@@ -296,14 +334,14 @@ service_start(const char* cfgfile, int v)
 }
 
 void
-wsvc_command_option(const char* wopt, const char* cfgfile, int v)
+wsvc_command_option(const char* wopt, const char* cfgfile, int v, int c)
 {
        if(strcmp(wopt, "install") == 0)
                wsvc_install(stdout, NULL);
        else if(strcmp(wopt, "remove") == 0)
                wsvc_remove(stdout);
        else if(strcmp(wopt, "service") == 0)
-               service_start(cfgfile, v);
+               service_start(cfgfile, v, c);
        else fatal_exit("unknown option: %s", wopt);
        exit(0);
 }
index 0b4ecfa60ed0bad9f48a65db6884b1b46d2c844c..332a5268cb1b102e18a4425f9d08cef57929e573 100644 (file)
@@ -51,13 +51,23 @@ struct worker;
 /** service name for unbound (internal to ServiceManager) */
 #define SERVICE_NAME "unbound"
 
+/** from gen_msg.h - success message record for windows message log */
+#define MSG_GENERIC_SUCCESS              ((DWORD)0x20010001L)
+/** from gen_msg.h - informational message record for windows message log */
+#define MSG_GENERIC_INFO                 ((DWORD)0x60010002L)
+/** from gen_msg.h - warning message record for windows message log */
+#define MSG_GENERIC_WARN                 ((DWORD)0xA0010003L)
+/** from gen_msg.h - error message record for windows message log */
+#define MSG_GENERIC_ERR                  ((DWORD)0xE0010004L)
+
 /**
  * Handle commandline service for windows.
  * @param wopt: windows option string (install, remove, service). 
  * @param cfgfile: configfile to open (default or passed with -c).
  * @param v: amount of commandline verbosity added with -v.
+ * @param c: true if cfgfile was set by commandline -c option.
  */
-void wsvc_command_option(const char* wopt, const char* cfgfile, int v);
+void wsvc_command_option(const char* wopt, const char* cfgfile, int v, int c);
 
 /**
  * Setup lead worker events.