diff --git a/compat/gmtime_r.c b/compat/gmtime_r.c new file mode 100644 index 000000000..2588ad85c --- /dev/null +++ b/compat/gmtime_r.c @@ -0,0 +1,12 @@ +#include "config.h" + +#ifdef HAVE_TIME_H +#include +#endif + +struct tm *gmtime_r(const time_t *timep, struct tm *result) +{ + /* no thread safety. */ + *result = *gmtime(timep); + return result; +} diff --git a/compat/inet_aton.c b/compat/inet_aton.c index 5b6ffa03c..33c323d99 100644 --- a/compat/inet_aton.c +++ b/compat/inet_aton.c @@ -56,8 +56,12 @@ #include #include +#ifdef HAVE_NETINET_IN_H #include +#endif +#ifdef HAVE_ARPA_INET_H #include +#endif #include #if 0 diff --git a/compat/inet_ntop.c b/compat/inet_ntop.c index 1361733ad..92e07c77a 100644 --- a/compat/inet_ntop.c +++ b/compat/inet_ntop.c @@ -23,8 +23,12 @@ #include #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif +#ifdef HAVE_NETINET_IN_H #include +#endif #include #include #include @@ -62,7 +66,11 @@ inet_ntop(int af, const void *src, char *dst, size_t size) case AF_INET6: return (inet_ntop6(src, dst, size)); default: +#ifdef EAFNOSUPPORT errno = EAFNOSUPPORT; +#else + errno = ENOSYS; +#endif return (NULL); } /* NOTREACHED */ diff --git a/compat/inet_pton.c b/compat/inet_pton.c index 91987917a..15780d0b7 100644 --- a/compat/inet_pton.c +++ b/compat/inet_pton.c @@ -70,7 +70,11 @@ inet_pton(af, src, dst) case AF_INET6: return (inet_pton6(src, dst)); default: +#ifdef EAFNOSUPPORT errno = EAFNOSUPPORT; +#else + errno = ENOSYS; +#endif return (-1); } /* NOTREACHED */ diff --git a/config.h.in b/config.h.in index 9328bc544..19d6c6289 100644 --- a/config.h.in +++ b/config.h.in @@ -21,6 +21,9 @@ /* Define to 1 if your system has a working `chown' function. */ #undef HAVE_CHOWN +/* Define to 1 if you have the `chroot' function. */ +#undef HAVE_CHROOT + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H @@ -36,6 +39,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_EVENT_H +/* Define to 1 if you have the `fcntl' function. */ +#undef HAVE_FCNTL + /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK @@ -48,6 +54,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H +/* Define to 1 if you have the `getpwnam' function. */ +#undef HAVE_GETPWNAM + +/* Define to 1 if you have the `getrlimit' function. */ +#undef HAVE_GETRLIMIT + +/* Define to 1 if you have the `gmtime_r' function. */ +#undef HAVE_GMTIME_R + /* Define to 1 if you have the `inet_aton' function. */ #undef HAVE_INET_ATON @@ -60,6 +75,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* if the function 'ioctlsocket' is available */ +#undef HAVE_IOCTLSOCKET + +/* Define to 1 if you have the `kill' function. */ +#undef HAVE_KILL + /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO @@ -100,6 +121,18 @@ /* Define to 1 if the system has the type `pthread_spinlock_t'. */ #undef HAVE_PTHREAD_SPINLOCK_T +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + +/* Define to 1 if you have the `sbrk' function. */ +#undef HAVE_SBRK + +/* Define to 1 if you have the `setsid' function. */ +#undef HAVE_SETSID + +/* Define to 1 if you have the `sigprocmask' function. */ +#undef HAVE_SIGPROCMASK + /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF @@ -151,6 +184,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UIO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H @@ -403,6 +439,10 @@ #define RAND_MAX 2147483647 #endif +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + #ifndef IPV6_MIN_MTU #define IPV6_MIN_MTU 1280 #endif /* IPV6_MIN_MTU */ @@ -446,6 +486,10 @@ void *memmove(void *dest, const void *src, size_t n); #define strlcpy strlcpy_unbound size_t strlcpy(char *dst, const char *src, size_t siz); #endif +#ifndef HAVE_GMTIME_T +#define gmtime_r gmtime_r_unbound +struct tm *gmtime_r(const time_t *timep, struct tm *result); +#endif #ifndef HAVE_GETADDRINFO #define getaddrinfo getaddrinfo_unbound #define gai_strerror gai_strerror_unbound diff --git a/configure b/configure index 75a96980e..d38780d54 100755 --- a/configure +++ b/configure @@ -18735,7 +18735,9 @@ fi -for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h + + +for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 @@ -23141,85 +23143,6 @@ fi -for ac_func in tzset -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - - echo "$as_me:$LINENO: checking for getaddrinfo" >&5 echo $ECHO_N "checking for getaddrinfo... $ECHO_C" >&6 @@ -23331,6 +23254,148 @@ if test $ac_cv_func_getaddrinfo = no; then LIBOBJS="$LIBOBJS fake-rfc2553.$ac_objext" fi + + + + + + + + +for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setsid sbrk chroot kill +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# check ioctlsocket +echo "$as_me:$LINENO: checking for ioctlsocket" >&5 +echo $ECHO_N "checking for ioctlsocket... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#ifdef HAVE_WINSOCK2_H +#include +#endif + +int +main () +{ + + (void)ioctlsocket(0, 0, NULL); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_IOCTLSOCKET 1 +_ACEOF + + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + + for ac_func in inet_aton do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -23817,6 +23882,87 @@ done +for ac_func in gmtime_r +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + LIBOBJS="$LIBOBJS $ac_func.$ac_objext" +fi +done + + + # check this after all other compilation checks, since the linking of the lib # may break checks after this. diff --git a/configure.ac b/configure.ac index af8f2dcfb..8c931ed52 100644 --- a/configure.ac +++ b/configure.ac @@ -393,7 +393,7 @@ AC_PROG_LIBTOOL # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h],,, [AC_INCLUDES_DEFAULT]) +AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h],,, [AC_INCLUDES_DEFAULT]) # check for types AC_CHECK_TYPE(int8_t, char) @@ -637,8 +637,6 @@ AC_TYPE_SIGNAL AC_FUNC_FSEEKO AC_SYS_LARGEFILE -AC_CHECK_FUNCS([tzset]) - AC_DEFUN([AC_CHECK_GETADDRINFO_WITH_INCLUDES], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING(for getaddrinfo) @@ -695,12 +693,28 @@ AC_CHECK_GETADDRINFO_WITH_INCLUDES if test $ac_cv_func_getaddrinfo = no; then AC_LIBOBJ([fake-rfc2553]) fi +AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setsid sbrk chroot kill]) + +# check ioctlsocket +AC_MSG_CHECKING(for ioctlsocket) +AC_LINK_IFELSE(AC_LANG_PROGRAM([ +#ifdef HAVE_WINSOCK2_H +#include +#endif +], [ + (void)ioctlsocket(0, 0, NULL); +]), [ +AC_MSG_RESULT(yes) +AC_DEFINE(HAVE_IOCTLSOCKET, 1, [if the function 'ioctlsocket' is available]) +],[AC_MSG_RESULT(no)]) + AC_REPLACE_FUNCS(inet_aton) AC_REPLACE_FUNCS(inet_pton) AC_REPLACE_FUNCS(inet_ntop) AC_REPLACE_FUNCS(snprintf) AC_REPLACE_FUNCS(strlcpy) AC_REPLACE_FUNCS(memmove) +AC_REPLACE_FUNCS(gmtime_r) # check this after all other compilation checks, since the linking of the lib # may break checks after this. @@ -831,6 +845,10 @@ AH_BOTTOM([ #define RAND_MAX 2147483647 #endif +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + #ifndef IPV6_MIN_MTU #define IPV6_MIN_MTU 1280 #endif /* IPV6_MIN_MTU */ @@ -874,6 +892,10 @@ void *memmove(void *dest, const void *src, size_t n); #define strlcpy strlcpy_unbound size_t strlcpy(char *dst, const char *src, size_t siz); #endif +#ifndef HAVE_GMTIME_T +#define gmtime_r gmtime_r_unbound +struct tm *gmtime_r(const time_t *timep, struct tm *result); +#endif #ifndef HAVE_GETADDRINFO #define getaddrinfo getaddrinfo_unbound #define gai_strerror gai_strerror_unbound diff --git a/daemon/daemon.c b/daemon/daemon.c index a31cede91..f235f76fa 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -76,15 +76,24 @@ static RETSIGTYPE record_sigh(int sig) switch(sig) { case SIGTERM: +#ifdef SIGQUIT case SIGQUIT: +#endif +#ifdef SIGBREAK + case SIGBREAK: +#endif case SIGINT: sig_record_quit++; break; +#ifdef SIGHUP case SIGHUP: sig_record_reload++; break; +#endif +#ifdef SIGPIPE case SIGPIPE: break; +#endif default: log_err("ignoring signal %d", sig); } @@ -98,10 +107,20 @@ static void signal_handling_record() { if( signal(SIGTERM, record_sigh) == SIG_ERR || +#ifdef SIGQUIT signal(SIGQUIT, record_sigh) == SIG_ERR || - signal(SIGINT, record_sigh) == SIG_ERR || +#endif +#ifdef SIGBREAK + signal(SIGBREAK, record_sigh) == SIG_ERR || +#endif +#ifdef SIGHUP signal(SIGHUP, record_sigh) == SIG_ERR || - signal(SIGPIPE, SIG_IGN) == SIG_ERR) +#endif +#ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN) == SIG_ERR || +#endif + signal(SIGINT, record_sigh) == SIG_ERR + ) log_err("install sighandler: %s", strerror(errno)); } @@ -112,8 +131,10 @@ signal_handling_record() static void signal_handling_playback(struct worker* wrk) { +#ifdef SIGHUP if(sig_record_reload) worker_sighandler(SIGHUP, wrk); +#endif if(sig_record_quit) worker_sighandler(SIGTERM, wrk); sig_record_quit = 0; diff --git a/daemon/unbound.c b/daemon/unbound.c index c3ab9739d..4d0f31882 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -52,7 +52,9 @@ #include "util/module.h" #include #include +#ifdef HAVE_PWD_H #include +#endif #ifdef HAVE_SYS_RESOURCE_H #include @@ -88,6 +90,7 @@ static void usage() static void checkrlimits(struct config_file* cfg) { +#ifdef HAVE_GETRLIMIT int list = ((cfg->do_ip4?1:0) + (cfg->do_ip6?1:0)) * ((cfg->do_udp?1:0) + (cfg->do_tcp?1 + (int)cfg->incoming_num_tcp:0)); @@ -134,6 +137,9 @@ checkrlimits(struct config_file* cfg) log_warn("increased limit(open files) from %u to %u", (unsigned)avail, (unsigned)total+10); } +#else + (void)cfg; +#endif /* HAVE_GETRLIMIT */ } /** set verbosity, check rlimits, cache settings */ @@ -166,6 +172,7 @@ apply_settings(struct daemon* daemon, struct config_file* cfg, checkrlimits(cfg); } +#ifdef HAVE_KILL /** Read existing pid from pidfile. * @param file: file name of pid file. * @return: the pid from the file or -1 if none. @@ -253,11 +260,13 @@ checkoldpid(struct config_file* cfg) (unsigned)old); } } +#endif /* HAVE_KILL */ /** detach from command line */ static void detach(struct config_file* cfg) { +#ifdef HAVE_WORKING_FORK int fd; /* Take off... */ switch (fork()) { @@ -271,8 +280,10 @@ detach(struct config_file* cfg) exit(0); } /* detach */ +#ifdef HAVE_SETSID if(setsid() == -1) fatal_exit("setsid() failed: %s", strerror(errno)); +#endif if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { (void)dup2(fd, STDIN_FILENO); (void)dup2(fd, STDOUT_FILENO); @@ -280,6 +291,9 @@ detach(struct config_file* cfg) if (fd > 2) (void)close(fd); } +#else + (void)cfg; +#endif /* HAVE_WORKING_FORK */ } /** daemonize, drop user priviliges and chroot if needed */ @@ -295,6 +309,7 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode, log_assert(cfg); /* daemonize last to be able to print error to user */ +#ifdef HAVE_GETPWNAM if(cfg->username && cfg->username[0]) { struct passwd *pwd; if((pwd = getpwnam(cfg->username)) == NULL) @@ -303,6 +318,8 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode, gid = pwd->pw_gid; endpwent(); } +#endif +#ifdef HAVE_CHROOT if(cfg->chrootdir && cfg->chrootdir[0]) { if(chdir(cfg->chrootdir)) { fatal_exit("unable to chdir to chroot %s: %s", @@ -317,6 +334,9 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode, strlen(cfg->chrootdir)) == 0) (*cfgfile) += strlen(cfg->chrootdir); } +#else + (void)cfgfile; +#endif if(cfg->directory && cfg->directory[0]) { char* dir = cfg->directory; if(cfg->chrootdir && cfg->chrootdir[0] && @@ -331,6 +351,7 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode, verbose(VERB_QUERY, "chdir to %s", dir); } } +#ifdef HAVE_GETPWNAM if(cfg->username && cfg->username[0]) { if(setgid(gid) != 0) fatal_exit("unable to set group id of %s: %s", @@ -341,16 +362,20 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode, verbose(VERB_QUERY, "drop user privileges, run as %s", cfg->username); } +#endif +#ifdef HAVE_KILL /* check old pid file before forking */ if(cfg->pidfile && cfg->pidfile[0]) { checkoldpid(cfg); } +#endif /* init logfile just before fork */ log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir); if(!debug_mode && cfg->do_daemonize) { detach(cfg); } +#ifdef HAVE_KILL if(cfg->pidfile && cfg->pidfile[0]) { char* pf = cfg->pidfile; if(cfg->chrootdir && cfg->chrootdir[0] && @@ -360,6 +385,9 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode, if(!(daemon->pidfile = strdup(pf))) log_err("pidf: malloc failed"); } +#else + (void)daemon; +#endif } /** @@ -434,8 +462,10 @@ main(int argc, char* argv[]) int cmdline_verbose = 0; int debug_mode = 0; +#ifdef HAVE_SBRK /* take debug snapshot of heap */ unbound_start_brk = sbrk(0); +#endif log_init(NULL, 0, NULL); /* parse the options */ diff --git a/daemon/worker.c b/daemon/worker.c index a7db6fae4..be28eb991 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -104,6 +104,7 @@ debug_memleak(size_t accounted, size_t heap, static void debug_total_mem(size_t calctotal) { +#ifdef HAVE_SBRK extern void* unbound_start_brk; extern size_t unbound_mem_alloc, unbound_mem_freed; void* cur = sbrk(0); @@ -113,6 +114,9 @@ debug_total_mem(size_t calctotal) (unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed); debug_memleak(calctotal, (size_t)total, unbound_mem_alloc, unbound_mem_freed); +#else + (void)calctotal; +#endif /* HAVE_SBRK */ } #endif /* UNBOUND_ALLOC_STATS */ @@ -842,20 +846,24 @@ worker_sighandler(int sig, void* arg) * in the cause for unbound to exit */ struct worker* worker = (struct worker*)arg; switch(sig) { +#ifdef SIGHUP case SIGHUP: verbose(VERB_QUERY, "caught signal SIGHUP"); comm_base_exit(worker->base); break; +#endif case SIGINT: verbose(VERB_QUERY, "caught signal SIGINT"); worker->need_to_exit = 1; comm_base_exit(worker->base); break; +#ifdef SIGQUIT case SIGQUIT: verbose(VERB_QUERY, "caught signal SIGQUIT"); worker->need_to_exit = 1; comm_base_exit(worker->base); break; +#endif case SIGTERM: verbose(VERB_QUERY, "caught signal SIGTERM"); worker->need_to_exit = 1; @@ -943,17 +951,26 @@ worker_init(struct worker* worker, struct config_file *cfg, return 0; } if(do_sigs) { +#ifdef SIGHUP ub_thread_sig_unblock(SIGHUP); +#endif ub_thread_sig_unblock(SIGINT); +#ifdef SIGQUIT ub_thread_sig_unblock(SIGQUIT); +#endif ub_thread_sig_unblock(SIGTERM); #ifndef LIBEVENT_SIGNAL_PROBLEM worker->comsig = comm_signal_create(worker->base, worker_sighandler, worker); - if(!worker->comsig || !comm_signal_bind(worker->comsig, SIGHUP) - || !comm_signal_bind(worker->comsig, SIGINT) + if(!worker->comsig +#ifdef SIGHUP + || !comm_signal_bind(worker->comsig, SIGHUP) +#endif +#ifdef SIGQUIT + || !comm_signal_bind(worker->comsig, SIGQUIT) +#endif || !comm_signal_bind(worker->comsig, SIGTERM) - || !comm_signal_bind(worker->comsig, SIGQUIT)) { + || !comm_signal_bind(worker->comsig, SIGINT)) { log_err("could not create signal handlers"); worker_delete(worker); return 0; diff --git a/doc/Changelog b/doc/Changelog index d157f9ba4..fcbb41c7c 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,18 @@ +23 May 2008: Wouter + - mingw32 porting. + - test for sys/wait.h + - WSAEWOULDBLOCK test after nonblocking TCP connect. + - write_iov_buffer removed: unused and no struct iov on windows. + - signed/unsigned warning fixup mini_event. + - use ioctlsocket to set nonblocking I/O if fnctl is unavailable. + - skip signals that are not defined + - detect pwd.h. + - detect getpwnam, getrlimit, setsid, sbrk, chroot. + - default config has no chroot if chroot() unavailable. + - if no kill() then no pidfile is read or written. + - gmtime_r is replaced by nonthreadsafe alternative if unavail. + used in rrsig time validation errors. + 22 May 2008: Wouter - contrib unbound.spec from Patrick Vande Walle. - fixup bug#175: call tzset before chroot to have correct timestamps diff --git a/services/outside_network.c b/services/outside_network.c index c2ff92590..59a3f6e55 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -150,7 +150,13 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) } fd_set_nonblock(s); if(connect(s, (struct sockaddr*)&w->addr, w->addrlen) == -1) { +#ifdef EINPROGRESS if(errno != EINPROGRESS) { +#elif defined(WSAEWOULDBLOCK) + if(errno != WSAEWOULDBLOCK) { +#else + if(1) { +#endif log_err("outgoing tcp: connect: %s", strerror(errno)); log_addr(0, "failed address", &w->addr, w->addrlen); close(s); diff --git a/smallapp/unbound-checkconf.c b/smallapp/unbound-checkconf.c index 44e734464..7acc0865b 100644 --- a/smallapp/unbound-checkconf.c +++ b/smallapp/unbound-checkconf.c @@ -51,7 +51,9 @@ #include "iterator/iterator.h" #include "validator/validator.h" #include "services/localzone.h" +#ifdef HAVE_PWD_H #include +#endif #ifdef HAVE_SYS_STAT_H #include #endif @@ -368,11 +370,13 @@ morechecks(struct config_file* cfg, char* fname) cfg->module_conf); } +#ifdef HAVE_GETPWNAM if(cfg->username && cfg->username[0]) { if(getpwnam(cfg->username) == NULL) fatal_exit("user '%s' does not exist.", cfg->username); endpwent(); } +#endif localzonechecks(cfg); } diff --git a/util/config_file.c b/util/config_file.c index 36e0b8b8e..a333c9679 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -102,7 +102,9 @@ config_create() goto error_exit; init_outgoing_availports(cfg->outgoing_avail_ports, 65536); if(!(cfg->username = strdup("unbound"))) goto error_exit; +#ifdef HAVE_CHROOT if(!(cfg->chrootdir = strdup(CHROOT_DIR))) goto error_exit; +#endif if(!(cfg->directory = strdup(RUN_DIR))) goto error_exit; if(!(cfg->logfile = strdup(""))) goto error_exit; if(!(cfg->pidfile = strdup(PIDFILE))) goto error_exit; diff --git a/util/locks.c b/util/locks.c index b2b1f49e3..47c275889 100644 --- a/util/locks.c +++ b/util/locks.c @@ -42,12 +42,15 @@ #include "config.h" #include "util/locks.h" #include +#ifdef HAVE_SYS_WAIT_H #include +#endif /** block all signals, masks them away. */ void ub_thread_blocksigs() { +#if defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS) || defined(HAVE_SIGPROCMASK) int err; sigset_t sigset; sigfillset(&sigset); @@ -64,11 +67,13 @@ ub_thread_blocksigs() fatal_exit("sigprocmask: %s", strerror(errno)); # endif /* HAVE_SOLARIS_THREADS */ #endif /* HAVE_PTHREAD */ +#endif /* have signal stuff */ } /** unblock one signal, so we can catch it */ void ub_thread_sig_unblock(int sig) { +#if defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS) || defined(HAVE_SIGPROCMASK) int err; sigset_t sigset; sigemptyset(&sigset); @@ -86,6 +91,9 @@ void ub_thread_sig_unblock(int sig) fatal_exit("sigprocmask: %s", strerror(errno)); # endif /* HAVE_SOLARIS_THREADS */ #endif /* HAVE_PTHREAD */ +#else + (void)sig; +#endif /* have signal stuff */ } #if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS) diff --git a/util/mini_event.c b/util/mini_event.c index 8d431822c..bd2a81a18 100644 --- a/util/mini_event.c +++ b/util/mini_event.c @@ -295,10 +295,20 @@ int event_add(struct event* ev, struct timeval* tv) return -1; if( (ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) { ev->ev_base->fds[ev->ev_fd] = ev; - if(ev->ev_events&EV_READ) + if(ev->ev_events&EV_READ) { +#ifdef _WINSOCK2_H + FD_SET((u_int)ev->ev_fd, &ev->ev_base->reads); +#else FD_SET(ev->ev_fd, &ev->ev_base->reads); - if(ev->ev_events&EV_WRITE) +#endif + } + if(ev->ev_events&EV_WRITE) { +#ifdef _WINSOCK2_H + FD_SET((u_int)ev->ev_fd, &ev->ev_base->writes); +#else FD_SET(ev->ev_fd, &ev->ev_base->writes); +#endif + } if(ev->ev_fd > ev->ev_base->maxfd) ev->ev_base->maxfd = ev->ev_fd; } @@ -327,8 +337,13 @@ int event_del(struct event* ev) (void)rbtree_delete(ev->ev_base->times, &ev->node); if((ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) { ev->ev_base->fds[ev->ev_fd] = NULL; +#ifdef _WINSOCK2_H + FD_CLR((u_int)ev->ev_fd, &ev->ev_base->reads); + FD_CLR((u_int)ev->ev_fd, &ev->ev_base->writes); +#else FD_CLR(ev->ev_fd, &ev->ev_base->reads); FD_CLR(ev->ev_fd, &ev->ev_base->writes); +#endif } ev->added = 0; return 0; diff --git a/util/net_help.c b/util/net_help.c index 536d1aa13..21ffe5d77 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -82,6 +82,7 @@ write_socket(int s, const void *buf, size_t size) int fd_set_nonblock(int s) { +#ifdef HAVE_FCNTL int flag; if((flag = fcntl(s, F_GETFL)) == -1) { log_err("can't fcntl F_GETFL: %s", strerror(errno)); @@ -92,12 +93,19 @@ fd_set_nonblock(int s) log_err("can't fcntl F_SETFL: %s", strerror(errno)); return 0; } +#elif defined(HAVE_IOCTLSOCKET) + unsigned long on = 1; + if(ioctlsocket(s, FIONBIO, &on) != 0) { + log_err("can't ioctlsocket FIONBIO on: %d", WSAGetLastError()); + } +#endif return 1; } int fd_set_block(int s) { +#ifdef HAVE_FCNTL int flag; if((flag = fcntl(s, F_GETFL)) == -1) { log_err("cannot fcntl F_GETFL: %s", strerror(errno)); @@ -108,6 +116,12 @@ fd_set_block(int s) log_err("cannot fcntl F_SETFL: %s", strerror(errno)); return 0; } +#elif defined(HAVE_IOCTLSOCKET) + unsigned long off = 0; + if(ioctlsocket(s, FIONBIO, &off) != 0) { + log_err("can't ioctlsocket FIONBIO off: %d", WSAGetLastError()); + } +#endif return 1; } @@ -118,21 +132,6 @@ is_pow2(size_t num) return (num & (num-1)) == 0; } -void -write_iov_buffer(ldns_buffer* buffer, struct iovec* iov, size_t iovlen) -{ - size_t i; - size_t s = 0; - ldns_buffer_clear(buffer); - for(i=0; i