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>
Sun, 21 Nov 2010 15:41:41 +0000 (16:41 +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 36f160a97fdd6b2af59130ed1f57c2e9d60b97e5..380a4c6254e7f911773b9af408ad495447f17f74 100644 (file)
@@ -202,7 +202,7 @@ int sock_read_to(int *sock, char *buf, int bytes, int timeout, int keep_reading_
 }
 
 
-int CtdlSockGetLine(int *sock, StrBuf *Target)
+int CtdlSockGetLine(int *sock, StrBuf * Target, int nSec)
 {
        CitContext *CCC=CC;
        const char *Error;
@@ -212,10 +212,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",
@@ -237,7 +234,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);
@@ -283,6 +280,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);
 }
@@ -294,14 +304,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);
@@ -322,13 +332,13 @@ int sock_getln_err(int *sock, char *buf, int bufsize, int *rc)
  * 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)
@@ -337,7 +347,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 0274052a5ec6a83ee0d3c0e4c3a5825dd0207d34..491d7e3b122de69f44ce18cdc4ad6606a20434ea 100644 (file)
@@ -24,9 +24,9 @@ int sock_connect(char *host, char *service, char *protocol);
 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 bd2cb71787116170b537d247b06088fe687fbadf..a4441674e2be1ede48ddec5cd744a3df8c834023 100644 (file)
@@ -43,6 +43,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <termios.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <pwd.h>
@@ -1120,7 +1121,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;
@@ -1145,7 +1146,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;
@@ -1155,7 +1156,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;
@@ -1182,7 +1183,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;
@@ -1206,7 +1207,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;
@@ -1229,7 +1230,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;
@@ -1251,7 +1252,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;
@@ -1280,7 +1281,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;
@@ -1305,7 +1307,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 f3b7f2dd8d94fa09c8908567bb650499ded2f2a7..abdacccb5af75008c9885f99ad61ce85f0e1622f 100644 (file)
@@ -3345,7 +3345,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;
                }