have flexible timouts while reading lines in our client mode connections
authorWilfried Goesgens <dothebart@citadel.org>
Sat, 6 Nov 2010 12:51:41 +0000 (13:51 +0100)
committerWilfried Goesgens <dothebart@citadel.org>
Sat, 6 Nov 2010 12:51:41 +0000 (13:51 +0100)
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
citadel/clientsocket.h
citadel/modules/smtp/serv_smtp.c
citadel/msgbase.c

index 159ec72125728f1ed8004d7c8712dcbbe3924d88..d8a3e6b017de5a3d919d6303b4c0957542afd3d0 100644 (file)
@@ -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)
index 55540098ce0a68d5d0d2b620ab1ce45179cee16d..ba5e35068b75cb392463cc4eea219948a5ae37c3 100644 (file)
@@ -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);
 
 
index 3c5e02c0acd145cd1517c8a49d1e20d8a3a726a6..159d36914e57bfe71aaa06900957c55e1b36887b 100644 (file)
@@ -41,6 +41,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <termios.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <pwd.h>
@@ -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);
index da60f313293babfe2531118ab407ccfd2b5ff95c..68484783b2cb52f21e1cd82334f42f1e91114f2e 100644 (file)
@@ -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;
                }