From a1b7d9e895e73401161427363611b0160f51225f Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Sat, 6 Nov 2010 13:51:41 +0100 Subject: [PATCH] have flexible timouts while reading lines in our client mode connections since some mailserver take a little longer to finish reading mails we need to wait after we send our '.\r\n'; its 90 seconds now, all other parts will wait 5s, quit will wait 1 second. --- citadel/clientsocket.c | 29 +++++++++++++++++++++-------- citadel/clientsocket.h | 4 ++-- citadel/modules/smtp/serv_smtp.c | 20 +++++++++++--------- citadel/msgbase.c | 2 +- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/citadel/clientsocket.c b/citadel/clientsocket.c index 159ec7212..d8a3e6b01 100644 --- a/citadel/clientsocket.c +++ b/citadel/clientsocket.c @@ -167,7 +167,7 @@ int sock_read_to(int *sock, char *buf, int bytes, int timeout, } -int CtdlSockGetLine(int *sock, StrBuf * Target) +int CtdlSockGetLine(int *sock, StrBuf * Target, int nSec) { CitContext *CCC = MyContext(); const char *Error; @@ -177,7 +177,7 @@ int CtdlSockGetLine(int *sock, StrBuf * Target) rc = StrBufTCP_read_buffered_line_fast(Target, CCC->sReadBuf, &CCC->sPos, - sock, 5, 1, &Error); + sock, nSec, 1, &Error); if ((rc < 0) && (Error != NULL)) CtdlLogPrintf(CTDL_CRIT, "%s failed: %s\n", __FUNCTION__, Error); @@ -197,7 +197,7 @@ int sock_getln(int *sock, char *buf, int bufsize) const char *pCh; FlushStrBuf(CCC->sMigrateBuf); - retval = CtdlSockGetLine(sock, CCC->sMigrateBuf); + retval = CtdlSockGetLine(sock, CCC->sMigrateBuf, 5); i = StrLength(CCC->sMigrateBuf); pCh = ChrPtr(CCC->sMigrateBuf); @@ -273,6 +273,19 @@ int sock_write(int *sock, const char *buf, int nbytes) return (-1); } bytes_written = bytes_written + retval; + if (IsNonBlock && (bytes_written == nbytes)){ + tv.tv_sec = selectresolution; + tv.tv_usec = 0; + + FD_ZERO(&rfds); + FD_SET(*sock, &rfds); + if (select(*sock + 1, NULL, &rfds, NULL, &tv) == -1) { +/// *Error = strerror(errno); + close (*sock); + *sock = -1; + return -1; + } + } } return (bytes_written); } @@ -284,14 +297,14 @@ int sock_write(int *sock, const char *buf, int nbytes) * (This is implemented in terms of client_read() and could be * justifiably moved out of sysdep.c) */ -int sock_getln_err(int *sock, char *buf, int bufsize, int *rc) +int sock_getln_err(int *sock, char *buf, int bufsize, int *rc, int nSec) { int i, retval; CitContext *CCC = MyContext(); const char *pCh; FlushStrBuf(CCC->sMigrateBuf); - *rc = retval = CtdlSockGetLine(sock, CCC->sMigrateBuf); + *rc = retval = CtdlSockGetLine(sock, CCC->sMigrateBuf, nSec); i = StrLength(CCC->sMigrateBuf); pCh = ChrPtr(CCC->sMigrateBuf); @@ -311,13 +324,13 @@ int sock_getln_err(int *sock, char *buf, int bufsize, int *rc) * client side protocol implementations. It only returns the first line of * a multiline response, discarding the rest. */ -int ml_sock_gets(int *sock, char *buf) +int ml_sock_gets(int *sock, char *buf, int nSec) { int rc = 0; char bigbuf[1024]; int g; - g = sock_getln_err(sock, buf, SIZ, &rc); + g = sock_getln_err(sock, buf, SIZ, &rc, nSec); if (rc < 0) return rc; if (g < 4) @@ -326,7 +339,7 @@ int ml_sock_gets(int *sock, char *buf) return (g); do { - g = sock_getln_err(sock, bigbuf, SIZ, &rc); + g = sock_getln_err(sock, bigbuf, SIZ, &rc, nSec); if (rc < 0) return rc; if (g < 0) diff --git a/citadel/clientsocket.h b/citadel/clientsocket.h index 55540098c..ba5e35068 100644 --- a/citadel/clientsocket.h +++ b/citadel/clientsocket.h @@ -22,9 +22,9 @@ int sock_connect(char *host, char *service); int sock_read_to(int *sock, char *buf, int bytes, int timeout, int keep_reading_until_full); int sock_read(int *sock, char *buf, int bytes, int keep_reading_until_full); int sock_write(int *sock, const char *buf, int nbytes); -int ml_sock_gets(int *sock, char *buf); +int ml_sock_gets(int *sock, char *buf, int nSec); int sock_getln(int *sock, char *buf, int bufsize); -int CtdlSockGetLine(int *sock, StrBuf *Target); +int CtdlSockGetLine(int *sock, StrBuf *Target, int nSec); int sock_puts(int *sock, char *buf); diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index 3c5e02c0a..159d36914 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1116,7 +1117,7 @@ void smtp_try(const char *key, const char *addr, int *status, CCC->sPos = NULL; /* Process the SMTP greeting from the server */ - if (ml_sock_gets(&sock, buf) < 0) { + if (ml_sock_gets(&sock, buf, 5) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP conversation"); goto bail; @@ -1141,7 +1142,7 @@ void smtp_try(const char *key, const char *addr, int *status, snprintf(buf, sizeof buf, "EHLO %s\r\n", config.c_fqdn); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); sock_write(&sock, buf, strlen(buf)); - if (ml_sock_gets(&sock, buf) < 0) { + if (ml_sock_gets(&sock, buf, 5) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP HELO"); goto bail; @@ -1151,7 +1152,7 @@ void smtp_try(const char *key, const char *addr, int *status, snprintf(buf, sizeof buf, "HELO %s\r\n", config.c_fqdn); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); sock_write(&sock, buf, strlen(buf)); - if (ml_sock_gets(&sock, buf) < 0) { + if (ml_sock_gets(&sock, buf, 5) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP HELO"); goto bail; @@ -1178,7 +1179,7 @@ void smtp_try(const char *key, const char *addr, int *status, snprintf(buf, sizeof buf, "AUTH PLAIN %s\r\n", encoded); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); sock_write(&sock, buf, strlen(buf)); - if (ml_sock_gets(&sock, buf) < 0) { + if (ml_sock_gets(&sock, buf, 5) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP AUTH"); goto bail; @@ -1202,7 +1203,7 @@ void smtp_try(const char *key, const char *addr, int *status, snprintf(buf, sizeof buf, "MAIL FROM:<%s>\r\n", envelope_from); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); sock_write(&sock, buf, strlen(buf)); - if (ml_sock_gets(&sock, buf) < 0) { + if (ml_sock_gets(&sock, buf, 5) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP MAIL"); goto bail; @@ -1225,7 +1226,7 @@ void smtp_try(const char *key, const char *addr, int *status, snprintf(buf, sizeof buf, "RCPT TO:<%s@%s>\r\n", user, node); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); sock_write(&sock, buf, strlen(buf)); - if (ml_sock_gets(&sock, buf) < 0) { + if (ml_sock_gets(&sock, buf, 5) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP RCPT"); goto bail; @@ -1247,7 +1248,7 @@ void smtp_try(const char *key, const char *addr, int *status, /* RCPT succeeded, now try the DATA command */ CtdlLogPrintf(CTDL_DEBUG, ">DATA\n"); sock_write(&sock, "DATA\r\n", 6); - if (ml_sock_gets(&sock, buf) < 0) { + if (ml_sock_gets(&sock, buf, 5) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP DATA"); goto bail; @@ -1276,7 +1277,8 @@ void smtp_try(const char *key, const char *addr, int *status, } sock_write(&sock, ".\r\n", 3); - if (ml_sock_gets(&sock, buf) < 0) { + tcdrain(sock); + if (ml_sock_gets(&sock, buf, 90) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP message transmit"); goto bail; @@ -1301,7 +1303,7 @@ void smtp_try(const char *key, const char *addr, int *status, CtdlLogPrintf(CTDL_DEBUG, ">QUIT\n"); sock_write(&sock, "QUIT\r\n", 6); - ml_sock_gets(&sock, buf); + ml_sock_gets(&sock, buf, 1); CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf); CtdlLogPrintf(CTDL_INFO, "SMTP client: delivery to <%s> @ <%s> (%s) succeeded\n", user, node, name); diff --git a/citadel/msgbase.c b/citadel/msgbase.c index da60f3132..68484783b 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -3398,7 +3398,7 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ /* read in the lines of message text one by one */ do { if (sock != NULL) { - if ((CtdlSockGetLine(sock, LineBuf) < 0) || + if ((CtdlSockGetLine(sock, LineBuf, 5) < 0) || (*sock == -1)) finished = 1; } -- 2.30.2