* custom sockets need to work buffered too...
authorWilfried Göesgens <willi@citadel.org>
Fri, 12 Feb 2010 20:05:21 +0000 (20:05 +0000)
committerWilfried Göesgens <willi@citadel.org>
Fri, 12 Feb 2010 20:05:21 +0000 (20:05 +0000)
* don't write / select to defunct sockets

citadel/clientsocket.c
citadel/clientsocket.h
citadel/context.h
citadel/modules/clamav/serv_virus.c
citadel/modules/network/serv_network.c
citadel/modules/pop3client/serv_pop3client.c
citadel/modules/smtp/serv_smtp.c
citadel/modules/spam/serv_spam.c
citadel/msgbase.c
citadel/msgbase.h
citadel/sysdep.c

index d0c397df0b7b5fb09c35f7aa3c2b322f8c0a78c9..7c69fe67333c93d3d82698f0291c3e078e667fb0 100644 (file)
@@ -135,41 +135,128 @@ int sock_connect(char *host, char *service, char *protocol)
 
 
 /*
- * sock_read_to() - input binary data from socket, with a settable timeout.
- * Returns the number of bytes read, or -1 for error.
- * If keep_reading_until_full is nonzero, we keep reading until we get the number of requested bytes
+ * Read data from the client socket.
+ *
+ * sock                socket fd to read from
+ * buf         buffer to read into 
+ * bytes       number of bytes to read
+ * timeout     Number of seconds to wait before timing out
+ *
+ * Possible return values:
+ *      1       Requested number of bytes has been read.
+ *      0       Request timed out.
+ *     -1      Connection is broken, or other error.
  */
-int sock_read_to(int sock, char *buf, int bytes, int timeout, int keep_reading_until_full)
+int socket_read_blob(int *Socket, 
+                    StrBuf *Target, 
+                    int bytes, 
+                    int timeout)
 {
-       int len,rlen;
-       fd_set rfds;
-       struct timeval tv;
-       int retval;
+       CitContext *CCC=CC;
+       const char *Error;
+       int retval = 0;
+
+
+       retval = StrBufReadBLOBBuffered(Target, 
+                                       CCC->sReadBuf,
+                                       &CCC->sPos,
+                                       Socket,
+                                       1, 
+                                       bytes,
+                                       O_TERM,
+                                       &Error);
+       if (retval < 0) {
+               CtdlLogPrintf(CTDL_CRIT, 
+                             "%s failed: %s\n",
+                             __FUNCTION__,
+                             Error);
+       }
+       return retval;
+}
 
-       len = 0;
-       while (len<bytes) {
-               FD_ZERO(&rfds);
-               FD_SET(sock, &rfds);
-               tv.tv_sec = timeout;
-               tv.tv_usec = 0;
 
-               retval = select(sock+1, &rfds, NULL, NULL, &tv);
+int sock_read_to(int *sock, char *buf, int bytes, int timeout, int keep_reading_until_full)
+{
+       CitContext *CCC=CC;
+       int rc;
+
+       rc = socket_read_blob(sock, 
+                             CCC->sMigrateBuf, 
+                             bytes, 
+                             timeout);
+       if (rc < 0)
+       {
+               *buf = '\0';
+               return rc;
+       }
+       else
+       {
+               if (StrLength(CCC->MigrateBuf) < bytes)
+                       bytes = StrLength(CCC->MigrateBuf);
+               memcpy(buf, 
+                      ChrPtr(CCC->MigrateBuf),
+                      bytes);
+
+               FlushStrBuf(CCC->MigrateBuf);
+               return rc;
+       }
+}
 
-               if (FD_ISSET(sock, &rfds) == 0) {       /* timed out */
-                       CtdlLogPrintf(CTDL_ERR, "sock_read() timed out.\n");
-                       return(-1);
-               }
 
-               rlen = read(sock, &buf[len], bytes-len);
-               if (rlen<1) {
-                       CtdlLogPrintf(CTDL_ERR, "sock_read() failed: %s\n",
-                               strerror(errno));
-                       return(-1);
-               }
-               len = len + rlen;
-               if (!keep_reading_until_full) return(len);
+int CtdlSockGetLine(int *sock, StrBuf *Target)
+{
+       CitContext *CCC=CC;
+       const char *Error;
+       int rc;
+
+       rc = StrBufTCP_read_buffered_line_fast(Target, 
+                                              CCC->sReadBuf,
+                                              &CCC->sPos,
+                                              sock,
+                                              5,
+                                              1,
+                                              &Error);
+       if ((rc < 0) && (Error != NULL))
+               CtdlLogPrintf(CTDL_CRIT, 
+                             "%s failed: %s\n",
+                             __FUNCTION__,
+                             Error);
+       return rc;
+}
+
+
+/*
+ * client_getln()   ...   Get a LF-terminated line of text from the client.
+ * (This is implemented in terms of client_read() and could be
+ * justifiably moved out of sysdep.c)
+ */
+int sock_getln(int *sock, char *buf, int bufsize)
+{
+       int i, retval;
+       CitContext *CCC=CC;
+       const char *pCh;
+
+       retval = CtdlSockGetLine(sock, CCC->sMigrateBuf);
+
+       i = StrLength(CCC->sMigrateBuf);
+       pCh = ChrPtr(CCC->sMigrateBuf);
+       /* Strip the trailing LF, and the trailing CR if present.
+        */
+       if (bufsize <= i)
+               i = bufsize - 1;
+       while ( (i > 0)
+               && ( (pCh[i - 1]==13)
+                    || ( pCh[i - 1]==10)) ) {
+               i--;
+       }
+       memcpy(buf, pCh, i);
+       buf[i] = 0;
+
+       FlushStrBuf(CCC->sMigrateBuf);
+       if (retval < 0) {
+               safestrncpy(&buf[i], "000", bufsize - i);
        }
-       return(bytes);
+       return(retval >= 0);
 }
 
 
@@ -177,7 +264,7 @@ int sock_read_to(int sock, char *buf, int bytes, int timeout, int keep_reading_u
  * sock_read() - input binary data from socket.
  * Returns the number of bytes read, or -1 for error.
  */
-INLINE int sock_read(int sock, char *buf, int bytes, int keep_reading_until_full)
+INLINE int sock_read(int *sock, char *buf, int bytes, int keep_reading_until_full)
 {
        return sock_read_to(sock, buf, bytes, CLIENT_TIMEOUT, keep_reading_until_full);
 }
@@ -203,47 +290,12 @@ int sock_write(int sock, char *buf, int nbytes)
 }
 
 
-
-/*
- * Input string from socket - implemented in terms of sock_read()
- * 
- */
-int sock_getln(int sock, char *buf, int bufsize)
-{
-       int i;
-
-       /* Read one character at a time.
-        */
-       for (i = 0;; i++) {
-               if (sock_read(sock, &buf[i], 1, 1) < 0) return(-1);
-               if (buf[i] == '\n' || i == (bufsize-1))
-                       break;
-       }
-
-       /* If we got a long line, discard characters until the newline.
-        */
-       if (i == (bufsize-1))
-               while (buf[i] != '\n')
-                       if (sock_read(sock, &buf[i], 1, 1) < 0) return(-1);
-
-       /* Strip any trailing CR and LF characters.
-        */
-       buf[i] = 0;
-       while ( (i > 0)
-               && ( (buf[i - 1]==13)
-                    || ( buf[i - 1]==10)) ) {
-               i--;
-               buf[i] = 0;
-       }
-       return(i);
-}
-
 /*
  * Multiline version of sock_gets() ... this is a convenience function for
  * 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) {
        char bigbuf[1024];
        int g;
 
index 2c9a5d3689a46af5cf4fd1f4d2070140b2c63f18..fcaf034b6944375365fc22ccbaf6e03a5bfb9495 100644 (file)
  */
 
 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_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, char *buf, int nbytes);
-int ml_sock_gets(int sock, char *buf);
-int sock_getln(int sock, char *buf, int bufsize);
+int ml_sock_gets(int *sock, char *buf);
+int sock_getln(int *sock, char *buf, int bufsize);
+int CtdlSockGetLine(int *sock, StrBuf *Target);
 int sock_puts(int sock, char *buf);
 
 
index f9c3aeada7a6241271a5ff513fe9ae6b04ace877..1e57f2f39fc9ec7798ae660fbde2348c7f35b0b2 100644 (file)
@@ -31,6 +31,10 @@ struct CitContext {
        const char *Pos;        /* Our read position inside of the ReadBuf */
        StrBuf *ReadBuf;        /* Our block buffered read buffer */
        StrBuf *MigrateBuf;        /* Our block buffered read buffer */
+
+       const char *sPos;        /* Our read position inside of the ReadBuf */
+       StrBuf *sReadBuf;        /* Our block buffered read buffer */
+       StrBuf *sMigrateBuf;        /* Our block buffered read buffer */
        int client_socket;
        int is_local_socket;    /* set to 1 if client is on unix domain sock */
        /* Redirect this session's output to a memory buffer? */
index 31086072015039335297be1bd3c1786f13cb5dea..6aeeaa9bf3819a2654ee9085b890e634018ede97 100644 (file)
@@ -124,7 +124,7 @@ int clamd(struct CtdlMessage *msg) {
        sock_write(sock, buf, strlen(buf));
 
        CtdlLogPrintf(CTDL_DEBUG, "Waiting for PORT number\n");
-        if (sock_getln(sock, buf, sizeof buf) < 0) {
+        if (sock_getln(&sock, buf, sizeof buf) < 0) {
                 goto bail;
         }
 
@@ -172,7 +172,7 @@ int clamd(struct CtdlMessage *msg) {
        
        /* Response */
        CtdlLogPrintf(CTDL_DEBUG, "Awaiting response\n");
-        if (sock_getln(sock, buf, sizeof buf) < 0) {
+        if (sock_getln(&sock, buf, sizeof buf) < 0) {
                 goto bail;
         }
         CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
index 5740feaa045534cdefd88d5add734ab1a04139c4..e2d16dd9aa08e521799e10ba0cbfa84cdbf15c23 100644 (file)
@@ -1786,7 +1786,7 @@ void network_purge_spoolout(void) {
 /*
  * receive network spool from the remote system
  */
-void receive_spool(int sock, char *remote_nodename) {
+void receive_spool(int *sock, char *remote_nodename) {
        size_t siz;
        long download_len = 0L;
        long bytes_received = 0L;
@@ -1799,7 +1799,7 @@ void receive_spool(int sock, char *remote_nodename) {
        FILE *fp, *newfp;
 
        CtdlMakeTempFileName(tempfilename, sizeof tempfilename);
-       if (sock_puts(sock, "NDOP") < 0) return;
+       if (sock_puts(*sock, "NDOP") < 0) return;
        if (sock_getln(sock, buf, sizeof buf) < 0) return;
        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
        if (buf[0] != '2') {
@@ -1830,7 +1830,7 @@ void receive_spool(int sock, char *remote_nodename) {
                        bytes_received,
                     ((download_len - bytes_received > IGNET_PACKET_SIZE)
                 ? IGNET_PACKET_SIZE : (download_len - bytes_received)));
-               if (sock_puts(sock, buf) < 0) {
+               if (sock_puts(*sock, buf) < 0) {
                        fclose(fp);
                        unlink(tempfilename);
                        return;
@@ -1859,7 +1859,7 @@ void receive_spool(int sock, char *remote_nodename) {
                unlink(tempfilename);
                return;
        }
-       if (sock_puts(sock, "CLOS") < 0) {
+       if (sock_puts(*sock, "CLOS") < 0) {
                unlink(tempfilename);
                return;
        }
@@ -1913,7 +1913,7 @@ void receive_spool(int sock, char *remote_nodename) {
 /*
  * transmit network spool to the remote system
  */
-void transmit_spool(int sock, char *remote_nodename)
+void transmit_spool(int *sock, char *remote_nodename)
 {
        char buf[SIZ];
        char pbuf[4096];
@@ -1922,7 +1922,7 @@ void transmit_spool(int sock, char *remote_nodename)
        int fd;
        char sfname[128];
 
-       if (sock_puts(sock, "NUOP") < 0) return;
+       if (sock_puts(*sock, "NUOP") < 0) return;
        if (sock_getln(sock, buf, sizeof buf) < 0) return;
        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
        if (buf[0] != '2') {
@@ -1953,7 +1953,7 @@ void transmit_spool(int sock, char *remote_nodename)
                        }
                        
                        snprintf(buf, sizeof buf, "WRIT %ld", bytes_to_write);
-                       if (sock_puts(sock, buf) < 0) {
+                       if (sock_puts(*sock, buf) < 0) {
                                close(fd);
                                return;
                        }
@@ -1963,7 +1963,7 @@ void transmit_spool(int sock, char *remote_nodename)
                        }
                        thisblock = atol(&buf[4]);
                        if (buf[0] == '7') {
-                               if (sock_write(sock, pbuf,
+                               if (sock_write(*sock, pbuf,
                                   (int) thisblock) < 0) {
                                        close(fd);
                                        return;
@@ -1982,7 +1982,7 @@ ABORTUPL:
        if(CtdlThreadCheckStop())
                return;
                
-       if (sock_puts(sock, "UCLS 1") < 0) return;
+       if (sock_puts(*sock, "UCLS 1") < 0) return;
        /**
         * From here on we must complete or messages will get lost
         */
@@ -2021,7 +2021,7 @@ void network_poll_node(char *node, char *secret, char *host, char *port) {
        CtdlLogPrintf(CTDL_DEBUG, "Connected!\n");
 
        /* Read the server greeting */
-       if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+       if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
        CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
 
        /* Check that the remote is who we think it is and warn the Aide if not */
@@ -2037,15 +2037,15 @@ void network_poll_node(char *node, char *secret, char *host, char *port) {
                snprintf(buf, sizeof buf, "NETP %s|%s", config.c_nodename, secret);
                CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
                if (sock_puts(sock, buf) <0) goto bail;
-               if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+               if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
                CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
                if (buf[0] != '2') goto bail;
        
                /* At this point we are authenticated. */
                if (!CtdlThreadCheckStop())
-                       receive_spool(sock, node);
+                       receive_spool(&sock, node);
                if (!CtdlThreadCheckStop())
-                       transmit_spool(sock, node);
+                       transmit_spool(&sock, node);
        }
 
        sock_puts(sock, "QUIT");
index e6ea572c96b29c4e56a999605e301156fdac4e26..7cc41a1778f42b6e020353cd2dc1269d8a43dcf5 100644 (file)
@@ -101,7 +101,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
        CtdlLogPrintf(CTDL_DEBUG, "Connected!\n");
 
        /* Read the server greeting */
-       if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+       if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
        CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
        if (strncasecmp(buf, "+OK", 3)) goto bail;
 
@@ -116,7 +116,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
        snprintf(buf, sizeof buf, "USER %s\r", pop3user);
        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
        if (sock_puts(sock, buf) <0) goto bail;
-       if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+       if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
        CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
        if (strncasecmp(buf, "+OK", 3)) goto bail;
 
@@ -127,7 +127,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
        snprintf(buf, sizeof buf, "PASS %s\r", pop3pass);
        CtdlLogPrintf(CTDL_DEBUG, "<PASS <password>\n");
        if (sock_puts(sock, buf) <0) goto bail;
-       if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+       if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
        CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
        if (strncasecmp(buf, "+OK", 3)) goto bail;
 
@@ -138,7 +138,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
        snprintf(buf, sizeof buf, "LIST\r");
        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
        if (sock_puts(sock, buf) <0) goto bail;
-       if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+       if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
        CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
        if (strncasecmp(buf, "+OK", 3)) goto bail;
 
@@ -149,7 +149,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
                if (CtdlThreadCheckStop())
                        goto bail;
 
-               if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+               if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
                CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
                msg_to_fetch = atoi(buf);
                if (msg_to_fetch > 0) {
@@ -172,7 +172,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
                snprintf(buf, sizeof buf, "UIDL %d\r", msglist[i]);
                CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
                if (sock_puts(sock, buf) <0) goto bail;
-               if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+               if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
                CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
                if (strncasecmp(buf, "+OK", 3)) goto bail;
                extract_token(this_uidl, buf, 2, ' ', sizeof this_uidl);
@@ -198,7 +198,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
                        snprintf(buf, sizeof buf, "RETR %d\r", msglist[i]);
                        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
                        if (sock_puts(sock, buf) <0) goto bail;
-                       if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+                       if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
                        CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
                        if (strncasecmp(buf, "+OK", 3)) goto bail;
        
@@ -206,7 +206,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
                                goto bail;
 
                        /* If we get to this point, the message is on its way.  Read it. */
-                       body = CtdlReadMessageBody(HKEY("."), config.c_maxmsglen, NULL, 1, sock);
+                       body = CtdlReadMessageBody(HKEY("."), config.c_maxmsglen, NULL, 1, &sock);
                        if (body == NULL) goto bail;
        
                        CtdlLogPrintf(CTDL_DEBUG, "Converting message...\n");
@@ -222,7 +222,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
                                        snprintf(buf, sizeof buf, "DELE %d\r", msglist[i]);
                                        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
                                        if (sock_puts(sock, buf) <0) goto bail;
-                                       if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+                                       if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
                                        CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf); /* errors here are non-fatal */
                                }
 
@@ -240,7 +240,7 @@ void pop3_do_fetching(char *roomname, char *pop3host, char *pop3user, char *pop3
        snprintf(buf, sizeof buf, "QUIT\r");
        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
        if (sock_puts(sock, buf) <0) goto bail;
-       if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+       if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
        CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
 bail:  sock_close(sock);
        if (msglist) free(msglist);
index 2647a83a0e538395a02279ec5ee2117e10781442..f673165ad2316997999c4d428e48602411663108 100644 (file)
@@ -668,6 +668,7 @@ void smtp_rcpt(char *argbuf) {
  */
 void smtp_data(void) {
        StrBuf *body;
+       char *defbody; //TODO: remove me
        struct CtdlMessage *msg = NULL;
        long msgnum = (-1L);
        char nowstamp[SIZ];
@@ -690,20 +691,20 @@ void smtp_data(void) {
        cprintf("354 Transmit message now - terminate with '.' by itself\r\n");
        
        datestring(nowstamp, sizeof nowstamp, time(NULL), DATESTRING_RFC822);
-       body = malloc(4096);
+       defbody = malloc(4096);
 
        if (body != NULL) {
                if (sSMTP->is_lmtp && (CC->cs_UDSclientUID != -1)) {
-                       snprintf(body, 4096,
-                                "Received: from %s (Citadel from userid %ld)\n"
-                                "      by %s; %s\n",
-                                sSMTP->helo_node,
-                                (long int) CC->cs_UDSclientUID,
-                                config.c_fqdn,
-                                nowstamp);
+                       snprintf(defbody, 4096,
+                              "Received: from %s (Citadel from userid %ld)\n"
+                              "        by %s; %s\n",
+                              sSMTP->helo_node,
+                              (long int) CC->cs_UDSclientUID,
+                              config.c_fqdn,
+                              nowstamp);
                }
                else {
-                       snprintf(body, 4096,
+                       snprintf(defbody, 4096,
                                 "Received: from %s (%s [%s])\n"
                                 "      by %s; %s\n",
                                 sSMTP->helo_node,
@@ -713,7 +714,7 @@ void smtp_data(void) {
                                 nowstamp);
                }
        }
-       body = CtdlReadMessageBodyBuf(HKEY("."), config.c_maxmsglen, body, 1, 0);
+       body = CtdlReadMessageBodyBuf(HKEY("."), config.c_maxmsglen, defbody, 1, NULL);
        if (body == NULL) {
                cprintf("550 Unable to save message: internal error.\r\n");
                return;
@@ -1102,7 +1103,7 @@ void smtp_try(const char *key, const char *addr, int *status,
        }
 
        /* Process the SMTP greeting from the server */
-       if (ml_sock_gets(sock, buf) < 0) {
+       if (ml_sock_gets(&sock, buf) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP conversation");
                goto bail;
@@ -1127,7 +1128,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) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP HELO");
                goto bail;
@@ -1137,7 +1138,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) < 0) {
                        *status = 4;
                        strcpy(dsn, "Connection broken during SMTP HELO");
                        goto bail;
@@ -1164,7 +1165,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) < 0) {
                        *status = 4;
                        strcpy(dsn, "Connection broken during SMTP AUTH");
                        goto bail;
@@ -1188,7 +1189,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) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP MAIL");
                goto bail;
@@ -1211,7 +1212,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) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP RCPT");
                goto bail;
@@ -1233,7 +1234,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) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP DATA");
                goto bail;
@@ -1262,7 +1263,7 @@ void smtp_try(const char *key, const char *addr, int *status,
        }
 
        sock_write(sock, ".\r\n", 3);
-       if (ml_sock_gets(sock, buf) < 0) {
+       if (ml_sock_gets(&sock, buf) < 0) {
                *status = 4;
                strcpy(dsn, "Connection broken during SMTP message transmit");
                goto bail;
@@ -1287,7 +1288,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);
        CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
        CtdlLogPrintf(CTDL_INFO, "SMTP client: delivery to <%s> @ <%s> (%s) succeeded\n",
                user, node, name);
index 7868545ad591194af0b996e1e0b68855f9d1b0a6..7ff266dea300b71a38d91f492a2b81849f042004 100644 (file)
@@ -133,14 +133,14 @@ int spam_assassin(struct CtdlMessage *msg) {
        
        /* Response */
        CtdlLogPrintf(CTDL_DEBUG, "Awaiting response\n");
-        if (sock_getln(sock, buf, sizeof buf) < 0) {
+        if (sock_getln(&sock, buf, sizeof buf) < 0) {
                 goto bail;
         }
         CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
        if (strncasecmp(buf, "SPAMD", 5)) {
                goto bail;
        }
-        if (sock_getln(sock, buf, sizeof buf) < 0) {
+        if (sock_getln(&sock, buf, sizeof buf) < 0) {
                 goto bail;
         }
         CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
index 700e12288c8577e74df97c4d9c184b54ab9b168b..c31e3615462d725381eb051c840b1dbefb550d98 100644 (file)
@@ -3229,7 +3229,7 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator,  /* token signalling EOT */
                               char *exist,             /* if non-null, append to it;
                                                           exist is ALWAYS freed  */
                               int crlf,                /* CRLF newlines instead of LF */
-                              int sock         /* socket handle or 0 for this session's client socket */
+                              int *sock                /* socket handle or 0 for this session's client socket */
                        ) 
 {
        StrBuf *Message;
@@ -3255,8 +3255,10 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */
 
        /* read in the lines of message text one by one */
        do {
-               if (sock > 0) {
-                       if (sock_getln(sock, buf, (sizeof buf - 3)) < 0) finished = 1;
+               if (sock != NULL) {
+                       if ((CtdlSockGetLine(sock, LineBuf) < 0) ||
+                           (*sock == -1))
+                               finished = 1;
                }
                else {
                        if (CtdlClientGetLine(LineBuf) < 0) finished = 1;
@@ -3302,7 +3304,7 @@ char *CtdlReadMessageBody(char *terminator,       /* token signalling EOT */
                          char *exist,          /* if non-null, append to it;
                                                   exist is ALWAYS freed  */
                          int crlf,             /* CRLF newlines instead of LF */
-                         int sock              /* socket handle or 0 for this session's client socket */
+                         int *sock             /* socket handle or 0 for this session's client socket */
        ) 
 {
        StrBuf *Message;
index 3202c1e6f6953c68afee54429d8021c574509107..ffb6da99489735a3d12feaf7ba321d4cacced60b 100644 (file)
@@ -146,14 +146,14 @@ void ReplicationChecks(struct CtdlMessage *);
 int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs,
                                int do_repl_check, struct CtdlMessage *supplied_msg);
 int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check, struct CtdlMessage *msg);
-char *CtdlReadMessageBody(char *terminator, long tlen, size_t maxlen, char *exist, int crlf, int sock);
+char *CtdlReadMessageBody(char *terminator, long tlen, size_t maxlen, char *exist, int crlf, int *sock);
 StrBuf *CtdlReadMessageBodyBuf(char *terminator,       /* token signalling EOT */
                               long tlen,
                               size_t maxlen,           /* maximum message length */
                               char *exist,             /* if non-null, append to it;
                                                           exist is ALWAYS freed  */
                               int crlf,                /* CRLF newlines instead of LF */
-                              int sock         /* socket handle or 0 for this session's client socket */
+                              int *sock                /* socket handle or 0 for this session's client socket */
        );
 
 int CtdlOutputMsg(long msg_num,                /* message number (local) to fetch */
index 0420bc6c168a2b8e1937be9304f77eb5388b3542..d75b27773d0080fc40b09a8f7e59f151b0275eda 100644 (file)
@@ -479,10 +479,11 @@ int client_write(const char *buf, int nbytes)
                return 0;
        }
 #endif
+       if (Ctx->client_socket == -1) return -1;
 
        fdflags = fcntl(Ctx->client_socket, F_GETFL);
 
-       while (bytes_written < nbytes) {
+       while ((bytes_written < nbytes) && (Ctx->client_socket != -1)){
                if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
                        FD_ZERO(&wset);
                        FD_SET(Ctx->client_socket, &wset);