From dd88abd1ae439ca2b96000316269a70304377200 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Sun, 30 Mar 2003 06:16:52 +0000 Subject: [PATCH] * Optimized CtdlReadMessageBody() and also gave it an option to store messages with CRLF newlines instead of LF. This option is used when reading SMTP in order to keep Pine from barfing on LF-terminated newlines while decoding quoted-printable. Once again, Mark Crispin is an idiot. --- citadel/ChangeLog | 7 ++++ citadel/control.c | 4 +-- citadel/msgbase.c | 87 ++++++++++++++++++++++++--------------------- citadel/msgbase.h | 2 +- citadel/serv_smtp.c | 2 +- 5 files changed, 58 insertions(+), 44 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 76b3446f5..fc5933a91 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,10 @@ $Log$ + Revision 605.29 2003/03/30 06:16:52 ajc + * Optimized CtdlReadMessageBody() and also gave it an option to store + messages with CRLF newlines instead of LF. This option is used when + reading SMTP in order to keep Pine from barfing on LF-terminated newlines + while decoding quoted-printable. Once again, Mark Crispin is an idiot. + Revision 605.28 2003/03/26 05:17:12 ajc * Downloading of attachments was completely broken by the change to the new protocol library. Located and fixed bugs. @@ -4597,3 +4603,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/control.c b/citadel/control.c index b69dded6f..c7c534139 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -360,8 +360,8 @@ void cmd_conf(char *argbuf) else if (!strcasecmp(cmd, "PUTSYS")) { extract(confname, argbuf, 1); cprintf("%d %s\n", SEND_LISTING, confname); - confptr = - CtdlReadMessageBody("000", config.c_maxmsglen, NULL); + confptr = CtdlReadMessageBody("000", + config.c_maxmsglen, NULL, 0); CtdlPutSysConfig(confname, confptr); phree(confptr); } diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 0d70d211a..d68451b14 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1004,7 +1004,12 @@ void output_preferred(char *name, char *filename, char *partnum, char *disp, cprintf("Content-type: %s\n", cbtype); cprintf("Content-length: %d\n", (int)(length + add_newline) ); - cprintf("Content-transfer-encoding: %s\n", encoding); + if (strlen(encoding) > 0) { + cprintf("Content-transfer-encoding: %s\n", encoding); + } + else { + cprintf("Content-transfer-encoding: 7bit\n"); + } cprintf("\n"); client_write(content, length); if (add_newline) cprintf("\n"); @@ -2198,8 +2203,9 @@ void quickie_message(char *from, char *to, char *room, char *text, */ char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */ size_t maxlen, /* maximum message length */ - char *exist /* if non-null, append to it; + char *exist, /* if non-null, append to it; exist is ALWAYS freed */ + int crlf /* CRLF newlines instead of LF */ ) { char buf[SIZ]; int linelen; @@ -2207,6 +2213,8 @@ char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */ size_t buffer_len = 0; char *ptr; char *m; + int flushing = 0; + int finished = 0; if (exist == NULL) { m = mallok(4096); @@ -2226,50 +2234,49 @@ char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */ /* flush the input if we have nowhere to store it */ if (m == NULL) { - while ( (client_gets(buf)>0) && strcmp(buf, terminator) ) ;; - return(NULL); + flushing = 1; } /* read in the lines of message text one by one */ - while ( (client_gets(buf)>0) && strcmp(buf, terminator) ) { - - /* Measure the line and strip trailing newline characters */ - linelen = strlen(buf); - if (linelen > 0) if (buf[linelen-1]==13) buf[linelen--]=0; - if (linelen > 0) if (buf[linelen-1]==10) buf[linelen--]=0; - - /* augment the buffer if we have to */ - if ((message_len + linelen + 2) > buffer_len) { - lprintf(9, "realloking\n"); - ptr = reallok(m, (buffer_len * 2) ); - if (ptr == NULL) { /* flush if can't allocate */ - while ( (client_gets(buf)>0) && - strcmp(buf, terminator)) ;; - return(m); - } else { - buffer_len = (buffer_len * 2); - m = ptr; - lprintf(9, "buffer_len is %ld\n", (long)buffer_len); - } + do { + if (client_gets(buf) < 1) finished = 1; + if (!strcmp(buf, terminator)) finished = 1; + if (crlf) { + strcat(buf, "\r\n"); + } + else { + strcat(buf, "\n"); } - /* 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); - m[message_len + linelen] = '\n'; - m[message_len + linelen + 1] = 0; - message_len = message_len + linelen + 1; + if ( (!flushing) && (!finished) ) { + /* Measure the line */ + linelen = strlen(buf); + + /* augment the buffer if we have to */ + if ((message_len + linelen) >= buffer_len) { + ptr = reallok(m, (buffer_len * 2) ); + if (ptr == NULL) { /* flush if can't allocate */ + flushing = 1; + } else { + buffer_len = (buffer_len * 2); + m = ptr; + lprintf(9, "buffer_len is now %ld\n", (long)buffer_len); + } + } + + /* 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; + } /* if we've hit the max msg length, flush the rest */ - if (message_len >= maxlen) { - while ( (client_gets(buf)>0) - && strcmp(buf, terminator)) ;; - return(m); - } - } + if (message_len >= maxlen) flushing = 1; + + } while (!finished); return(m); } @@ -2353,7 +2360,7 @@ struct CtdlMessage *CtdlMakeMessage( } else { msg->cm_fields['M'] = CtdlReadMessageBody("000", - config.c_maxmsglen, NULL); + config.c_maxmsglen, NULL, 0); } return(msg); diff --git a/citadel/msgbase.h b/citadel/msgbase.h index f902a4048..e1dbe8499 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -107,7 +107,7 @@ void serialize_message(struct ser_ret *, struct CtdlMessage *); int is_valid_message(struct CtdlMessage *); int ReplicationChecks(struct CtdlMessage *); int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int flags); -char *CtdlReadMessageBody(char *terminator, size_t maxlen, char *exist); +char *CtdlReadMessageBody(char *terminator, size_t maxlen, char *exist, int crlf); char *CtdlGetSysConfig(char *sysconfname); void CtdlPutSysConfig(char *sysconfname, char *sysconfdata); int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ diff --git a/citadel/serv_smtp.c b/citadel/serv_smtp.c index b9070b468..01141d1ee 100644 --- a/citadel/serv_smtp.c +++ b/citadel/serv_smtp.c @@ -497,7 +497,7 @@ void smtp_data(void) { config.c_fqdn, nowstamp); - body = CtdlReadMessageBody(".", config.c_maxmsglen, body); + body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1); if (body == NULL) { cprintf("550 Unable to save message: internal error.\r\n"); return; -- 2.39.2