windows work.
git-svn-id: https://unbound.nlnetlabs.nl/svn/trunk@1520 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
f89272deeb
commit
47844cdccd
@ -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
|
||||
|
@ -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.
|
||||
|
10
makedist.sh
10
makedist.sh
@ -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"
|
||||
|
41
util/log.c
41
util/log.c
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -52,15 +52,6 @@
|
||||
#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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user