Make sure the 1.1 branch compiles in a MinGW environment.
authorGuus Sliepen <guus@sliepen.eu.org>
Thu, 5 Nov 2009 22:29:28 +0000 (23:29 +0100)
committerGuus Sliepen <guus@sliepen.eu.org>
Thu, 5 Nov 2009 22:29:28 +0000 (23:29 +0100)
UNIX domain sockets, of course, don't exist on Windows. For now, when compiling
tinc in a MinGW environment, try to use a TCP socket bound to localhost as an
alternative.

configure.in
have.h
lib/utils.h
src/control.c
src/net.c
src/tincctl.c
src/tincd.c

index 1db53d1cd38476a7712f6923c14106e00cdfbc2b..573a30eeb41a482ae59ab6f4caa4f560ce5fa8d0 100644 (file)
@@ -98,7 +98,7 @@ dnl Checks for header files.
 dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies.
 
 AC_HEADER_STDC
-AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h])
+AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/un.h sys/wait.h netdb.h arpa/inet.h])
 AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h],
   [], [], [#include "have.h"]
 )
diff --git a/have.h b/have.h
index 49af86165364df34d0603d009007371264421db2..682fd2b7c21f6c75bab7824f65ba8455c7915591 100644 (file)
--- a/have.h
+++ b/have.h
 #include <sys/uio.h>
 #endif
 
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
 /* SunOS really wants sys/socket.h BEFORE net/if.h,
    and FreeBSD wants these lines below the rest. */
 
index 4456616d8669daa35a4704fbe32f9b6e8248e2c8..fddb8a67a3a279c3a35d3247811c5b9abc063be5 100644 (file)
@@ -32,12 +32,14 @@ extern const char *winerror(int);
 #define sockwouldblock(x) ((x) == WSAEWOULDBLOCK || (x) == WSAEINTR)
 #define sockmsgsize(x) ((x) == WSAEMSGSIZE)
 #define sockinprogress(x) ((x) == WSAEINPROGRESS || (x) == WSAEWOULDBLOCK)
+#define sockinuse(x) ((x) == WSAEADDRINUSE)
 #else
 #define sockerrno errno
 #define sockstrerror(x) strerror(x)
 #define sockwouldblock(x) ((x) == EWOULDBLOCK || (x) == EINTR)
 #define sockmsgsize(x) ((x) == EMSGSIZE)
 #define sockinprogress(x) ((x) == EINPROGRESS)
+#define sockinuse(x) ((x) == EADDRINUSE)
 #endif
 
 extern unsigned int bitfield_to_int(void *bitfield, size_t size);
index 4775bdd4c6c114e0014fe3131cc6b6c765c049bb..8493f254fe3e7a5287083432412f92a355d54936 100644 (file)
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include <sys/un.h>
-
 #include "system.h"
 #include "conf.h"
 #include "control.h"
 #include "control_common.h"
 #include "graph.h"
 #include "logger.h"
+#include "utils.h"
 #include "xalloc.h"
 
 static int control_socket = -1;
@@ -211,6 +210,16 @@ static int control_compare(const struct event *a, const struct event *b) {
 
 bool init_control() {
        int result;
+
+#ifdef HAVE_MINGW
+       struct sockaddr_in addr;
+       memset(&addr, 0, sizeof addr);
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = htonl(0x7f000001);
+       addr.sin_port = htons(55555);
+
+       control_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+#else
        struct sockaddr_un addr;
        char *lastslash;
 
@@ -261,16 +270,20 @@ bool init_control() {
                logger(LOG_ERR, "Control socket directory ownership/permissions insecure.");
                goto bail;
        }
+#endif
 
        result = bind(control_socket, (struct sockaddr *)&addr, sizeof addr);
 
-       if(result < 0 && errno == EADDRINUSE) {
+       if(result < 0 && sockinuse(sockerrno)) {
                result = connect(control_socket, (struct sockaddr *)&addr, sizeof addr);
+#ifndef HAVE_MINGW
                if(result < 0) {
                        logger(LOG_WARNING, "Removing old control socket.");
                        unlink(controlsocketname);
                        result = bind(control_socket, (struct sockaddr *)&addr, sizeof addr);
-               } else {
+               } else
+#endif
+               {
                        if(netname)
                                logger(LOG_ERR, "Another tincd is already running for net `%s'.", netname);
                        else
@@ -297,7 +310,7 @@ bool init_control() {
 
 bail:
        if(control_socket != -1) {
-               close(control_socket);
+               closesocket(control_socket);
                control_socket = -1;
        }
        return false;
@@ -305,6 +318,6 @@ bail:
 
 void exit_control() {
        event_del(&control_event);
-       close(control_socket);
+       closesocket(control_socket);
        unlink(controlsocketname);
 }
index 9445b68a046d6f0489eba826c9c0647cbc003514..31cb3df5b09df049d9256ae7d6141c936b636bc0 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -307,12 +307,19 @@ int main_loop(void) {
 
        timeout_set(&timeout_event, timeout_handler, &timeout_event);
        event_add(&timeout_event, &(struct timeval){pingtimeout, 0});
+
+#ifdef SIGHUP
        signal_set(&sighup_event, SIGHUP, sighup_handler, NULL);
        signal_add(&sighup_event, NULL);
+#endif
+#ifdef SIGTERM
        signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL);
        signal_add(&sigterm_event, NULL);
+#endif
+#ifdef SIGQUIT
        signal_set(&sigquit_event, SIGQUIT, sigterm_handler, NULL);
        signal_add(&sigquit_event, NULL);
+#endif
 
        if(event_loop(0) < 0) {
                logger(LOG_ERR, "Error while waiting for input: %s", strerror(errno));
index f98547ba70aa9e248887be1c397262c2629b387f..7d82dc442037329ac9bdb1080e897da48196e541 100644 (file)
 
 #include "system.h"
 
-#include <sys/un.h>
 #include <getopt.h>
 
 #include "xalloc.h"
 #include "protocol.h"
 #include "control_common.h"
 #include "rsagen.h"
+#include "utils.h"
 
 /* The name this program was run with. */
 char *program_name = NULL;
@@ -47,6 +47,10 @@ static char *controlsocketname = NULL;                       /* pid file location */
 char *netname = NULL;
 char *confbase = NULL;
 
+#ifdef HAVE_MINGW
+static struct WSAData wsa_state;
+#endif
+
 static struct option const long_options[] = {
        {"config", required_argument, NULL, 'c'},
        {"net", required_argument, NULL, 'n'},
@@ -261,8 +265,6 @@ static void make_names(void) {
 #ifdef HAVE_MINGW
        if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) {
                if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) {
-                       if(!logfilename)
-                               xasprintf(&logfilename, "%s/log/%s.log", identname);
                        if(!confbase) {
                                if(netname)
                                        xasprintf(&confbase, "%s/%s", installdir, netname);
@@ -300,7 +302,11 @@ static int fullread(int fd, void *data, size_t datalen) {
                else if(rv == -1)
                        return rv;
                else if(rv == 0) {
+#ifdef HAVE_MINGW
+                       errno = 0;
+#else
                        errno = ENODATA;
+#endif
                        return -1;
                }
                len += rv;
@@ -317,23 +323,29 @@ static int send_ctl_request(int fd, enum request_type type,
                                                   size_t *indatalen_p) {
        tinc_ctl_request_t req;
        int rv;
+       void *indata;
+
+       memset(&req, 0, sizeof req);
+       req.length = sizeof req + outdatalen;
+       req.type = type;
+       req.res_errno = 0;
+
+#ifdef HAVE_MINGW
+       if(send(fd, (void *)&req, sizeof req, 0) != sizeof req || send(fd, outdata, outdatalen, 0) != outdatalen)
+               return -1;
+#else
        struct iovec vector[2] = {
                {&req, sizeof req},
                {(void*) outdata, outdatalen}
        };
-       void *indata;
 
        if(res_errno_p == NULL)
                return -1;
 
-       memset(&req, 0, sizeof req);
-       req.length = sizeof req + outdatalen;
-       req.type = type;
-       req.res_errno = 0;
-
        while((rv = writev(fd, vector, 2)) == -1 && errno == EINTR) ;
        if(rv != req.length)
                return -1;
+#endif
 
        if(fullread(fd, &req, sizeof req) == -1)
                return -1;
@@ -394,7 +406,6 @@ static int send_ctl_request_cooked(int fd, enum request_type type, void const *o
 }
 
 int main(int argc, char *argv[], char *envp[]) {
-       struct sockaddr_un addr;
        tinc_ctl_greeting_t greeting;
        int fd;
        int result;
@@ -449,6 +460,33 @@ int main(int argc, char *argv[], char *envp[]) {
         * ancestors are writable only by trusted users, which we don't verify.
         */
 
+#ifdef HAVE_MINGW
+       if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
+               fprintf(stderr, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
+               return 1;
+       }
+
+       struct sockaddr_in addr;
+       memset(&addr, 0, sizeof addr);
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = htonl(0x7f000001);
+       addr.sin_port = htons(55555);
+
+       fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+       if(fd < 0) {
+               fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno));
+               return 1;
+       }
+
+       fprintf(stderr, "Got socket %d\n", fd);
+
+       unsigned long arg = 0;
+
+       if(ioctlsocket(fd, FIONBIO, &arg) != 0) {
+               fprintf(stderr, "ioctlsocket failed: %s", sockstrerror(sockerrno));
+       }
+#else
+       struct sockaddr_un addr;
        struct stat statbuf;
        char *lastslash = strrchr(controlsocketname, '/');
        if(lastslash != NULL) {
@@ -483,15 +521,19 @@ int main(int argc, char *argv[], char *envp[]) {
        memset(&addr, 0, sizeof addr);
        addr.sun_family = AF_UNIX;
        strncpy(addr.sun_path, controlsocketname, sizeof addr.sun_path - 1);
+#endif
 
        if(connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0) {
-               fprintf(stderr, "Cannot connect to %s: %s\n", controlsocketname, strerror(errno));
+                       
+               fprintf(stderr, "Cannot connect to %s: %s\n", controlsocketname, sockstrerror(sockerrno));
                return 1;
        }
 
+       fprintf(stderr, "Connected!\n");
+
        if(fullread(fd, &greeting, sizeof greeting) == -1) {
                fprintf(stderr, "Cannot read greeting from control socket: %s\n",
-                               strerror(errno));
+                               sockstrerror(sockerrno));
                return 1;
        }
 
index 1a9bad0d55cea46abe899685bd89ecfa80d1b2d6..1761dc212ad46c173d881a42c1d9f759e8d289f9 100644 (file)
@@ -345,6 +345,13 @@ int main(int argc, char **argv) {
                return 0;
        }
 
+#ifdef HAVE_MINGW
+       if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
+               logger(LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
+               return 1;
+       }
+#endif
+
        openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR);
 
        if(!event_init()) {
@@ -373,11 +380,6 @@ int main(int argc, char **argv) {
        }
 
 #ifdef HAVE_MINGW
-       if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
-               logger(LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
-               return 1;
-       }
-
        if(!do_detach || !init_service())
                return main2(argc, argv);
        else