]> Pileus Git - ~andy/fetchmail/commitdiff
Graceful socket closing.
authorEric S. Raymond <esr@thyrsus.com>
Mon, 31 Jan 2000 22:16:23 +0000 (22:16 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Mon, 31 Jan 2000 22:16:23 +0000 (22:16 -0000)
svn path=/trunk/; revision=2726

NEWS
driver.c
fetchmail-FAQ.html
fetchmail.c
interface.c
sink.c
socket.c

diff --git a/NEWS b/NEWS
index 8dc6f564127f20be4dbf54d1f00c7b34193fd8d9..05f9204de54991071dc53502de35900b0bd3d492 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,11 @@
                                Things to do:
 
+Scrollbars on fetchmailconf help windows (Debian bug #51770). 
+
+Log bounced messages via syslog (Debian bug #50184).
+
+Notify user by mail when pop server nonexistent (Debian bug #47143).
+
 In the SSL support, we need to add server certificate validation (In
 other words, does the certificate match the system we are trying to
 contact?).  Also, add authentication of Certifying Authority (Is this
@@ -15,12 +21,18 @@ package will have two security verifications instead of one...
 
 (The `lines' figures total .c, .h, .l, and .y files under version control.)
 
+* Close down sockets using shutdown(2) and discarding read data until we
+  get a TCP FIN.  With any luck this will squash our socket leak.
+* Added Martijn Lievaart's sendmail hacks for multidrop to the contrib 
+  directory.
+* Debian buglist cleanup.
+
 fetchmail-5.2.5 (Mon Jan 31 02:02:48 EST 2000), 18445 lines:
 
 * Fixed bugs in BSMTP generation reported by Jaap Lutz.
 * Make fetchmailconf better at handling backslashes in usernames
   and passwords.
-* Jochen Hayeek's patch to handle spaces in UID usernames.
+* Jochen Hayek's patch to handle spaces in UID usernames.
 
 There are 279 people on fetchmail-friends and 497 on fetchmail-announce.
 
index 655bf4d3cb1c7459553b4dbac248a5cfe79f4f7d..f627d2cb60ba1119447db865bccece854e6c7c18 100644 (file)
--- a/driver.c
+++ b/driver.c
@@ -1537,7 +1537,7 @@ const int maxfetch;               /* maximum number of messages to fetch */
        /* try to clean up all streams */
        release_sink(ctl);
        if (ctl->smtp_socket != -1)
-           close(ctl->smtp_socket);
+           SockClose(ctl->smtp_socket);
        if (mailserver_socket != -1)
            SockClose(mailserver_socket);
     }
index 6107b82956c0b3381f8646882de379713670fc56..256406c38a53aeebf2aecc9ccde38231e06a0e08 100644 (file)
@@ -10,7 +10,7 @@
 <table width="100%" cellpadding=0><tr>
 <td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
 <td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 2000/01/31 04:07:30 $
+<td width="30%" align=right>$Date: 2000/01/31 22:16:21 $
 </table>
 <HR>
 <H1>Frequently Asked Questions About Fetchmail</H1>
@@ -1042,6 +1042,9 @@ reliably even when the Received header omits the envelope address
 (which will typically be the case when the message has multiple
 recipients). <P>  
 
+Martijn Lievart has a more detailed recipe in the contrib subdirectory
+of the fetchmail source distribution.
+
 <hr>
 <h2><a name="T2">T2. How can I use fetchmail with qmail?</a></h2>
 
@@ -2578,7 +2581,7 @@ terminate it.<p>
 <table width="100%" cellpadding=0><tr>
 <td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
 <td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 2000/01/31 04:07:30 $
+<td width="30%" align=right>$Date: 2000/01/31 22:16:21 $
 </table>
 
 <P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com">&lt;esr@snark.thyrsus.com&gt;</A></ADDRESS>
index bbd6bfab949107aa24406de4b4b523666212945c..c6b2e72f79663cf366d1f4f24fe056101fcf3e60 100644 (file)
@@ -1322,7 +1322,7 @@ static void terminate_poll(int sig)
            if (ctl->smtp_socket != -1)
            {
                SMTP_quit(ctl->smtp_socket);
-               close(ctl->smtp_socket);
+               SockClose(ctl->smtp_socket);
                ctl->smtp_socket = -1;
            }
     }
index 6ddbbbbf798fca18adb33fa6de64ca5e70e9711f..7a485e78e1e74fce3626d8d107035935add4892a 100644 (file)
@@ -174,7 +174,7 @@ static int get_ifinfo(const char *ifname, ifinfo_t *ifinfo)
                *sp = '/';
        }
        if (socket_fd >= 0)
-           close(socket_fd);   /* not checking should be safe, mode was "r" */
+           SockClose(close(socket_fd));
        if (stats_file)
            fclose(stats_file); /* not checking should be safe, mode was "r" */
        return(result);
diff --git a/sink.c b/sink.c
index 3a001f7a8afe06c8639c729111669f898b01133e..d6e25d8946e6f5a64ff9797b8266fb29be828138 100644 (file)
--- a/sink.c
+++ b/sink.c
@@ -51,7 +51,7 @@ static int smtp_open(struct query *ctl)
     /* maybe it's time to close the socket in order to force delivery */
     if (NUM_NONZERO(ctl->batchlimit) && (ctl->smtp_socket != -1) && ++batchcount == ctl->batchlimit)
     {
-       close(ctl->smtp_socket);
+       SockClose(ctl->smtp_socket);
        ctl->smtp_socket = -1;
        batchcount = 0;
     }
index 4dde204888f60477f36ae4f9fb82f1dd610e8a2b..f8e40c342920248bc087654fca0ecadb1841daad 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -163,7 +163,7 @@ int SockOpen(const char *host, const char *service, const char *options,
     }
     if (connect(i, (struct sockaddr *) ai->ai_addr, ai->ai_addrlen) < 0) {
        freeaddrinfo(ai);
-       close(i);
+       SockClose(i);
        return -1;
     }
 #endif
@@ -226,7 +226,7 @@ int SockOpen(const char *host, int clientPort, const char *options,
         if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
         {
             int olderr = errno;
-            close(sock);
+            SockClose(sock);
             h_errno = 0;
             errno = olderr;
             return -1;
@@ -272,14 +272,14 @@ int SockOpen(const char *host, int clientPort, const char *options,
            memcpy(&ad.sin_addr, *pptr, sizeof(struct in_addr));
            if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) == 0)
                break; /* success */
-           close(sock);
+           SockClose(sock);
            memset(&ad, 0, sizeof(ad));
            ad.sin_family = AF_INET;
        }
        if(*pptr == NULL)
        {
            int olderr = errno;
-           close(sock);
+           SockClose(sock);
            h_errno = 0;
            errno = olderr;
            return -1;
@@ -651,8 +651,9 @@ int SSLOpen(int sock, char *mycert, char *mykey, char *servercname )
 #endif
 
 int SockClose(int sock)
-/* close a socket (someday we may do other cleanup here) */
+/* close a socket gracefully */
 {
+    char ch;
 #ifdef SSL_ENABLE
     SSL *ssl;
 
@@ -662,15 +663,35 @@ int SockClose(int sock)
         _ssl_context[sock] = NULL;
     }
 #endif
-    return(close(sock));
+
+    /* Half-close the connection first so the other end gets notified.
+     *
+     * This stops sends but allows receives (effectively, it sends a
+     * TCP <FIN>).  We ignore the return from this function because
+     * some older BSD-based implementations fail shutdown() if a TCP
+     * reset has been recieved.  In any case, if it fails it means the
+     * connection is already closed anyway, so it doesn't matter.
+     */
+    shutdown(sock, 1);
+
+    /* If there is any data still waiting in the queue, discard it.
+     * Call recv() until either it returns 0 (meaning we received a FIN)
+     * or any error occurs.  This makes sure all data sent by the other
+     * side is acknowledged at the TCP level.
+     */
+    if (recv(sock, &ch, 1, MSG_PEEK) > 0)
+       while (recv(sock, &ch, 1, MSG_NOSIGNAL) > 0)
+           continue;
+
+    /* if there's an error closing at this point, not much we can do */
+    return(close(sock));       /* this is guarded */
 }
 
 #ifdef MAIN
 /*
  * Use the chargen service to test input buffering directly.
  * You may have to uncomment the `chargen' service description in your
- * inetd.conf (and then SIGHUP inetd) for this to work. 
- */
+ * inetd.conf (and then SIGHUP inetd) for this to work.  */
 main()
 {
     int                sock = SockOpen("localhost", 19, NULL);