]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/smtp/serv_smtp.c
SMTP Async I/O:
[citadel.git] / citadel / modules / smtp / serv_smtp.c
index 7d1e26f49df302ed3d87319bdf61b491c9202e58..fc43a9624529001f924df11e379d9ef126e565d4 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>
@@ -1002,7 +1003,7 @@ void smtp_try(const char *key, const char *addr, int *status,
                scan_done = 0;
                ptr = msgtext;
                do {
-                       if (ptr = memreadline(ptr, buf, sizeof buf), *ptr == 0) {
+                       if (ptr = cmemreadline(ptr, buf, sizeof buf), *ptr == 0) {
                                scan_done = 1;
                        }
                        if (!strncasecmp(buf, "From:", 5)) {
@@ -1085,7 +1086,21 @@ void smtp_try(const char *key, const char *addr, int *status,
                CtdlLogPrintf(CTDL_DEBUG, "SMTP client: connecting to %s : %s ...\n", mx_host, mx_port);
                sock = sock_connect(mx_host, mx_port, "tcp");
                snprintf(dsn, SIZ, "Could not connect: %s", strerror(errno));
-               if (sock >= 0) CtdlLogPrintf(CTDL_DEBUG, "SMTP client: connected!\n");
+               if (sock >= 0) 
+               {
+                       CtdlLogPrintf(CTDL_DEBUG, "SMTP client: connected!\n");
+                               int fdflags; 
+                               fdflags = fcntl(sock, F_GETFL);
+                               if (fdflags < 0)
+                                       CtdlLogPrintf(CTDL_DEBUG,
+                                                     "unable to get SMTP-Client socket flags! %s \n",
+                                                     strerror(errno));
+                               fdflags = fdflags | O_NONBLOCK;
+                               if (fcntl(sock, F_SETFL, fdflags) < 0)
+                                       CtdlLogPrintf(CTDL_DEBUG,
+                                                     "unable to set SMTP-Client socket nonblocking flags! %s \n",
+                                                     strerror(errno));
+               }
                if (sock < 0) {
                        if (errno > 0) {
                                snprintf(dsn, SIZ, "%s", strerror(errno));
@@ -1106,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, 90) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP conversation");
                goto bail;
@@ -1131,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, 30) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP HELO");
                goto bail;
@@ -1141,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, 30) < 0) {
                        *status = 4;
                        strcpy(dsn, "Connection broken during SMTP HELO");
                        goto bail;
@@ -1168,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, 30) < 0) {
                        *status = 4;
                        strcpy(dsn, "Connection broken during SMTP AUTH");
                        goto bail;
@@ -1192,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, 30) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP MAIL");
                goto bail;
@@ -1215,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, 30) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP RCPT");
                goto bail;
@@ -1237,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, 30) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP DATA");
                goto bail;
@@ -1257,7 +1272,10 @@ void smtp_try(const char *key, const char *addr, int *status,
        }
 
        /* If we reach this point, the server is expecting data.*/
-       sock_write(&sock, msgtext, msg_size);
+       sock_write_timeout(&sock, 
+                          msgtext, 
+                          msg_size, 
+                          (msg_size / 128) + 50);
        if (msgtext[msg_size-1] != 10) {
                CtdlLogPrintf(CTDL_WARNING, "Possible problem: message did not "
                        "correctly terminate. (expecting 0x10, got 0x%02x)\n",
@@ -1266,7 +1284,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;
@@ -1291,7 +1310,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, 30);
        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
        CtdlLogPrintf(CTDL_INFO, "SMTP client: delivery to <%s> @ <%s> (%s) succeeded\n",
                user, node, name);
@@ -1466,6 +1485,8 @@ void smtp_do_bounce(char *instr) {
         StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
        StrBufAppendBuf(BounceMB, boundary, 0);
        StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0);
+       if (bmsg->cm_fields['A'] != NULL)
+               free(bmsg->cm_fields['A']);
        bmsg->cm_fields['A'] = SmashStrBuf(&BounceMB);
        /* Deliver the bounce if there's anything worth mentioning */
        CtdlLogPrintf(CTDL_DEBUG, "num_bounces = %d\n", num_bounces);