Hi!

I've come up with some patches regarding the timeout setting on Windows
(which doesn't work right now).

The first patch correctly handles timeout on send()/recv() operations.

--- msmtp-1.6.6/src/net.c       2016-11-11 15:12:04.000000000 +0700
+++ msmtp/src/net.c     2018-06-09 18:03:35.407374256 +0700
@@ -179,7 +179,7 @@
     {
 #ifdef W32_NATIVE
         int e = WSAGetLastError();
-        if (e == WSAEWOULDBLOCK)
+        if (e == WSAETIMEDOUT)
         {
             *errstr = xasprintf(_("network read error: %s"),
                     _("the operation timed out"));
@@ -226,7 +226,7 @@
     {
 #ifdef W32_NATIVE
         int e = WSAGetLastError();
-        if (e == WSAEWOULDBLOCK)
+        if (e == WSAETIMEDOUT)
         {
             *errstr = xasprintf(_("network write error: %s"),
                     _("the operation timed out"))

The second patch implements timeout on connect() for Windows. I also removed
the unnecessary rset variable (it doesn't matter for select() on connect()).

--- msmtp-1.6.6/src/net.c       2016-11-11 15:12:04.000000000 +0700
+++ msmtp/src/net.c     2018-06-09 18:23:11.721796148 +0700
@@ -319,16 +319,17 @@
         int timeout)
 {
 #ifdef W32_NATIVE
-    /* TODO: I don't know how to do this on Win32. Please send a patch. */
-    return connect(fd, serv_addr, addrlen);
-#else /* UNIX or DJGPP */
-
+    u_long flags;
+    DWORD err;
+    int optlen;
+    fd_set eset;
+#else
     int flags;
-    struct timeval tv;
-    fd_set rset;
-    fd_set wset;
     int err;
     socklen_t optlen;
+#endif
+    struct timeval tv;
+    fd_set wset;

     if (timeout <= 0)
     {
@@ -337,8 +338,13 @@
     else
     {
         /* make socket non-blocking */
+#ifdef W32_NATIVE
+        flags = 1;
+        if (ioctlsocket(fd, FIONBIO, &flags) == SOCKET_ERROR)
+#else
         flags = fcntl(fd, F_GETFL, 0);
         if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
+#endif
         {
             return -1;
         }
@@ -346,51 +352,75 @@
         /* start connect */
         if (connect(fd, serv_addr, addrlen) < 0)
         {
+#ifdef W32_NATIVE
+            if (WSAGetLastError() != WSAEWOULDBLOCK)
+#else
             if (errno != EINPROGRESS)
+#endif
             {
                 return -1;
             }

             tv.tv_sec = timeout;
             tv.tv_usec = 0;
-            FD_ZERO(&rset);
             FD_ZERO(&wset);
-            FD_SET(fd, &rset);
             FD_SET(fd, &wset);
+#ifdef W32_NATIVE
+            FD_ZERO(&eset);
+            FD_SET(fd, &eset);
+#endif

             /* wait for connect() to finish */
-            if ((err = select(fd + 1, &rset, &wset, NULL, &tv)) <= 0)
+#ifdef W32_NATIVE
+            /* In case of an error on connect(), eset will be affected instead
+             * of wset (on Windows only). */
+            if ((err = select(fd + 1, NULL, &wset, &eset, &tv)) <= 0)
+#else
+            if ((err = select(fd + 1, NULL, &wset, NULL, &tv)) <= 0)
+#endif
             {
                 /* errno is already set if err < 0 */
                 if (err == 0)
                 {
+#ifdef W32_NATIVE
+                    WSASetLastError(WSAETIMEDOUT);
+#else
                     errno = ETIMEDOUT;
+#endif
                 }
                 return -1;
             }

             /* test for success, set errno */
-            optlen = sizeof(int);
+            optlen = sizeof(err);
             if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &optlen) < 0)
             {
                 return -1;
             }
             if (err != 0)
             {
+#ifdef W32_NATIVE
+                WSASetLastError(err);
+#else
                 errno = err;
+#endif
                 return -1;
             }
         }

         /* restore blocking mode */
+#ifdef W32_NATIVE
+        flags = 0;
+        if (ioctlsocket(fd, FIONBIO, &flags) == SOCKET_ERROR)
+#else
         if (fcntl(fd, F_SETFL, flags) == -1)
+#endif
         {
             return -1;
         }

         return 0;
     }
-#endif /* UNIX */
 }

And the third patch just closes Windows sockets properly.

--- msmtp-1.6.6/src/net.c   2016-11-11 15:12:04.000000000 +0700
+++ msmtp/src/net.c     2018-06-09 18:38:52.920735844 +0700
@@ -682,7 +712,7 @@
                 failure_errno = errno;
             }
 #endif
-            close(fd);
+            net_close_socket(fd);
             fd = -1;
             continue;
         }

I've tested the patches mildly on both Windows 7 and Wine.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
msmtp-users mailing list
msmtp-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/msmtp-users

Reply via email to