static int cleanupSockClose (int fd)
/* close sockets in maximum CLEANUP_TIMEOUT seconds during cleanup */
{
- (void)SockTimeout(fd, CLEANUP_TIMEOUT); /* ignore errors */
- return SockClose(fd);
+ int scerror;
+ SIGHANDLERTYPE alrmsave;
+ alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
+ set_timeout(CLEANUP_TIMEOUT);
+ scerror = SockClose(fd);
+ set_timeout(0);
+ set_signal_handler(SIGALRM, alrmsave);
+ return (scerror);
}
#ifdef KERBEROS_V5
}
/* restore normal timeout value */
+ set_timeout(0);
mytimeout = saved_timeout;
stage = STAGE_GETRANGE;
oldphase = phase;
phase = LISTENER_WAIT;
+ set_timeout(ctl->server.timeout);
for (idp = ctl->smtphunt; idp; idp = idp->next)
{
char *cp;
const char *portnum = SMTP_PORT;
- set_timeout(ctl->server.timeout);
ctl->smtphost = idp->id; /* remember last host tried. */
if (ctl->smtphost[0]=='/')
{
* so it's safest not to assume the socket will still be good.
*/
smtp_close(ctl, 0);
- set_timeout(ctl->server.timeout);
/* if opening for ESMTP failed, try SMTP */
if (ctl->smtphost[0]=='/')
{
struct opt *hp;
char auth_response[511];
+ SIGHANDLERTYPE alrmsave;
const int tmout = (mytimeout >= TIMEOUT_HELO ? mytimeout : TIMEOUT_HELO);
- if (SockTimeout(sock, tmout) != 0)
- return SM_UNRECOVERABLE;
-
SockPrintf(sock,"%cHLO %s\r\n", (smtp_mode == 'S') ? 'E' : smtp_mode, host);
if (outlevel >= O_MONITOR)
report(stdout, "%cMTP> %cHLO %s\n",
smtp_mode, (smtp_mode == 'S') ? 'E' : smtp_mode, host);
+ alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
+ set_timeout(tmout);
+
*opt = 0;
while ((SockRead(sock, smtp_response, sizeof(smtp_response)-1)) != -1)
{
size_t n;
set_timeout(0);
+ (void)set_signal_handler(SIGALRM, alrmsave);
n = strlen(smtp_response);
if (n > 0 && smtp_response[n-1] == '\n')
}
else if (smtp_response[3] != '-')
return SM_ERROR;
+
+ alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
+ set_timeout(tmout);
}
return SM_UNRECOVERABLE;
}
* smtp_response, without trailing [CR]LF, but with normalized CRLF
* between multiple lines of multi-line replies */
{
+ SIGHANDLERTYPE alrmsave;
char reply[MSGBUFSIZE], *i;
- int tmo = mytimeout >= mintimeout ? mytimeout : mintimeout;
- smtp_response[0] = '\0';
+ /* set an alarm for smtp ok */
+ alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
+ set_timeout(mytimeout >= mintimeout ? mytimeout : mintimeout);
- if (SockTimeout(sock, tmo))
- return SM_UNRECOVERABLE;
+ smtp_response[0] = '\0';
while ((SockRead(sock, reply, sizeof(reply)-1)) != -1)
{
size_t n;
+ /* restore alarm */
+ set_timeout(0);
+ set_signal_handler(SIGALRM, alrmsave);
+
n = strlen(reply);
if (n > 0 && reply[n-1] == '\n')
reply[--n] = '\0';
return SM_ERROR;
strlcat(smtp_response, "\r\n", sizeof(smtp_response));
+
+ /* set an alarm for smtp ok */
+ set_signal_handler(SIGALRM, null_signal_handler);
+ set_timeout(mytimeout);
}
+ /* restore alarm */
+ set_timeout(0);
+ set_signal_handler(SIGALRM, alrmsave);
+
if (outlevel >= O_MONITOR)
report(stderr, GT_("smtp listener protocol error\n"));
return SM_UNRECOVERABLE;
report(stderr, GT_("fetchmail: socketpair failed\n"));
return -1;
}
-
- if (SockTimeout(fds[0], mytimeout)) return -1;
- if (SockTimeout(fds[1], mytimeout)) return -1;
-
switch (fork()) {
case -1:
/* error */
return fds[1];
}
-static int setsocktimeout(int sock, int which, int timeout) {
- struct timeval tv;
- int rc;
-
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- rc = setsockopt(sock, SOL_SOCKET, which, &tv, sizeof(tv));
- if (rc) {
- report(stderr, GT_("setsockopt(%d, SOL_SOCKET) failed: %s"), sock, strerror(errno));
- }
- return rc;
-}
-
-/** Configure socket options such as send/receive timeout at the socket
- * level, to avoid network-induced stalls. \return 0 for success, 1 for
- * error.
- */
-int SockTimeout(int sock, int timeout)
-{
- int err = 0;
-
- if (setsocktimeout(sock, SO_RCVTIMEO, timeout)) err = 1;
- if (setsocktimeout(sock, SO_SNDTIMEO, timeout)) err = 1;
- return err;
-}
-
/** Set socket to SO_KEEPALIVE. \return 0 for success. */
int SockKeepalive(int sock) {
int keepalive = 1;
/** Create a new client socket; returns -1 on error */
int SockOpen(const char *host, const char *service, const char *plugin, struct addrinfo **);
-/** Sets the send/receive timeouts for socket \a sock to \a timeout
- * seconds. \return zero on success. */
-int SockTimeout(int sock, int timeout);
-
/**
Get a string terminated by an '\n' (matches interface of fgets).
Pass it a valid socket, a buffer for the string, and
do {
char *sp, *tp;
- SockTimeout(sock, mytimeout);
- n = SockRead(sock, buf, sizeof(buf) - 1);
-
- if (n == -1) {
+ set_timeout(mytimeout);
+ if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1) {
+ set_timeout(0);
free(line);
return(PS_SOCKET);
}
+ set_timeout(0);
/*
* Smash out any NULs, they could wreak havoc later on.
}
/* check for RFC822 continuations */
- SockTimeout(sock, mytimeout);
+ set_timeout(mytimeout);
ch = SockPeek(sock);
+ set_timeout(0);
} while
(ch == ' ' || ch == '\t'); /* continuation to next line? */
*/
while (protocol->delimited || len > 0)
{
- SockTimeout(sock, mytimeout);
+ set_timeout(mytimeout);
/* XXX FIXME: for undelimited protocols that ship the size, such
* as IMAP, we might want to use the count of remaining characters
* instead of the buffer size -- not for fetchmail 6.3.X though */
- linelen = SockRead(sock, inbufp, sizeof(buf)-4-(inbufp-buf));
- if (linelen == -1)
+ if ((linelen = SockRead(sock, inbufp, sizeof(buf)-4-(inbufp-buf)))==-1)
{
+ set_timeout(0);
release_sink(ctl);
return(PS_SOCKET);
}
+ set_timeout(0);
/* write the message size dots */
if (linelen > 0)
{
size_t n;
int oldphase = phase; /* we don't have to be re-entrant */
- int retval;
phase = SERVER_WAIT;
- SockTimeout(sock, mytimeout);
- retval = SockRead(sock, buf, size);
- phase = oldphase;
-
- if (retval == -1)
+ set_timeout(mytimeout);
+ if (SockRead(sock, buf, size) == -1)
{
+ set_timeout(0);
+ phase = oldphase;
if(is_idletimeout())
{
resetidletimeout();
buf[--n] = '\0';
if (outlevel >= O_MONITOR)
report(stdout, "%s< %s\n", protocol->name, buf);
+ phase = oldphase;
return(PS_SUCCESS);
}
}