Hi! Today I updated gnulib for msmtp and subsequently added the socket-related modules for W32 portability. This allowed me to remove 430 lines of workarounds in the networking code, most of them W32-specific. Thanks a lot! However, I had to introduce one new workaround: if a socket is given to some external library (e.g. GnuTLS or OpenSSL), I have to convert it using FD_TO_SOCKET() first. It took me some time to figure this out ;)
A small patch to the setsockopt module allows me to set socket timeouts (SO_RCVTIMEO and SO_SNDTIMEO) portably. On POSIX systems, a struct timeval is used to pass the time information to setsockopt. W32 uses an integer that stores the time in milliseconds. The patch below converts the struct timeval to milliseconds in the W32-specific setsockopt replacement function. Martin diff -ur gnulib/lib/setsockopt.c gnulib-local/lib/setsockopt.c --- gnulib/lib/setsockopt.c 2008-12-24 17:08:35.000000000 +0100 +++ gnulib-local/lib/setsockopt.c 2008-12-25 13:39:32.000000000 +0100 @@ -23,6 +23,9 @@ /* Get winsock2.h. */ #include <sys/socket.h> +/* Get struct timeval */ +#include <sys/time.h> + /* Get set_winsock_errno, FD_TO_SOCKET etc. */ #include "w32sock.h" @@ -31,8 +34,20 @@ int rpl_setsockopt (int fd, int level, int optname, const void *optval, int optlen) { + int r; SOCKET sock = FD_TO_SOCKET (fd); - int r = setsockopt (sock, level, optname, optval, optlen); + + if (level == SOL_SOCKET && (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) + { + const struct timeval *tv = optval; + int milliseconds = tv->tv_sec * 1000 + tv->tv_usec / 1000; + r = setsockopt (sock, level, optname, &milliseconds, sizeof(int)); + } + else + { + r = setsockopt (sock, level, optname, optval, optlen); + } + if (r < 0) set_winsock_errno (); diff -ur gnulib/modules/setsockopt gnulib-local/modules/setsockopt --- gnulib/modules/setsockopt 2008-12-24 17:08:35.000000000 +0100 +++ gnulib-local/modules/setsockopt 2008-12-25 09:11:51.000000000 +0100 @@ -7,6 +7,7 @@ Depends-on: sys_socket +sys_time errno configure.ac: