* change CtdlReadMessageBody to use StrBuf for concattenating the lines
authorWilfried Göesgens <willi@citadel.org>
Tue, 9 Feb 2010 23:48:27 +0000 (23:48 +0000)
committerWilfried Göesgens <willi@citadel.org>
Tue, 9 Feb 2010 23:48:27 +0000 (23:48 +0000)
citadel/control.c
citadel/modules/calendar/serv_calendar.c
citadel/modules/pop3client/serv_pop3client.c
citadel/modules/sieve/serv_sieve.c
citadel/modules/smtp/serv_smtp.c
citadel/msgbase.c
citadel/msgbase.h
citadel/sysdep_decls.h

index eef125c7266bf59e6bbfd97dac1a4eb8826f114d..8b57b698c11e06363723421816ec2233827846d6 100644 (file)
@@ -700,7 +700,7 @@ void cmd_conf(char *argbuf)
                extract_token(confname, argbuf, 1, '|', sizeof confname);
                unbuffer_output();
                cprintf("%d %s\n", SEND_LISTING, confname);
-               confptr = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
+               confptr = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
                CtdlPutSysConfig(confname, confptr);
                free(confptr);
        }
index bf9f2e9afa2bc1b3a082ca8c83e00ad0972de59d..5cb20dbc9ac14e7c6b436cdb60c249e7cc9a96b7 100644 (file)
@@ -1741,7 +1741,7 @@ void ical_putics(void)
        }
 
        cprintf("%d Transmit data now\n", SEND_LISTING);
-       calstream = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
+       calstream = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
        if (calstream == NULL) {
                return;
        }
index de70ea86522769df4de7ba21469c8a141755a6d1..e6ea572c96b29c4e56a999605e301156fdac4e26 100644 (file)
@@ -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(".", 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");
index 960393d96dfcde2065b05959f794f63284996ec3..9de59d91664071ddd922f7c856ac0ad44ebffa2c 100644 (file)
@@ -1171,7 +1171,7 @@ void cmd_msiv(char *argbuf) {
                extract_token(script_name, argbuf, 1, '|', sizeof script_name);
                if (!IsEmptyStr(script_name)) {
                        cprintf("%d Transmit script now\n", SEND_LISTING);
-                       script_content = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
+                       script_content = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
                        msiv_putscript(&u, script_name, script_content);
                        changes_made = 1;
                }
index 947e436f7b502b06d3fbf6dbba93478306df29d4..cc8057f8b80f06a5a101f174a99ff8da07b78096 100644 (file)
@@ -713,7 +713,7 @@ void smtp_data(void) {
                                 nowstamp);
                }
        }
-       body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1, 0);
+       body = CtdlReadMessageBody(HKEY("."), config.c_maxmsglen, body, 1, 0);
        if (body == NULL) {
                cprintf("550 Unable to save message: internal error.\r\n");
                return;
index 85809adb3cd477581fd109b477d1b2ac5522fe09..ef7bdf8c0c9d397927d75641ca941a8aacc03b53 100644 (file)
@@ -3224,101 +3224,71 @@ void quickie_message(const char *from, const char *fromaddr, char *to, char *roo
  * Back end function used by CtdlMakeMessage() and similar functions
  */
 char *CtdlReadMessageBody(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 */
-                       ) {
+                       ) 
+{
+       StrBuf *Message;
+       StrBuf *LineBuf;
        char buf[1024];
-       int linelen;
-       size_t message_len = 0;
-       size_t buffer_len = 0;
-       char *ptr;
-       char *m;
        int flushing = 0;
        int finished = 0;
        int dotdot = 0;
 
+       LineBuf = NewStrBufPlain(NULL, SIZ);
        if (exist == NULL) {
-               m = malloc(4096);
-               m[0] = 0;
-               buffer_len = 4096;
-               message_len = 0;
+               Message = NewStrBufPlain(NULL, 4 * SIZ);
        }
        else {
-               message_len = strlen(exist);
-               buffer_len = message_len + 4096;
-               m = realloc(exist, buffer_len);
-               if (m == NULL) {
-                       free(exist);
-                       return m;
-               }
+               Message = NewStrBufPlain(exist, -1);
+               free(exist);
        }
 
        /* Do we need to change leading ".." to "." for SMTP escaping? */
-       if (!strcmp(terminator, ".")) {
+       if ((tlen == 1) && (*terminator == '.')) {
                dotdot = 1;
        }
 
-       /* flush the input if we have nowhere to store it */
-       if (m == NULL) {
-               flushing = 1;
-       }
-
        /* 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;
                }
                else {
-                       if (client_getln(buf, (sizeof buf - 3)) < 1) finished = 1;
-               }
-               if (!strcmp(buf, terminator)) finished = 1;
-               if (crlf) {
-                       strcat(buf, "\r\n");
-               }
-               else {
-                       strcat(buf, "\n");
-               }
-
-               /* Unescape SMTP-style input of two dots at the beginning of the line */
-               if (dotdot) {
-                       if (!strncmp(buf, "..", 2)) {
-                               strcpy(buf, &buf[1]);
-                       }
+                       if (CtdlClientGetLine(LineBuf) < 0) finished = 1;
                }
+               if ((StrLength(LineBuf) == tlen) && 
+                   (!strcmp(ChrPtr(LineBuf), terminator)))
+                       finished = 1;
 
                if ( (!flushing) && (!finished) ) {
-                       /* Measure the line */
-                       linelen = strlen(buf);
-       
-                       /* augment the buffer if we have to */
-                       if ((message_len + linelen) >= buffer_len) {
-                               ptr = realloc(m, (buffer_len * 2) );
-                               if (ptr == NULL) {      /* flush if can't allocate */
-                                       flushing = 1;
-                               } else {
-                                       buffer_len = (buffer_len * 2);
-                                       m = ptr;
-                                       CtdlLogPrintf(CTDL_DEBUG, "buffer_len is now %ld\n", (long)buffer_len);
-                               }
+                       if (crlf) {
+                               StrBufAppendBufPlain(LineBuf, HKEY("\r\n"), 0);
                        }
-       
-                       /* Add the new line to the buffer.  NOTE: this loop must avoid
-                       * using functions like strcat() and strlen() because they
-                       * traverse the entire buffer upon every call, and doing that
-                       * for a multi-megabyte message slows it down beyond usability.
-                       */
-                       strcpy(&m[message_len], buf);
-                       message_len += linelen;
+                       else {
+                               StrBufAppendBufPlain(LineBuf, HKEY("\n"), 0);
+                       }
+                       
+                       /* Unescape SMTP-style input of two dots at the beginning of the line */
+                       if ((dotdot) &&
+                           (StrLength(LineBuf) == 2) && 
+                           (!strcmp(ChrPtr(LineBuf), "..")))
+                       {
+                               StrBufCutLeft(LineBuf, 1);
+                       }
+                       
+                       StrBufAppendBuf(Message, LineBuf, 0);
                }
 
                /* if we've hit the max msg length, flush the rest */
-               if (message_len >= maxlen) flushing = 1;
+               if (StrLength(Message) >= maxlen) flushing = 1;
 
        } while (!finished);
-       return(m);
+       return SmashStrBuf(&Message);
 }
 
 
@@ -3447,7 +3417,7 @@ struct CtdlMessage *CtdlMakeMessage(
                msg->cm_fields['M'] = preformatted_text;
        }
        else {
-               msg->cm_fields['M'] = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
+               msg->cm_fields['M'] = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
        }
 
        return(msg);
index 29a9a28ae293c33e3bb833edc79609868ddeeec6..854cefee4cee71cce0cfb4c11fbf292d355250e5 100644 (file)
@@ -146,7 +146,7 @@ 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, size_t maxlen, char *exist, int crlf, int sock);
+char *CtdlReadMessageBody(char *terminator, long tlen, size_t maxlen, char *exist, int crlf, int sock);
 int CtdlOutputMsg(long msg_num,                /* message number (local) to fetch */
                  int mode,             /* how would you like that message? */
                  int headers_only,     /* eschew the message body? */
index 617d906518b9782c3066cb751d4012e3a0b92a37..d0433222356c5e415b5ac88ba67df9c830bdd4ad 100644 (file)
@@ -63,6 +63,8 @@ int client_write (const char *buf, int nbytes);
 int client_read_to (char *buf, int bytes, int timeout);
 int client_read (char *buf, int bytes);
 int client_getln (char *buf, int maxbytes);
+int CtdlClientGetLine(StrBuf *Target);
+int client_read_blob(StrBuf *Target, int bytes, int timeout);
 void sysdep_master_cleanup (void);
 void kill_session (int session_to_kill);
 void start_daemon (int do_close_stdio);