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
(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.
/* 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);
}
<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>
(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>
<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"><esr@snark.thyrsus.com></A></ADDRESS>
if (ctl->smtp_socket != -1)
{
SMTP_quit(ctl->smtp_socket);
- close(ctl->smtp_socket);
+ SockClose(ctl->smtp_socket);
ctl->smtp_socket = -1;
}
}
*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);
/* 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;
}
}
if (connect(i, (struct sockaddr *) ai->ai_addr, ai->ai_addrlen) < 0) {
freeaddrinfo(ai);
- close(i);
+ SockClose(i);
return -1;
}
#endif
if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
{
int olderr = errno;
- close(sock);
+ SockClose(sock);
h_errno = 0;
errno = olderr;
return -1;
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;
#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;
_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);