From d00f9984a5119790b40f8797b5655e62574a042f Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Tue, 24 Nov 2009 21:42:02 -0800 Subject: [PATCH] Make roken build on windows Signed-off-by: Love Hornquist Astrand --- appl/ftp/ftpd/ftpd.c | 2 +- appl/gssmask/gssmask.c | 2 +- appl/kf/kfd.c | 2 +- appl/kx/kxd.c | 2 +- appl/popper/pop_init.c | 2 +- appl/rsh/rshd.c | 2 +- appl/telnet/telnetd/telnetd.c | 2 +- appl/test/tcp_server.c | 2 +- kadmin/kadmind.c | 2 +- kdc/hpropd.c | 2 +- lib/krb5/kuserok.c | 2 - lib/roken/NTMakefile | 2 +- lib/roken/base64.c | 4 +- lib/roken/base64.h | 8 +- lib/roken/bswap.c | 4 +- lib/roken/chown.c | 2 +- lib/roken/cloexec.c | 7 +- lib/roken/closefrom.c | 2 +- lib/roken/concat.c | 8 +- lib/roken/copyhostent.c | 2 +- lib/roken/daemon.c | 2 +- lib/roken/dirent-test.c | 278 ++++++++++++++++++++ lib/roken/dirent.c | 180 +++++++++++++ lib/roken/dirent.hin | 66 +++++ lib/roken/dlfcn.h | 78 ++++++ lib/roken/dlfcn_w32.c | 96 +++++++ lib/roken/dumpdata.c | 6 +- lib/roken/ecalloc.c | 2 +- lib/roken/emalloc.c | 2 +- lib/roken/environment.c | 4 +- lib/roken/eread.c | 5 +- lib/roken/erealloc.c | 2 +- lib/roken/err.c | 2 +- lib/roken/err.hin | 20 +- lib/roken/errx.c | 2 +- lib/roken/esetenv.c | 2 +- lib/roken/estrdup.c | 2 +- lib/roken/ewrite.c | 5 +- lib/roken/fchown.c | 2 +- lib/roken/flock.c | 76 +++++- lib/roken/fnmatch.c | 8 +- lib/roken/fnmatch.hin | 4 +- lib/roken/freeaddrinfo.c | 2 +- lib/roken/freehostent.c | 2 +- lib/roken/gai_strerror.c | 2 +- lib/roken/get_default_username.c | 8 +- lib/roken/get_window_size.c | 16 +- lib/roken/getaddrinfo.c | 2 +- lib/roken/getaddrinfo_hostspec.c | 4 +- lib/roken/getarg.c | 16 +- lib/roken/getarg.h | 12 +- lib/roken/getcap.c | 30 +-- lib/roken/getcwd.c | 2 +- lib/roken/getdtablesize.c | 2 +- lib/roken/getegid.c | 2 +- lib/roken/geteuid.c | 2 +- lib/roken/getgid.c | 2 +- lib/roken/gethostname.c | 2 +- lib/roken/getifaddrs-test.c | 46 ++++ lib/roken/getifaddrs.c | 10 +- lib/roken/getifaddrs_w32.c | 163 ++++++++++++ lib/roken/getipnodebyaddr.c | 2 +- lib/roken/getipnodebyname.c | 2 +- lib/roken/getnameinfo.c | 2 +- lib/roken/getnameinfo_verified.c | 2 +- lib/roken/getopt.c | 2 +- lib/roken/getprogname.c | 2 +- lib/roken/gettimeofday.c | 4 +- lib/roken/getuid.c | 2 +- lib/roken/getusershell.c | 6 +- lib/roken/glob.c | 4 +- lib/roken/hex.c | 4 +- lib/roken/hex.h | 8 +- lib/roken/hostent_find_fqdn.c | 2 +- lib/roken/hstrerror.c | 2 +- lib/roken/inet_aton.c | 2 +- lib/roken/inet_ntop.c | 2 +- lib/roken/inet_pton.c | 61 ++++- lib/roken/initgroups.c | 2 +- lib/roken/innetgr.c | 2 +- lib/roken/iruserok.c | 2 +- lib/roken/issuid.c | 2 +- lib/roken/k_getpwnam.c | 2 +- lib/roken/k_getpwuid.c | 2 +- lib/roken/localtime_r.c | 2 +- lib/roken/lstat.c | 2 +- lib/roken/memmove.c | 2 +- lib/roken/mini_inetd.c | 106 ++++++-- lib/roken/mkstemp.c | 4 +- lib/roken/ndbm_wrap.c | 16 +- lib/roken/ndbm_wrap.h | 22 +- lib/roken/net_read.c | 47 +++- lib/roken/net_write.c | 39 ++- lib/roken/parse_bytes.c | 6 +- lib/roken/parse_bytes.h | 10 +- lib/roken/parse_time-test.c | 6 +- lib/roken/parse_time.c | 8 +- lib/roken/parse_time.h | 12 +- lib/roken/parse_units.c | 20 +- lib/roken/parse_units.h | 18 +- lib/roken/putenv.c | 2 +- lib/roken/rcmd.c | 2 +- lib/roken/readv.c | 2 +- lib/roken/realloc.c | 2 +- lib/roken/recvmsg.c | 2 +- lib/roken/resolve-test.c | 4 +- lib/roken/resolve.c | 16 +- lib/roken/resolve.h | 14 +- lib/roken/rkpty.c | 2 + lib/roken/roken-common.h | 139 ++++++---- lib/roken/roken.h.in | 394 +++++++++++++++++++++------- lib/roken/roken_gethostby.c | 6 +- lib/roken/rtbl.c | 44 ++-- lib/roken/rtbl.h | 36 +-- lib/roken/sendmsg.c | 90 ++++++- lib/roken/setegid.c | 2 +- lib/roken/setenv.c | 14 +- lib/roken/seteuid.c | 2 +- lib/roken/setprogname.c | 2 +- lib/roken/signal.c | 2 +- lib/roken/simple_exec.c | 44 ++-- lib/roken/simple_exec_w32.c | 434 +++++++++++++++++++++++++++++++ lib/roken/sleep.c | 47 ++++ lib/roken/snprintf.c | 26 +- lib/roken/socket.c | 60 +++-- lib/roken/sockstartup_w32.c | 77 ++++++ lib/roken/strcasecmp.c | 2 +- lib/roken/strcollect.c | 4 +- lib/roken/strdup.c | 2 +- lib/roken/strerror.c | 2 +- lib/roken/strftime.c | 6 +- lib/roken/strlcat.c | 3 +- lib/roken/strlcpy.c | 18 +- lib/roken/strlwr.c | 2 +- lib/roken/strncasecmp.c | 2 +- lib/roken/strndup.c | 2 +- lib/roken/strnlen.c | 2 +- lib/roken/strpftime-test.c | 2 +- lib/roken/strpftime-test.h | 7 + lib/roken/strpool.c | 6 +- lib/roken/strptime.c | 6 +- lib/roken/strsep.c | 2 +- lib/roken/strsep_copy.c | 2 +- lib/roken/strtok_r.c | 2 +- lib/roken/strupr.c | 2 +- lib/roken/swab.c | 2 +- lib/roken/syslog.h | 248 ++++++++++++++++++ lib/roken/syslogc.c | 341 ++++++++++++++++++++++++ lib/roken/test-mem.c | 24 +- lib/roken/test-mem.h | 4 +- lib/roken/test-mini_inetd.c | 369 ++++++++++++++++++++++++++ lib/roken/timeval.c | 6 +- lib/roken/tm2time.c | 2 +- lib/roken/unsetenv.c | 2 +- lib/roken/unvis.c | 8 +- lib/roken/verify.c | 2 +- lib/roken/verr.c | 2 +- lib/roken/verrx.c | 2 +- lib/roken/vis.c | 25 +- lib/roken/vis.hin | 23 +- lib/roken/vsyslog.c | 2 +- lib/roken/vwarn.c | 2 +- lib/roken/vwarnx.c | 2 +- lib/roken/warnerr.c | 2 +- lib/roken/warnx.c | 2 +- lib/roken/write_pid.c | 11 +- lib/roken/writev.c | 2 +- lib/roken/xfree.c | 2 - 168 files changed, 3688 insertions(+), 607 deletions(-) create mode 100644 lib/roken/dirent-test.c create mode 100644 lib/roken/dirent.c create mode 100644 lib/roken/dirent.hin create mode 100644 lib/roken/dlfcn.h create mode 100644 lib/roken/dlfcn_w32.c create mode 100644 lib/roken/getifaddrs_w32.c create mode 100644 lib/roken/simple_exec_w32.c create mode 100644 lib/roken/sleep.c create mode 100644 lib/roken/sockstartup_w32.c create mode 100644 lib/roken/syslog.h create mode 100644 lib/roken/syslogc.c create mode 100644 lib/roken/test-mini_inetd.c diff --git a/appl/ftp/ftpd/ftpd.c b/appl/ftp/ftpd/ftpd.c index 138f9b55e..e97bb1d79 100644 --- a/appl/ftp/ftpd/ftpd.c +++ b/appl/ftp/ftpd/ftpd.c @@ -329,7 +329,7 @@ main(int argc, char **argv) #endif if(interactive_flag) - mini_inetd (port); + mini_inetd(port, NULL); /* * LOG_NDELAY sets up the logging connection immediately, diff --git a/appl/gssmask/gssmask.c b/appl/gssmask/gssmask.c index 8cee0695b..46c3fc03e 100644 --- a/appl/gssmask/gssmask.c +++ b/appl/gssmask/gssmask.c @@ -1252,7 +1252,7 @@ main(int argc, char **argv) err(1, "error opening %s", lf); } - mini_inetd(htons(port)); + mini_inetd(htons(port), NULL); fprintf(logfile, "connected\n"); { diff --git a/appl/kf/kfd.c b/appl/kf/kfd.c index 10f8ef3df..71f48c935 100644 --- a/appl/kf/kfd.c +++ b/appl/kf/kfd.c @@ -284,7 +284,7 @@ static int doit (int port, const char *service) { if (do_inetd) - mini_inetd(port); + mini_inetd(port, NULL); return proto (STDIN_FILENO, service); } diff --git a/appl/kx/kxd.c b/appl/kx/kxd.c index 65bd1a18f..be36cd4f2 100644 --- a/appl/kx/kxd.c +++ b/appl/kx/kxd.c @@ -772,7 +772,7 @@ main (int argc, char **argv) } if (!inetd_flag) - mini_inetd (port); + mini_inetd (port, NULL); signal (SIGCHLD, childhandler); return doit(STDIN_FILENO, tcp_flag); diff --git a/appl/popper/pop_init.c b/appl/popper/pop_init.c index a2924877d..fd7987bb9 100644 --- a/appl/popper/pop_init.c +++ b/appl/popper/pop_init.c @@ -301,7 +301,7 @@ pop_init(POP *p,int argcount,char **argmessage) portnum = p->kerberosp ? pop_getportbyname(p, "kpop", "tcp", 1109) : pop_getportbyname(p, "pop", "tcp", 110); - mini_inetd (portnum); + mini_inetd (portnum, NULL); } /* Get the address and socket of the client to whom I am speaking */ diff --git a/appl/rsh/rshd.c b/appl/rsh/rshd.c index b22918b40..93ca33969 100644 --- a/appl/rsh/rshd.c +++ b/appl/rsh/rshd.c @@ -961,7 +961,7 @@ main(int argc, char **argv) errx (1, "getaddrinfo: %s", gai_strerror (error)); } } - mini_inetd_addrinfo (ai); + mini_inetd_addrinfo (ai, NULL); freeaddrinfo(ai); } diff --git a/appl/telnet/telnetd/telnetd.c b/appl/telnet/telnetd/telnetd.c index 2d0bb24ce..bce2e1d76 100644 --- a/appl/telnet/telnetd/telnetd.c +++ b/appl/telnet/telnetd/telnetd.c @@ -370,7 +370,7 @@ main(int argc, char **argv) port = k_getportbyname("telnet", "tcp", htons(23)); #endif } - mini_inetd (port); + mini_inetd (port, NULL); } else if (argc > 0) { usage(1); /* NOT REACHED */ diff --git a/appl/test/tcp_server.c b/appl/test/tcp_server.c index f8df34fc9..7da97e6aa 100644 --- a/appl/test/tcp_server.c +++ b/appl/test/tcp_server.c @@ -155,7 +155,7 @@ proto (int sock, const char *service) static int doit (int port, const char *service) { - mini_inetd (port); + mini_inetd (port, NULL); return proto (STDIN_FILENO, service); } diff --git a/kadmin/kadmind.c b/kadmin/kadmind.c index 318989adf..1df640c02 100644 --- a/kadmin/kadmind.c +++ b/kadmin/kadmind.c @@ -168,7 +168,7 @@ main(int argc, char **argv) "tcp", 749); else debug_port = htons(atoi(port_str)); - mini_inetd(debug_port); + mini_inetd(debug_port, NULL); } else { struct sockaddr_storage __ss; struct sockaddr *sa = (struct sockaddr *)&__ss; diff --git a/kdc/hpropd.c b/kdc/hpropd.c index 73dc85d18..c34a2c85c 100644 --- a/kdc/hpropd.c +++ b/kdc/hpropd.c @@ -133,7 +133,7 @@ main(int argc, char **argv) } if (!inetd_flag) { mini_inetd (krb5_getportbyname (context, "hprop", "tcp", - HPROP_PORT)); + HPROP_PORT), NULL); } sin_len = sizeof(ss); if(getpeername(fd, sa, &sin_len) < 0) diff --git a/lib/krb5/kuserok.c b/lib/krb5/kuserok.c index 6a951844a..ccfe28130 100644 --- a/lib/krb5/kuserok.c +++ b/lib/krb5/kuserok.c @@ -132,7 +132,6 @@ check_directory(krb5_context context, if((d = opendir(dirname)) == NULL) return errno; -#ifdef HAVE_DIRFD { int fd; struct stat st2; @@ -147,7 +146,6 @@ check_directory(krb5_context context, return EACCES; } } -#endif while((dent = readdir(d)) != NULL) { if(strcmp(dent->d_name, ".") == 0 || diff --git a/lib/roken/NTMakefile b/lib/roken/NTMakefile index f6d2e30dc..05f01382e 100644 --- a/lib/roken/NTMakefile +++ b/lib/roken/NTMakefile @@ -79,7 +79,7 @@ libroken_la_OBJS = \ $(OBJ)\resolve.obj \ $(OBJ)\roken_gethostby.obj \ $(OBJ)\rtbl.obj \ - $(OBJ)\sendmsg_w32.obj \ + $(OBJ)\sendmsg.obj \ $(OBJ)\setenv.obj \ $(OBJ)\setprogname.obj \ $(OBJ)\simple_exec_w32.obj \ diff --git a/lib/roken/base64.c b/lib/roken/base64.c index a9f0535dd..4c06bd2d1 100644 --- a/lib/roken/base64.c +++ b/lib/roken/base64.c @@ -51,7 +51,7 @@ pos(char c) return -1; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL base64_encode(const void *data, int size, char **str) { char *s, *p; @@ -120,7 +120,7 @@ token_decode(const char *token) return (marker << 24) | val; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL base64_decode(const char *str, void *data) { const char *p; diff --git a/lib/roken/base64.h b/lib/roken/base64.h index f42c0ba42..dfae4c13b 100644 --- a/lib/roken/base64.h +++ b/lib/roken/base64.h @@ -38,16 +38,18 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL base64_encode(const void *, int, char **); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL base64_decode(const char *, void *); #endif diff --git a/lib/roken/bswap.c b/lib/roken/bswap.c index 67d240c23..7f8c1c22b 100644 --- a/lib/roken/bswap.c +++ b/lib/roken/bswap.c @@ -36,7 +36,7 @@ #ifndef HAVE_BSWAP32 -unsigned int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION unsigned int ROKEN_LIB_CALL bswap32 (unsigned int val) { return (val & 0xff) << 24 | @@ -48,7 +48,7 @@ bswap32 (unsigned int val) #ifndef HAVE_BSWAP16 -unsigned short ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION unsigned short ROKEN_LIB_CALL bswap16 (unsigned short val) { return (val & 0xff) << 8 | diff --git a/lib/roken/chown.c b/lib/roken/chown.c index c01e2aa94..90a82d958 100644 --- a/lib/roken/chown.c +++ b/lib/roken/chown.c @@ -35,7 +35,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL chown(const char *path, uid_t owner, gid_t group) { return 0; diff --git a/lib/roken/cloexec.c b/lib/roken/cloexec.c index c015b1d8f..901512a9d 100644 --- a/lib/roken/cloexec.c +++ b/lib/roken/cloexec.c @@ -33,14 +33,12 @@ #include -#include -#include - #include "roken.h" void ROKEN_LIB_FUNCTION rk_cloexec(int fd) { +#ifdef HAVE_FCNTL int ret; ret = fcntl(fd, F_GETFD); @@ -48,10 +46,13 @@ rk_cloexec(int fd) return; if (fcntl(fd, F_SETFD, ret | FD_CLOEXEC) == -1) return; +#endif } void ROKEN_LIB_FUNCTION rk_cloexec_file(FILE *f) { +#ifdef HAVE_FCNTL rk_cloexec(fileno(f)); +#endif } diff --git a/lib/roken/closefrom.c b/lib/roken/closefrom.c index 7aa0ef737..770eb2c67 100644 --- a/lib/roken/closefrom.c +++ b/lib/roken/closefrom.c @@ -42,7 +42,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL closefrom(int fd) { int num = getdtablesize(); diff --git a/lib/roken/concat.c b/lib/roken/concat.c index 631a0786b..2ae777d5d 100644 --- a/lib/roken/concat.c +++ b/lib/roken/concat.c @@ -35,7 +35,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_concat (char *s, size_t len, ...) { int ret; @@ -47,7 +47,7 @@ roken_concat (char *s, size_t len, ...) return ret; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_vconcat (char *s, size_t len, va_list args) { const char *a; @@ -65,7 +65,7 @@ roken_vconcat (char *s, size_t len, va_list args) return 0; } -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL roken_vmconcat (char **s, size_t max_len, va_list args) { const char *a; @@ -97,7 +97,7 @@ roken_vmconcat (char **s, size_t max_len, va_list args) return len; } -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL roken_mconcat (char **s, size_t max_len, ...) { int ret; diff --git a/lib/roken/copyhostent.c b/lib/roken/copyhostent.c index 69c1ba40f..4ed630210 100644 --- a/lib/roken/copyhostent.c +++ b/lib/roken/copyhostent.c @@ -39,7 +39,7 @@ * return a malloced copy of `h' */ -struct hostent * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL copyhostent (const struct hostent *h) { struct hostent *res; diff --git a/lib/roken/daemon.c b/lib/roken/daemon.c index 2fc98371b..591a9a953 100644 --- a/lib/roken/daemon.c +++ b/lib/roken/daemon.c @@ -47,7 +47,7 @@ static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93"; #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL daemon(int nochdir, int noclose) { int fd; diff --git a/lib/roken/dirent-test.c b/lib/roken/dirent-test.c new file mode 100644 index 000000000..ac87339fe --- /dev/null +++ b/lib/roken/dirent-test.c @@ -0,0 +1,278 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "dirent.h" + +/* Note that we create a known directory structure in a subdirectory + of the current directory to run our tests. */ + +#define TESTDIR "dirent-test-dir" + +const char * dir_entries[] = { + "A", + "B", + "C", + "CAA", + "CAAA", + "CABBBB", + "CAABBB.txt", + "A filename with spaces" +}; + +const char * entries_begin_with_C[] = { + "C", + "CAA", + "CAAA", + "CABBBB", + "CAABBB.txt" +}; + +const char * entries_end_with_A[] = { + "A", + "CAA", + "CAAA" +}; + +const int n_dir_entries = sizeof(dir_entries)/sizeof(dir_entries[0]); + +int teardown_test(void); + +void fail_test(const char * reason, ...) +{ + va_list args; + + va_start(args, reason); + vfprintf(stderr, reason, args); + va_end(args); + + fprintf(stderr, " : errno = %d (%s)\n", errno, strerror(errno)); + teardown_test(); + abort(); +} + +void fail_test_nf(const char * format, ...) +{ + va_list args; + + fprintf(stderr, "FAIL:"); + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + fprintf(stderr, " : errno = %d (%s)\n", errno, strerror(errno)); +} + +int touch(const char * filename) +{ + int fd; + + fd = _open(filename, _O_CREAT, _S_IREAD| _S_IWRITE); + + if (fd == -1) + return -1; + + return _close(fd); +} + +int setup_test(void) +{ + int i; + + fprintf(stderr, "Creating test directory %s ...\n", TESTDIR); + + if (_mkdir(TESTDIR)) + fail_test("Can't create test directory \"" TESTDIR "\""); + + if (_chdir(TESTDIR)) + fail_test("Can't change to test directory"); + + for (i=0; i < n_dir_entries; i++) { + if (touch(dir_entries[i])) + fail_test("Can't create test file '%s'", dir_entries[i]); + } + + fprintf(stderr, "Done with test setup.\n"); + + return 0; +} + +int teardown_test(void) +{ + char dirname[_MAX_PATH]; + size_t len; + int i; + + printf ("Begin cleanup...\n"); + + if (_getcwd(dirname, sizeof(dirname)/sizeof(char)) != NULL && + + (len = strlen(dirname)) > sizeof(TESTDIR)/sizeof(char) && + + !strcmp(dirname + len + 1 - sizeof(TESTDIR)/sizeof(char), TESTDIR)) { + + /* fallthrough */ + + } else { + /* did we create the directory? */ + + if (!_rmdir( TESTDIR )) { + fprintf(stderr, "Removed test directory\n"); + return 0; + } else { + if (errno == ENOTEMPTY) { + if (_chdir(TESTDIR)) { + fprintf(stderr, "Can't change to test directory. Aborting cleanup.\n"); + return -1; + } else { + /* fallthrough */ + } + } else { + return -1; + } + } + } + + fprintf(stderr, "Cleaning up test directory %s ...\n", TESTDIR); + + for (i=0; i < n_dir_entries; i++) { + if (_unlink(dir_entries[i])) { + /* if the test setup failed, we expect this to happen for + at least some files */ + } + } + + if (_chdir("..")) { + fprintf(stderr, "Can't escape test directory. Giving in.\n"); + return -1; + } + + if (_rmdir( TESTDIR )) { + fprintf(stderr, "Can't remove test directory.\n"); + return -1; + } + + printf("Cleaned up test directory\n"); + return 0; +} + +int check_list(const char * filespec, const char ** list, int n, int expect_dot_and_dotdot) +{ + DIR * d; + struct dirent * e; + int n_found = 0; + int i; + int rv = 0; + int retry = 1; + + d = opendir(filespec); + if (d == NULL) { + fail_test_nf("opendir failed for [%s]", filespec); + return -1; + } + + printf("Checking filespec [%s]... ", filespec); + + retry: + while ((e = readdir(d)) != NULL) { + n_found ++; + + if (expect_dot_and_dotdot && + (!strcmp(e->d_name, ".") || + !strcmp(e->d_name, ".."))) + continue; + + for (i=0; i < n; i++) { + if (!strcmp(list[i], e->d_name)) + break; + } + + if (i == n) { + fail_test_nf("Found unexpected entry [%s]", e->d_name); + rv = -1; + } + } + + if (n_found != n) { + fail_test_nf("Unexpected number of entries [%d]. Expected %d", n_found, n); + rv = -1; + } + + if (retry) { + retry = 0; + n_found = 0; + + rewinddir(d); + goto retry; + } + + if (closedir(d)) { + fail_test_nf("closedir() failed"); + } + + printf("done\n"); + + return rv; +} + +int run_tests() +{ + /* assumes that the test directory has been set up and we have + changed into the test directory. */ + + check_list("*", dir_entries, n_dir_entries + 2, 1); + check_list("*.*", dir_entries, n_dir_entries + 2, 1); + check_list("C*", entries_begin_with_C, sizeof(entries_begin_with_C)/sizeof(entries_begin_with_C[0]), 0); + check_list("*A", entries_end_with_A, sizeof(entries_end_with_A)/sizeof(entries_end_with_A[0]), 0); + + return 0; +} + +int main(int argc, char ** argv) +{ + if (setup_test()) + return 1; + + run_tests(); + + teardown_test(); + + return 0; +} diff --git a/lib/roken/dirent.c b/lib/roken/dirent.c new file mode 100644 index 000000000..7e16bc84d --- /dev/null +++ b/lib/roken/dirent.c @@ -0,0 +1,180 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + **********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include "dirent.h" + +#ifndef _WIN32 +#error Only implemented for Win32 +#endif + +struct _dirent_dirinfo { + int magic; + long n_entries; + long nc_entries; + long cursor; + struct dirent **entries; +}; +#define DIRINFO_MAGIC 0xf8c0639d +#define IS_DP(p) ((p) && ((DIR *)(p))->magic == DIRINFO_MAGIC) + +#define INITIAL_ENTRIES 16 + +ROKEN_LIB_FUNCTION DIR * ROKEN_LIB_CALL +opendir(const char * filespec) +{ + DIR * dp; + struct _finddata_t fd; + intptr_t fd_handle; + + memset(&fd, 0, sizeof(fd)); + + fd_handle = _findfirst(filespec, &fd); + + if (fd_handle == -1) + return NULL; + + dp = malloc(sizeof(*dp)); + if (dp == NULL) + goto done; + + memset(dp, 0, sizeof(*dp)); + dp->magic = DIRINFO_MAGIC; + dp->cursor = 0; + dp->n_entries = 0; + dp->nc_entries = INITIAL_ENTRIES; + dp->entries = calloc(dp->nc_entries, sizeof(dp->entries[0])); + + if (dp->entries == NULL) { + closedir(dp); + dp = NULL; + goto done; + } + + do { + long len = strlen(fd.name); + struct dirent * e; + + if (dp->n_entries == dp->nc_entries) { + struct dirent ** ne; + + dp->nc_entries *= 2; + ne = realloc(dp->entries, sizeof(dp->entries[0]) * dp->nc_entries); + + if (ne == NULL) { + closedir(dp); + dp = NULL; + goto done; + } + + dp->entries = ne; + } + + e = malloc(sizeof(*e) + len * sizeof(char)); + if (e == NULL) { + closedir(dp); + dp = NULL; + goto done; + } + + e->d_ino = 0; /* no inodes :( */ + strcpy_s(e->d_name, len + 1, fd.name); + + dp->entries[dp->n_entries++] = e; + + } while (_findnext(fd_handle, &fd) == 0); + + done: + if (fd_handle != -1) + _findclose(fd_handle); + + return dp; +} + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +closedir(DIR * dp) +{ + if (!IS_DP(dp)) + return EINVAL; + + if (dp->entries) { + long i; + + for (i=0; i < dp->n_entries; i++) { + free(dp->entries[i]); + } + + free(dp->entries); + } + + free(dp); + + return 0; +} + +ROKEN_LIB_FUNCTION struct dirent * ROKEN_LIB_CALL +readdir(DIR * dp) +{ + if (!IS_DP(dp) || + dp->cursor < 0 || + dp->cursor >= dp->n_entries) + + return NULL; + + return dp->entries[dp->cursor++]; +} + +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +rewinddir(DIR * dp) +{ + if (IS_DP(dp)) + dp->cursor = 0; +} + +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +seekdir(DIR * dp, long offset) +{ + if (IS_DP(dp) && offset >= 0 && offset < dp->n_entries) + dp->cursor = offset; +} + +ROKEN_LIB_FUNCTION long ROKEN_LIB_CALL +telldir(DIR * dp) +{ + return dp->cursor; +} diff --git a/lib/roken/dirent.hin b/lib/roken/dirent.hin new file mode 100644 index 000000000..c9a86c63f --- /dev/null +++ b/lib/roken/dirent.hin @@ -0,0 +1,66 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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 __DIRENT_H__ +#define __DIRENT_H__ + +#ifndef ROKEN_LIB_FUNCTION +#ifdef _WIN32 +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl +#else +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL +#endif +#endif + +#include + +struct dirent { + ino_t d_ino; + char d_name[1]; +}; + +typedef struct _dirent_dirinfo DIR; + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL closedir(DIR *); + +ROKEN_LIB_FUNCTION DIR * ROKEN_LIB_CALL opendir(const char *); + +ROKEN_LIB_FUNCTION struct dirent * ROKEN_LIB_CALL readdir(DIR *); + +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rewinddir(DIR *); + +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL seekdir(DIR *, long); + +ROKEN_LIB_FUNCTION long ROKEN_LIB_CALL telldir(DIR *); + +#endif diff --git a/lib/roken/dlfcn.h b/lib/roken/dlfcn.h new file mode 100644 index 000000000..d0972573d --- /dev/null +++ b/lib/roken/dlfcn.h @@ -0,0 +1,78 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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 __dlfcn_h__ +#define __dlfcn_h__ + +#ifndef ROKEN_LIB_FUNCTION +#ifdef _WIN32 +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl +#else +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL +#endif +#endif + +#define DLSYM_RET_TYPE void * + +#ifdef __cplusplus +extern "C" +#endif + +/* Implementation based on + http://www.opengroup.org/onlinepubs/009695399/basedefs/dlfcn.h.html */ + +#define RTLD_LAZY (1<<0) + +#define RTLD_NOW (1<<1) + +#define RTLD_GLOBAL (1<<2) + +#define RTLD_LOCAL (1<<3) + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +dlclose(void *); + +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL +dlerror(void); + +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL +dlopen(const char *, int); + +ROKEN_LIB_FUNCTION DLSYM_RET_TYPE ROKEN_LIB_CALL +dlsym(void *, const char *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __dlfcn_h__ */ diff --git a/lib/roken/dlfcn_w32.c b/lib/roken/dlfcn_w32.c new file mode 100644 index 000000000..713887330 --- /dev/null +++ b/lib/roken/dlfcn_w32.c @@ -0,0 +1,96 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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 +#include +#include + +#define ERR_STR_LEN 256 + +__declspec(thread) static char err_str[ERR_STR_LEN]; + +static void set_error(const char * e) { + StringCbCopy(err_str, sizeof(err_str), e); +} + +static void set_error_from_last(void) { + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + 0, GetLastError(), 0, + err_str, sizeof(err_str)/sizeof(err_str[0]), + NULL); +} + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +dlclose(void * vhm) +{ + BOOL brv; + + brv = FreeLibrary((HMODULE) vhm); + if (!brv) { + set_error_from_last(); + } + return !brv; +} + +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL +dlerror(void) +{ + return err_str; +} + +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL +dlopen(const char *fn, int flags) +{ + HMODULE hm; + + /* We don't support dlopen(0, ...) on Windows.*/ + if ( fn == NULL ) { + set_error("Not implemented"); + return NULL; + } + + hm = LoadLibrary(fn); + + if (hm == NULL) { + set_error_from_last(); + } + + return (void *) hm; +} + +ROKEN_LIB_FUNCTION DLSYM_RET_TYPE ROKEN_LIB_CALL +dlsym(void * vhm, const char * func_name) +{ + HMODULE hm = (HMODULE) vhm; + + return GetProcAddress(hm, func_name); +} + diff --git a/lib/roken/dumpdata.c b/lib/roken/dumpdata.c index c5513c323..f30f0e54c 100644 --- a/lib/roken/dumpdata.c +++ b/lib/roken/dumpdata.c @@ -33,15 +33,13 @@ #include -#include - #include "roken.h" /* * Write datablob to a filename, don't care about errors. */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_dumpdata (const char *filename, const void *buf, size_t size) { int fd; @@ -57,7 +55,7 @@ rk_dumpdata (const char *filename, const void *buf, size_t size) * Read all data from a filename, care about errors. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_undumpdata(const char *filename, void **buf, size_t *size) { struct stat sb; diff --git a/lib/roken/ecalloc.c b/lib/roken/ecalloc.c index c8e650403..04b37330c 100644 --- a/lib/roken/ecalloc.c +++ b/lib/roken/ecalloc.c @@ -42,7 +42,7 @@ * Like calloc but never fails. */ -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL ecalloc (size_t number, size_t size) { void *tmp = calloc (number, size); diff --git a/lib/roken/emalloc.c b/lib/roken/emalloc.c index c937e6d70..2520230a3 100644 --- a/lib/roken/emalloc.c +++ b/lib/roken/emalloc.c @@ -42,7 +42,7 @@ * Like malloc but never fails. */ -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL emalloc (size_t sz) { void *tmp = malloc (sz); diff --git a/lib/roken/environment.c b/lib/roken/environment.c index 49a6f4a54..64c354d62 100644 --- a/lib/roken/environment.c +++ b/lib/roken/environment.c @@ -127,7 +127,7 @@ read_env_file(FILE *F, char ***env, int *assigned) * list of malloced strings in `env' */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL read_environment(const char *file, char ***env) { int assigned; @@ -141,7 +141,7 @@ read_environment(const char *file, char ***env) return assigned; } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL free_environment(char **env) { int i; diff --git a/lib/roken/eread.c b/lib/roken/eread.c index 18de0b85e..ba30f0230 100644 --- a/lib/roken/eread.c +++ b/lib/roken/eread.c @@ -33,16 +33,13 @@ #include -#include -#include - #include "roken.h" /* * Like read but never fails (and never returns partial data). */ -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL eread (int fd, void *buf, size_t nbytes) { ssize_t ret; diff --git a/lib/roken/erealloc.c b/lib/roken/erealloc.c index f77c8ec73..1c30ecc60 100644 --- a/lib/roken/erealloc.c +++ b/lib/roken/erealloc.c @@ -42,7 +42,7 @@ * Like realloc but never fails. */ -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL erealloc (void *ptr, size_t sz) { void *tmp = realloc (ptr, sz); diff --git a/lib/roken/err.c b/lib/roken/err.c index a5c3dddb5..5fbe84fdf 100644 --- a/lib/roken/err.c +++ b/lib/roken/err.c @@ -35,7 +35,7 @@ #include "err.h" -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL err(int eval, const char *fmt, ...) { va_list ap; diff --git a/lib/roken/err.hin b/lib/roken/err.hin index 9fd1856e2..96fe5cf85 100644 --- a/lib/roken/err.hin +++ b/lib/roken/err.hin @@ -48,40 +48,42 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL verr(int eval, const char *fmt, va_list ap) __attribute__ ((noreturn, format (printf, 2, 0))); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL err(int eval, const char *fmt, ...) __attribute__ ((noreturn, format (printf, 2, 3))); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL verrx(int eval, const char *fmt, va_list ap) __attribute__ ((noreturn, format (printf, 2, 0))); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL errx(int eval, const char *fmt, ...) __attribute__ ((noreturn, format (printf, 2, 3))); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL vwarn(const char *fmt, va_list ap) __attribute__ ((format (printf, 1, 0))); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL warn(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL vwarnx(const char *fmt, va_list ap) __attribute__ ((format (printf, 1, 0))); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL warnx(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/lib/roken/errx.c b/lib/roken/errx.c index 60fc7e7c0..f75ad0179 100644 --- a/lib/roken/errx.c +++ b/lib/roken/errx.c @@ -35,7 +35,7 @@ #include "err.h" -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL errx(int eval, const char *fmt, ...) { va_list ap; diff --git a/lib/roken/esetenv.c b/lib/roken/esetenv.c index bbafdbea1..3cbf5ed36 100644 --- a/lib/roken/esetenv.c +++ b/lib/roken/esetenv.c @@ -37,7 +37,7 @@ #include -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL esetenv(const char *var, const char *val, int rewrite) { if (setenv (rk_UNCONST(var), rk_UNCONST(val), rewrite)) diff --git a/lib/roken/estrdup.c b/lib/roken/estrdup.c index ab7f26550..d275a2830 100644 --- a/lib/roken/estrdup.c +++ b/lib/roken/estrdup.c @@ -42,7 +42,7 @@ * Like strdup but never fails. */ -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL estrdup (const char *str) { char *tmp = strdup (str); diff --git a/lib/roken/ewrite.c b/lib/roken/ewrite.c index ac00f3b94..fce570529 100644 --- a/lib/roken/ewrite.c +++ b/lib/roken/ewrite.c @@ -33,16 +33,13 @@ #include -#include -#include - #include "roken.h" /* * Like write but never fails (and never returns partial data). */ -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL ewrite (int fd, const void *buf, size_t nbytes) { ssize_t ret; diff --git a/lib/roken/fchown.c b/lib/roken/fchown.c index 453bb3eb0..050c2dd3b 100644 --- a/lib/roken/fchown.c +++ b/lib/roken/fchown.c @@ -35,7 +35,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL fchown(int fd, uid_t owner, gid_t group) { return 0; diff --git a/lib/roken/flock.c b/lib/roken/flock.c index e15a3f796..525ad8a83 100644 --- a/lib/roken/flock.c +++ b/lib/roken/flock.c @@ -37,11 +37,11 @@ #include "roken.h" - #define OP_MASK (LOCK_SH | LOCK_EX | LOCK_UN) -int ROKEN_LIB_FUNCTION -rk_flock(int fd, int operation) + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +fk_flock(int fd, int operation) { #if defined(HAVE_FCNTL) && defined(F_SETLK) struct flock arg; @@ -75,6 +75,76 @@ rk_flock(int fd, int operation) break; } return code; + +#elif defined(_WIN32) + /* Windows */ + +#define FLOCK_OFFSET_LOW 0 +#define FLOCK_OFFSET_HIGH 0 +#define FLOCK_LENGTH_LOW 0x00000000 +#define FLOCK_LENGTH_HIGH 0x80000000 + + HANDLE hFile; + OVERLAPPED ov; + BOOL rv = FALSE; + DWORD f = 0; + + hFile = (HANDLE) _get_osfhandle(fd); + if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) { + _set_errno(EBADF); + return -1; + } + + ZeroMemory(&ov, sizeof(ov)); + ov.hEvent = NULL; + ov.Offset = FLOCK_OFFSET_LOW; + ov.OffsetHigh = FLOCK_OFFSET_HIGH; + + if (operation & LOCK_NB) + f = LOCKFILE_FAIL_IMMEDIATELY; + + switch (operation & OP_MASK) { + case LOCK_UN: /* Unlock */ + rv = UnlockFileEx(hFile, 0, + FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH, &ov); + break; + + case LOCK_SH: /* Shared lock */ + rv = LockFileEx(hFile, f, 0, + FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH, &ov); + break; + + case LOCK_EX: /* Exclusive lock */ + rv = LockFileEx(hFile, f|LOCKFILE_EXCLUSIVE_LOCK, 0, + FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH, + &ov); + break; + + default: + _set_errno(EINVAL); + return -1; + } + + if (!rv) { + switch (GetLastError()) { + case ERROR_SHARING_VIOLATION: + case ERROR_LOCK_VIOLATION: + case ERROR_IO_PENDING: + _set_errno(EWOULDBLOCK); + break; + + case ERROR_ACCESS_DENIED: + _set_errno(EACCES); + break; + + default: + _set_errno(ENOLCK); + } + return -1; + } + + return 0; + #else return -1; #endif diff --git a/lib/roken/fnmatch.c b/lib/roken/fnmatch.c index 179b17f90..f693faec8 100644 --- a/lib/roken/fnmatch.c +++ b/lib/roken/fnmatch.c @@ -45,6 +45,12 @@ static char rcsid[] = "$NetBSD: fnmatch.c,v 1.11 1995/02/27 03:43:06 cgd Exp $"; * Compares a filename or pathname to a pattern. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + #include #include @@ -52,7 +58,7 @@ static char rcsid[] = "$NetBSD: fnmatch.c,v 1.11 1995/02/27 03:43:06 cgd Exp $"; static const char *rangematch (const char *, int, int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_fnmatch(const char *pattern, const char *string, int flags) { const char *stringstart; diff --git a/lib/roken/fnmatch.hin b/lib/roken/fnmatch.hin index d5d54a562..1a66d4274 100644 --- a/lib/roken/fnmatch.hin +++ b/lib/roken/fnmatch.hin @@ -36,9 +36,11 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION __declspec(dllimport) +#define ROKEN_LIB_CALL __stdcall #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif diff --git a/lib/roken/freeaddrinfo.c b/lib/roken/freeaddrinfo.c index 434e49e88..7132e95dd 100644 --- a/lib/roken/freeaddrinfo.c +++ b/lib/roken/freeaddrinfo.c @@ -39,7 +39,7 @@ * free the list of `struct addrinfo' starting at `ai' */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL freeaddrinfo(struct addrinfo *ai) { struct addrinfo *tofree; diff --git a/lib/roken/freehostent.c b/lib/roken/freehostent.c index 335504300..61fbb223b 100644 --- a/lib/roken/freehostent.c +++ b/lib/roken/freehostent.c @@ -39,7 +39,7 @@ * free a malloced hostent */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL freehostent (struct hostent *h) { char **p; diff --git a/lib/roken/gai_strerror.c b/lib/roken/gai_strerror.c index 10beac05e..1e326bee3 100644 --- a/lib/roken/gai_strerror.c +++ b/lib/roken/gai_strerror.c @@ -62,7 +62,7 @@ static struct gai_error { * */ -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL gai_strerror(int ecode) { struct gai_error *g; diff --git a/lib/roken/get_default_username.c b/lib/roken/get_default_username.c index 96fa1b06d..da6806b15 100644 --- a/lib/roken/get_default_username.c +++ b/lib/roken/get_default_username.c @@ -40,7 +40,7 @@ * NULL if we can't guess at all. */ -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL get_default_username (void) { const char *user; @@ -73,5 +73,11 @@ get_default_username (void) return pwd->pw_name; } #endif +#ifdef _WIN32 + /* TODO: We can call GetUserNameEx() and figure out a + username. However, callers do not free the return value of this + function. */ +#endif + return user; } diff --git a/lib/roken/get_window_size.c b/lib/roken/get_window_size.c index 60fb1764f..13e7ebf15 100644 --- a/lib/roken/get_window_size.c +++ b/lib/roken/get_window_size.c @@ -57,7 +57,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL get_window_size(int fd, struct winsize *wp) { int ret = -1; @@ -85,6 +85,20 @@ get_window_size(int fd, struct winsize *wp) wp->ws_col = dst[0]; ret = 0; } +#elif defined(_WIN32) + { + intptr_t fh = 0; + CONSOLE_SCREEN_BUFFER_INFO sb_info; + + fh = _get_osfhandle(fd); + if (fh != (intptr_t) INVALID_HANDLE_VALUE && + GetConsoleScreenBufferInfo((HANDLE) fh, &sb_info)) { + wp->ws_row = 1 + sb_info.srWindow.Bottom - sb_info.srWindow.Top; + wp->ws_col = 1 + sb_info.srWindow.Right - sb_info.srWindow.Left; + + ret = 0; + } + } #endif if (ret != 0) { char *s; diff --git a/lib/roken/getaddrinfo.c b/lib/roken/getaddrinfo.c index 8c6129976..c8ed95413 100644 --- a/lib/roken/getaddrinfo.c +++ b/lib/roken/getaddrinfo.c @@ -365,7 +365,7 @@ get_nodes (const char *nodename, * }; */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, diff --git a/lib/roken/getaddrinfo_hostspec.c b/lib/roken/getaddrinfo_hostspec.c index 44694eeb8..b18c54fb6 100644 --- a/lib/roken/getaddrinfo_hostspec.c +++ b/lib/roken/getaddrinfo_hostspec.c @@ -37,7 +37,7 @@ /* getaddrinfo via string specifying host and port */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_getaddrinfo_hostspec2(const char *hostspec, int socktype, int port, @@ -92,7 +92,7 @@ roken_getaddrinfo_hostspec2(const char *hostspec, return getaddrinfo (host, portstr, &hints, ai); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_getaddrinfo_hostspec(const char *hostspec, int port, struct addrinfo **ai) diff --git a/lib/roken/getarg.c b/lib/roken/getarg.c index 60b0f645a..d182f0019 100644 --- a/lib/roken/getarg.c +++ b/lib/roken/getarg.c @@ -91,7 +91,7 @@ mandoc_template(struct getargs *args, const char *extra_string, char *(i18n)(const char *)) { - int i; + size_t i; char timestr[64], cmd[64]; char buf[128]; const char *p; @@ -207,7 +207,7 @@ builtin_i18n(const char *str) return rk_UNCONST(str); } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL arg_printusage (struct getargs *args, size_t num_args, const char *progname, @@ -217,7 +217,7 @@ arg_printusage (struct getargs *args, progname, extra_string, builtin_i18n); } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL arg_printusage_i18n (struct getargs *args, size_t num_args, const char *usage, @@ -225,8 +225,7 @@ arg_printusage_i18n (struct getargs *args, const char *extra_string, char *(i18n)(const char *)) { - int i; - size_t max_len = 0; + size_t i, max_len = 0; char buf[128]; int col = 0, columns; struct winsize ws; @@ -474,6 +473,7 @@ arg_match_long(struct getargs *args, size_t num_args, default: abort (); + UNREACHABLE(return 0); } /* not reached */ @@ -550,7 +550,7 @@ arg_match_short (struct getargs *args, size_t num_args, return 0; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getarg(struct getargs *args, size_t num_args, int argc, char **argv, int *goptind) { @@ -562,7 +562,7 @@ getarg(struct getargs *args, size_t num_args, #elif defined(HAVE_RANDOM) srandom(time(NULL)); #else - srand (time(NULL)); + srand ((int) time(NULL)); #endif (*goptind)++; for(i = *goptind; i < argc; i++) { @@ -586,7 +586,7 @@ getarg(struct getargs *args, size_t num_args, return ret; } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL free_getarg_strings (getarg_strings *s) { free (s->strings); diff --git a/lib/roken/getarg.h b/lib/roken/getarg.h index 64b65aa76..79573a0ea 100644 --- a/lib/roken/getarg.h +++ b/lib/roken/getarg.h @@ -40,9 +40,11 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif @@ -86,17 +88,17 @@ typedef struct getarg_collect_info { void *data; } getarg_collect_info; -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getarg(struct getargs *args, size_t num_args, int argc, char **argv, int *goptind); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL arg_printusage (struct getargs *args, size_t num_args, const char *progname, const char *extra_string); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL arg_printusage_i18n (struct getargs *args, size_t num_args, const char *usage, @@ -104,7 +106,7 @@ arg_printusage_i18n (struct getargs *args, const char *extra_string, char *(i18n)(const char *)); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL free_getarg_strings (getarg_strings *); #endif /* __GETARG_H__ */ diff --git a/lib/roken/getcap.c b/lib/roken/getcap.c index fc90870d8..d6250f525 100644 --- a/lib/roken/getcap.c +++ b/lib/roken/getcap.c @@ -83,24 +83,24 @@ static int getent (char **, size_t *, char **, int, const char *, int, char *); static int nfcmp (char *, char *); -int ROKEN_LIB_FUNCTION cgetset(const char *ent); -char *ROKEN_LIB_FUNCTION cgetcap(char *buf, const char *cap, int type); -int ROKEN_LIB_FUNCTION cgetent(char **buf, char **db_array, const char *name); -int ROKEN_LIB_FUNCTION cgetmatch(const char *buf, const char *name); -int ROKEN_LIB_FUNCTION cgetclose(void); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetset(const char *ent); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL cgetcap(char *buf, const char *cap, int type); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetent(char **buf, char **db_array, const char *name); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetmatch(const char *buf, const char *name); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetclose(void); #if 0 int cgetfirst(char **buf, char **db_array); int cgetnext(char **bp, char **db_array); #endif -int ROKEN_LIB_FUNCTION cgetstr(char *buf, const char *cap, char **str); -int ROKEN_LIB_FUNCTION cgetustr(char *buf, const char *cap, char **str); -int ROKEN_LIB_FUNCTION cgetnum(char *buf, const char *cap, long *num); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetstr(char *buf, const char *cap, char **str); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetustr(char *buf, const char *cap, char **str); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetnum(char *buf, const char *cap, long *num); /* * Cgetset() allows the addition of a user specified buffer to be added * to the database array, in effect "pushing" the buffer on top of the * virtual database. 0 is returned on success, -1 on failure. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetset(const char *ent) { const char *source, *check; @@ -153,7 +153,7 @@ cgetset(const char *ent) * If (cap, '@') or (cap, terminator, '@') is found before (cap, terminator) * return NULL. */ -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL cgetcap(char *buf, const char *cap, int type) { char *bp; @@ -204,7 +204,7 @@ cgetcap(char *buf, const char *cap, int type) * encountered (couldn't open/read a file, etc.), and -3 if a potential * reference loop is detected. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetent(char **buf, char **db_array, const char *name) { size_t dummy; @@ -700,7 +700,7 @@ static FILE *pfp; static int slash; static char **dbp; -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetclose(void) { if (pfp != NULL) { @@ -847,7 +847,7 @@ cgetnext(char **bp, char **db_array) * couldn't be found, -2 if a system error was encountered (storage * allocation failure). */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetstr(char *buf, const char *cap, char **str) { u_int m_room; @@ -980,7 +980,7 @@ cgetstr(char *buf, const char *cap, char **str) * -1 if the requested string capability couldn't be found, -2 if a system * error was encountered (storage allocation failure). */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetustr(char *buf, const char *cap, char **str) { u_int m_room; @@ -1049,7 +1049,7 @@ cgetustr(char *buf, const char *cap, char **str) * the long pointed to by num. 0 is returned on success, -1 if the requested * numeric capability couldn't be found. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetnum(char *buf, const char *cap, long *num) { long n; diff --git a/lib/roken/getcwd.c b/lib/roken/getcwd.c index c83b56e2d..f8917b245 100644 --- a/lib/roken/getcwd.c +++ b/lib/roken/getcwd.c @@ -42,7 +42,7 @@ #include "roken.h" -char* ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char* ROKEN_LIB_CALL getcwd(char *path, size_t size) { char xxx[MaxPathLen]; diff --git a/lib/roken/getdtablesize.c b/lib/roken/getdtablesize.c index a515af345..08c0661fa 100644 --- a/lib/roken/getdtablesize.c +++ b/lib/roken/getdtablesize.c @@ -61,7 +61,7 @@ #include #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getdtablesize(void) { int files = -1; diff --git a/lib/roken/getegid.c b/lib/roken/getegid.c index dfd82db1a..663fb1df1 100644 --- a/lib/roken/getegid.c +++ b/lib/roken/getegid.c @@ -37,7 +37,7 @@ #ifndef HAVE_GETEGID -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getegid(void) { return getgid(); diff --git a/lib/roken/geteuid.c b/lib/roken/geteuid.c index 3246d0256..598a73929 100644 --- a/lib/roken/geteuid.c +++ b/lib/roken/geteuid.c @@ -37,7 +37,7 @@ #ifndef HAVE_GETEUID -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL geteuid(void) { return getuid(); diff --git a/lib/roken/getgid.c b/lib/roken/getgid.c index 6a8e66db6..b24ceebc8 100644 --- a/lib/roken/getgid.c +++ b/lib/roken/getgid.c @@ -36,7 +36,7 @@ #ifndef HAVE_GETGID -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getgid(void) { return 17; diff --git a/lib/roken/gethostname.c b/lib/roken/gethostname.c index 7051667f7..838909140 100644 --- a/lib/roken/gethostname.c +++ b/lib/roken/gethostname.c @@ -47,7 +47,7 @@ * interface is identical to gethostname(2).) */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL gethostname(char *name, int namelen) { #if defined(HAVE_UNAME) diff --git a/lib/roken/getifaddrs-test.c b/lib/roken/getifaddrs-test.c index 76ed061bc..ef5dbb327 100644 --- a/lib/roken/getifaddrs-test.c +++ b/lib/roken/getifaddrs-test.c @@ -3,6 +3,8 @@ * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * + * Portions Copyright (c) 2009, Secure Endpoints Inc. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -38,18 +40,62 @@ #include +static void +print_addr(const char *s, struct sockaddr *sa) +{ + int i; + printf(" %s=%d/", s, sa->sa_family); +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + for(i = 0; i < sa->sa_len - ((long)sa->sa_data - (long)&sa->sa_family); i++) + printf("%02x", ((unsigned char*)sa->sa_data)[i]); +#else + for(i = 0; i < sizeof(sa->sa_data); i++) + printf("%02x", ((unsigned char*)sa->sa_data)[i]); +#endif + printf("\n"); +} + +static void +print_ifaddrs(struct ifaddrs *x) +{ + struct ifaddrs *p; + + for(p = x; p; p = p->ifa_next) { + printf("%s\n", p->ifa_name); + printf(" flags=%x\n", p->ifa_flags); + if(p->ifa_addr) + print_addr("addr", p->ifa_addr); + if(p->ifa_dstaddr) + print_addr("dstaddr", p->ifa_dstaddr); + if(p->ifa_netmask) + print_addr("netmask", p->ifa_netmask); + printf(" %p\n", p->ifa_data); + } +} + int main(int argc, char **argv) { struct ifaddrs *addrs = NULL; int ret; + if (rk_SOCK_INIT()) + errx(1, "Couldn't initialize sockets. Err=%d\n", rk_SOCK_ERRNO); + ret = getifaddrs(&addrs); if (ret != 0) err(1, "getifaddrs"); + if (addrs == NULL) + errx(1, "address == NULL"); + + print_ifaddrs(addrs); + /* Check that freeifaddrs doesn't crash */ freeifaddrs(addrs); + if (rk_SOCK_EXIT()) + errx(1, "Couldn't uninitialize sockets. Err=%d\n", rk_SOCK_ERRNO); + return 0; } diff --git a/lib/roken/getifaddrs.c b/lib/roken/getifaddrs.c index 6acbc1676..3770ebbee 100644 --- a/lib/roken/getifaddrs.c +++ b/lib/roken/getifaddrs.c @@ -498,7 +498,7 @@ nl_open(void) } /* ====================================================================== */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_getifaddrs(struct ifaddrs **ifap) { int sd; @@ -1165,7 +1165,7 @@ getlifaddrs2(struct ifaddrs **ifap, } #endif /* defined(HAVE_IPV6) && defined(SIOCGLIFCONF) && defined(SIOCGLIFFLAGS) */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_getifaddrs(struct ifaddrs **ifap) { int ret = -1; @@ -1193,7 +1193,9 @@ rk_getifaddrs(struct ifaddrs **ifap) return ret; } -void ROKEN_LIB_FUNCTION +#endif /* !AF_NETLINK */ + +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_freeifaddrs(struct ifaddrs *ifp) { struct ifaddrs *p, *q; @@ -1214,8 +1216,6 @@ rk_freeifaddrs(struct ifaddrs *ifp) } } -#endif /* !AF_NETLINK */ - #ifdef TEST void diff --git a/lib/roken/getifaddrs_w32.c b/lib/roken/getifaddrs_w32.c new file mode 100644 index 000000000..96ab497fc --- /dev/null +++ b/lib/roken/getifaddrs_w32.c @@ -0,0 +1,163 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + **********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include + +#ifndef _WIN32 +#error This is a Windows specific implementation. +#endif + +static struct sockaddr * +dupaddr(const sockaddr_gen * src) +{ + sockaddr_gen * d = malloc(sizeof(*d)); + + if (d) { + memcpy(d, src, sizeof(*d)); + } + + return (struct sockaddr *) d; +} + +int ROKEN_LIB_FUNCTION +rk_getifaddrs(struct ifaddrs **ifpp) +{ + SOCKET s = INVALID_SOCKET; + size_t il_len = 8192; + int ret = -1; + INTERFACE_INFO *il = NULL; + + *ifpp = NULL; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == INVALID_SOCKET) + return -1; + + for (;;) { + DWORD cbret = 0; + + il = malloc(il_len); + if (!il) + break; + + ZeroMemory(il, il_len); + + if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, + (LPVOID) il, il_len, &cbret, + NULL, NULL) == 0) { + il_len = cbret; + break; + } + + free (il); + il = NULL; + + if (WSAGetLastError() == WSAEFAULT && cbret > il_len) { + il_len = cbret; + } else { + break; + } + } + + if (!il) + goto _exit; + + /* il is an array of INTERFACE_INFO structures. il_len has the + actual size of the buffer. The number of elements is + il_len/sizeof(INTERFACE_INFO) */ + + { + size_t n = il_len / sizeof(INTERFACE_INFO); + size_t i; + + for (i = 0; i < n; i++ ) { + struct ifaddrs *ifp; + + ifp = malloc(sizeof(*ifp)); + if (ifp == NULL) + break; + + ZeroMemory(ifp, sizeof(*ifp)); + + ifp->ifa_next = NULL; + ifp->ifa_name = NULL; + ifp->ifa_flags = il[i].iiFlags; + ifp->ifa_addr = dupaddr(&il[i].iiAddress); + ifp->ifa_netmask = dupaddr(&il[i].iiNetmask); + ifp->ifa_broadaddr = dupaddr(&il[i].iiBroadcastAddress); + ifp->ifa_data = NULL; + + *ifpp = ifp; + ifpp = &ifp->ifa_next; + } + + if (i == n) + ret = 0; + } + + _exit: + + if (s != INVALID_SOCKET) + closesocket(s); + + if (il) + free (il); + + return ret; +} + +void ROKEN_LIB_FUNCTION +rk_freeifaddrs(struct ifaddrs *ifp) +{ + struct ifaddrs *p, *q; + + for(p = ifp; p; ) { + if (p->ifa_name) + free(p->ifa_name); + if(p->ifa_addr) + free(p->ifa_addr); + if(p->ifa_dstaddr) + free(p->ifa_dstaddr); + if(p->ifa_netmask) + free(p->ifa_netmask); + if(p->ifa_data) + free(p->ifa_data); + q = p; + p = p->ifa_next; + free(q); + } +} diff --git a/lib/roken/getipnodebyaddr.c b/lib/roken/getipnodebyaddr.c index ddaec03a8..7d4095f1d 100644 --- a/lib/roken/getipnodebyaddr.c +++ b/lib/roken/getipnodebyaddr.c @@ -40,7 +40,7 @@ * to a malloced struct hostent or NULL. */ -struct hostent * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL getipnodebyaddr (const void *src, size_t len, int af, int *error_num) { struct hostent *tmp; diff --git a/lib/roken/getipnodebyname.c b/lib/roken/getipnodebyname.c index 16fdbdd24..2ff282707 100644 --- a/lib/roken/getipnodebyname.c +++ b/lib/roken/getipnodebyname.c @@ -44,7 +44,7 @@ static int h_errno = NO_RECOVERY; * to a malloced struct hostent or NULL. */ -struct hostent * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL getipnodebyname (const char *name, int af, int flags, int *error_num) { struct hostent *tmp; diff --git a/lib/roken/getnameinfo.c b/lib/roken/getnameinfo.c index 0621cfeee..b23ad01eb 100644 --- a/lib/roken/getnameinfo.c +++ b/lib/roken/getnameinfo.c @@ -91,7 +91,7 @@ doit (int af, * */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, diff --git a/lib/roken/getnameinfo_verified.c b/lib/roken/getnameinfo_verified.c index 43e4c049f..6175291e4 100644 --- a/lib/roken/getnameinfo_verified.c +++ b/lib/roken/getnameinfo_verified.c @@ -43,7 +43,7 @@ * NI_NAMEREQD flag is set or return the numeric address as a string. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getnameinfo_verified(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, diff --git a/lib/roken/getopt.c b/lib/roken/getopt.c index 12bf138d0..9f54c2b69 100644 --- a/lib/roken/getopt.c +++ b/lib/roken/getopt.c @@ -51,7 +51,7 @@ char *optarg; /* argument associated with option */ #define BADARG (int)':' #define EMSG "" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getopt(nargc, nargv, ostr) int nargc; char * const *nargv; diff --git a/lib/roken/getprogname.c b/lib/roken/getprogname.c index 933b6dec7..a310208a8 100644 --- a/lib/roken/getprogname.c +++ b/lib/roken/getprogname.c @@ -40,7 +40,7 @@ const char *__progname; #endif #ifndef HAVE_GETPROGNAME -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL getprogname(void) { return __progname; diff --git a/lib/roken/gettimeofday.c b/lib/roken/gettimeofday.c index dcce56329..e6e2e04a3 100644 --- a/lib/roken/gettimeofday.c +++ b/lib/roken/gettimeofday.c @@ -38,13 +38,13 @@ /* * Simple gettimeofday that only returns seconds. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL gettimeofday (struct timeval *tp, void *ignore) { time_t t; t = time(NULL); - tp->tv_sec = t; + tp->tv_sec = (long) t; tp->tv_usec = 0; return 0; } diff --git a/lib/roken/getuid.c b/lib/roken/getuid.c index 86bca77e1..63fdec19d 100644 --- a/lib/roken/getuid.c +++ b/lib/roken/getuid.c @@ -36,7 +36,7 @@ #ifndef HAVE_GETUID -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getuid(void) { return 17; diff --git a/lib/roken/getusershell.c b/lib/roken/getusershell.c index a1e6333e7..6f7145d52 100644 --- a/lib/roken/getusershell.c +++ b/lib/roken/getusershell.c @@ -81,7 +81,7 @@ static char **initshells (void); /* * Get a list of shells from _PATH_SHELLS, if it exists. */ -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL getusershell() { char *ret; @@ -94,7 +94,7 @@ getusershell() return (ret); } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL endusershell() { if (shells != NULL) @@ -106,7 +106,7 @@ endusershell() curshell = NULL; } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL setusershell() { curshell = initshells(); diff --git a/lib/roken/glob.c b/lib/roken/glob.c index 4cdb9037f..9b37319eb 100644 --- a/lib/roken/glob.c +++ b/lib/roken/glob.c @@ -164,7 +164,7 @@ static int match (Char *, Char *, Char *); static void qprintf (const char *, Char *); #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL glob(const char *pattern, int flags, int (*errfunc)(const char *, int), @@ -739,7 +739,7 @@ match(Char *name, Char *pat, Char *patend) } /* Free allocated data belonging to a glob_t structure. */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL globfree(glob_t *pglob) { int i; diff --git a/lib/roken/hex.c b/lib/roken/hex.c index 95488af5c..91590dd49 100644 --- a/lib/roken/hex.c +++ b/lib/roken/hex.c @@ -50,7 +50,7 @@ pos(char c) return -1; } -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL hex_encode(const void *data, size_t size, char **str) { const unsigned char *q = data; @@ -80,7 +80,7 @@ hex_encode(const void *data, size_t size, char **str) return i * 2; } -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL hex_decode(const char *str, void *data, size_t len) { size_t l; diff --git a/lib/roken/hex.h b/lib/roken/hex.h index b3c45511c..c266268ea 100644 --- a/lib/roken/hex.h +++ b/lib/roken/hex.h @@ -38,18 +38,20 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif #define hex_encode rk_hex_encode #define hex_decode rk_hex_decode -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL hex_encode(const void *, size_t, char **); -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL hex_decode(const char *, void *, size_t); #endif /* _rk_HEX_H_ */ diff --git a/lib/roken/hostent_find_fqdn.c b/lib/roken/hostent_find_fqdn.c index b5f2b42f6..dc3c17ff2 100644 --- a/lib/roken/hostent_find_fqdn.c +++ b/lib/roken/hostent_find_fqdn.c @@ -39,7 +39,7 @@ * Try to find a fqdn (with `.') in he if possible, else return h_name */ -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL hostent_find_fqdn (const struct hostent *he) { const char *ret = he->h_name; diff --git a/lib/roken/hstrerror.c b/lib/roken/hstrerror.c index 79eab2dd5..70b63016e 100644 --- a/lib/roken/hstrerror.c +++ b/lib/roken/hstrerror.c @@ -64,7 +64,7 @@ extern int h_nerr; #endif -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL hstrerror(int herr) { if (0 <= herr && herr < h_nerr) diff --git a/lib/roken/inet_aton.c b/lib/roken/inet_aton.c index c9b21e00f..31644a0cd 100644 --- a/lib/roken/inet_aton.c +++ b/lib/roken/inet_aton.c @@ -38,7 +38,7 @@ /* Minimal implementation of inet_aton. * Cannot distinguish between failure and a local broadcast address. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL inet_aton(const char *cp, struct in_addr *addr) { addr->s_addr = inet_addr(cp); diff --git a/lib/roken/inet_ntop.c b/lib/roken/inet_ntop.c index daf3e926d..0c72b27fc 100644 --- a/lib/roken/inet_ntop.c +++ b/lib/roken/inet_ntop.c @@ -113,7 +113,7 @@ inet_ntop_v6 (const void *src, char *dst, size_t size) } #endif /* HAVE_IPV6 */ -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL inet_ntop(int af, const void *src, char *dst, size_t size) { switch (af) { diff --git a/lib/roken/inet_pton.c b/lib/roken/inet_pton.c index ad60824f4..3db1f49f2 100644 --- a/lib/roken/inet_pton.c +++ b/lib/roken/inet_pton.c @@ -35,7 +35,64 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +#ifdef HAVE_WINSOCK + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +inet_pton(int af, const char *src, void *dst) +{ + switch (af) { + case AF_INET: + { + struct sockaddr_in si4; + INT r; + INT s = sizeof(si4); + + si4.sin_family = AF_INET; + r = WSAStringToAddress(src, AF_INET, NULL, (LPSOCKADDR) &si4, &s); + + if (r == 0) { + memcpy(dst, &si4.sin_addr, sizeof(si4.sin_addr)); + return 1; + } + } + break; + + case AF_INET6: + { + struct sockaddr_in6 si6; + INT r; + INT s = sizeof(si6); + + si6.sin6_family = AF_INET6; + r = WSAStringToAddress(src, AF_INET6, NULL, (LPSOCKADDR) &si6, &s); + + if (r == 0) { + memcpy(dst, &si6.sin6_addr, sizeof(si6.sin6_addr)); + return 1; + } + } + break; + + default: + _set_errno( EAFNOSUPPORT ); + return -1; + } + + /* the call failed */ + { + int le = WSAGetLastError(); + + if (le == WSAEINVAL) + return 0; + + _set_errno(le); + return -1; + } +} + +#else /* !HAVE_WINSOCK */ + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL inet_pton(int af, const char *src, void *dst) { if (af != AF_INET) { @@ -44,3 +101,5 @@ inet_pton(int af, const char *src, void *dst) } return inet_aton (src, dst); } + +#endif diff --git a/lib/roken/initgroups.c b/lib/roken/initgroups.c index 50ac23aa4..2ba944c1a 100644 --- a/lib/roken/initgroups.c +++ b/lib/roken/initgroups.c @@ -35,7 +35,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL initgroups(const char *name, gid_t basegid) { return 0; diff --git a/lib/roken/innetgr.c b/lib/roken/innetgr.c index 2f6d9a1dc..e1783bbfb 100644 --- a/lib/roken/innetgr.c +++ b/lib/roken/innetgr.c @@ -35,7 +35,7 @@ #ifndef HAVE_INNETGR -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL innetgr(const char *netgroup, const char *machine, const char *user, const char *domain) { diff --git a/lib/roken/iruserok.c b/lib/roken/iruserok.c index 3f0b5a0a5..95f654681 100644 --- a/lib/roken/iruserok.c +++ b/lib/roken/iruserok.c @@ -214,7 +214,7 @@ __ivaliduser(FILE *hostf, unsigned raddr, const char *luser, * * Returns 0 if ok, -1 if not ok. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL iruserok(unsigned raddr, int superuser, const char *ruser, const char *luser) { char *cp; diff --git a/lib/roken/issuid.c b/lib/roken/issuid.c index 2999e8249..ea0db803e 100644 --- a/lib/roken/issuid.c +++ b/lib/roken/issuid.c @@ -35,7 +35,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL issuid(void) { #if defined(HAVE_ISSETUGID) diff --git a/lib/roken/k_getpwnam.c b/lib/roken/k_getpwnam.c index 0c50118dd..c0db757c4 100644 --- a/lib/roken/k_getpwnam.c +++ b/lib/roken/k_getpwnam.c @@ -38,7 +38,7 @@ #include #endif -struct passwd * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct passwd * ROKEN_LIB_CALL k_getpwnam (const char *user) { struct passwd *p; diff --git a/lib/roken/k_getpwuid.c b/lib/roken/k_getpwuid.c index 29b7228e2..d533738d9 100644 --- a/lib/roken/k_getpwuid.c +++ b/lib/roken/k_getpwuid.c @@ -38,7 +38,7 @@ #include #endif -struct passwd * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct passwd * ROKEN_LIB_CALL k_getpwuid (uid_t uid) { struct passwd *p; diff --git a/lib/roken/localtime_r.c b/lib/roken/localtime_r.c index 3335180b1..e7d03ef6d 100644 --- a/lib/roken/localtime_r.c +++ b/lib/roken/localtime_r.c @@ -39,7 +39,7 @@ #ifndef HAVE_LOCALTIME_R -struct tm * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct tm * ROKEN_LIB_CALL localtime_r(const time_t *timer, struct tm *result) { struct tm *tm; diff --git a/lib/roken/lstat.c b/lib/roken/lstat.c index a850efd75..469258850 100644 --- a/lib/roken/lstat.c +++ b/lib/roken/lstat.c @@ -35,7 +35,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL lstat(const char *path, struct stat *buf) { return stat(path, buf); diff --git a/lib/roken/memmove.c b/lib/roken/memmove.c index c5cdf6fd6..1825d7eb3 100644 --- a/lib/roken/memmove.c +++ b/lib/roken/memmove.c @@ -41,7 +41,7 @@ #include #endif -void* ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void* ROKEN_LIB_CALL memmove(void *s1, const void *s2, size_t n) { char *s=(char*)s2, *d=(char*)s1; diff --git a/lib/roken/mini_inetd.c b/lib/roken/mini_inetd.c index f3321eaac..a9398f4fd 100644 --- a/lib/roken/mini_inetd.c +++ b/lib/roken/mini_inetd.c @@ -41,61 +41,93 @@ */ static void -accept_it (int s) +accept_it (rk_socket_t s, rk_socket_t *ret_socket) { - int s2; + rk_socket_t as; - s2 = accept(s, NULL, NULL); - if(s2 < 0) + as = accept(s, NULL, NULL); + if(rk_IS_BAD_SOCKET(as)) err (1, "accept"); - close(s); - dup2(s2, STDIN_FILENO); - dup2(s2, STDOUT_FILENO); - /* dup2(s2, STDERR_FILENO); */ - close(s2); + + if (ret_socket) { + + *ret_socket = as; + + } else { + int fd = socket_to_fd(as, 0); + + /* We would use _O_RDONLY for the socket_to_fd() call for + STDIN, but there are instances where we assume that STDIN + is a r/w socket. */ + + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + + rk_closesocket(as); + } } -/* - * Listen on a specified port, emulating inetd. +/** + * Listen on a specified addresses + * + * Listens on the specified addresses for incoming connections. If + * the \a ret_socket parameter is \a NULL, on return STDIN and STDOUT + * will be connected to an accepted socket. If the \a ret_socket + * parameter is non-NULL, the accepted socket will be returned in + * *ret_socket. In the latter case, STDIN and STDOUT will be left + * unmodified. + * + * This function does not return if there is an error or if no + * connection is established. + * + * @param[in] ai Addresses to listen on + * @param[out] ret_socket If non-NULL receives the accepted socket. + * + * @see mini_inetd() */ - -void ROKEN_LIB_FUNCTION -mini_inetd_addrinfo (struct addrinfo *ai) +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +mini_inetd_addrinfo (struct addrinfo *ai, rk_socket_t *ret_socket) { int ret; struct addrinfo *a; int n, nalloc, i; - int *fds; + rk_socket_t *fds; fd_set orig_read_set, read_set; - int max_fd = -1; + rk_socket_t max_fd = (rk_socket_t)-1; for (nalloc = 0, a = ai; a != NULL; a = a->ai_next) ++nalloc; fds = malloc (nalloc * sizeof(*fds)); - if (fds == NULL) + if (fds == NULL) { errx (1, "mini_inetd: out of memory"); + UNREACHABLE(return); + } FD_ZERO(&orig_read_set); for (i = 0, a = ai; a != NULL; a = a->ai_next) { fds[i] = socket (a->ai_family, a->ai_socktype, a->ai_protocol); - if (fds[i] < 0) + if (rk_IS_BAD_SOCKET(fds[i])) continue; socket_set_reuseaddr (fds[i], 1); socket_set_ipv6only(fds[i], 1); - if (bind (fds[i], a->ai_addr, a->ai_addrlen) < 0) { + if (rk_IS_SOCKET_ERROR(bind (fds[i], a->ai_addr, a->ai_addrlen))) { warn ("bind af = %d", a->ai_family); - close(fds[i]); + rk_closesocket(fds[i]); + fds[i] = rk_INVALID_SOCKET; continue; } - if (listen (fds[i], SOMAXCONN) < 0) { + if (rk_IS_SOCKET_ERROR(listen (fds[i], SOMAXCONN))) { warn ("listen af = %d", a->ai_family); - close(fds[i]); + rk_closesocket(fds[i]); + fds[i] = rk_INVALID_SOCKET; continue; } +#ifndef NO_LIMIT_FD_SETSIZE if (fds[i] >= FD_SETSIZE) errx (1, "fd too large"); +#endif FD_SET(fds[i], &orig_read_set); max_fd = max(max_fd, fds[i]); ++i; @@ -108,23 +140,40 @@ mini_inetd_addrinfo (struct addrinfo *ai) read_set = orig_read_set; ret = select (max_fd + 1, &read_set, NULL, NULL, NULL); - if (ret < 0 && errno != EINTR) + if (rk_IS_SOCKET_ERROR(ret) && rk_SOCK_ERRNO != EINTR) err (1, "select"); } while (ret <= 0); for (i = 0; i < n; ++i) if (FD_ISSET (fds[i], &read_set)) { - accept_it (fds[i]); + accept_it (fds[i], ret_socket); for (i = 0; i < n; ++i) - close(fds[i]); + rk_closesocket(fds[i]); free(fds); return; } abort (); } -void ROKEN_LIB_FUNCTION -mini_inetd (int port) +/** + * Listen on a specified port + * + * Listens on the specified port for incoming connections. If the \a + * ret_socket parameter is \a NULL, on return STDIN and STDOUT will be + * connected to an accepted socket. If the \a ret_socket parameter is + * non-NULL, the accepted socket will be returned in *ret_socket. In + * the latter case, STDIN and STDOUT will be left unmodified. + * + * This function does not return if there is an error or if no + * connection is established. + * + * @param[in] port Port to listen on + * @param[out] ret_socket If non-NULL receives the accepted socket. + * + * @see mini_inetd_addrinfo() + */ +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +mini_inetd(int port, rk_socket_t * ret_socket) { int error; struct addrinfo *ai, hints; @@ -141,7 +190,8 @@ mini_inetd (int port) if (error) errx (1, "getaddrinfo: %s", gai_strerror (error)); - mini_inetd_addrinfo(ai); + mini_inetd_addrinfo(ai, ret_socket); freeaddrinfo(ai); } + diff --git a/lib/roken/mkstemp.c b/lib/roken/mkstemp.c index d47919e63..a3ca6c717 100644 --- a/lib/roken/mkstemp.c +++ b/lib/roken/mkstemp.c @@ -42,9 +42,11 @@ #endif #include +#include + #ifndef HAVE_MKSTEMP -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL mkstemp(char *template) { int start, i; diff --git a/lib/roken/ndbm_wrap.c b/lib/roken/ndbm_wrap.c index 8db3662a1..4fbdb4da0 100644 --- a/lib/roken/ndbm_wrap.c +++ b/lib/roken/ndbm_wrap.c @@ -60,7 +60,7 @@ static DBC *cursor; #define D(X) ((DB*)(X)) -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL dbm_close (DBM *db) { #ifdef HAVE_DB3 @@ -71,7 +71,7 @@ dbm_close (DBM *db) #endif } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL dbm_delete (DBM *db, datum dkey) { DBT key; @@ -129,19 +129,19 @@ dbm_get (DB *db, int flags) #define DB_KEYEXIST 1 #endif -datum ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION datum ROKEN_LIB_CALL dbm_firstkey (DBM *db) { return dbm_get(D(db), DB_FIRST); } -datum ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION datum ROKEN_LIB_CALL dbm_nextkey (DBM *db) { return dbm_get(D(db), DB_NEXT); } -DBM* ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION DBM* ROKEN_LIB_CALL dbm_open (const char *file, int flags, mode_t mode) { DB *db; @@ -184,7 +184,7 @@ dbm_open (const char *file, int flags, mode_t mode) return (DBM*)db; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL dbm_store (DBM *db, datum dkey, datum dvalue, int flags) { int ret; @@ -204,13 +204,13 @@ dbm_store (DBM *db, datum dkey, datum dvalue, int flags) RETURN(ret); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL dbm_error (DBM *db) { return 0; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL dbm_clearerr (DBM *db) { return 0; diff --git a/lib/roken/ndbm_wrap.h b/lib/roken/ndbm_wrap.h index 360d502e3..a2ec4f206 100644 --- a/lib/roken/ndbm_wrap.h +++ b/lib/roken/ndbm_wrap.h @@ -41,9 +41,11 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif @@ -78,14 +80,14 @@ typedef struct { } DBM; #endif -int ROKEN_LIB_FUNCTION dbm_clearerr (DBM*); -void ROKEN_LIB_FUNCTION dbm_close (DBM*); -int ROKEN_LIB_FUNCTION dbm_delete (DBM*, datum); -int ROKEN_LIB_FUNCTION dbm_error (DBM*); -datum ROKEN_LIB_FUNCTION dbm_fetch (DBM*, datum); -datum ROKEN_LIB_FUNCTION dbm_firstkey (DBM*); -datum ROKEN_LIB_FUNCTION dbm_nextkey (DBM*); -DBM* ROKEN_LIB_FUNCTION dbm_open (const char*, int, mode_t); -int ROKEN_LIB_FUNCTION dbm_store (DBM*, datum, datum, int); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL dbm_clearerr (DBM*); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL dbm_close (DBM*); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL dbm_delete (DBM*, datum); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL dbm_error (DBM*); +ROKEN_LIB_FUNCTION datum ROKEN_LIB_CALL dbm_fetch (DBM*, datum); +ROKEN_LIB_FUNCTION datum ROKEN_LIB_CALL dbm_firstkey (DBM*); +ROKEN_LIB_FUNCTION datum ROKEN_LIB_CALL dbm_nextkey (DBM*); +ROKEN_LIB_FUNCTION DBM* ROKEN_LIB_CALL dbm_open (const char*, int, mode_t); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL dbm_store (DBM*, datum, datum, int); #endif /* __ndbm_wrap_h__ */ diff --git a/lib/roken/net_read.c b/lib/roken/net_read.c index 9d055d006..b57dda3dd 100644 --- a/lib/roken/net_read.c +++ b/lib/roken/net_read.c @@ -33,29 +33,23 @@ #include -#include -#include -#include - #include "roken.h" /* * Like read but never return partial data. */ -ssize_t ROKEN_LIB_FUNCTION -net_read (int fd, void *buf, size_t nbytes) +#ifndef _WIN32 + +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL +net_read (rk_socket_t fd, void *buf, size_t nbytes) { char *cbuf = (char *)buf; ssize_t count; size_t rem = nbytes; while (rem > 0) { -#ifdef WIN32 - count = recv (fd, cbuf, rem, 0); -#else count = read (fd, cbuf, rem); -#endif if (count < 0) { if (errno == EINTR) continue; @@ -69,3 +63,36 @@ net_read (int fd, void *buf, size_t nbytes) } return nbytes; } + +#else + +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL +net_read(rk_socket_t sock, void *buf, size_t nbytes) +{ + char *cbuf = (char *)buf; + ssize_t count; + size_t rem = nbytes; + + while (rem > 0) { + count = recv (sock, cbuf, rem, 0); + if (count < 0) { + + /* With WinSock, the error EINTR (WSAEINTR), is used to + indicate that a blocking call was cancelled using + WSACancelBlockingCall(). */ + +#ifndef HAVE_WINSOCK + if (rk_SOCK_ERRNO == EINTR) + continue; +#endif + return count; + } else if (count == 0) { + return count; + } + cbuf += count; + rem -= count; + } + return nbytes; +} + +#endif diff --git a/lib/roken/net_write.c b/lib/roken/net_write.c index 515f21097..94c9df1c3 100644 --- a/lib/roken/net_write.c +++ b/lib/roken/net_write.c @@ -33,29 +33,23 @@ #include -#include -#include -#include - #include "roken.h" /* * Like write but never return partial data. */ -ssize_t ROKEN_LIB_FUNCTION -net_write (int fd, const void *buf, size_t nbytes) +#ifndef _WIN32 + +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL +net_write (rk_socket_t fd, const void *buf, size_t nbytes) { const char *cbuf = (const char *)buf; ssize_t count; size_t rem = nbytes; while (rem > 0) { -#ifdef WIN32 - count = send (fd, cbuf, rem, 0); -#else count = write (fd, cbuf, rem); -#endif if (count < 0) { if (errno == EINTR) continue; @@ -67,3 +61,28 @@ net_write (int fd, const void *buf, size_t nbytes) } return nbytes; } + +#else + +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL +net_write(rk_socket_t sock, const void *buf, size_t nbytes) +{ + const char *cbuf = (const char *)buf; + ssize_t count; + size_t rem = nbytes; + + while (rem > 0) { + count = send (sock, cbuf, rem, 0); + if (count < 0) { + if (errno == EINTR) + continue; + else + return count; + } + cbuf += count; + rem -= count; + } + return nbytes; +} + +#endif diff --git a/lib/roken/parse_bytes.c b/lib/roken/parse_bytes.c index 4a7df94e7..561079afc 100644 --- a/lib/roken/parse_bytes.c +++ b/lib/roken/parse_bytes.c @@ -56,19 +56,19 @@ static struct units bytes_short_units[] = { { NULL, 0 } }; -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL parse_bytes (const char *s, const char *def_unit) { return parse_units (s, bytes_units, def_unit); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_bytes (int t, char *s, size_t len) { return unparse_units (t, bytes_units, s, len); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_bytes_short (int t, char *s, size_t len) { return unparse_units_approx (t, bytes_short_units, s, len); diff --git a/lib/roken/parse_bytes.h b/lib/roken/parse_bytes.h index 7d389e808..8a88eca49 100644 --- a/lib/roken/parse_bytes.h +++ b/lib/roken/parse_bytes.h @@ -38,19 +38,21 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL parse_bytes (const char *s, const char *def_unit); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_bytes (int t, char *s, size_t len); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_bytes_short (int t, char *s, size_t len); #endif /* __PARSE_BYTES_H__ */ diff --git a/lib/roken/parse_time-test.c b/lib/roken/parse_time-test.c index d6ba4cbb9..10c0f6dea 100644 --- a/lib/roken/parse_time-test.c +++ b/lib/roken/parse_time-test.c @@ -40,8 +40,8 @@ static struct testcase { size_t size; - time_t val; - char *str; + int val; + char *str; } tests[] = { { 8, 1, "1 second" }, { 17, 61, "1 minute 1 second" }, @@ -97,6 +97,7 @@ main(int argc, char **argv) errx(1, "test %i not zero terminated", i); rk_test_mem_free("underrun"); } + buf = rk_test_mem_alloc(RK_TM_OVERRUN, "overrun", tests[i].str, tests[i].size + 1); j = parse_time(buf, "s"); @@ -110,6 +111,7 @@ main(int argc, char **argv) if (j != tests[i].val) errx(1, "parse_time failed for test %d", i); rk_test_mem_free("underrun"); + } return 0; } diff --git a/lib/roken/parse_time.c b/lib/roken/parse_time.c index b581970bd..febd6a5d2 100644 --- a/lib/roken/parse_time.c +++ b/lib/roken/parse_time.c @@ -50,25 +50,25 @@ static struct units time_units[] = { {NULL, 0}, }; -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL parse_time (const char *s, const char *def_unit) { return parse_units (s, time_units, def_unit); } -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL unparse_time (int t, char *s, size_t len) { return unparse_units (t, time_units, s, len); } -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL unparse_time_approx (int t, char *s, size_t len) { return unparse_units_approx (t, time_units, s, len); } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL print_time_table (FILE *f) { print_units_table (time_units, f); diff --git a/lib/roken/parse_time.h b/lib/roken/parse_time.h index 23aae2fc9..dabcefd81 100644 --- a/lib/roken/parse_time.h +++ b/lib/roken/parse_time.h @@ -38,22 +38,24 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif -int +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL parse_time (const char *s, const char *def_unit); -size_t +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL unparse_time (int t, char *s, size_t len); -size_t +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL unparse_time_approx (int t, char *s, size_t len); -void +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL print_time_table (FILE *f); #endif /* __PARSE_TIME_H__ */ diff --git a/lib/roken/parse_units.c b/lib/roken/parse_units.c index a848298c5..bca4040f1 100644 --- a/lib/roken/parse_units.c +++ b/lib/roken/parse_units.c @@ -70,7 +70,7 @@ parse_something (const char *s, const struct units *units, p = s; while (*p) { - double val; + int val; char *next; const struct units *u, *partial_unit; size_t u_len; @@ -80,7 +80,7 @@ parse_something (const char *s, const struct units *units, while(isspace((unsigned char)*p) || *p == ',') ++p; - val = strtod (p, &next); /* strtol(p, &next, 0); */ + val = (int) strtod (p, &next); /* strtol(p, &next, 0); */ if (p == next) { val = 0; if(!accept_no_val_p) @@ -149,7 +149,7 @@ acc_units(int res, int val, unsigned mult) return res + val * mult; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL parse_units (const char *s, const struct units *units, const char *def_unit) { @@ -175,7 +175,7 @@ acc_flags(int res, int val, unsigned mult) return -1; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL parse_flags (const char *s, const struct units *units, int orig) { @@ -208,7 +208,7 @@ unparse_something (int num, const struct units *units, char *s, size_t len, tmp = (*print) (s, len, divisor, u->name, num); if (tmp < 0) return tmp; - if (tmp > len) { + if (tmp > (int) len) { len = 0; s = NULL; } else { @@ -245,7 +245,7 @@ update_unit_approx (int in, unsigned mult) return update_unit (in, mult); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_units (int num, const struct units *units, char *s, size_t len) { return unparse_something (num, units, s, len, @@ -254,7 +254,7 @@ unparse_units (int num, const struct units *units, char *s, size_t len) "0"); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_units_approx (int num, const struct units *units, char *s, size_t len) { return unparse_something (num, units, s, len, @@ -263,7 +263,7 @@ unparse_units_approx (int num, const struct units *units, char *s, size_t len) "0"); } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL print_units_table (const struct units *units, FILE *f) { const struct units *u, *u2; @@ -308,7 +308,7 @@ update_flag (int in, unsigned mult) return in - mult; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_flags (int num, const struct units *units, char *s, size_t len) { return unparse_something (num, units, s, len, @@ -317,7 +317,7 @@ unparse_flags (int num, const struct units *units, char *s, size_t len) ""); } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL print_flags_table (const struct units *units, FILE *f) { const struct units *u; diff --git a/lib/roken/parse_units.h b/lib/roken/parse_units.h index 2f2235bb0..2d1c28690 100644 --- a/lib/roken/parse_units.h +++ b/lib/roken/parse_units.h @@ -41,9 +41,11 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif @@ -52,28 +54,28 @@ struct units { unsigned mult; }; -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL parse_units (const char *s, const struct units *units, const char *def_unit); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL print_units_table (const struct units *units, FILE *f); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL parse_flags (const char *s, const struct units *units, int orig); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_units (int num, const struct units *units, char *s, size_t len); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_units_approx (int num, const struct units *units, char *s, size_t len); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unparse_flags (int num, const struct units *units, char *s, size_t len); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL print_flags_table (const struct units *units, FILE *f); #endif /* __PARSE_UNITS_H__ */ diff --git a/lib/roken/putenv.c b/lib/roken/putenv.c index a1a119e33..647eb7a34 100644 --- a/lib/roken/putenv.c +++ b/lib/roken/putenv.c @@ -47,7 +47,7 @@ extern char **environ; * value by altering an existing variable or creating a new one. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL putenv(const char *string) { int i; diff --git a/lib/roken/rcmd.c b/lib/roken/rcmd.c index c1ff33919..7fa85a35b 100644 --- a/lib/roken/rcmd.c +++ b/lib/roken/rcmd.c @@ -36,7 +36,7 @@ #include "roken.h" #include -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rcmd(char **ahost, unsigned short inport, const char *locuser, diff --git a/lib/roken/readv.c b/lib/roken/readv.c index 4523b4a48..a15601589 100644 --- a/lib/roken/readv.c +++ b/lib/roken/readv.c @@ -35,7 +35,7 @@ #include "roken.h" -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL readv(int d, const struct iovec *iov, int iovcnt) { ssize_t ret, nb; diff --git a/lib/roken/realloc.c b/lib/roken/realloc.c index 850ab9b3a..8cbc0d63e 100644 --- a/lib/roken/realloc.c +++ b/lib/roken/realloc.c @@ -37,7 +37,7 @@ #include #include "roken.h" -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL rk_realloc(void *ptr, size_t size) { if (ptr == NULL) diff --git a/lib/roken/recvmsg.c b/lib/roken/recvmsg.c index 184e9c6a7..aba298b90 100644 --- a/lib/roken/recvmsg.c +++ b/lib/roken/recvmsg.c @@ -35,7 +35,7 @@ #include "roken.h" -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL recvmsg(int s, struct msghdr *msg, int flags) { ssize_t ret, nb; diff --git a/lib/roken/resolve-test.c b/lib/roken/resolve-test.c index 576d6893d..b6572eeba 100644 --- a/lib/roken/resolve-test.c +++ b/lib/roken/resolve-test.c @@ -144,7 +144,7 @@ main(int argc, char **argv) } case rk_ns_t_sshfp : { struct rk_sshfp_record *sshfp = rr->u.sshfp; - int i; + size_t i; printf ("alg %u type %u length %lu data ", sshfp->algorithm, sshfp->type, (unsigned long)sshfp->sshfp_len); @@ -156,7 +156,7 @@ main(int argc, char **argv) } case rk_ns_t_ds : { struct rk_ds_record *ds = rr->u.ds; - int i; + size_t i; printf ("key tag %u alg %u type %u length %u data ", ds->key_tag, ds->algorithm, ds->digest_type, diff --git a/lib/roken/resolve.c b/lib/roken/resolve.c index 419c8d94e..0c0fc1dd9 100644 --- a/lib/roken/resolve.c +++ b/lib/roken/resolve.c @@ -78,7 +78,7 @@ static struct stot{ int _resolve_debug = 0; -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_dns_string_to_type(const char *name) { struct stot *p = stot; @@ -88,7 +88,7 @@ rk_dns_string_to_type(const char *name) return -1; } -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL rk_dns_type_to_string(int type) { struct stot *p = stot; @@ -110,7 +110,7 @@ dns_free_rr(struct rk_resource_record *rr) free(rr); } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_dns_free_data(struct rk_dns_reply *r) { struct rk_resource_record *rr; @@ -584,7 +584,7 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type) return r; } -struct rk_dns_reply * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct rk_dns_reply * ROKEN_LIB_CALL rk_dns_lookup(const char *domain, const char *type_name) { int type; @@ -614,7 +614,7 @@ compare_srv(const void *a, const void *b) #endif /* try to rearrange the srv-records by the algorithm in RFC2782 */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_dns_srv_order(struct rk_dns_reply *r) { struct rk_resource_record **srvs, **ss, **headp; @@ -704,18 +704,18 @@ rk_dns_srv_order(struct rk_dns_reply *r) #else /* NOT defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */ -struct rk_dns_reply * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct rk_dns_reply * ROKEN_LIB_CALL rk_dns_lookup(const char *domain, const char *type_name) { return NULL; } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_dns_free_data(struct rk_dns_reply *r) { } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_dns_srv_order(struct rk_dns_reply *r) { } diff --git a/lib/roken/resolve.h b/lib/roken/resolve.h index 91b2afefe..adec8084b 100644 --- a/lib/roken/resolve.h +++ b/lib/roken/resolve.h @@ -38,9 +38,11 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif @@ -231,15 +233,15 @@ struct rk_dns_reply{ extern "C" { #endif -struct rk_dns_reply* ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct rk_dns_reply* ROKEN_LIB_CALL rk_dns_lookup(const char *, const char *); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_dns_free_data(struct rk_dns_reply *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_dns_string_to_type(const char *name); -const char *ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL rk_dns_type_to_string(int type); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_dns_srv_order(struct rk_dns_reply*); #ifdef __cplusplus diff --git a/lib/roken/rkpty.c b/lib/roken/rkpty.c index 6043e2b81..0faf66861 100644 --- a/lib/roken/rkpty.c +++ b/lib/roken/rkpty.c @@ -41,7 +41,9 @@ #endif #include #include +#ifdef HAVE_UNISTD_H #include +#endif #ifdef HAVE_PTY_H #include #endif diff --git a/lib/roken/roken-common.h b/lib/roken/roken-common.h index ea7dcaade..ac7a92d15 100644 --- a/lib/roken/roken-common.h +++ b/lib/roken/roken-common.h @@ -38,9 +38,11 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif @@ -120,6 +122,8 @@ #define O_ACCMODE 003 #endif +#ifndef _WIN32 + #ifndef _PATH_DEV #define _PATH_DEV "/dev/" #endif @@ -144,6 +148,16 @@ #define MAXPATHLEN (1024+4) #endif +#endif /* !_WIN32 */ + +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif + +#ifndef RETSIGTYPE +#define RETSIGTYPE void +#endif + #ifndef SIG_ERR #define SIG_ERR ((RETSIGTYPE (*)(int))-1) #endif @@ -261,193 +275,212 @@ ROKEN_CPP_START #ifndef IRIX4 /* fix for compiler bug */ +#ifndef _WIN32 #ifdef RETSIGTYPE typedef RETSIGTYPE (*SigAction)(int); SigAction signal(int iSig, SigAction pAction); /* BSD compatible */ #endif #endif +#endif + +#define SE_E_UNSPECIFIED (-1) +#define SE_E_FORKFAILED (-2) +#define SE_E_WAITPIDFAILED (-3) +#define SE_E_EXECTIMEOUT (-4) +#define SE_E_NOEXEC 126 +#define SE_E_NOTFOUND 127 + +#define SE_PROCSTATUS(st) (((st) >= 0 && (st) < 126)? st: -1) +#define SE_PROCSIGNAL(st) (((st) >= 128)? (st) - 128: -1) +#define SE_IS_ERROR(st) ((st) < 0 || (st) >= 126) + #define simple_execve rk_simple_execve -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execve(const char*, char*const[], char*const[]); #define simple_execve_timed rk_simple_execve_timed -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execve_timed(const char *, char *const[], char *const [], time_t (*)(void *), void *, time_t); #define simple_execvp rk_simple_execvp -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execvp(const char*, char *const[]); #define simple_execvp_timed rk_simple_execvp_timed -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execvp_timed(const char *, char *const[], time_t (*)(void *), void *, time_t); #define simple_execlp rk_simple_execlp -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execlp(const char*, ...); #define simple_execle rk_simple_execle -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execle(const char*, ...); #define wait_for_process rk_wait_for_process -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL wait_for_process(pid_t); #define wait_for_process_timed rk_wait_for_process_timed -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL wait_for_process_timed(pid_t, time_t (*)(void *), - void *, time_t); + void *, time_t); + #define pipe_execv rk_pipe_execv -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL pipe_execv(FILE**, FILE**, FILE**, const char*, ...); #define print_version rk_print_version -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL print_version(const char *); #define eread rk_eread -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL eread (int fd, void *buf, size_t nbytes); #define ewrite rk_ewrite -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL ewrite (int fd, const void *buf, size_t nbytes); struct hostent; #define hostent_find_fqdn rk_hostent_find_fqdn -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL hostent_find_fqdn (const struct hostent *); #define esetenv rk_esetenv -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL esetenv(const char *, const char *, int); #define socket_set_address_and_port rk_socket_set_address_and_port -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL socket_set_address_and_port (struct sockaddr *, const void *, int); #define socket_addr_size rk_socket_addr_size -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL socket_addr_size (const struct sockaddr *); #define socket_set_any rk_socket_set_any -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL socket_set_any (struct sockaddr *, int); #define socket_sockaddr_size rk_socket_sockaddr_size -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL socket_sockaddr_size (const struct sockaddr *); #define socket_get_address rk_socket_get_address -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL socket_get_address (const struct sockaddr *); #define socket_get_port rk_socket_get_port -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL socket_get_port (const struct sockaddr *); #define socket_set_port rk_socket_set_port -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL socket_set_port (struct sockaddr *, int); #define socket_set_portrange rk_socket_set_portrange -void ROKEN_LIB_FUNCTION -socket_set_portrange (int, int, int); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_portrange (rk_socket_t, int, int); #define socket_set_debug rk_socket_set_debug -void ROKEN_LIB_FUNCTION -socket_set_debug (int); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_debug (rk_socket_t); #define socket_set_tos rk_socket_set_tos -void ROKEN_LIB_FUNCTION -socket_set_tos (int, int); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_tos (rk_socket_t, int); #define socket_set_reuseaddr rk_socket_set_reuseaddr -void ROKEN_LIB_FUNCTION -socket_set_reuseaddr (int, int); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_reuseaddr (rk_socket_t, int); #define socket_set_ipv6only rk_socket_set_ipv6only -void ROKEN_LIB_FUNCTION -socket_set_ipv6only (int, int); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_ipv6only (rk_socket_t, int); + +#define socket_to_fd rk_socket_to_fd +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +socket_to_fd(rk_socket_t, int); #define vstrcollect rk_vstrcollect -char ** ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char ** ROKEN_LIB_CALL vstrcollect(va_list *ap); #define strcollect rk_strcollect -char ** ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char ** ROKEN_LIB_CALL strcollect(char *first, ...); #define timevalfix rk_timevalfix -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL timevalfix(struct timeval *t1); #define timevaladd rk_timevaladd -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL timevaladd(struct timeval *t1, const struct timeval *t2); #define timevalsub rk_timevalsub -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL timevalsub(struct timeval *t1, const struct timeval *t2); #define pid_file_write rk_pid_file_write -char *ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL pid_file_write (const char *progname); #define pid_file_delete rk_pid_file_delete -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL pid_file_delete (char **); #define read_environment rk_read_environment -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL read_environment(const char *file, char ***env); #define free_environment rk_free_environment -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL free_environment(char **); #define warnerr rk_warnerr -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_warnerr(int doerrno, const char *fmt, va_list ap) __attribute__ ((format (printf, 2, 0))); -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL rk_realloc(void *, size_t); struct rk_strpool; -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL rk_strpoolcollect(struct rk_strpool *); -struct rk_strpool * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct rk_strpool * ROKEN_LIB_CALL rk_strpoolprintf(struct rk_strpool *, const char *, ...) __attribute__ ((format (printf, 2, 3))); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_strpoolfree(struct rk_strpool *); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_dumpdata (const char *, const void *, size_t); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_undumpdata (const char *, void **, size_t *); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_xfree (void *); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_cloexec(int); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_cloexec_file(FILE *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL ct_memcmp(const void *, const void *, size_t); ROKEN_CPP_END diff --git a/lib/roken/roken.h.in b/lib/roken/roken.h.in index 6fc533c69..edea16a8b 100644 --- a/lib/roken/roken.h.in +++ b/lib/roken/roken.h.in @@ -41,6 +41,94 @@ #include #include +#ifndef ROKEN_LIB_FUNCTION +#ifdef _WIN32 +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl +#else +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL +#endif +#endif + +#ifdef HAVE_WINSOCK +/* Declarations for Microsoft Windows */ + +#include + +/* + * error codes for inet_ntop/inet_pton + */ +#define EAFNOSUPPORT WSAEAFNOSUPPORT + +typedef SOCKET rk_socket_t; + +#define rk_IS_BAD_SOCKET(s) ((s) == INVALID_SOCKET) +#define rk_IS_SOCKET_ERROR(rv) ((rv) == SOCKET_ERROR) +#define rk_SOCK_ERRNO WSAGetLastError() +#define rk_SOCK_IOCTL(s,c,a) ioctlsocket((s),(c),(a)) + +#define ETIMEDOUT WSAETIMEDOUT +#define EWOULDBLOCK WSAEWOULDBLOCK +#define ENOTSOCK WSAENOTSOCK + +#define rk_SOCK_INIT rk_WSAStartup() +#define rk_SOCK_EXIT rk_WSACleanup() + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_WSAStartup(void); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_WSACleanup(void); + +#else /* not WinSock */ + +typedef int rk_socket_t; + +#define rk_closesocket(x) close(x) +#define rk_SOCK_IOCTL(s,c,a) ioctl((s),(c),(a)) +#define rk_IS_BAD_SOCKET(s) ((s) < 0) +#define rk_IS_SOCKET_ERROR(rv) ((rv) < 0) +#define rk_SOCK_ERRNO errno +#define rk_INVALID_SOCKET (-1) + +#define rk_SOCK_INIT() 0 +#define rk_SOCK_EXIT() 0 + +#endif + +#ifdef _MSC_VER +/* Declarations for Microsoft Visual C runtime on Windows */ + +#include + +#include + +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ + +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +typedef uint64_t u_int64_t; + +#endif /* __BIT_TYPES_DEFINED__ */ + +#define UNREACHABLE(x) x +#define UNUSED_ARGUMENT(x) ((void) x) + +#else + +#define UNREACHABLE(x) +#define UNUSED_ARGUMENT(x) + +#endif + #ifdef _AIX struct ether_addr; struct sockaddr_dl; @@ -133,8 +221,12 @@ struct sockaddr_dl; #endif #ifndef HAVE_SSIZE_T +#ifdef _WIN64 +typedef __int64 ssize_t; +#else typedef int ssize_t; #endif +#endif #include @@ -150,23 +242,86 @@ ROKEN_CPP_START #define setsid _setsid #endif +#ifdef _MSC_VER +/* Additional macros for Visual C/C++ runtime */ + +#define close _close + +#define getpid _getpid + +#define open _open + +#define chdir _chdir + +#define fsync _commit + +/* The MSVC implementation of snprintf is not C99 compliant. */ +#define snprintf rk_snprintf +#define vsnprintf rk_vsnprintf +#define vasnprintf rk_vasnprintf +#define vasprintf rk_vasprintf +#define asnprintf rk_asnprintf +#define asprintf rk_asprintf + +#define _PIPE_BUFFER_SZ 8192 +#define pipe(fds) _pipe((fds), _PIPE_BUFFER_SZ, O_BINARY); + +#define ftruncate(fd, sz) _chsize((fd), (sz)) + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +rk_snprintf (char *str, size_t sz, const char *format, ...); + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +rk_asprintf (char **ret, const char *format, ...); + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +rk_asnprintf (char **ret, size_t max_sz, const char *format, ...); + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +rk_vasprintf (char **ret, const char *format, va_list args); + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +rk_vasnprintf (char **ret, size_t max_sz, const char *format, va_list args); + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +rk_vsnprintf (char *str, size_t sz, const char *format, va_list args); + +/* missing stat.h predicates */ + +#define S_ISREG(m) (((m) & _S_IFREG) == _S_IFREG) + +#define S_ISDIR(m) (((m) & _S_IFDIR) == _S_IFDIR) + +#define S_ISCHR(m) (((m) & _S_IFCHR) == _S_IFCHR) + +#define S_ISFIFO(m) (((m) & _S_IFIFO) == _S_IFIFO) + +/* The following are not implemented: + + S_ISLNK(m) + S_ISSOCK(m) + S_ISBLK(m) +*/ + +#endif + #ifndef HAVE_PUTENV #define putenv rk_putenv -int ROKEN_LIB_FUNCTION putenv(const char *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL putenv(const char *); #endif #if !defined(HAVE_SETENV) || defined(NEED_SETENV_PROTO) #ifndef HAVE_SETENV #define setenv rk_setenv #endif -int ROKEN_LIB_FUNCTION setenv(const char *, const char *, int); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL setenv(const char *, const char *, int); #endif #if !defined(HAVE_UNSETENV) || defined(NEED_UNSETENV_PROTO) #ifndef HAVE_UNSETENV #define unsetenv rk_unsetenv #endif -void ROKEN_LIB_FUNCTION unsetenv(const char *); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL unsetenv(const char *); #endif #if !defined(HAVE_GETUSERSHELL) || defined(NEED_GETUSERSHELL_PROTO) @@ -174,15 +329,15 @@ void ROKEN_LIB_FUNCTION unsetenv(const char *); #define getusershell rk_getusershell #define endusershell rk_endusershell #endif -char * ROKEN_LIB_FUNCTION getusershell(void); -void ROKEN_LIB_FUNCTION endusershell(void); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL getusershell(void); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL endusershell(void); #endif #if !defined(HAVE_SNPRINTF) || defined(NEED_SNPRINTF_PROTO) #ifndef HAVE_SNPRINTF #define snprintf rk_snprintf #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_snprintf (char *, size_t, const char *, ...) __attribute__ ((format (printf, 3, 4))); #endif @@ -191,7 +346,7 @@ int ROKEN_LIB_FUNCTION #ifndef HAVE_VSNPRINTF #define vsnprintf rk_vsnprintf #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_vsnprintf (char *, size_t, const char *, va_list) __attribute__((format (printf, 3, 0))); #endif @@ -200,7 +355,7 @@ int ROKEN_LIB_FUNCTION #ifndef HAVE_ASPRINTF #define asprintf rk_asprintf #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_asprintf (char **, const char *, ...) __attribute__ ((format (printf, 2, 3))); #endif @@ -209,7 +364,7 @@ int ROKEN_LIB_FUNCTION #ifndef HAVE_VASPRINTF #define vasprintf rk_vasprintf #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_vasprintf (char **, const char *, va_list) __attribute__((format (printf, 2, 0))); #endif @@ -218,7 +373,7 @@ int ROKEN_LIB_FUNCTION #ifndef HAVE_ASNPRINTF #define asnprintf rk_asnprintf #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_asnprintf (char **, size_t, const char *, ...) __attribute__ ((format (printf, 3, 4))); #endif @@ -227,83 +382,83 @@ int ROKEN_LIB_FUNCTION #ifndef HAVE_VASNPRINTF #define vasnprintf rk_vasnprintf #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL vasnprintf (char **, size_t, const char *, va_list) __attribute__((format (printf, 3, 0))); #endif #ifndef HAVE_STRDUP #define strdup rk_strdup -char * ROKEN_LIB_FUNCTION strdup(const char *); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strdup(const char *); #endif #if !defined(HAVE_STRNDUP) || defined(NEED_STRNDUP_PROTO) #ifndef HAVE_STRNDUP #define strndup rk_strndup #endif -char * ROKEN_LIB_FUNCTION strndup(const char *, size_t); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strndup(const char *, size_t); #endif #ifndef HAVE_STRLWR #define strlwr rk_strlwr -char * ROKEN_LIB_FUNCTION strlwr(char *); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strlwr(char *); #endif #ifndef HAVE_STRNLEN #define strnlen rk_strnlen -size_t ROKEN_LIB_FUNCTION strnlen(const char*, size_t); +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL strnlen(const char*, size_t); #endif #if !defined(HAVE_STRSEP) || defined(NEED_STRSEP_PROTO) #ifndef HAVE_STRSEP #define strsep rk_strsep #endif -char * ROKEN_LIB_FUNCTION strsep(char**, const char*); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strsep(char**, const char*); #endif #if !defined(HAVE_STRSEP_COPY) || defined(NEED_STRSEP_COPY_PROTO) #ifndef HAVE_STRSEP_COPY #define strsep_copy rk_strsep_copy #endif -ssize_t ROKEN_LIB_FUNCTION strsep_copy(const char**, const char*, char*, size_t); +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL strsep_copy(const char**, const char*, char*, size_t); #endif #ifndef HAVE_STRCASECMP #define strcasecmp rk_strcasecmp -int ROKEN_LIB_FUNCTION strcasecmp(const char *, const char *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL strcasecmp(const char *, const char *); #endif #ifdef NEED_FCLOSE_PROTO -int ROKEN_LIB_FUNCTION fclose(FILE *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL fclose(FILE *); #endif #ifdef NEED_STRTOK_R_PROTO -char * ROKEN_LIB_FUNCTION strtok_r(char *, const char *, char **); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strtok_r(char *, const char *, char **); #endif #ifndef HAVE_STRUPR #define strupr rk_strupr -char * ROKEN_LIB_FUNCTION strupr(char *); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strupr(char *); #endif #ifndef HAVE_STRLCPY #define strlcpy rk_strlcpy -size_t ROKEN_LIB_FUNCTION strlcpy (char *, const char *, size_t); +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL strlcpy (char *, const char *, size_t); #endif #ifndef HAVE_STRLCAT #define strlcat rk_strlcat -size_t ROKEN_LIB_FUNCTION strlcat (char *, const char *, size_t); +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL strlcat (char *, const char *, size_t); #endif #ifndef HAVE_GETDTABLESIZE #define getdtablesize rk_getdtablesize -int ROKEN_LIB_FUNCTION getdtablesize(void); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getdtablesize(void); #endif #if !defined(HAVE_STRERROR) && !defined(strerror) #define strerror rk_strerror -char * ROKEN_LIB_FUNCTION strerror(int); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strerror(int); #endif #if !defined(HAVE_STRERROR) && !defined(strerror) @@ -319,6 +474,7 @@ int ROKEN_LIB_FUNCTION strerror_r(int, char *, size_t); /* This causes a fatal error under Psoriasis */ #ifndef SunOS const char * ROKEN_LIB_FUNCTION hstrerror(int); +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL hstrerror(int); #endif #endif @@ -330,88 +486,88 @@ extern int h_errno; #ifndef HAVE_INET_ATON #define inet_aton rk_inet_aton #endif -int ROKEN_LIB_FUNCTION inet_aton(const char *, struct in_addr *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL inet_aton(const char *, struct in_addr *); #endif #ifndef HAVE_INET_NTOP #define inet_ntop rk_inet_ntop -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL inet_ntop(int af, const void *src, char *dst, size_t size); #endif #ifndef HAVE_INET_PTON #define inet_pton rk_inet_pton -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL inet_pton(int, const char *, void *); #endif #ifndef HAVE_GETCWD #define getcwd rk_getcwd -char* ROKEN_LIB_FUNCTION getcwd(char *, size_t); +ROKEN_LIB_FUNCTION char* ROKEN_LIB_CALL getcwd(char *, size_t); #endif #ifdef HAVE_PWD_H #include -struct passwd * ROKEN_LIB_FUNCTION k_getpwnam (const char *); -struct passwd * ROKEN_LIB_FUNCTION k_getpwuid (uid_t); +ROKEN_LIB_FUNCTION struct passwd * ROKEN_LIB_CALL k_getpwnam (const char *); +ROKEN_LIB_FUNCTION struct passwd * ROKEN_LIB_CALL k_getpwuid (uid_t); #endif -const char * ROKEN_LIB_FUNCTION get_default_username (void); +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL get_default_username (void); #ifndef HAVE_SETEUID #define seteuid rk_seteuid -int ROKEN_LIB_FUNCTION seteuid(uid_t); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL seteuid(uid_t); #endif #ifndef HAVE_SETEGID #define setegid rk_setegid -int ROKEN_LIB_FUNCTION setegid(gid_t); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL setegid(gid_t); #endif #ifndef HAVE_LSTAT #define lstat rk_lstat -int ROKEN_LIB_FUNCTION lstat(const char *, struct stat *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL lstat(const char *, struct stat *); #endif #if !defined(HAVE_MKSTEMP) || defined(NEED_MKSTEMP_PROTO) #ifndef HAVE_MKSTEMP #define mkstemp rk_mkstemp #endif -int ROKEN_LIB_FUNCTION mkstemp(char *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL mkstemp(char *); #endif #ifndef HAVE_CGETENT #define cgetent rk_cgetent #define cgetstr rk_cgetstr -int ROKEN_LIB_FUNCTION cgetent(char **, char **, const char *); -int ROKEN_LIB_FUNCTION cgetstr(char *, const char *, char **); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetent(char **, char **, const char *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetstr(char *, const char *, char **); #endif #ifndef HAVE_INITGROUPS #define initgroups rk_initgroups -int ROKEN_LIB_FUNCTION initgroups(const char *, gid_t); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL initgroups(const char *, gid_t); #endif #ifndef HAVE_FCHOWN #define fchown rk_fchown -int ROKEN_LIB_FUNCTION fchown(int, uid_t, gid_t); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL fchown(int, uid_t, gid_t); #endif #if !defined(HAVE_DAEMON) || defined(NEED_DAEMON_PROTO) #ifndef HAVE_DAEMON #define daemon rk_daemon #endif -int ROKEN_LIB_FUNCTION daemon(int, int); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL daemon(int, int); #endif #ifndef HAVE_CHOWN #define chown rk_chown -int ROKEN_LIB_FUNCTION chown(const char *, uid_t, gid_t); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL chown(const char *, uid_t, gid_t); #endif #ifndef HAVE_RCMD #define rcmd rk_rcmd -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rcmd(char **, unsigned short, const char *, const char *, const char *, int *); #endif @@ -420,13 +576,13 @@ int ROKEN_LIB_FUNCTION #ifndef HAVE_INNETGR #define innetgr rk_innetgr #endif -int ROKEN_LIB_FUNCTION innetgr(const char*, const char*, +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL innetgr(const char*, const char*, const char*, const char*); #endif #ifndef HAVE_IRUSEROK #define iruserok rk_iruserok -int ROKEN_LIB_FUNCTION iruserok(unsigned, int, +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL iruserok(unsigned, int, const char *, const char *); #endif @@ -434,34 +590,38 @@ int ROKEN_LIB_FUNCTION iruserok(unsigned, int, #ifndef HAVE_GETHOSTNAME #define gethostname rk_gethostname #endif -int ROKEN_LIB_FUNCTION gethostname(char *, int); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL gethostname(char *, int); #endif #ifndef HAVE_WRITEV #define writev rk_writev -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL writev(int, const struct iovec *, int); #endif #ifndef HAVE_READV #define readv rk_readv -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL readv(int, const struct iovec *, int); #endif #ifndef HAVE_PIDFILE +#ifdef NO_PIDFILES +#define pidfile(x) ((void) 0) +#else #define pidfile rk_pidfile -void ROKEN_LIB_FUNCTION pidfile (const char*); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL pidfile (const char*); +#endif #endif #ifndef HAVE_BSWAP32 #define bswap32 rk_bswap32 -unsigned int ROKEN_LIB_FUNCTION bswap32(unsigned int); +ROKEN_LIB_FUNCTION unsigned int ROKEN_LIB_CALL bswap32(unsigned int); #endif #ifndef HAVE_BSWAP16 #define bswap16 rk_bswap16 -unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short); +ROKEN_LIB_FUNCTION unsigned short ROKEN_LIB_CALL bswap16(unsigned short); #endif #ifndef HAVE_FLOCK @@ -486,24 +646,27 @@ int rk_flock(int fd, int operation); #define dirfd(x) ((x)->dd_fd) #endif -time_t ROKEN_LIB_FUNCTION tm2time (struct tm, int); +ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL tm2time (struct tm, int); -int ROKEN_LIB_FUNCTION unix_verify_user(char *, char *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unix_verify_user(char *, char *); -int ROKEN_LIB_FUNCTION roken_concat (char *, size_t, ...); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_concat (char *, size_t, ...); -size_t ROKEN_LIB_FUNCTION roken_mconcat (char **, size_t, ...); +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL roken_mconcat (char **, size_t, ...); -int ROKEN_LIB_FUNCTION roken_vconcat (char *, size_t, va_list); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_vconcat (char *, size_t, va_list); -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL roken_vmconcat (char **, size_t, va_list); -ssize_t ROKEN_LIB_FUNCTION net_write (int, const void *, size_t); +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL + net_write (rk_socket_t, const void *, size_t); -ssize_t ROKEN_LIB_FUNCTION net_read (int, void *, size_t); +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL + net_read (rk_socket_t, void *, size_t); -int ROKEN_LIB_FUNCTION issuid(void); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL + issuid(void); #ifndef HAVE_STRUCT_WINSIZE struct winsize { @@ -512,11 +675,11 @@ struct winsize { }; #endif -int ROKEN_LIB_FUNCTION get_window_size(int fd, struct winsize *); +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL get_window_size(int fd, struct winsize *); #ifndef HAVE_VSYSLOG #define vsyslog rk_vsyslog -void ROKEN_LIB_FUNCTION vsyslog(int, const char *, va_list); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL vsyslog(int, const char *, va_list); #endif #if !HAVE_DECL_OPTARG @@ -531,25 +694,25 @@ extern int opterr; #ifndef HAVE_GETIPNODEBYNAME #define getipnodebyname rk_getipnodebyname -struct hostent * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL getipnodebyname (const char *, int, int, int *); #endif #ifndef HAVE_GETIPNODEBYADDR #define getipnodebyaddr rk_getipnodebyaddr -struct hostent * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL getipnodebyaddr (const void *, size_t, int, int *); #endif #ifndef HAVE_FREEHOSTENT #define freehostent rk_freehostent -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL freehostent (struct hostent *); #endif #ifndef HAVE_COPYHOSTENT #define copyhostent rk_copyhostent -struct hostent * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL copyhostent (const struct hostent *); #endif @@ -617,7 +780,7 @@ struct addrinfo { #ifndef HAVE_GETADDRINFO #define getaddrinfo rk_getaddrinfo -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getaddrinfo(const char *, const char *, const struct addrinfo *, @@ -626,7 +789,7 @@ getaddrinfo(const char *, #ifndef HAVE_GETNAMEINFO #define getnameinfo rk_getnameinfo -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, @@ -635,65 +798,101 @@ getnameinfo(const struct sockaddr *, socklen_t, #ifndef HAVE_FREEADDRINFO #define freeaddrinfo rk_freeaddrinfo -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL freeaddrinfo(struct addrinfo *); #endif #ifndef HAVE_GAI_STRERROR #define gai_strerror rk_gai_strerror -const char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL gai_strerror(int); #endif -int ROKEN_LIB_FUNCTION +#ifdef HAVE_WINSOCK + +/* While we are at it, define WinSock specific scatter gather socket + I/O. */ + +#define iovec _WSABUF +#define iov_base buf +#define iov_len len + +struct msghdr { + void *msg_name; + socklen_t msg_namelen; + struct iovec *msg_iov; + size_t msg_iovlen; + void *msg_control; + socklen_t msg_controllen; + int msg_flags; +}; + +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL +sendmsg(rk_socket_t s, const struct msghdr * msg, int flags); + +#endif + +#ifdef NO_SLEEP + +ROKEN_LIB_FUNCTION unsigned int ROKEN_LIB_CALL +sleep(unsigned int seconds); + +#endif + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getnameinfo_verified(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_getaddrinfo_hostspec(const char *, int, struct addrinfo **); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_getaddrinfo_hostspec2(const char *, int, int, struct addrinfo **); #ifndef HAVE_STRFTIME #define strftime rk_strftime -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL strftime (char *, size_t, const char *, const struct tm *); #endif #ifndef HAVE_STRPTIME #define strptime rk_strptime -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strptime (const char *, const char *, struct tm *); #endif +#ifndef HAVE_GETTIMEOFDAY +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +gettimeofday (struct timeval *, void *); +#endif + #ifndef HAVE_EMALLOC #define emalloc rk_emalloc -void * ROKEN_LIB_FUNCTION emalloc (size_t); +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL emalloc (size_t); #endif #ifndef HAVE_ECALLOC #define ecalloc rk_ecalloc -void * ROKEN_LIB_FUNCTION ecalloc(size_t, size_t); +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL ecalloc(size_t, size_t); #endif #ifndef HAVE_EREALLOC #define erealloc rk_erealloc -void * ROKEN_LIB_FUNCTION erealloc (void *, size_t); +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL erealloc (void *, size_t); #endif #ifndef HAVE_ESTRDUP #define estrdup rk_estrdup -char * ROKEN_LIB_FUNCTION estrdup (const char *); +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL estrdup (const char *); #endif /* * kludges and such */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_gethostby_setup(const char*, const char*); -struct hostent* ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent* ROKEN_LIB_CALL roken_gethostbyname(const char*); -struct hostent* ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent* ROKEN_LIB_CALL roken_gethostbyaddr(const void*, size_t, int); #ifdef GETSERVBYNAME_PROTO_COMPATIBLE @@ -716,24 +915,27 @@ roken_gethostbyaddr(const void*, size_t, int); #ifndef HAVE_SETPROGNAME #define setprogname rk_setprogname -void ROKEN_LIB_FUNCTION setprogname(const char *); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL setprogname(const char *); #endif #ifndef HAVE_GETPROGNAME #define getprogname rk_getprogname -const char * ROKEN_LIB_FUNCTION getprogname(void); +ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL getprogname(void); #endif #if !defined(HAVE_SETPROGNAME) && !defined(HAVE_GETPROGNAME) && !HAVE_DECL___PROGNAME extern const char *__progname; #endif -void ROKEN_LIB_FUNCTION mini_inetd_addrinfo (struct addrinfo*); -void ROKEN_LIB_FUNCTION mini_inetd (int); +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +mini_inetd_addrinfo (struct addrinfo*, rk_socket_t *); + +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +mini_inetd (int, rk_socket_t *); #ifndef HAVE_LOCALTIME_R #define localtime_r rk_localtime_r -struct tm * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct tm * ROKEN_LIB_CALL localtime_r(const time_t *, struct tm *); #endif @@ -741,7 +943,7 @@ localtime_r(const time_t *, struct tm *); #ifndef HAVE_STRSVIS #define strsvis rk_strsvis #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL strsvis(char *, const char *, int, const char *); #endif @@ -749,7 +951,7 @@ strsvis(char *, const char *, int, const char *); #ifndef HAVE_STRUNVIS #define strunvis rk_strunvis #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL strunvis(char *, const char *); #endif @@ -757,7 +959,7 @@ strunvis(char *, const char *); #ifndef HAVE_STRVIS #define strvis rk_strvis #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL strvis(char *, const char *, int); #endif @@ -765,7 +967,7 @@ strvis(char *, const char *, int); #ifndef HAVE_STRVISX #define strvisx rk_strvisx #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL strvisx(char *, const char *, size_t, int); #endif @@ -773,7 +975,7 @@ strvisx(char *, const char *, size_t, int); #ifndef HAVE_SVIS #define svis rk_svis #endif -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL svis(char *, int, int, int, const char *); #endif @@ -781,7 +983,7 @@ svis(char *, int, int, int, const char *); #ifndef HAVE_UNVIS #define unvis rk_unvis #endif -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unvis(char *, int, int *, int); #endif @@ -789,19 +991,19 @@ unvis(char *, int, int *, int); #ifndef HAVE_VIS #define vis rk_vis #endif -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL vis(char *, int, int, int); #endif #if !defined(HAVE_CLOSEFROM) #define closefrom rk_closefrom -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL closefrom(int); #endif #if !defined(HAVE_TIMEGM) #define timegm rk_timegm -time_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL rk_timegm(struct tm *tm); #endif diff --git a/lib/roken/roken_gethostby.c b/lib/roken/roken_gethostby.c index d87a49a04..c99596c53 100644 --- a/lib/roken/roken_gethostby.c +++ b/lib/roken/roken_gethostby.c @@ -104,7 +104,7 @@ split_spec(const char *spec, char **host, int *port, char **path, int def_port) } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL roken_gethostby_setup(const char *proxy_spec, const char *dns_spec) { char *proxy_host = NULL; @@ -207,7 +207,7 @@ roken_gethostby(const char *hostname) } } -struct hostent* +ROKEN_LIB_FUNCTION struct hostent* ROKEN_LIB_CALL roken_gethostbyname(const char *hostname) { struct hostent *he; @@ -217,7 +217,7 @@ roken_gethostbyname(const char *hostname) return roken_gethostby(hostname); } -struct hostent* ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct hostent* ROKEN_LIB_CALL roken_gethostbyaddr(const void *addr, size_t len, int type) { struct in_addr a; diff --git a/lib/roken/rtbl.c b/lib/roken/rtbl.c index 7d11a487c..fe0fde662 100644 --- a/lib/roken/rtbl.c +++ b/lib/roken/rtbl.c @@ -59,19 +59,19 @@ struct rtbl_data { char *column_separator; }; -rtbl_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION rtbl_t ROKEN_LIB_CALL rtbl_create (void) { return calloc (1, sizeof (struct rtbl_data)); } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rtbl_set_flags (rtbl_t table, unsigned int flags) { table->flags = flags; } -unsigned int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION unsigned int ROKEN_LIB_CALL rtbl_get_flags (rtbl_t table) { return table->flags; @@ -80,7 +80,7 @@ rtbl_get_flags (rtbl_t table) static struct column_data * rtbl_get_column_by_id (rtbl_t table, unsigned int id) { - int i; + size_t i; for(i = 0; i < table->num_columns; i++) if(table->columns[i]->column_id == id) return table->columns[i]; @@ -90,17 +90,17 @@ rtbl_get_column_by_id (rtbl_t table, unsigned int id) static struct column_data * rtbl_get_column (rtbl_t table, const char *column) { - int i; + size_t i; for(i = 0; i < table->num_columns; i++) if(strcmp(table->columns[i]->header, column) == 0) return table->columns[i]; return NULL; } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rtbl_destroy (rtbl_t table) { - int i, j; + size_t i, j; for (i = 0; i < table->num_columns; i++) { struct column_data *c = table->columns[i]; @@ -119,7 +119,7 @@ rtbl_destroy (rtbl_t table) free (table); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_by_id (rtbl_t table, unsigned int id, const char *header, unsigned int flags) { @@ -148,13 +148,13 @@ rtbl_add_column_by_id (rtbl_t table, unsigned int id, return 0; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column (rtbl_t table, const char *header, unsigned int flags) { return rtbl_add_column_by_id(table, 0, header, flags); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_new_row(rtbl_t table) { size_t max_rows = 0; @@ -183,18 +183,18 @@ rtbl_new_row(rtbl_t table) static void column_compute_width (rtbl_t table, struct column_data *column) { - int i; + size_t i; if(table->flags & RTBL_HEADER_STYLE_NONE) column->width = 0; else column->width = strlen (column->header); for (i = 0; i < column->num_rows; i++) - column->width = max (column->width, strlen (column->rows[i].data)); + column->width = max (column->width, (int) strlen (column->rows[i].data)); } /* DEPRECATED */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_set_prefix (rtbl_t table, const char *prefix) { if (table->column_prefix) @@ -205,7 +205,7 @@ rtbl_set_prefix (rtbl_t table, const char *prefix) return 0; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_set_separator (rtbl_t table, const char *separator) { if (table->column_separator) @@ -216,7 +216,7 @@ rtbl_set_separator (rtbl_t table, const char *separator) return 0; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_set_column_prefix (rtbl_t table, const char *column, const char *prefix) { @@ -232,7 +232,7 @@ rtbl_set_column_prefix (rtbl_t table, const char *column, return 0; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_set_column_affix_by_id(rtbl_t table, unsigned int id, const char *prefix, const char *suffix) { @@ -301,7 +301,7 @@ add_column_entry (struct column_data *c, const char *data) return 0; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_entry_by_id (rtbl_t table, unsigned int id, const char *data) { struct column_data *c = rtbl_get_column_by_id (table, id); @@ -312,7 +312,7 @@ rtbl_add_column_entry_by_id (rtbl_t table, unsigned int id, const char *data) return add_column_entry(c, data); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_entryv_by_id (rtbl_t table, unsigned int id, const char *fmt, ...) { @@ -330,7 +330,7 @@ rtbl_add_column_entryv_by_id (rtbl_t table, unsigned int id, return ret; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_entry (rtbl_t table, const char *column, const char *data) { struct column_data *c = rtbl_get_column (table, column); @@ -341,7 +341,7 @@ rtbl_add_column_entry (rtbl_t table, const char *column, const char *data) return add_column_entry(c, data); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_entryv (rtbl_t table, const char *column, const char *fmt, ...) { va_list ap; @@ -359,10 +359,10 @@ rtbl_add_column_entryv (rtbl_t table, const char *column, const char *fmt, ...) } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_format (rtbl_t table, FILE * f) { - int i, j; + size_t i, j; for (i = 0; i < table->num_columns; i++) column_compute_width (table, table->columns[i]); diff --git a/lib/roken/rtbl.h b/lib/roken/rtbl.h index 60bbc9f87..549d3a8aa 100644 --- a/lib/roken/rtbl.h +++ b/lib/roken/rtbl.h @@ -37,9 +37,11 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif @@ -60,55 +62,55 @@ typedef struct rtbl_data *rtbl_t; /* flags */ #define RTBL_HEADER_STYLE_NONE 1 -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column (rtbl_t, const char*, unsigned int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_by_id (rtbl_t, unsigned int, const char*, unsigned int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_entryv_by_id (rtbl_t table, unsigned int id, const char *fmt, ...) __attribute__ ((format (printf, 3, 0))); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_entry (rtbl_t, const char*, const char*); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_entryv (rtbl_t, const char*, const char*, ...) __attribute__ ((format (printf, 3, 0))); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_add_column_entry_by_id (rtbl_t, unsigned int, const char*); -rtbl_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION rtbl_t ROKEN_LIB_CALL rtbl_create (void); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rtbl_destroy (rtbl_t); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_format (rtbl_t, FILE*); -unsigned int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION unsigned int ROKEN_LIB_CALL rtbl_get_flags (rtbl_t); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_new_row (rtbl_t); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_set_column_affix_by_id (rtbl_t, unsigned int, const char*, const char*); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_set_column_prefix (rtbl_t, const char*, const char*); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rtbl_set_flags (rtbl_t, unsigned int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_set_prefix (rtbl_t, const char*); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rtbl_set_separator (rtbl_t, const char*); #ifdef __cplusplus diff --git a/lib/roken/sendmsg.c b/lib/roken/sendmsg.c index 2c087bd1b..bbe5c303f 100644 --- a/lib/roken/sendmsg.c +++ b/lib/roken/sendmsg.c @@ -35,8 +35,10 @@ #include "roken.h" -ssize_t ROKEN_LIB_FUNCTION -sendmsg(int s, const struct msghdr *msg, int flags) +#ifndef _WIN32 + +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL +sendmsg(rk_socket_t s, const struct msghdr *msg, int flags) { ssize_t ret; size_t tot = 0; @@ -60,3 +62,87 @@ sendmsg(int s, const struct msghdr *msg, int flags) free (buf); return ret; } + +#else /* _WIN32 */ + +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of Secure Endpoints Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + * + **********************************************************************/ + +/* + * Implementation of sendmsg() for WIN32 + * + * We are using a contrived definition of msghdr which actually uses + * an array of ::_WSABUF structures instead of ::iovec . This allows + * us to call WSASend directly using the given ::msghdr instead of + * having to allocate another array of ::_WSABUF and copying data for + * each call. + * + * Limitations: + * + * - msg->msg_name is ignored. So is msg->control. + * - WSASend() only supports ::MSG_DONTROUTE, ::MSG_OOB and + * ::MSG_PARTIAL. + * + * @param[in] s The socket to use. + * @param[in] msg The message + * @param[in] flags Flags. A combination of ::MSG_DONTROUTE, + * ::MSG_OOB and ::MSG_PARTIAL + * + * @return The number of bytes sent, on success. Or -1 on error. + */ +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL +sendmsg_w32(rk_socket_t s, const struct msghdr * msg, int flags) +{ + int srv; + DWORD num_bytes_sent = 0; + + /* TODO: For _WIN32_WINNT >= 0x0600 we can use WSASendMsg using + WSAMSG which is a much more direct analogue to sendmsg(). */ + + srv = WSASend(s, msg->msg_iov, msg->msg_iovlen, + &num_bytes_sent, flags, NULL, NULL); + + if (srv == 0) + return (int) num_bytes_sent; + + /* srv == SOCKET_ERROR and WSAGetLastError() == WSA_IO_PENDING + indicates that a non-blocking transfer has been scheduled. + We'll have to check for that if we ever support non-blocking + I/O. */ + + return -1; +} + +#endif /* !_WIN32 */ diff --git a/lib/roken/setegid.c b/lib/roken/setegid.c index b4b3b036a..d9aef122d 100644 --- a/lib/roken/setegid.c +++ b/lib/roken/setegid.c @@ -39,7 +39,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL setegid(gid_t egid) { #ifdef HAVE_SETREGID diff --git a/lib/roken/setenv.c b/lib/roken/setenv.c index b6d0c0a6a..403db67cf 100644 --- a/lib/roken/setenv.c +++ b/lib/roken/setenv.c @@ -44,9 +44,10 @@ * anyway. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL setenv(const char *var, const char *val, int rewrite) { +#ifndef _WIN32 char *t; if (!rewrite && getenv(var) != 0) @@ -60,4 +61,15 @@ setenv(const char *var, const char *val, int rewrite) return 0; else return -1; +#else /* Win32 */ + char dummy[8]; + + if (!rewrite && GetEnvironmentVariable(var, dummy, sizeof(dummy)/sizeof(char)) != 0) + return 0; + + if (SetEnvironmentVariable(var, val) == 0) + return -1; + else + return 0; +#endif } diff --git a/lib/roken/seteuid.c b/lib/roken/seteuid.c index cff8f24d8..2d8c14829 100644 --- a/lib/roken/seteuid.c +++ b/lib/roken/seteuid.c @@ -39,7 +39,7 @@ #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL seteuid(uid_t euid) { #ifdef HAVE_SETREUID diff --git a/lib/roken/setprogname.c b/lib/roken/setprogname.c index 225e6ae09..115af77b8 100644 --- a/lib/roken/setprogname.c +++ b/lib/roken/setprogname.c @@ -40,7 +40,7 @@ extern const char *__progname; #endif #ifndef HAVE_SETPROGNAME -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL setprogname(const char *argv0) { #ifndef HAVE___PROGNAME diff --git a/lib/roken/signal.c b/lib/roken/signal.c index 19a484543..284f1e792 100644 --- a/lib/roken/signal.c +++ b/lib/roken/signal.c @@ -47,7 +47,7 @@ * Do we need any extra hacks for SIGCLD and/or SIGCHLD? */ -SigAction ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION SigAction ROKEN_LIB_CALL signal(int iSig, SigAction pAction) { struct sigaction saNew, saOld; diff --git a/lib/roken/simple_exec.c b/lib/roken/simple_exec.c index 86dde1bad..97679d7e4 100644 --- a/lib/roken/simple_exec.c +++ b/lib/roken/simple_exec.c @@ -52,13 +52,13 @@ #define EX_NOTFOUND 127 /* return values: - -1 on `unspecified' system errors - -2 on fork failures - -3 on waitpid errors - -4 exec timeout + SE_E_UNSPECIFIED on `unspecified' system errors + SE_E_FORKFAILED on fork failures + SE_E_WAITPIDFAILED on waitpid errors + SE_E_EXECTIMEOUT exec timeout 0- is return value from subprocess - 126 if the program couldn't be executed - 127 if the program couldn't be found + SE_E_NOEXEC if the program couldn't be executed + SE_E_NOTFOUND if the program couldn't be found 128- is 128 + signal that killed subprocess possible values `func' can return: @@ -78,7 +78,7 @@ sigtimeout(int sig) SIGRETURN(0); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL wait_for_process_timed(pid_t pid, time_t (*func)(void *), void *ptr, time_t timeout) { @@ -98,7 +98,7 @@ wait_for_process_timed(pid_t pid, time_t (*func)(void *), while(waitpid(pid, &status, 0) < 0) { if (errno != EINTR) { - ret = -3; + ret = SE_E_WAITPIDFAILED; goto out; } if (func == NULL) @@ -110,7 +110,7 @@ wait_for_process_timed(pid_t pid, time_t (*func)(void *), kill(pid, SIGTERM); continue; } else if (timeout == (time_t)-2) { - ret = -4; + ret = SE_E_EXECTIMEOUT; goto out; } alarm(timeout); @@ -134,13 +134,13 @@ wait_for_process_timed(pid_t pid, time_t (*func)(void *), return ret; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL wait_for_process(pid_t pid) { return wait_for_process_timed(pid, NULL, NULL, 0); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL pipe_execv(FILE **stdin_fd, FILE **stdout_fd, FILE **stderr_fd, const char *file, ...) { @@ -211,7 +211,7 @@ pipe_execv(FILE **stdin_fd, FILE **stdout_fd, FILE **stderr_fd, close(err_fd[0]); close(err_fd[1]); } - return -2; + return SE_E_FORKFAILED; default: if(stdin_fd != NULL) { close(in_fd[0]); @@ -229,14 +229,14 @@ pipe_execv(FILE **stdin_fd, FILE **stdout_fd, FILE **stderr_fd, return pid; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execvp_timed(const char *file, char *const args[], time_t (*func)(void *), void *ptr, time_t timeout) { pid_t pid = fork(); switch(pid){ case -1: - return -2; + return SE_E_FORKFAILED; case 0: execvp(file, args); exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC); @@ -245,21 +245,21 @@ simple_execvp_timed(const char *file, char *const args[], } } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execvp(const char *file, char *const args[]) { return simple_execvp_timed(file, args, NULL, NULL, 0); } /* gee, I'd like a execvpe */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execve_timed(const char *file, char *const args[], char *const envp[], time_t (*func)(void *), void *ptr, time_t timeout) { pid_t pid = fork(); switch(pid){ case -1: - return -2; + return SE_E_FORKFAILED; case 0: execve(file, args, envp); exit((errno == ENOENT) ? EX_NOTFOUND : EX_NOEXEC); @@ -268,13 +268,13 @@ simple_execve_timed(const char *file, char *const args[], char *const envp[], } } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execve(const char *file, char *const args[], char *const envp[]) { return simple_execve_timed(file, args, envp, NULL, NULL, 0); } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execlp(const char *file, ...) { va_list ap; @@ -285,13 +285,13 @@ simple_execlp(const char *file, ...) argv = vstrcollect(&ap); va_end(ap); if(argv == NULL) - return -1; + return SE_E_UNSPECIFIED; ret = simple_execvp(file, argv); free(argv); return ret; } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL simple_execle(const char *file, ... /* ,char *const envp[] */) { va_list ap; @@ -304,7 +304,7 @@ simple_execle(const char *file, ... /* ,char *const envp[] */) envp = va_arg(ap, char **); va_end(ap); if(argv == NULL) - return -1; + return SE_E_UNSPECIFIED; ret = simple_execve(file, argv, envp); free(argv); return ret; diff --git a/lib/roken/simple_exec_w32.c b/lib/roken/simple_exec_w32.c new file mode 100644 index 000000000..ae778ce60 --- /dev/null +++ b/lib/roken/simple_exec_w32.c @@ -0,0 +1,434 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + **********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +RCSID("$Id$"); +#endif + +#include +#include + +#ifndef _WIN32 +#error This implementation is Windows specific. +#endif + +/** + * wait_for_process_timed waits for a process to terminate or until a + * specified timeout occurs. + * + * @param[in] pid Process id for the monitored process + + * @param[in] func Timeout callback function. When the wait times out, + * the callback function is called. The possible return values + * from the callback function are: + * + * - ((time_t) -2) Exit loop without killing child and return SE_E_EXECTIMEOUT. + * - ((time_t) -1) Kill child with SIGTERM and wait for child to exit. + * - 0 Don't timeout again + * - n Seconds to next timeout + * + * @param[in] ptr Optional parameter for func() + * + * @param[in] timeout Seconds to first timeout. + * + * @retval SE_E_UNSPECIFIED Unspecified system error + * @retval SE_E_FORKFAILED Fork failure (not applicable for _WIN32 targets) + * @retval SE_E_WAITPIDFAILED waitpid errors + * @retval SE_E_EXECTIMEOUT exec timeout + * @retval 0 <= Return value from subprocess + * @retval SE_E_NOTFOUND The program coudln't be found + * @retval 128- The signal that killed the subprocess +128. + */ +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +wait_for_process_timed(pid_t pid, time_t (*func)(void *), + void *ptr, time_t timeout) +{ + HANDLE hProcess; + DWORD wrv = 0; + DWORD dtimeout; + int rv = 0; + + hProcess = OpenProcess(SYNCHRONIZE, FALSE, pid); + + if (hProcess == NULL) { + DWORD dw = GetLastError(); + return SE_E_WAITPIDFAILED; + } + + dtimeout = (DWORD) ((timeout == 0)? INFINITE: timeout * 1000); + + do { + wrv = WaitForSingleObject(hProcess, dtimeout); + + if (wrv == WAIT_OBJECT_0) { + + DWORD prv = 0; + + GetExitCodeProcess(hProcess, &prv); + rv = (int) prv; + break; + + } else if (wrv == WAIT_TIMEOUT) { + + if (func == NULL) + continue; + + timeout = (*func)(ptr); + + if (timeout == (time_t)-1) { + + if (TerminateProcess(hProcess, 128 + 9)) { + dtimeout = INFINITE; + continue; + } + rv = SE_E_UNSPECIFIED; + break; + + } else if (timeout == (time_t) -2) { + + rv = SE_E_EXECTIMEOUT; + break; + + } else { + + dtimeout = (DWORD) ((timeout == 0)? INFINITE: timeout * 1000); + continue; + + } + + } else { + + rv = SE_E_UNSPECIFIED; + break; + + } + + } while(TRUE); + + CloseHandle(hProcess); + + return rv; +} + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +wait_for_process(pid_t pid) +{ + return wait_for_process_timed(pid, NULL, NULL, 0); +} + +static char * +collect_commandline(const char * fn, va_list * ap) +{ + size_t len = 0; + size_t alloc_len = 0; + const char * s; + char * cmd = NULL; + + for (s = fn; s; s = (char *) va_arg(*ap, char *)) { + size_t cmp_len; + int need_quote = FALSE; + + if (FAILED(StringCchLength(s, MAX_PATH, &cmp_len))) { + if (cmd) + free(cmd); + return NULL; + } + + if (cmp_len == 0) + continue; + + if (strchr(s, ' ') && /* need to quote any component that + has embedded spaces, but not if + they are already quoted. */ + s[0] != '"' && + s[cmp_len - 1] != '"') { + need_quote = TRUE; + cmp_len += 2 * sizeof(char); + } + + if (s != fn) + cmp_len += 1 * sizeof(char); + + if (alloc_len < len + cmp_len + 1) { + char * nc; + + alloc_len += ((len + cmp_len - alloc_len) / MAX_PATH + 1) * MAX_PATH; + nc = (char *) realloc(cmd, alloc_len * sizeof(char)); + if (nc == NULL) { + if (cmd) + free(cmd); + return NULL; + } + } + + if (cmd == NULL) + return NULL; + + if (s != fn) + cmd[len++] = ' '; + + if (need_quote) { + StringCchPrintf(cmd + len, alloc_len - len, "\"%s\"", s); + } else { + StringCchCopy(cmd + len, alloc_len - len, s); + } + + len += cmp_len; + } + + return cmd; +} + +ROKEN_LIB_FUNCTION pid_t ROKEN_LIB_CALL +pipe_execv(FILE **stdin_fd, FILE **stdout_fd, FILE **stderr_fd, + const char *file, ...) +{ + HANDLE hOut_r = NULL; + HANDLE hOut_w = NULL; + HANDLE hIn_r = NULL; + HANDLE hIn_w = NULL; + HANDLE hErr_r = NULL; + HANDLE hErr_w = NULL; + + SECURITY_ATTRIBUTES sa; + STARTUPINFO si; + PROCESS_INFORMATION pi; + + char * commandline = NULL; + + pid_t rv = (pid_t) -1; + + { + va_list ap; + + va_start(ap, file); + commandline = collect_commandline(file, &ap); + + if (commandline == NULL) + return rv; + } + + ZeroMemory(&si, sizeof(si)); + ZeroMemory(&pi, sizeof(pi)); + ZeroMemory(&sa, sizeof(sa)); + + pi.hProcess = NULL; + pi.hThread = NULL; + + sa.nLength = sizeof(sa); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + + if ((stdout_fd && !CreatePipe(&hOut_r, &hOut_w, &sa, 0 /* Use default */)) || + + (stdin_fd && !CreatePipe(&hIn_r, &hIn_w, &sa, 0)) || + + (stderr_fd && !CreatePipe(&hErr_r, &hErr_w, &sa, 0)) || + + (!stdout_fd && (hOut_w = CreateFile("CON", GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) || + + (!stdin_fd && (hIn_r = CreateFile("CON",GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) || + + (!stderr_fd && (hErr_w = CreateFile("CON", GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)) + + goto _exit; + + /* We don't want the child processes inheriting these */ + if (hOut_r) + SetHandleInformation(hOut_r, HANDLE_FLAG_INHERIT, FALSE); + + if (hIn_w) + SetHandleInformation(hIn_w, HANDLE_FLAG_INHERIT, FALSE); + + if (hErr_r) + SetHandleInformation(hErr_r, HANDLE_FLAG_INHERIT, FALSE); + + si.cb = sizeof(si); + si.lpReserved = NULL; + si.lpDesktop = NULL; + si.lpTitle = NULL; + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = hIn_r; + si.hStdOutput = hOut_w; + si.hStdError = hErr_w; + + if (!CreateProcess(file, commandline, NULL, NULL, + TRUE, /* bInheritHandles */ + CREATE_NO_WINDOW, /* dwCreationFlags */ + NULL, /* lpEnvironment */ + NULL, /* lpCurrentDirectory */ + &si, + &pi)) { + + rv = (pid_t) (GetLastError() == ERROR_FILE_NOT_FOUND)? 127 : -1; + goto _exit; + } + + if (stdin_fd) { + *stdin_fd = _fdopen(_open_osfhandle((intptr_t) hIn_w, 0), "wb"); + if (*stdin_fd) + hIn_w = NULL; + } + + if (stdout_fd) { + *stdout_fd = _fdopen(_open_osfhandle((intptr_t) hOut_r, _O_RDONLY), "rb"); + if (*stdout_fd) + hOut_r = NULL; + } + + if (stderr_fd) { + *stderr_fd = _fdopen(_open_osfhandle((intptr_t) hErr_r, _O_RDONLY), "rb"); + if (*stderr_fd) + hErr_r = NULL; + } + + rv = (pid_t) pi.dwProcessId; + + _exit: + + if (pi.hProcess) CloseHandle(pi.hProcess); + + if (pi.hThread) CloseHandle(pi.hThread); + + if (hIn_r) CloseHandle(hIn_r); + + if (hIn_w) CloseHandle(hIn_w); + + if (hOut_r) CloseHandle(hOut_r); + + if (hOut_w) CloseHandle(hOut_w); + + if (hErr_r) CloseHandle(hErr_r); + + if (hErr_w) CloseHandle(hErr_w); + + return rv; +} + + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +simple_execvp_timed(const char *file, char *const args[], + time_t (*func)(void *), void *ptr, time_t timeout) +{ + intptr_t hp; + int rv; + + hp = spawnvp(_P_NOWAIT, file, args); + + if (hp == -1) + return (errno == ENOENT)? 127: 126; + else if (hp == 0) + return 0; + + rv = wait_for_process_timed(GetProcessId((HANDLE) hp), func, ptr, timeout); + + CloseHandle((HANDLE) hp); + + return rv; +} + + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +simple_execvp(const char *file, char *const args[]) +{ + return simple_execvp_timed(file, args, NULL, NULL, 0); +} + + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +simple_execve_timed(const char *file, char *const args[], char *const envp[], + time_t (*func)(void *), void *ptr, time_t timeout) +{ + intptr_t hp; + int rv; + + hp = spawnve(_P_NOWAIT, file, args, envp); + + if (hp == -1) + return (errno == ENOENT)? 127: 126; + else if (hp == 0) + return 0; + + rv = wait_for_process_timed(GetProcessId((HANDLE) hp), func, ptr, timeout); + + CloseHandle((HANDLE) hp); + + return rv; +} + + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +simple_execve(const char *file, char *const args[], char *const envp[]) +{ + return simple_execve_timed(file, args, envp, NULL, NULL, 0); +} + + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +simple_execlp(const char *file, ...) +{ + va_list ap; + char **argv; + int ret; + + va_start(ap, file); + argv = vstrcollect(&ap); + va_end(ap); + if(argv == NULL) + return SE_E_UNSPECIFIED; + ret = simple_execvp(file, argv); + free(argv); + return ret; +} + + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +simple_execle(const char *file, ... /* ,char *const envp[] */) +{ + va_list ap; + char **argv; + char *const* envp; + int ret; + + va_start(ap, file); + argv = vstrcollect(&ap); + envp = va_arg(ap, char **); + va_end(ap); + if(argv == NULL) + return SE_E_UNSPECIFIED; + ret = simple_execve(file, argv, envp); + free(argv); + return ret; +} diff --git a/lib/roken/sleep.c b/lib/roken/sleep.c new file mode 100644 index 000000000..c19439c53 --- /dev/null +++ b/lib/roken/sleep.c @@ -0,0 +1,47 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + **********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#ifndef _WIN32 +#error Only implemented on Windows +#endif + +ROKEN_LIB_FUNCTION unsigned int ROKEN_LIB_CALL +sleep(unsigned int seconds) +{ + SleepEx(1000 * (DWORD) seconds, FALSE); + return 0; +} diff --git a/lib/roken/snprintf.c b/lib/roken/snprintf.c index 6beab4fe3..a20054672 100644 --- a/lib/roken/snprintf.c +++ b/lib/roken/snprintf.c @@ -119,10 +119,10 @@ typedef long longest; -static int +static size_t pad(struct snprintf_state *state, int width, char c) { - int len = 0; + size_t len = 0; while(width-- > 0){ (*state->append_char)(state, c); ++len; @@ -252,14 +252,14 @@ append_number(struct snprintf_state *state, * return length */ -static int +static size_t append_string (struct snprintf_state *state, const unsigned char *arg, int width, int prec, int flags) { - int len = 0; + size_t len = 0; if(arg == NULL) arg = (const unsigned char*)"(null)"; @@ -344,12 +344,12 @@ else \ * zyxprintf - return length, as snprintf */ -static int +static size_t xyzprintf (struct snprintf_state *state, const char *char_format, va_list ap) { const unsigned char *format = (const unsigned char *)char_format; unsigned char c; - int len = 0; + size_t len = 0; while((c = *format++)) { if (c == '%') { @@ -531,7 +531,7 @@ xyzprintf (struct snprintf_state *state, const char *char_format, va_list ap) } #if !defined(HAVE_SNPRINTF) || defined(TEST_SNPRINTF) -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_snprintf (char *str, size_t sz, const char *format, ...) { va_list args; @@ -564,7 +564,7 @@ rk_snprintf (char *str, size_t sz, const char *format, ...) #endif #if !defined(HAVE_ASPRINTF) || defined(TEST_SNPRINTF) -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_asprintf (char **ret, const char *format, ...) { va_list args; @@ -596,7 +596,7 @@ rk_asprintf (char **ret, const char *format, ...) #endif #if !defined(HAVE_ASNPRINTF) || defined(TEST_SNPRINTF) -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_asnprintf (char **ret, size_t max_sz, const char *format, ...) { va_list args; @@ -626,7 +626,7 @@ rk_asnprintf (char **ret, size_t max_sz, const char *format, ...) #endif #if !defined(HAVE_VASPRINTF) || defined(TEST_SNPRINTF) -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_vasprintf (char **ret, const char *format, va_list args) { return vasnprintf (ret, 0, format, args); @@ -635,10 +635,10 @@ rk_vasprintf (char **ret, const char *format, va_list args) #if !defined(HAVE_VASNPRINTF) || defined(TEST_SNPRINTF) -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_vasnprintf (char **ret, size_t max_sz, const char *format, va_list args) { - int st; + size_t st; struct snprintf_state state; state.max_sz = max_sz; @@ -674,7 +674,7 @@ rk_vasnprintf (char **ret, size_t max_sz, const char *format, va_list args) #endif #if !defined(HAVE_VSNPRINTF) || defined(TEST_SNPRINTF) -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_vsnprintf (char *str, size_t sz, const char *format, va_list args) { struct snprintf_state state; diff --git a/lib/roken/socket.c b/lib/roken/socket.c index ab1b7ff34..bfc4b7102 100644 --- a/lib/roken/socket.c +++ b/lib/roken/socket.c @@ -40,7 +40,7 @@ * Set `sa' to the unitialized address of address family `af' */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL socket_set_any (struct sockaddr *sa, int af) { switch (af) { @@ -74,7 +74,7 @@ socket_set_any (struct sockaddr *sa, int af) * set `sa' to (`ptr', `port') */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL socket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port) { switch (sa->sa_family) { @@ -108,7 +108,7 @@ socket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port) * Return the size of an address of the type in `sa' */ -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL socket_addr_size (const struct sockaddr *sa) { switch (sa->sa_family) { @@ -120,7 +120,7 @@ socket_addr_size (const struct sockaddr *sa) #endif default : errx (1, "unknown address family %d", sa->sa_family); - break; + UNREACHABLE(return 0); } } @@ -128,7 +128,7 @@ socket_addr_size (const struct sockaddr *sa) * Return the size of a `struct sockaddr' in `sa'. */ -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL socket_sockaddr_size (const struct sockaddr *sa) { switch (sa->sa_family) { @@ -140,7 +140,7 @@ socket_sockaddr_size (const struct sockaddr *sa) #endif default : errx (1, "unknown address family %d", sa->sa_family); - break; + UNREACHABLE(return 0); } } @@ -148,7 +148,7 @@ socket_sockaddr_size (const struct sockaddr *sa) * Return the binary address of `sa'. */ -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL socket_get_address (const struct sockaddr *sa) { switch (sa->sa_family) { @@ -164,7 +164,7 @@ socket_get_address (const struct sockaddr *sa) #endif default : errx (1, "unknown address family %d", sa->sa_family); - break; + UNREACHABLE(return NULL); } } @@ -172,7 +172,7 @@ socket_get_address (const struct sockaddr *sa) * Return the port number from `sa'. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL socket_get_port (const struct sockaddr *sa) { switch (sa->sa_family) { @@ -188,7 +188,7 @@ socket_get_port (const struct sockaddr *sa) #endif default : errx (1, "unknown address family %d", sa->sa_family); - break; + UNREACHABLE(return 0); } } @@ -196,7 +196,7 @@ socket_get_port (const struct sockaddr *sa) * Set the port in `sa' to `port'. */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL socket_set_port (struct sockaddr *sa, int port) { switch (sa->sa_family) { @@ -221,8 +221,8 @@ socket_set_port (struct sockaddr *sa, int port) /* * Set the range of ports to use when binding with port = 0. */ -void ROKEN_LIB_FUNCTION -socket_set_portrange (int sock, int restr, int af) +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_portrange (rk_socket_t sock, int restr, int af) { #if defined(IP_PORTRANGE) if (af == AF_INET) { @@ -247,8 +247,8 @@ socket_set_portrange (int sock, int restr, int af) * Enable debug on `sock'. */ -void ROKEN_LIB_FUNCTION -socket_set_debug (int sock) +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_debug (rk_socket_t sock) { #if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT) int on = 1; @@ -262,8 +262,8 @@ socket_set_debug (int sock) * Set the type-of-service of `sock' to `tos'. */ -void ROKEN_LIB_FUNCTION -socket_set_tos (int sock, int tos) +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_tos (rk_socket_t sock, int tos) { #if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) if (setsockopt (sock, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof (int)) < 0) @@ -276,8 +276,8 @@ socket_set_tos (int sock, int tos) * set the reuse of addresses on `sock' to `val'. */ -void ROKEN_LIB_FUNCTION -socket_set_reuseaddr (int sock, int val) +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_reuseaddr (rk_socket_t sock, int val) { #if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT) if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val, @@ -290,10 +290,28 @@ socket_set_reuseaddr (int sock, int val) * Set the that the `sock' should bind to only IPv6 addresses. */ -void ROKEN_LIB_FUNCTION -socket_set_ipv6only (int sock, int val) +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +socket_set_ipv6only (rk_socket_t sock, int val) { #if defined(IPV6_V6ONLY) && defined(HAVE_SETSOCKOPT) setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val, sizeof(val)); #endif } + +/** + * Create a file descriptor from a socket + * + * While the socket handle in \a sock can be used with WinSock + * functions after calling socket_to_fd(), it should not be closed + * with rk_closesocket(). The socket will be closed when the associated + * file descriptor is closed. + */ +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +socket_to_fd(rk_socket_t sock, int flags) +{ +#ifndef _WIN32 + return sock; +#else + return _open_osfhandle((intptr_t) sock, flags); +#endif +} diff --git a/lib/roken/sockstartup_w32.c b/lib/roken/sockstartup_w32.c new file mode 100644 index 000000000..675d5aad7 --- /dev/null +++ b/lib/roken/sockstartup_w32.c @@ -0,0 +1,77 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + **********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#ifndef _WIN32 +#error Only implemented for Windows +#endif + +volatile LONG _startup_count = 0; + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +rk_WSAStartup(void) +{ + WSADATA wsad; + + if (!WSAStartup( MAKEWORD(2, 2), &wsad )) { + if (wsad.wVersion != MAKEWORD(2, 2)) { + /* huh? We can't use 2.2? */ + WSACleanup(); + return -1; + } + + InterlockedIncrement(&_startup_count); + return 0; + } + + return -1; +} + + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +rk_WSACleanup(void) +{ + LONG l; + + if ((l = InterlockedDecrement(&_startup_count)) < 0) { + l = InterlockedIncrement(&_startup_count) - 1; + } + + if (l >= 0) { + return WSACleanup(); + } + return -1; +} diff --git a/lib/roken/strcasecmp.c b/lib/roken/strcasecmp.c index 200175d67..00a0a8ef0 100644 --- a/lib/roken/strcasecmp.c +++ b/lib/roken/strcasecmp.c @@ -40,7 +40,7 @@ #ifndef HAVE_STRCASECMP -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL strcasecmp(const char *s1, const char *s2) { while(toupper((unsigned char)*s1) == toupper((unsigned char)*s2)) { diff --git a/lib/roken/strcollect.c b/lib/roken/strcollect.c index f444d05e2..0afc3f0c6 100644 --- a/lib/roken/strcollect.c +++ b/lib/roken/strcollect.c @@ -66,7 +66,7 @@ sub (char **argv, int i, int argc, va_list *ap) * terminated by NULL. */ -char ** ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char ** ROKEN_LIB_CALL vstrcollect(va_list *ap) { return sub (NULL, 0, 0, ap); @@ -76,7 +76,7 @@ vstrcollect(va_list *ap) * */ -char ** ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char ** ROKEN_LIB_CALL strcollect(char *first, ...) { va_list ap; diff --git a/lib/roken/strdup.c b/lib/roken/strdup.c index e06ac5222..ce004562f 100644 --- a/lib/roken/strdup.c +++ b/lib/roken/strdup.c @@ -36,7 +36,7 @@ #include #ifndef HAVE_STRDUP -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strdup(const char *old) { char *t = malloc(strlen(old)+1); diff --git a/lib/roken/strerror.c b/lib/roken/strerror.c index 015d5c57c..b5ec6918e 100644 --- a/lib/roken/strerror.c +++ b/lib/roken/strerror.c @@ -40,7 +40,7 @@ extern int sys_nerr; extern char *sys_errlist[]; -char* ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char* ROKEN_LIB_CALL strerror(int eno) { static char emsg[1024]; diff --git a/lib/roken/strftime.c b/lib/roken/strftime.c index 08c78ea7f..18faa71a4 100644 --- a/lib/roken/strftime.c +++ b/lib/roken/strftime.c @@ -31,10 +31,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include "roken.h" #ifdef TEST_STRPFTIME #include "strpftime-test.h" #endif -#include "roken.h" static const char *abb_weekdays[] = { "Sun", @@ -166,7 +166,7 @@ week_number_mon4 (const struct tm *tm) * */ -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL strftime (char *buf, size_t maxsize, const char *format, const struct tm *tm) { @@ -382,7 +382,7 @@ strftime (char *buf, size_t maxsize, const char *format, "%%%c", *format); break; } - if (ret < 0 || ret >= maxsize - n) + if (ret < 0 || ret >= (int)(maxsize - n)) return 0; n += ret; buf += ret; diff --git a/lib/roken/strlcat.c b/lib/roken/strlcat.c index 2d3744a5f..0b676ef98 100644 --- a/lib/roken/strlcat.c +++ b/lib/roken/strlcat.c @@ -36,7 +36,7 @@ #ifndef HAVE_STRLCAT -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL strlcat (char *dst, const char *src, size_t dst_sz) { size_t len = strlen(dst); @@ -49,4 +49,5 @@ strlcat (char *dst, const char *src, size_t dst_sz) return len + strlcpy (dst + len, src, dst_sz - len); } + #endif diff --git a/lib/roken/strlcpy.c b/lib/roken/strlcpy.c index b151d2184..7c1789bd1 100644 --- a/lib/roken/strlcpy.c +++ b/lib/roken/strlcpy.c @@ -36,7 +36,21 @@ #ifndef HAVE_STRLCPY -size_t ROKEN_LIB_FUNCTION +#if defined(_MSC_VER) && _MSC_VER >= 1400 + +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL +strlcpy (char *dst, const char *src, size_t dst_cch) +{ + errno_t e; + + e = strcpy_s(dst, dst_cch, src); + + return strlen (src); +} + +#else + +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL strlcpy (char *dst, const char *src, size_t dst_sz) { size_t n; @@ -54,3 +68,5 @@ strlcpy (char *dst, const char *src, size_t dst_sz) } #endif + +#endif diff --git a/lib/roken/strlwr.c b/lib/roken/strlwr.c index 1a6634b73..68bd4edad 100644 --- a/lib/roken/strlwr.c +++ b/lib/roken/strlwr.c @@ -38,7 +38,7 @@ #include "roken.h" #ifndef HAVE_STRLWR -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strlwr(char *str) { char *s; diff --git a/lib/roken/strncasecmp.c b/lib/roken/strncasecmp.c index 0af38e173..f244fb582 100644 --- a/lib/roken/strncasecmp.c +++ b/lib/roken/strncasecmp.c @@ -39,7 +39,7 @@ #ifndef HAVE_STRNCASECMP -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL strncasecmp(const char *s1, const char *s2, size_t n) { while(n > 0 diff --git a/lib/roken/strndup.c b/lib/roken/strndup.c index af89664d8..e67c9983a 100644 --- a/lib/roken/strndup.c +++ b/lib/roken/strndup.c @@ -38,7 +38,7 @@ #include "roken.h" #ifndef HAVE_STRNDUP -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strndup(const char *old, size_t sz) { size_t len = strnlen (old, sz); diff --git a/lib/roken/strnlen.c b/lib/roken/strnlen.c index dfbcc2bf5..f26cd8451 100644 --- a/lib/roken/strnlen.c +++ b/lib/roken/strnlen.c @@ -35,7 +35,7 @@ #include "roken.h" -size_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL strnlen(const char *s, size_t len) { size_t i; diff --git a/lib/roken/strpftime-test.c b/lib/roken/strpftime-test.c index 855216b42..8524ff5ee 100644 --- a/lib/roken/strpftime-test.c +++ b/lib/roken/strpftime-test.c @@ -31,10 +31,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #ifdef TEST_STRPFTIME #include "strpftime-test.h" #endif -#include "roken.h" enum { MAXSIZE = 26 }; diff --git a/lib/roken/strpftime-test.h b/lib/roken/strpftime-test.h index 5d1f74256..5f9b23fda 100644 --- a/lib/roken/strpftime-test.h +++ b/lib/roken/strpftime-test.h @@ -45,4 +45,11 @@ #define strftime test_strftime #define strptime test_strptime +ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL +strftime (char *buf, size_t maxsize, const char *format, + const struct tm *tm); + +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL +strptime (const char *buf, const char *format, struct tm *timeptr); + #endif /* __STRFTIME_TEST_H__ */ diff --git a/lib/roken/strpool.c b/lib/roken/strpool.c index 642d335de..6e6a737bc 100644 --- a/lib/roken/strpool.c +++ b/lib/roken/strpool.c @@ -46,7 +46,7 @@ struct rk_strpool { * */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_strpoolfree(struct rk_strpool *p) { if (p->str) { @@ -60,7 +60,7 @@ rk_strpoolfree(struct rk_strpool *p) * */ -struct rk_strpool * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION struct rk_strpool * ROKEN_LIB_CALL rk_strpoolprintf(struct rk_strpool *p, const char *fmt, ...) { va_list ap; @@ -97,7 +97,7 @@ rk_strpoolprintf(struct rk_strpool *p, const char *fmt, ...) * */ -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL rk_strpoolcollect(struct rk_strpool *p) { char *str; diff --git a/lib/roken/strptime.c b/lib/roken/strptime.c index 91eb62918..75c27a328 100644 --- a/lib/roken/strptime.c +++ b/lib/roken/strptime.c @@ -31,11 +31,11 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include "roken.h" #ifdef TEST_STRPFTIME #include "strpftime-test.h" #endif #include -#include "roken.h" static const char *abb_weekdays[] = { "Sun", @@ -177,7 +177,7 @@ first_day (int year) int ret = 4; for (; year > 1970; --year) - ret = (ret + 365 + is_leap_year (year) ? 1 : 0) % 7; + ret = (ret + (is_leap_year (year) ? 366 : 365)) % 7; return ret; } @@ -237,7 +237,7 @@ set_week_number_mon4 (struct tm *timeptr, int wnum) * */ -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strptime (const char *buf, const char *format, struct tm *timeptr) { char c; diff --git a/lib/roken/strsep.c b/lib/roken/strsep.c index 5cbf8557a..76b447c37 100644 --- a/lib/roken/strsep.c +++ b/lib/roken/strsep.c @@ -39,7 +39,7 @@ #ifndef HAVE_STRSEP -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strsep(char **str, const char *delim) { char *save = *str; diff --git a/lib/roken/strsep_copy.c b/lib/roken/strsep_copy.c index 908e37ca4..9624b5a46 100644 --- a/lib/roken/strsep_copy.c +++ b/lib/roken/strsep_copy.c @@ -41,7 +41,7 @@ /* strsep, but with const stringp, so return string in buf */ -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL strsep_copy(const char **stringp, const char *delim, char *buf, size_t len) { const char *save = *stringp; diff --git a/lib/roken/strtok_r.c b/lib/roken/strtok_r.c index a8ffde58e..16a9daf24 100644 --- a/lib/roken/strtok_r.c +++ b/lib/roken/strtok_r.c @@ -39,7 +39,7 @@ #ifndef HAVE_STRTOK_R -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strtok_r(char *s1, const char *s2, char **lasts) { char *ret; diff --git a/lib/roken/strupr.c b/lib/roken/strupr.c index db2d987f9..fdff7f44a 100644 --- a/lib/roken/strupr.c +++ b/lib/roken/strupr.c @@ -38,7 +38,7 @@ #include "roken.h" #ifndef HAVE_STRUPR -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strupr(char *str) { char *s; diff --git a/lib/roken/swab.c b/lib/roken/swab.c index 19a443eca..9b8d1d1f9 100644 --- a/lib/roken/swab.c +++ b/lib/roken/swab.c @@ -36,7 +36,7 @@ #ifndef HAVE_SWAB -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL swab (char *from, char *to, int nbytes) { while(nbytes >= 2) { diff --git a/lib/roken/syslog.h b/lib/roken/syslog.h new file mode 100644 index 000000000..f68dd1134 --- /dev/null +++ b/lib/roken/syslog.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1982, 1986, 1988, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)syslog.h 8.1 (Berkeley) 6/2/93 + */ + +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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 _SYS_SYSLOG_H +#define _SYS_SYSLOG_H 1 + +#include + +/* + * priorities/facilities are encoded into a single 32-bit quantity, where the + * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility + * (0-big number). Both the priorities and the facilities map roughly + * one-to-one to strings in the syslogd(8) source code. This mapping is + * included in this file. + * + * priorities (these are ordered) + */ +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but significant condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ + +#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */ + /* extract priority */ +#define LOG_PRI(p) ((p) & LOG_PRIMASK) +#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri)) + +#ifdef SYSLOG_NAMES +#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ + /* mark "facility" */ +#define INTERNAL_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0) +typedef struct _code { + char *c_name; + int c_val; +} CODE; + +CODE prioritynames[] = + { + { "alert", LOG_ALERT }, + { "crit", LOG_CRIT }, + { "debug", LOG_DEBUG }, + { "emerg", LOG_EMERG }, + { "err", LOG_ERR }, + { "error", LOG_ERR }, /* DEPRECATED */ + { "info", LOG_INFO }, + { "none", INTERNAL_NOPRI }, /* INTERNAL */ + { "notice", LOG_NOTICE }, + { "panic", LOG_EMERG }, /* DEPRECATED */ + { "warn", LOG_WARNING }, /* DEPRECATED */ + { "warning", LOG_WARNING }, + { NULL, -1 } + }; +#endif + +/* facility codes */ +#define LOG_KERN (0<<3) /* kernel messages */ +#define LOG_USER (1<<3) /* random user-level messages */ +#define LOG_MAIL (2<<3) /* mail system */ +#define LOG_DAEMON (3<<3) /* system daemons */ +#define LOG_AUTH (4<<3) /* security/authorization messages */ +#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */ +#define LOG_LPR (6<<3) /* line printer subsystem */ +#define LOG_NEWS (7<<3) /* network news subsystem */ +#define LOG_UUCP (8<<3) /* UUCP subsystem */ +#define LOG_CRON (9<<3) /* clock daemon */ +#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */ +#define LOG_FTP (11<<3) /* ftp daemon */ + + /* other codes through 15 reserved for system use */ +#define LOG_LOCAL0 (16<<3) /* reserved for local use */ +#define LOG_LOCAL1 (17<<3) /* reserved for local use */ +#define LOG_LOCAL2 (18<<3) /* reserved for local use */ +#define LOG_LOCAL3 (19<<3) /* reserved for local use */ +#define LOG_LOCAL4 (20<<3) /* reserved for local use */ +#define LOG_LOCAL5 (21<<3) /* reserved for local use */ +#define LOG_LOCAL6 (22<<3) /* reserved for local use */ +#define LOG_LOCAL7 (23<<3) /* reserved for local use */ + +#define LOG_NFACILITIES 24 /* current number of facilities */ +#define LOG_FACMASK 0x03f8 /* mask to extract facility part */ + /* facility of pri */ +#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3) + +#ifdef SYSLOG_NAMES +CODE facilitynames[] = + { + { "auth", LOG_AUTH }, + { "authpriv", LOG_AUTHPRIV }, + { "cron", LOG_CRON }, + { "daemon", LOG_DAEMON }, + { "ftp", LOG_FTP }, + { "kern", LOG_KERN }, + { "lpr", LOG_LPR }, + { "mail", LOG_MAIL }, + { "mark", INTERNAL_MARK }, /* INTERNAL */ + { "news", LOG_NEWS }, + { "security", LOG_AUTH }, /* DEPRECATED */ + { "syslog", LOG_SYSLOG }, + { "user", LOG_USER }, + { "uucp", LOG_UUCP }, + { "local0", LOG_LOCAL0 }, + { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, + { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, + { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, + { "local7", LOG_LOCAL7 }, + { NULL, -1 } + }; +#endif + +/* + * arguments to setlogmask. + */ +#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */ +#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */ + +/* + * Option flags for openlog. + * + * LOG_ODELAY no longer does anything. + * LOG_NDELAY is the inverse of what it used to be. + */ +#define LOG_PID 0x01 /* log the pid with each message */ +#define LOG_CONS 0x02 /* log on the console if errors in sending */ +#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */ +#define LOG_NDELAY 0x08 /* don't delay open */ +#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */ +#define LOG_PERROR 0x20 /* log to stderr as well */ + +#define SYSLOG_PORT 514 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Close desriptor used to write to system logger. */ +extern void closelog (void); + +/* Open connection to system logger. */ +extern void openlog (char *__ident, int __option, int __facility); + +/* Set the log mask level. */ +extern int setlogmask (int __mask); + +/* Generate a log message using FMT string and option arguments. */ +extern void syslog (int __pri, char *__fmt, ...); + +/* Generate a log message using FMT and using arguments pointed to by AP. */ +extern void vsyslog (int __pri, char *__fmt, va_list __ap); + +#ifdef _WIN32 + /* Windows specific. + + init_syslog() *must* be called before calling any of the above + functions. exit_syslog() will be scheduled using atexit(). + However, it is not an error and encouraged to call + exit_syslog() before the application exits. + + During operation, the application is free to call exit_syslog() + followed by init_syslog() to re-initialize the library. i.e. if + a different syslog host is to be used. + + */ + + /* Initializes the syslog library and sets the syslog host. The + hostname parameter is of the form "[:]". The + may be a numeric port or it may be a name of a service. + If the is specified using a service name, it will be + looked up using getservbyname(). + + On failure, the hostname and port will be set to "localhost" + and SYSLOG_PORT respectively. + */ + extern void init_syslog(const char * hostname); + + extern void exit_syslog(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* syslog.h */ diff --git a/lib/roken/syslogc.c b/lib/roken/syslogc.c new file mode 100644 index 000000000..b5b3901ca --- /dev/null +++ b/lib/roken/syslogc.c @@ -0,0 +1,341 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + **********************************************************************/ + +/* + * Based on code by Alexander Yaworsky + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#define SYSLOG_DGRAM_SIZE 1024 + +static BOOL syslog_opened = FALSE; + +static int syslog_mask = 0xFF; +static char syslog_ident[ 128 ] = ""; +static int syslog_facility = LOG_USER; +static char syslog_procid_str[ 20 ]; + +static SOCKADDR_IN syslog_hostaddr; +static SOCKET syslog_socket = INVALID_SOCKET; +static char local_hostname[ MAX_COMPUTERNAME_LENGTH + 1 ]; + +static char syslog_hostname[ MAX_COMPUTERNAME_LENGTH + 1 ] = "localhost"; +static unsigned short syslog_port = SYSLOG_PORT; + +static int datagramm_size; + +volatile BOOL initialized = FALSE; +BOOL wsa_initialized = FALSE; +CRITICAL_SECTION cs_syslog; + +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +init_syslog(const char * hostname) +{ + WSADATA wsd; + char * service; + + if ( initialized ) + return; + + if( WSAStartup( MAKEWORD( 2, 2 ), &wsd ) ) { + fprintf(stderr, "Can't initialize WinSock\n"); + /* we let the rest of the initialization code go through, + although none of the syslog calls would succeed. */ + } else { + wsa_initialized = TRUE; + } + + if (hostname) + strcpy_s(syslog_hostname, sizeof(syslog_hostname), hostname); + else + strcpy_s(syslog_hostname, sizeof(syslog_hostname), ""); + + service = strchr(syslog_hostname, ':'); + + if (service) { + int tp; + + *service++ = '\0'; + + if ((tp = atoi(service)) <= 0) { + struct servent * se; + + se = getservbyname(service, "udp"); + + syslog_port = (se == NULL)? SYSLOG_PORT: se->s_port; + } else { + syslog_port = (unsigned short) tp; + } + } else { + syslog_port = SYSLOG_PORT; + } + + InitializeCriticalSection(&cs_syslog); + initialized = TRUE; + + atexit(exit_syslog); +} + +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +exit_syslog(void) +{ + if ( !initialized ) + return; + + closelog(); + + if ( wsa_initialized ) + WSACleanup(); + + DeleteCriticalSection(&cs_syslog); + initialized = FALSE; +} + +static void init_logger_addr() +{ + struct hostent * phe = NULL; + + memset( &syslog_hostaddr, 0, sizeof(SOCKADDR_IN) ); + syslog_hostaddr.sin_family = AF_INET; + + if (syslog_hostname[0] == '\0') + goto use_default; + + phe = gethostbyname( syslog_hostname ); + if( !phe ) + goto use_default; + + memcpy( &syslog_hostaddr.sin_addr.s_addr, phe->h_addr, phe->h_length ); + + syslog_hostaddr.sin_port = htons( syslog_port ); + return; + +use_default: + syslog_hostaddr.sin_addr.S_un.S_addr = htonl( 0x7F000001 ); + syslog_hostaddr.sin_port = htons( SYSLOG_PORT ); +} + +/****************************************************************************** + * closelog + * + * Close desriptor used to write to system logger. + */ +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +closelog() +{ + if ( !initialized ) + return; + + EnterCriticalSection(&cs_syslog); + if( syslog_opened ) { + closesocket( syslog_socket ); + syslog_socket = INVALID_SOCKET; + syslog_opened = FALSE; + } + LeaveCriticalSection(&cs_syslog); +} + +/****************************************************************************** + * openlog + * + * Open connection to system logger. + */ +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +openlog( char* ident, int option, int facility ) +{ + BOOL failed = FALSE; + SOCKADDR_IN sa_local; + DWORD n; + int size; + + if ( !initialized ) + return; + + EnterCriticalSection(&cs_syslog); + + if( syslog_opened ) + goto done; + + failed = TRUE; + + syslog_facility = facility? facility : LOG_USER; + + if( option & LOG_PID ) + sprintf_s( syslog_procid_str, sizeof(syslog_procid_str), "[%lu]", GetCurrentProcessId() ); + else + syslog_procid_str[0] = '\0'; + + /* FIXME: handle other options */ + + n = sizeof(local_hostname); + if( !GetComputerName( local_hostname, &n ) ) + goto done; + + syslog_socket = INVALID_SOCKET; + + init_logger_addr(); + + for( n = 0;; n++ ) + { + syslog_socket = socket( AF_INET, SOCK_DGRAM, 0 ); + if( INVALID_SOCKET == syslog_socket ) + goto done; + + memset( &sa_local, 0, sizeof(SOCKADDR_IN) ); + sa_local.sin_family = AF_INET; + if( bind( syslog_socket, (SOCKADDR*) &sa_local, sizeof(SOCKADDR_IN) ) == 0 ) + break; + rk_closesocket( syslog_socket ); + syslog_socket = INVALID_SOCKET; + if( n == 100 ) + goto done; + Sleep(0); + } + + /* get size of datagramm */ + size = sizeof(datagramm_size); + if( getsockopt( syslog_socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*) &datagramm_size, &size ) ) + goto done; + if( datagramm_size - strlen(local_hostname) - (ident? strlen(ident) : 0) < 64 ) + goto done; + if( datagramm_size > SYSLOG_DGRAM_SIZE ) + datagramm_size = SYSLOG_DGRAM_SIZE; + + if (ident) + strcpy_s(syslog_ident, sizeof(syslog_ident), ident); + + syslog_facility = (facility ? facility : LOG_USER); + failed = FALSE; + + done: + if( failed ) { + if( syslog_socket != INVALID_SOCKET ) + rk_closesocket( syslog_socket ); + } + syslog_opened = !failed; + + LeaveCriticalSection(&cs_syslog); +} + +/****************************************************************************** + * setlogmask + * + * Set the log mask level. + */ +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL +setlogmask( int mask ) +{ + int ret; + + if ( !initialized ) + return 0; + + EnterCriticalSection(&cs_syslog); + + ret = syslog_mask; + if( mask ) + syslog_mask = mask; + + LeaveCriticalSection(&cs_syslog); + + return ret; +} + +/****************************************************************************** + * syslog + * + * Generate a log message using FMT string and option arguments. + */ +ROKEN_LIB_FUNCTION void +syslog( int pri, char* fmt, ... ) +{ + va_list ap; + + va_start( ap, fmt ); + vsyslog( pri, fmt, ap ); + va_end( ap ); +} + +/****************************************************************************** + * vsyslog + * + * Generate a log message using FMT and using arguments pointed to by AP. + */ +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL +vsyslog( int pri, char* fmt, va_list ap ) +{ + static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + char datagramm[ SYSLOG_DGRAM_SIZE ]; + SYSTEMTIME stm; + int len; + char *p; + + if ( !initialized ) + return; + + EnterCriticalSection(&cs_syslog); + + if( !(LOG_MASK( LOG_PRI( pri )) & syslog_mask) ) + goto done; + + openlog( NULL, 0, pri & LOG_FACMASK ); + if( !syslog_opened ) + goto done; + + if( !(pri & LOG_FACMASK) ) + pri |= syslog_facility; + + GetLocalTime( &stm ); + len = sprintf_s( datagramm, sizeof(datagramm), + "<%d>%s %2d %02d:%02d:%02d %s %s%s: ", + pri, + month[ stm.wMonth - 1 ], stm.wDay, stm.wHour, stm.wMinute, stm.wSecond, + local_hostname, syslog_ident, syslog_procid_str ); + vsprintf_s( datagramm + len, datagramm_size - len, fmt, ap ); + p = strchr( datagramm, '\n' ); + if( p ) + *p = 0; + p = strchr( datagramm, '\r' ); + if( p ) + *p = 0; + + sendto( syslog_socket, datagramm, strlen(datagramm), 0, (SOCKADDR*) &syslog_hostaddr, sizeof(SOCKADDR_IN) ); + + done: + LeaveCriticalSection(&cs_syslog); +} + diff --git a/lib/roken/test-mem.c b/lib/roken/test-mem.c index ef2a5ed77..2ce961e06 100644 --- a/lib/roken/test-mem.c +++ b/lib/roken/test-mem.c @@ -54,8 +54,16 @@ struct { int fd; } map; +#ifdef HAVE_SIGACTION + struct sigaction sa, osa; +#else + +void (* osigh)(int); + +#endif + char *testname; static RETSIGTYPE @@ -82,7 +90,7 @@ segv_handler(int sig) errx(1, "malloc"); -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL rk_test_mem_alloc(enum rk_test_mem_type type, const char *name, void *buf, size_t size) { @@ -98,7 +106,7 @@ rk_test_mem_alloc(enum rk_test_mem_type type, const char *name, map.start = p; map.size = size + 2; p[0] = 0xff; - p[map.size] = 0xff; + p[map.size-1] = 0xff; map.data_start = p + 1; #else unsigned char *p; @@ -149,6 +157,7 @@ rk_test_mem_alloc(enum rk_test_mem_type type, const char *name, abort(); } #endif +#ifdef HAVE_SIGACTION sigemptyset (&sa.sa_mask); sa.sa_flags = 0; #ifdef SA_RESETHAND @@ -156,6 +165,9 @@ rk_test_mem_alloc(enum rk_test_mem_type type, const char *name, #endif sa.sa_handler = segv_handler; sigaction (SIGSEGV, &sa, &osa); +#else + osigh = signal(SIGSEGV, segv_handler); +#endif map.data_size = size; if (buf) @@ -163,7 +175,7 @@ rk_test_mem_alloc(enum rk_test_mem_type type, const char *name, return map.data_start; } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_test_mem_free(const char *map_name) { #ifndef HAVE_MMAP @@ -174,7 +186,7 @@ rk_test_mem_free(const char *map_name) if (p[0] != 0xff) errx(1, "%s: %s underrun %x\n", testname, map_name, p[0]); - if (p[map.size] != 0xff) + if (p[map.size-1] != 0xff) errx(1, "%s: %s overrun %x\n", testname, map_name, p[map.size - 1]); free(map.start); #else @@ -192,5 +204,9 @@ rk_test_mem_free(const char *map_name) free(testname); testname = NULL; +#ifdef HAVE_SIGACTION sigaction (SIGSEGV, &osa, NULL); +#else + signal (SIGSEGV, osigh); +#endif } diff --git a/lib/roken/test-mem.h b/lib/roken/test-mem.h index a00004afa..4d900b4a6 100644 --- a/lib/roken/test-mem.h +++ b/lib/roken/test-mem.h @@ -33,7 +33,7 @@ enum rk_test_mem_type { RK_TM_OVERRUN, RK_TM_UNDERRUN }; -void * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL rk_test_mem_alloc(enum rk_test_mem_type, const char *, void *, size_t); -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_test_mem_free(const char *); diff --git a/lib/roken/test-mini_inetd.c b/lib/roken/test-mini_inetd.c new file mode 100644 index 000000000..0e58fdbfd --- /dev/null +++ b/lib/roken/test-mini_inetd.c @@ -0,0 +1,369 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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 +#include +#include +#include +#include + +#define PORT 8013 +#define PORT_S "8013" + +char * prog = "Master"; +int is_client = 0; + +static int +get_address(int flags, struct addrinfo ** ret) +{ + struct addrinfo ai; + int rv; + + memset(&ai, 0, sizeof(ai)); + + ai.ai_flags = flags | AI_NUMERICHOST; + ai.ai_family = AF_INET; + ai.ai_socktype = SOCK_STREAM; + ai.ai_protocol = PF_UNSPEC; + + rv = getaddrinfo("127.0.0.1", PORT_S, &ai, ret); + if (rv) + warnx("getaddrinfo: %s", gai_strerror(rv)); + return rv; +} + +static int +get_connected_socket(rk_socket_t * s_ret) +{ + struct addrinfo * ai = NULL; + int rv = 0; + rk_socket_t s = rk_INVALID_SOCKET; + + rv = get_address(0, &ai); + if (rv) + return rv; + + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (rk_IS_BAD_SOCKET(s)) { + rv = 1; + goto done; + } + + rv = connect(s, ai->ai_addr, ai->ai_addrlen); + if (rk_IS_SOCKET_ERROR(rv)) + goto done; + + *s_ret = s; + s = INVALID_SOCKET; + rv = 0; + + done: + if (!rk_IS_BAD_SOCKET(s)) + rk_closesocket(s); + + if (ai) + freeaddrinfo(ai); + + return (rv) ? rk_SOCK_ERRNO : 0; +} + +const char * test_strings[] = { + "Hello", + "01234566789012345689012345678901234567890123456789", + "Another test", + "exit" +}; + +static int +test_simple_echo_client(void) +{ + rk_socket_t s = INVALID_SOCKET; + int rv; + char buf[81]; + int i; + + fprintf(stderr, "[%s] Getting connected socket...", getprogname()); + rv = get_connected_socket(&s); + if (rv) { + fprintf(stderr, "\n[%s] get_connected_socket() failed (%s)\n", + getprogname(), strerror(rk_SOCK_ERRNO)); + return 1; + } + + fprintf(stderr, "[%s] done\n", getprogname()); + + for (i=0; i < sizeof(test_strings)/sizeof(test_strings[0]); i++) { + rv = send(s, test_strings[i], strlen(test_strings[i]), 0); + if (rk_IS_SOCKET_ERROR(rv)) { + fprintf(stderr, "[%s] send() failure (%s)\n", + getprogname(), strerror(rk_SOCK_ERRNO)); + rk_closesocket(s); + return 1; + } + + rv = recv(s, buf, sizeof(buf), 0); + if (rk_IS_SOCKET_ERROR(rv)) { + fprintf (stderr, "[%s] recv() failure (%s)\n", + getprogname(), strerror(rk_SOCK_ERRNO)); + rk_closesocket(s); + return 1; + } + + if (rv == 0) { + fprintf (stderr, "[%s] No data received\n", prog); + rk_closesocket(s); + return 1; + } + + if (rv != strlen(test_strings[i])) { + fprintf (stderr, "[%s] Data length mismatch %d != %d\n", prog, rv, strlen(test_strings[i])); + rk_closesocket(s); + return 1; + } + } + + fprintf (stderr, "[%s] Done\n", prog); + rk_closesocket(s); + return 0; +} + +static int +test_simple_echo_socket(void) +{ + fprintf (stderr, "[%s] Process ID %d\n", prog, GetCurrentProcessId()); + fprintf (stderr, "[%s] Starting echo test with sockets\n", prog); + + if (is_client) { + return test_simple_echo_client(); + } else { + + rk_socket_t s = INVALID_SOCKET; + + fprintf (stderr, "[%s] Listening for connections...\n", prog); + mini_inetd(htons(PORT), &s); + if (rk_IS_BAD_SOCKET(s)) { + fprintf (stderr, "[%s] Connect failed (%s)\n", + getprogname(), strerror(rk_SOCK_ERRNO)); + } else { + fprintf (stderr, "[%s] Connected\n", prog); + } + + { + char buf[81]; + int rv, srv; + + while ((rv = recv(s, buf, sizeof(buf), 0)) != 0 && !rk_IS_SOCKET_ERROR(rv)) { + buf[rv] = 0; + fprintf(stderr, "[%s] Received [%s]\n", prog, buf); + + /* simple echo */ + srv = send(s, buf, rv, 0); + if (srv != rv) { + if (rk_IS_SOCKET_ERROR(srv)) + fprintf(stderr, "[%s] send() error [%s]\n", + getprogname(), strerror(rk_SOCK_ERRNO)); + else + fprintf(stderr, "[%s] send() size mismatch %d != %d", + getprogname(), srv, rv); + } + + if (!strcmp(buf, "exit")) { + fprintf(stderr, "[%s] Exiting...\n", prog); + shutdown(s, SD_SEND); + rk_closesocket(s); + return 0; + } + } + + fprintf(stderr, "[%s] recv() failed (%s)\n", + getprogname(), + strerror(rk_SOCK_ERRNO)); + } + + rk_closesocket(s); + } + + return 1; +} + +static int +test_simple_echo(void) +{ + fprintf (stderr, "[%s] Starting echo test\n", prog); + + if (is_client) { + + return test_simple_echo_client(); + + } else { + + fprintf (stderr, "[%s] Listening for connections...\n", prog); + mini_inetd(htons(PORT), NULL); + fprintf (stderr, "[%s] Connected\n", prog); + + { + char buf[81]; + while (gets(buf)) { + fprintf(stderr, "[%s] Received [%s]\n", prog, buf); + + if (!strcmp(buf, "exit")) + return 0; + + /* simple echo */ + puts(buf); + } + + fprintf(stderr, "[%s] gets() failed (%s)\n", prog, _strerror("gets")); + } + } + + return 1; +} + +static int +do_client(void) +{ + int rv = 0; + + SOCK_INIT; + + prog = "Client"; + is_client = 1; + + fprintf(stderr, "Starting client...\n"); + + rv = test_simple_echo_socket(); + + SOCK_EXIT; + + return rv; +} + +static int +do_server(void) +{ + int rv = 0; + + SOCK_INIT; + + prog = "Server"; + + fprintf(stderr, "Starting server...\n"); + + rv = test_simple_echo_socket(); + + SOCK_EXIT; + + return rv; +} + +static time_t +wait_callback(void *p) +{ + return (time_t)-1; +} + +static int +do_test(char * path) +{ + intptr_t p_server; + intptr_t p_client; + int client_rv; + int server_rv; + + p_server = _spawnl(_P_NOWAIT, path, path, "--server", NULL); + if (p_server <= 0) { + fprintf(stderr, "%s: %s", path, _strerror("Can't start server process")); + return 1; + } +#ifdef _WIN32 + /* On Windows, the _spawn*() functions return a process handle on + success. We need a process ID for use with + wait_for_process_timed(). */ + + p_server = GetProcessId((HANDLE) p_server); +#endif + fprintf(stderr, "Created server process ID %d\n", p_server); + + p_client = _spawnl(_P_NOWAIT, path, path, "--client", NULL); + if (p_client <= 0) { + fprintf(stderr, "%s: %s", path, _strerror("Can't start client process")); + fprintf(stderr, "Waiting for server process to terminate ..."); + wait_for_process_timed(p_server, wait_callback, NULL, 5); + fprintf(stderr, "DONE\n"); + return 1; + } +#ifdef _WIN32 + p_client = GetProcessId((HANDLE) p_client); +#endif + fprintf(stderr, "Created client process ID %d\n", p_client); + + fprintf(stderr, "Waiting for client process to terminate ..."); + client_rv = wait_for_process_timed(p_client, wait_callback, NULL, 5); + if (SE_IS_ERROR(client_rv)) { + fprintf(stderr, "\nwait_for_process_timed() failed for client. rv=%d\n", client_rv); + } else { + fprintf(stderr, "DONE\n"); + } + + fprintf(stderr, "Waiting for server process to terminate ..."); + server_rv = wait_for_process_timed(p_server, wait_callback, NULL, 5); + if (SE_IS_ERROR(server_rv)) { + fprintf(stderr, "\nwait_for_process_timed() failed for server. rv=%d\n", server_rv); + } else { + fprintf(stderr, "DONE\n"); + } + + if (client_rv == 0 && server_rv == 0) { + fprintf(stderr, "PASS\n"); + return 0; + } else { + fprintf(stderr, "FAIL: Client rv=%d, Server rv=%d\n", client_rv, server_rv); + return 1; + } +} + +int main(int argc, char ** argv) +{ + setprogname(argv[0]); + + if (argc == 2 && strcmp(argv[1], "--client") == 0) + return do_client(); + else if (argc == 2 && strcmp(argv[1], "--server") == 0) + return do_server(); + else if (argc == 1) + return do_test(argv[0]); + else { + printf ("%s: Test mini_inetd() function. Run with no arguments to start test\n", + argv[0]); + return 1; + } +} diff --git a/lib/roken/timeval.c b/lib/roken/timeval.c index 082bfc8b9..38b1f7ce9 100644 --- a/lib/roken/timeval.c +++ b/lib/roken/timeval.c @@ -43,7 +43,7 @@ * Make `t1' consistent. */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL timevalfix(struct timeval *t1) { if (t1->tv_usec < 0) { @@ -60,7 +60,7 @@ timevalfix(struct timeval *t1) * t1 += t2 */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL timevaladd(struct timeval *t1, const struct timeval *t2) { t1->tv_sec += t2->tv_sec; @@ -72,7 +72,7 @@ timevaladd(struct timeval *t1, const struct timeval *t2) * t1 -= t2 */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL timevalsub(struct timeval *t1, const struct timeval *t2) { t1->tv_sec -= t2->tv_sec; diff --git a/lib/roken/tm2time.c b/lib/roken/tm2time.c index d61ea0b01..ba69a0487 100644 --- a/lib/roken/tm2time.c +++ b/lib/roken/tm2time.c @@ -43,7 +43,7 @@ #endif #include "roken.h" -time_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL tm2time (struct tm tm, int local) { time_t t; diff --git a/lib/roken/unsetenv.c b/lib/roken/unsetenv.c index 5e4545726..55ba5e36d 100644 --- a/lib/roken/unsetenv.c +++ b/lib/roken/unsetenv.c @@ -45,7 +45,7 @@ extern char **environ; /* * unsetenv -- */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL unsetenv(const char *name) { int len; diff --git a/lib/roken/unvis.c b/lib/roken/unvis.c index d284f50b3..ed6ef9dfa 100644 --- a/lib/roken/unvis.c +++ b/lib/roken/unvis.c @@ -79,16 +79,16 @@ __warn_references(unvis, #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strunvis (char *, const char *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_unvis (char *, int, int *, int); /* * unvis - decode characters previously encoded by vis */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_unvis(char *cp, int c, int *astate, int flag) { @@ -250,7 +250,7 @@ rk_unvis(char *cp, int c, int *astate, int flag) * Dst is null terminated. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strunvis(char *dst, const char *src) { char c; diff --git a/lib/roken/verify.c b/lib/roken/verify.c index 396b3c581..fc8fc57b6 100644 --- a/lib/roken/verify.c +++ b/lib/roken/verify.c @@ -42,7 +42,7 @@ #endif #include "roken.h" -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL unix_verify_user(char *user, char *password) { struct passwd *pw; diff --git a/lib/roken/verr.c b/lib/roken/verr.c index eff0420b4..cd3cdf35e 100644 --- a/lib/roken/verr.c +++ b/lib/roken/verr.c @@ -36,7 +36,7 @@ #include "roken.h" #include -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL verr(int eval, const char *fmt, va_list ap) { rk_warnerr(1, fmt, ap); diff --git a/lib/roken/verrx.c b/lib/roken/verrx.c index 0833c5404..84645181c 100644 --- a/lib/roken/verrx.c +++ b/lib/roken/verrx.c @@ -36,7 +36,7 @@ #include "roken.h" #include -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL verrx(int eval, const char *fmt, va_list ap) { rk_warnerr(0, fmt, ap); diff --git a/lib/roken/vis.c b/lib/roken/vis.c index 155b148e8..19ff29d95 100644 --- a/lib/roken/vis.c +++ b/lib/roken/vis.c @@ -106,17 +106,17 @@ static char *do_svis(char *, int, int, int, const char *); #define BELL '\007' #endif -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL rk_vis (char *, int, int, int); -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL rk_svis (char *, int, int, int, const char *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strvis (char *, const char *, int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strsvis (char *, const char *, int, const char *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strvisx (char *, const char *, size_t, int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strsvisx (char *, const char *, size_t, int, const char *); @@ -249,7 +249,7 @@ do_svis(char *dst, int c, int flag, int nextc, const char *extra) * svis - visually encode characters, also encoding the characters * pointed to by `extra' */ -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL rk_svis(char *dst, int c, int flag, int nextc, const char *extra) { char *nextra = NULL; @@ -286,7 +286,8 @@ rk_svis(char *dst, int c, int flag, int nextc, const char *extra) * Strsvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ -int ROKEN_LIB_FUNCTION + +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strsvis(char *dst, const char *csrc, int flag, const char *extra) { int c; @@ -315,7 +316,7 @@ rk_strsvis(char *dst, const char *csrc, int flag, const char *extra) } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra) { unsigned char c; @@ -353,7 +354,7 @@ rk_strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra /* * vis - visually encode characters */ -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL rk_vis(char *dst, int c, int flag, int nextc) { char *extra = NULL; @@ -386,7 +387,7 @@ rk_vis(char *dst, int c, int flag, int nextc) * Strvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strvis(char *dst, const char *src, int flag) { char *extra = NULL; @@ -403,7 +404,7 @@ rk_strvis(char *dst, const char *src, int flag) } -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strvisx(char *dst, const char *src, size_t len, int flag) { char *extra = NULL; diff --git a/lib/roken/vis.hin b/lib/roken/vis.hin index a1481b789..25d662a98 100644 --- a/lib/roken/vis.hin +++ b/lib/roken/vis.hin @@ -36,9 +36,11 @@ #ifndef ROKEN_LIB_FUNCTION #ifdef _WIN32 -#define ROKEN_LIB_FUNCTION _stdcall +#define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL __cdecl #else #define ROKEN_LIB_FUNCTION +#define ROKEN_LIB_CALL #endif #endif @@ -84,24 +86,25 @@ ROKEN_CPP_START -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL rk_vis(char *, int, int, int); -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL rk_svis(char *, int, int, int, const char *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strvis(char *, const char *, int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strsvis(char *, const char *, int, const char *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strvisx(char *, const char *, size_t, int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strsvisx(char *, const char *, size_t, int, const char *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strunvis(char *, const char *); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_strunvisx(char *, const char *, int); -int ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_unvis(char *, int, int *, int); + ROKEN_CPP_END #ifndef HAVE_VIS diff --git a/lib/roken/vsyslog.c b/lib/roken/vsyslog.c index dbcec2ace..91541fb73 100644 --- a/lib/roken/vsyslog.c +++ b/lib/roken/vsyslog.c @@ -58,7 +58,7 @@ simple_vsyslog(int pri, const char *fmt, va_list ap) * do like syslog but with a `va_list' */ -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL vsyslog(int pri, const char *fmt, va_list ap) { char *fmt2; diff --git a/lib/roken/vwarn.c b/lib/roken/vwarn.c index 771729231..8f1706d4a 100644 --- a/lib/roken/vwarn.c +++ b/lib/roken/vwarn.c @@ -36,7 +36,7 @@ #include "roken.h" #include -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL vwarn(const char *fmt, va_list ap) { rk_warnerr(1, fmt, ap); diff --git a/lib/roken/vwarnx.c b/lib/roken/vwarnx.c index 5337987c0..6fb1d8c87 100644 --- a/lib/roken/vwarnx.c +++ b/lib/roken/vwarnx.c @@ -36,7 +36,7 @@ #include "roken.h" #include -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL vwarnx(const char *fmt, va_list ap) { rk_warnerr(0, fmt, ap); diff --git a/lib/roken/warnerr.c b/lib/roken/warnerr.c index 05c10e5ee..9e670239a 100644 --- a/lib/roken/warnerr.c +++ b/lib/roken/warnerr.c @@ -36,7 +36,7 @@ #include "roken.h" #include "err.h" -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL rk_warnerr(int doerrno, const char *fmt, va_list ap) { int sverrno = errno; diff --git a/lib/roken/warnx.c b/lib/roken/warnx.c index 1ffc64785..cf33939b2 100644 --- a/lib/roken/warnx.c +++ b/lib/roken/warnx.c @@ -35,7 +35,7 @@ #include "err.h" -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL warnx(const char *fmt, ...) { va_list ap; diff --git a/lib/roken/write_pid.c b/lib/roken/write_pid.c index e4af6f607..2a6ada586 100644 --- a/lib/roken/write_pid.c +++ b/lib/roken/write_pid.c @@ -33,14 +33,9 @@ #include -#include -#include -#include #include "roken.h" -#include "roken.h" - -char * ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL pid_file_write (const char *progname) { FILE *fp; @@ -59,7 +54,7 @@ pid_file_write (const char *progname) return ret; } -void ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL pid_file_delete (char **filename) { if (*filename != NULL) { @@ -79,7 +74,7 @@ pidfile_cleanup(void) pid_file_delete(&pidfile_path); } -void +ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL pidfile(const char *basename) { if(pidfile_path != NULL) diff --git a/lib/roken/writev.c b/lib/roken/writev.c index db44b2ef3..80945e95d 100644 --- a/lib/roken/writev.c +++ b/lib/roken/writev.c @@ -35,7 +35,7 @@ #include "roken.h" -ssize_t ROKEN_LIB_FUNCTION +ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL writev(int d, const struct iovec *iov, int iovcnt) { ssize_t ret; diff --git a/lib/roken/xfree.c b/lib/roken/xfree.c index 13366ce13..c7e30daf8 100644 --- a/lib/roken/xfree.c +++ b/lib/roken/xfree.c @@ -33,8 +33,6 @@ #include -#include - #include "roken.h" void ROKEN_LIB_FUNCTION