From f94eea12856a5e17844d12eb9a36b44ae147902b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Tue, 9 Feb 2010 23:48:27 +0000 Subject: [PATCH] * change CtdlReadMessageBody to use StrBuf for concattenating the lines --- citadel/control.c | 2 +- citadel/modules/calendar/serv_calendar.c | 2 +- citadel/modules/pop3client/serv_pop3client.c | 2 +- citadel/modules/sieve/serv_sieve.c | 2 +- citadel/modules/smtp/serv_smtp.c | 2 +- citadel/msgbase.c | 94 +++++++------------- citadel/msgbase.h | 2 +- citadel/sysdep_decls.h | 2 + 8 files changed, 40 insertions(+), 68 deletions(-) diff --git a/citadel/control.c b/citadel/control.c index eef125c72..8b57b698c 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -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); } diff --git a/citadel/modules/calendar/serv_calendar.c b/citadel/modules/calendar/serv_calendar.c index bf9f2e9af..5cb20dbc9 100644 --- a/citadel/modules/calendar/serv_calendar.c +++ b/citadel/modules/calendar/serv_calendar.c @@ -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; } diff --git a/citadel/modules/pop3client/serv_pop3client.c b/citadel/modules/pop3client/serv_pop3client.c index de70ea865..e6ea572c9 100644 --- a/citadel/modules/pop3client/serv_pop3client.c +++ b/citadel/modules/pop3client/serv_pop3client.c @@ -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"); diff --git a/citadel/modules/sieve/serv_sieve.c b/citadel/modules/sieve/serv_sieve.c index 960393d96..9de59d916 100644 --- a/citadel/modules/sieve/serv_sieve.c +++ b/citadel/modules/sieve/serv_sieve.c @@ -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; } diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index 947e436f7..cc8057f8b 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -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; diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 85809adb3..ef7bdf8c0 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -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); diff --git a/citadel/msgbase.h b/citadel/msgbase.h index 29a9a28ae..854cefee4 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -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? */ diff --git a/citadel/sysdep_decls.h b/citadel/sysdep_decls.h index 617d90651..d04332223 100644 --- a/citadel/sysdep_decls.h +++ b/citadel/sysdep_decls.h @@ -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); -- 2.30.2