From 984583756d062536382d78da5ffc70eba9378bfb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Sat, 13 Mar 2010 18:04:48 +0000 Subject: [PATCH] * migrate redirect_buffer logic to StrBuf, valgrind reported some related errors. * migrate the creation of bounce messages to strbuf --- citadel/clientsocket.c | 2 +- citadel/clientsocket.h | 2 +- citadel/context.h | 4 +- citadel/internet_addressing.c | 2 +- citadel/internet_addressing.h | 2 +- citadel/journaling.c | 8 +- citadel/journaling.h | 4 +- citadel/modules/clamav/serv_virus.c | 14 +-- citadel/modules/fulltext/serv_fulltext.c | 14 +-- citadel/modules/imap/imap_fetch.c | 145 +++++++++++------------ citadel/modules/imap/imap_search.c | 11 +- citadel/modules/network/serv_network.c | 17 ++- citadel/modules/pop3/serv_pop3.c | 27 ++--- citadel/modules/sieve/serv_sieve.c | 11 +- citadel/modules/smtp/serv_smtp.c | 112 +++++++---------- citadel/modules/spam/serv_spam.c | 16 +-- citadel/msgbase.c | 10 +- citadel/sysdep.c | 10 +- 18 files changed, 166 insertions(+), 245 deletions(-) diff --git a/citadel/clientsocket.c b/citadel/clientsocket.c index 3a3ac483e..385f25e94 100644 --- a/citadel/clientsocket.c +++ b/citadel/clientsocket.c @@ -274,7 +274,7 @@ INLINE int sock_read(int *sock, char *buf, int bytes, int keep_reading_until_ful * sock_write() - send binary to server. * Returns the number of bytes written, or -1 for error. */ -int sock_write(int *sock, char *buf, int nbytes) +int sock_write(int *sock, const char *buf, int nbytes) { int bytes_written = 0; int retval; diff --git a/citadel/clientsocket.h b/citadel/clientsocket.h index 6d5189d4a..0274052a5 100644 --- a/citadel/clientsocket.h +++ b/citadel/clientsocket.h @@ -23,7 +23,7 @@ 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_write(int *sock, char *buf, int nbytes); +int sock_write(int *sock, const char *buf, int nbytes); int ml_sock_gets(int *sock, char *buf); int sock_getln(int *sock, char *buf, int bufsize); int CtdlSockGetLine(int *sock, StrBuf *Target); diff --git a/citadel/context.h b/citadel/context.h index ddf8d6ca1..42e0b2898 100644 --- a/citadel/context.h +++ b/citadel/context.h @@ -38,9 +38,7 @@ struct CitContext { 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? */ - char *redirect_buffer; /* the buffer */ - size_t redirect_len; /* length of data in buffer */ - size_t redirect_alloc; /* length of allocated buffer */ + StrBuf *redirect_buffer; /* the buffer */ #ifdef HAVE_OPENSSL SSL *ssl; int redirect_ssl; diff --git a/citadel/internet_addressing.c b/citadel/internet_addressing.c index 5f3a8b5c9..006ad8e9b 100644 --- a/citadel/internet_addressing.c +++ b/citadel/internet_addressing.c @@ -838,7 +838,7 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822) * The caller is responsible for freeing the returned buffer. If the requested * field is not present, or anything else goes wrong, it returns NULL. */ -char *rfc822_fetch_field(char *rfc822, const char *fieldname) { +char *rfc822_fetch_field(const char *rfc822, const char *fieldname) { char *fieldbuf = NULL; const char *end_of_headers; const char *field_start; diff --git a/citadel/internet_addressing.h b/citadel/internet_addressing.h index ca4c2da6e..77486d061 100644 --- a/citadel/internet_addressing.h +++ b/citadel/internet_addressing.h @@ -15,7 +15,7 @@ struct internet_address_list { int fuzzy_match(struct ctdluser *us, char *matchstring); void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name); -char *rfc822_fetch_field(char *rfc822, const char *fieldname); +char *rfc822_fetch_field(const char *rfc822, const char *fieldname); int IsDirectory(char *addr, int allow_masq_domains); void CtdlDirectoryInit(void); diff --git a/citadel/journaling.c b/citadel/journaling.c index 80122f25a..38201ff52 100644 --- a/citadel/journaling.c +++ b/citadel/journaling.c @@ -56,20 +56,20 @@ struct jnlq *jnlq = NULL; /* journal queue */ * Hand off a copy of a message to be journalized. */ void JournalBackgroundSubmit(struct CtdlMessage *msg, - char *saved_rfc822_version, + StrBuf *saved_rfc822_version, struct recptypes *recps) { struct jnlq *jptr = NULL; /* Avoid double journaling! */ if (msg->cm_fields['J'] != NULL) { - free(saved_rfc822_version); + FreeStrBuf(&saved_rfc822_version); return; } jptr = (struct jnlq *)malloc(sizeof(struct jnlq)); if (jptr == NULL) { - free(saved_rfc822_version); + FreeStrBuf(&saved_rfc822_version); return; } memset(jptr, 0, sizeof(struct jnlq)); @@ -79,7 +79,7 @@ void JournalBackgroundSubmit(struct CtdlMessage *msg, if (msg->cm_fields['F'] != NULL) jptr->rfca = strdup(msg->cm_fields['F']); if (msg->cm_fields['U'] != NULL) jptr->subj = strdup(msg->cm_fields['U']); if (msg->cm_fields['I'] != NULL) jptr->msgn = strdup(msg->cm_fields['I']); - jptr->rfc822 = saved_rfc822_version; + jptr->rfc822 = SmashStrBuf(&saved_rfc822_version); /* Add to the queue */ begin_critical_section(S_JOURNAL_QUEUE); diff --git a/citadel/journaling.h b/citadel/journaling.h index 2432ddeb4..017bc6a37 100644 --- a/citadel/journaling.h +++ b/citadel/journaling.h @@ -1,4 +1,4 @@ -/* $Id: $ */ +/* $Id$ */ struct jnlq { struct jnlq *next; @@ -12,7 +12,7 @@ struct jnlq { }; void JournalBackgroundSubmit(struct CtdlMessage *msg, - char *saved_rfc822_version, + StrBuf *saved_rfc822_version, struct recptypes *recps); void JournalRunQueueMsg(struct jnlq *jmsg); void JournalRunQueue(void); diff --git a/citadel/modules/clamav/serv_virus.c b/citadel/modules/clamav/serv_virus.c index 7d2aba4c7..155349892 100644 --- a/citadel/modules/clamav/serv_virus.c +++ b/citadel/modules/clamav/serv_virus.c @@ -83,8 +83,7 @@ int clamd(struct CtdlMessage *msg) { char portbuf[SIZ]; int is_virus = 0; int clamhost; - char *msgtext; - size_t msglen; + StrBuf *msgtext; CitContext *CCC; /* Don't care if you're logged in. You can still spread viruses. @@ -159,18 +158,13 @@ int clamd(struct CtdlMessage *msg) { /* Message */ - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, 0); msgtext = CC->redirect_buffer; - msglen = CC->redirect_len; CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; - sock_write(&streamsock, msgtext, msglen); - free(msgtext); + sock_write(&streamsock, SKEY(msgtext)); + FreeStrBuf(&msgtext); /* Close the streamsocket connection; this tells clamd * that we're done. diff --git a/citadel/modules/fulltext/serv_fulltext.c b/citadel/modules/fulltext/serv_fulltext.c index 0c2786d0d..1e461a152 100644 --- a/citadel/modules/fulltext/serv_fulltext.c +++ b/citadel/modules/fulltext/serv_fulltext.c @@ -123,7 +123,8 @@ void ft_index_message(long msgnum, int op) { int *tokens = NULL; int i, j; struct cdbdata *cdb_bucket; - char *msgtext; + StrBuf *msgtext; + char *txt; int tok; struct CtdlMessage *msg = NULL; @@ -146,18 +147,15 @@ void ft_index_message(long msgnum, int op) { /* Output the message as text before indexing it, so we don't end up * indexing a bunch of encoded base64, etc. */ - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_CITADEL, HEADERS_ALL, 0, 1, 0); CtdlFreeMessage(msg); msgtext = CC->redirect_buffer; CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; CtdlLogPrintf(CTDL_DEBUG, "Wordbreaking message %ld...\n", msgnum); - wordbreaker(msgtext, &num_tokens, &tokens); - free(msgtext); + txt = SmashStrBuf(&msgtext); + wordbreaker(txt, &num_tokens, &tokens); + free(txt); CtdlLogPrintf(CTDL_DEBUG, "Indexing message %ld [%d tokens]\n", msgnum, num_tokens); if (num_tokens > 0) { diff --git a/citadel/modules/imap/imap_fetch.c b/citadel/modules/imap/imap_fetch.c index 5b80dd974..d0afd3207 100644 --- a/citadel/modules/imap/imap_fetch.c +++ b/citadel/modules/imap/imap_fetch.c @@ -185,21 +185,16 @@ void imap_fetch_rfc822(long msgnum, const char *whichfmt) { /* * Load the message into memory for translation & measurement */ - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputMsg(msgnum, MT_RFC822, (need_body ? HEADERS_ALL : HEADERS_FAST), 0, 1, NULL, SUPPRESS_ENV_TO ); if (!need_body) cprintf("\r\n"); /* extra trailing newline */ - IMAP->cached_rfc822_data = CC->redirect_buffer; - IMAP->cached_rfc822_len = CC->redirect_len; + IMAP->cached_rfc822_len = StrLength(CC->redirect_buffer); + IMAP->cached_rfc822_data = SmashStrBuf(&CC->redirect_buffer); IMAP->cached_rfc822_msgnum = msgnum; IMAP->cached_rfc822_withbody = need_body; - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; if ( (need_to_rewrite_metadata) && (IMAP->cached_rfc822_len > 0) ) { smi.meta_rfc822_length = (long)IMAP->cached_rfc822_len; PutMetaData(&smi); @@ -507,57 +502,60 @@ void imap_fetch_envelope(struct CtdlMessage *msg) { * RFC822 headers with no body attached. Its job is to strip that set of * headers down to *only* the ones we're interested in. */ -void imap_strip_headers(char *section) { +void imap_strip_headers(StrBuf *section) { + citimap_command Cmd; char buf[SIZ]; - char *which_fields = NULL; + StrBuf *which_fields = NULL; int doing_headers = 0; int headers_not = 0; - char *parms[SIZ]; - int num_parms = 0; + int num_parms = 0; int i; - char *boiled_headers = NULL; + StrBuf *boiled_headers = NULL; + StrBuf *Line; int ok = 0; int done_headers = 0; - const char *ptr = NULL; + const char *Ptr = NULL; if (CC->redirect_buffer == NULL) return; - which_fields = strdup(section); + which_fields = NewStrBufDup(section); - if (!strncasecmp(which_fields, "HEADER.FIELDS", 13)) + if (!strncasecmp(ChrPtr(which_fields), "HEADER.FIELDS", 13)) doing_headers = 1; - if (!strncasecmp(which_fields, "HEADER.FIELDS.NOT", 17)) + if (!strncasecmp(ChrPtr(which_fields), "HEADER.FIELDS.NOT", 17)) headers_not = 1; - for (i=0; which_fields[i]; ++i) { - if (which_fields[i]=='(') - strcpy(which_fields, &which_fields[i+1]); + for (i=0; i < StrLength(which_fields); ++i) { + if (ChrPtr(which_fields)[i]=='(') + StrBufReplaceToken(which_fields, i, 1, HKEY("")); } - for (i=0; which_fields[i]; ++i) { - if (which_fields[i]==')') { - which_fields[i] = 0; + for (i=0; i < StrLength(which_fields); ++i) { + if (ChrPtr(which_fields)[i]==')') { + StrBufCutAt(which_fields, i, NULL); break; } } - num_parms = old_imap_parameterize(parms, which_fields); - - boiled_headers = malloc(CC->redirect_alloc); - strcpy(boiled_headers, ""); + memset(&Cmd, 0, sizeof(citimap_command)); + Cmd.CmdBuf = which_fields; + num_parms = imap_parameterize(&Cmd); - ptr = CC->redirect_buffer; + boiled_headers = NewStrBufPlain(NULL, StrLength(CC->redirect_buffer)); + Ptr = NULL; ok = 0; do { - ptr = memreadline(ptr, buf, sizeof buf); - if (!isspace(buf[0])) { + StrBufSipLine(CC->redirect_buffer, Line, &Ptr); + + if (!isspace(ChrPtr(Line)[0])) { ok = 0; if (doing_headers == 0) ok = 1; else { if (headers_not) ok = 1; else ok = 0; for (i=0; iredirect_buffer, boiled_headers); - CC->redirect_len = strlen(boiled_headers); + FreeStrBuf(&CC->redirect_buffer); + CC->redirect_buffer = boiled_headers; - free(which_fields); - free(boiled_headers); + FreeStrBuf(&which_fields); + FreeStrBuf(&Line); } /* * Implements the BODY and BODY.PEEK fetch items */ -void imap_fetch_body(long msgnum, const char *item, int is_peek) { +void imap_fetch_body(long msgnum, ConstStr item, int is_peek) { struct CtdlMessage *msg = NULL; - char section[SIZ]; + StrBuf *section; char partial[SIZ]; int is_partial = 0; size_t pstart, pbytes; @@ -601,13 +599,14 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { int burn_the_cache = 0; /* extract section */ - safestrncpy(section, item, sizeof section); - if (strchr(section, '[') != NULL) { - stripallbut(section, '[', ']'); + section = NewStrBufPlain(CKEY(item)); + + if (strchr(ChrPtr(section), '[') != NULL) { + StrBufStripAllBut(section, '[', ']'); } CtdlLogPrintf(CTDL_DEBUG, "Section is: %s%s\n", - section, - IsEmptyStr(section) ? "(empty)" : "" + ChrPtr(section), + (StrLength(section) == 0) ? "(empty)" : "" ); /* Burn the cache if we don't have the same section of the @@ -620,7 +619,7 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { else if ( (!IMAP->cached_body_withbody) && (need_body) ) { burn_the_cache = 1; } - else if (strcasecmp(IMAP->cached_bodypart, section)) { + else if (strcasecmp(IMAP->cached_bodypart, ChrPtr(section))) { burn_the_cache = 1; } if (burn_the_cache) { @@ -634,7 +633,7 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { } /* extract partial */ - safestrncpy(partial, item, sizeof partial); + safestrncpy(partial, item.Key, sizeof partial); if (strchr(partial, '<') != NULL) { stripallbut(partial, '<', '>'); is_partial = 1; @@ -643,9 +642,7 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { /* if (!IsEmptyStr(partial)) CtdlLogPrintf(CTDL_DEBUG, "Partial is %s\n", partial); */ if (IMAP->cached_body == NULL) { - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); loading_body_now = 1; msg = CtdlFetchMessage(msgnum, (need_body ? 1 : 0)); } @@ -656,11 +653,11 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { /* What we want is already in memory */ } - else if ( (!strcmp(section, "1")) && (msg->cm_format_type != 4) ) { + else if ( (!strcmp(ChrPtr(section), "1")) && (msg->cm_format_type != 4) ) { CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_NONE, 0, 1, SUPPRESS_ENV_TO); } - else if (!strcmp(section, "")) { + else if (StrLength(section) == 0) { CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, SUPPRESS_ENV_TO); } @@ -668,7 +665,7 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { * If the client asked for just headers, or just particular header * fields, strip it down. */ - else if (!strncasecmp(section, "HEADER", 6)) { + else if (!strncasecmp(ChrPtr(section), "HEADER", 6)) { /* This used to work with HEADERS_FAST, but then Apple got stupid with their * IMAP library and this broke Mail.App and iPhone Mail, so we had to change it * to HEADERS_ONLY so the trendy hipsters with their iPhones can read mail. @@ -680,7 +677,7 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { /* * Strip it down if the client asked for everything _except_ headers. */ - else if (!strncasecmp(section, "TEXT", 4)) { + else if (!strncasecmp(ChrPtr(section), "TEXT", 4)) { CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_NONE, 0, 1, SUPPRESS_ENV_TO); } @@ -696,18 +693,15 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { } if (loading_body_now) { - IMAP->cached_body = CC->redirect_buffer; - IMAP->cached_body_len = CC->redirect_len; + IMAP->cached_body_len = StrLength(CC->redirect_buffer); + IMAP->cached_body = SmashStrBuf(&CC->redirect_buffer); IMAP->cached_bodymsgnum = msgnum; IMAP->cached_body_withbody = need_body; - strcpy(IMAP->cached_bodypart, section); - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; + strcpy(IMAP->cached_bodypart, ChrPtr(section)); } if (is_partial == 0) { - cprintf("BODY[%s] {" SIZE_T_FMT "}\r\n", section, IMAP->cached_body_len); + cprintf("BODY[%s] {" SIZE_T_FMT "}\r\n", ChrPtr(section), IMAP->cached_body_len); pstart = 0; pbytes = IMAP->cached_body_len; } @@ -716,7 +710,7 @@ void imap_fetch_body(long msgnum, const char *item, int is_peek) { if (pbytes > (IMAP->cached_body_len - pstart)) { pbytes = IMAP->cached_body_len - pstart; } - cprintf("BODY[%s]<" SIZE_T_FMT "> {" SIZE_T_FMT "}\r\n", section, pstart, pbytes); + cprintf("BODY[%s]<" SIZE_T_FMT "> {" SIZE_T_FMT "}\r\n", ChrPtr(section), pstart, pbytes); } /* Here we go -- output it */ @@ -923,15 +917,10 @@ void imap_fetch_bodystructure (long msgnum, const char *item, * to measure it. FIXME use smi cached fields if possible */ - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_RFC822, 0, 0, 1, SUPPRESS_ENV_TO); - rfc822 = pch = CC->redirect_buffer; - rfc822_len = CC->redirect_len; - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; + rfc822_len = StrLength(CC->redirect_buffer); + rfc822 = pch = SmashStrBuf(&CC->redirect_buffer); ptr = rfc822; do { @@ -1010,10 +999,10 @@ void imap_do_fetch_msg(int seq, citimap_command *Cmd) { /* BODY fetches do their own fetching and caching too. */ else if (!strncasecmp(Cmd->Params[i].Key, "BODY[", 5)) { - imap_fetch_body(Imap->msgids[seq-1], Cmd->Params[i].Key, 0); + imap_fetch_body(Imap->msgids[seq-1], Cmd->Params[i], 0); } else if (!strncasecmp(Cmd->Params[i].Key, "BODY.PEEK[", 10)) { - imap_fetch_body(Imap->msgids[seq-1], Cmd->Params[i].Key, 1); + imap_fetch_body(Imap->msgids[seq-1], Cmd->Params[i], 1); } /* Otherwise, load the message into memory. diff --git a/citadel/modules/imap/imap_search.c b/citadel/modules/imap/imap_search.c index 9fe720513..4972e98e7 100644 --- a/citadel/modules/imap/imap_search.c +++ b/citadel/modules/imap/imap_search.c @@ -256,12 +256,10 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, if (msg != NULL) { - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_FAST, 0, 1, 0); - fieldptr = rfc822_fetch_field(CC->redirect_buffer, itemlist[pos+1].Key); + fieldptr = rfc822_fetch_field(ChrPtr(CC->redirect_buffer), itemlist[pos+1].Key); if (fieldptr != NULL) { if (bmstrcasestr(fieldptr, itemlist[pos+2].Key)) { match = 1; @@ -269,10 +267,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg, free(fieldptr); } - free(CC->redirect_buffer); - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; + FreeStrBuf(&CC->redirect_buffer); } pos += 3; /* Yes, three */ diff --git a/citadel/modules/network/serv_network.c b/citadel/modules/network/serv_network.c index 6e053c961..71f895c48 100644 --- a/citadel/modules/network/serv_network.c +++ b/citadel/modules/network/serv_network.c @@ -716,20 +716,17 @@ void network_spool_msg(long msgnum, void *userdata) { fprintf(sc->digestfp, "Subject: %s\n", msg->cm_fields['U']); } - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; - + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); + safestrncpy(CC->preferred_formats, "text/plain", sizeof CC->preferred_formats); CtdlOutputPreLoadedMsg(msg, MT_CITADEL, HEADERS_NONE, 0, 0, 0); - striplt(CC->redirect_buffer); - fprintf(sc->digestfp, "\n%s\n", CC->redirect_buffer); + StrBufTrim(CC->redirect_buffer); + fwrite(HKEY("\n"), 1, sc->digestfp); + fwrite(SKEY(CC->redirect_buffer), 1, sc->digestfp); + fwrite(HKEY("\n"), 1, sc->digestfp); - free(CC->redirect_buffer); - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; + FreeStrBuf(&CC->redirect_buffer); sc->num_msgs_spooled += 1; free(msg); diff --git a/citadel/modules/pop3/serv_pop3.c b/citadel/modules/pop3/serv_pop3.c index 258193ab5..7dd317db3 100644 --- a/citadel/modules/pop3/serv_pop3.c +++ b/citadel/modules/pop3/serv_pop3.c @@ -169,15 +169,10 @@ void pop3_add_message(long msgnum, void *userdata) { */ GetMetaData(&smi, msgnum); if (smi.meta_rfc822_length <= 0L) { - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL, SUPPRESS_ENV_TO); - smi.meta_rfc822_length = CC->redirect_len; - free(CC->redirect_buffer); - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; + smi.meta_rfc822_length = StrLength(CC->redirect_buffer); + FreeStrBuf(&CC->redirect_buffer); /* TODO: WHEW, all this for just knowing the length???? */ PutMetaData(&smi); } POP3->msgs[POP3->num_msgs-1].rfc822_length = smi.meta_rfc822_length; @@ -402,7 +397,7 @@ void pop3_top(char *argbuf) { int lines_requested = 0; int lines_dumped = 0; char buf[1024]; - char *msgtext; + StrBuf *msgtext; const char *ptr; int in_body = 0; int done = 0; @@ -418,19 +413,15 @@ void pop3_top(char *argbuf) { return; } - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputMsg(POP3->msgs[which_one - 1].msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL, SUPPRESS_ENV_TO); msgtext = CC->redirect_buffer; CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; cprintf("+OK Message %d:\r\n", which_one); - - ptr = msgtext; - + + ptr = ChrPtr(msgtext); + // TODO: use buffer stuff here while (ptr = memreadline(ptr, buf, (sizeof buf - 2)), ( (*ptr != 0) && (done == 0))) { strcat(buf, "\r\n"); @@ -449,7 +440,7 @@ void pop3_top(char *argbuf) { } if (buf[strlen(buf)-1] != 10) cprintf("\n"); - free(msgtext); + FreeStrBuf(&msgtext); cprintf(".\r\n"); } diff --git a/citadel/modules/sieve/serv_sieve.c b/citadel/modules/sieve/serv_sieve.c index 4ca061eae..e166964e1 100644 --- a/citadel/modules/sieve/serv_sieve.c +++ b/citadel/modules/sieve/serv_sieve.c @@ -542,15 +542,10 @@ void sieve_do_msg(long msgnum, void *userdata) { * Grab the message headers so we can feed them to libSieve. * Use HEADERS_ONLY rather than HEADERS_FAST in order to include second-level headers. */ - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ONLY, 0, 1, 0); - my.rfc822headers = CC->redirect_buffer; - headers_len = CC->redirect_len; - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; + headers_len = StrLength(CC->redirect_buffer); + my.rfc822headers = SmashStrBuf(&CC->redirect_buffer); /* * libSieve clobbers the stack if it encounters badly formed diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index e0253672c..5e5707d2f 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -988,15 +988,10 @@ void smtp_try(const char *key, const char *addr, int *status, user, node, name); /* Load the message out of the database */ - CCC->redirect_buffer = malloc(SIZ); - CCC->redirect_len = 0; - CCC->redirect_alloc = SIZ; + CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL, ESC_DOT); - msgtext = CC->redirect_buffer; - msg_size = CC->redirect_len; - CCC->redirect_buffer = NULL; - CCC->redirect_len = 0; - CCC->redirect_alloc = 0; + msg_size = StrLength(CC->redirect_buffer); + msgtext = SmashStrBuf(&CC->redirect_buffer); /* If no envelope_from is supplied, extract one from the message */ if ( (envelope_from == NULL) || (IsEmptyStr(envelope_from)) ) { @@ -1336,7 +1331,7 @@ void smtp_do_bounce(char *instr) { char addr[1024]; char dsn[1024]; char bounceto[1024]; - char boundary[64]; + StrBuf *boundary; int num_bounces = 0; int bounce_this = 0; long bounce_msgid = (-1); @@ -1346,13 +1341,13 @@ void smtp_do_bounce(char *instr) { struct recptypes *valid; int successful_bounce = 0; static int seq = 0; - char *omsgtext; - size_t omsgsize; + StrBuf *BounceMB; long omsgid = (-1); CtdlLogPrintf(CTDL_DEBUG, "smtp_do_bounce() called\n"); strcpy(bounceto, ""); - sprintf(boundary, "=_Citadel_Multipart_%s_%04x%04x", config.c_fqdn, getpid(), ++seq); + boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_")); + StrBufAppendPrintf(boundary, "%s_%04x%04x", config.c_fqdn, getpid(), ++seq); lines = num_tokens(instr, '\n'); /* See if it's time to give up on delivery of this message */ @@ -1374,6 +1369,7 @@ void smtp_do_bounce(char *instr) { bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); if (bmsg == NULL) return; memset(bmsg, 0, sizeof(struct CtdlMessage)); + BounceMB = NewStrBufPlain(NULL, 1024); bmsg->cm_magic = CTDLMESSAGE_MAGIC; bmsg->cm_anon_type = MES_NORMAL; @@ -1382,39 +1378,39 @@ void smtp_do_bounce(char *instr) { bmsg->cm_fields['O'] = strdup(MAILROOM); bmsg->cm_fields['N'] = strdup(config.c_nodename); bmsg->cm_fields['U'] = strdup("Delivery Status Notification (Failure)"); - bmsg->cm_fields['M'] = malloc(1024); - - strcpy(bmsg->cm_fields['M'], "Content-type: multipart/mixed; boundary=\""); - strcat(bmsg->cm_fields['M'], boundary); - strcat(bmsg->cm_fields['M'], "\"\r\n"); - strcat(bmsg->cm_fields['M'], "MIME-Version: 1.0\r\n"); - strcat(bmsg->cm_fields['M'], "X-Mailer: " CITADEL "\r\n"); - strcat(bmsg->cm_fields['M'], "\r\nThis is a multipart message in MIME format.\r\n\r\n"); - strcat(bmsg->cm_fields['M'], "--"); - strcat(bmsg->cm_fields['M'], boundary); - strcat(bmsg->cm_fields['M'], "\r\n"); - strcat(bmsg->cm_fields['M'], "Content-type: text/plain\r\n\r\n"); - - if (give_up) strcat(bmsg->cm_fields['M'], + StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0); + StrBufAppendBuf(BounceMB, boundary, 0); + StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("\r\nThis is a multipart message in MIME format.\r\n\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); + StrBufAppendBuf(BounceMB, boundary, 0); + StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0); + + if (give_up) StrBufAppendBufPlain(BounceMB, HKEY( "A message you sent could not be delivered to some or all of its recipients\n" "due to prolonged unavailability of its destination(s).\n" "Giving up on the following addresses:\n\n" -); + ), 0); - else strcat(bmsg->cm_fields['M'], + else StrBufAppendBufPlain(BounceMB, HKEY( "A message you sent could not be delivered to some or all of its recipients.\n" "The following addresses were undeliverable:\n\n" -); + ), 0); /* * Now go through the instructions checking for stuff. */ for (i=0; i addr=<%s> status=%d dsn=<%s>\n", @@ -1436,17 +1432,10 @@ void smtp_do_bounce(char *instr) { if (bounce_this) { ++num_bounces; - if (bmsg->cm_fields['M'] == NULL) { - CtdlLogPrintf(CTDL_ERR, "ERROR ... M field is null " - "(%s:%d)\n", __FILE__, __LINE__); - } - - bmsg->cm_fields['M'] = realloc(bmsg->cm_fields['M'], - strlen(bmsg->cm_fields['M']) + 1024 ); - strcat(bmsg->cm_fields['M'], addr); - strcat(bmsg->cm_fields['M'], ": "); - strcat(bmsg->cm_fields['M'], dsn); - strcat(bmsg->cm_fields['M'], "\r\n"); + StrBufAppendBufPlain(BounceMB, addr, addrlen, 0); + StrBufAppendBufPlain(BounceMB, HKEY(": "), 0); + StrBufAppendBufPlain(BounceMB, dsn, dsnlen, 0); + StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); remove_token(instr, i, '\n'); --i; @@ -1456,34 +1445,25 @@ void smtp_do_bounce(char *instr) { /* Attach the original message */ if (omsgid >= 0) { - strcat(bmsg->cm_fields['M'], "--"); - strcat(bmsg->cm_fields['M'], boundary); - strcat(bmsg->cm_fields['M'], "\r\n"); - strcat(bmsg->cm_fields['M'], "Content-type: message/rfc822\r\n"); - strcat(bmsg->cm_fields['M'], "Content-Transfer-Encoding: 7bit\r\n"); - strcat(bmsg->cm_fields['M'], "Content-Disposition: inline\r\n"); - strcat(bmsg->cm_fields['M'], "\r\n"); + StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); + StrBufAppendBuf(BounceMB, boundary, 0); + StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("Content-type: message/rfc822\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("Content-Disposition: inline\r\n"), 0); + StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputMsg(omsgid, MT_RFC822, HEADERS_ALL, 0, 1, NULL, 0); - omsgtext = CC->redirect_buffer; - omsgsize = CC->redirect_len; - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; - bmsg->cm_fields['M'] = realloc(bmsg->cm_fields['M'], - (strlen(bmsg->cm_fields['M']) + omsgsize + 1024) ); - strcat(bmsg->cm_fields['M'], omsgtext); - free(omsgtext); + StrBufAppendBuf(BounceMB, CC->redirect_buffer, 0); + FreeStrBuf(&CC->redirect_buffer); } /* Close the multipart MIME scope */ - strcat(bmsg->cm_fields['M'], "--"); - strcat(bmsg->cm_fields['M'], boundary); - strcat(bmsg->cm_fields['M'], "--\r\n"); - + StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); + StrBufAppendBuf(BounceMB, boundary, 0); + StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0); + bmsg->cm_fields['A'] = SmashStrBuf(&BounceMB); /* Deliver the bounce if there's anything worth mentioning */ CtdlLogPrintf(CTDL_DEBUG, "num_bounces = %d\n", num_bounces); if (num_bounces > 0) { @@ -1514,7 +1494,7 @@ void smtp_do_bounce(char *instr) { free_recipients(valid); } } - + FreeStrBuf(&boundary); CtdlFreeMessage(bmsg); CtdlLogPrintf(CTDL_DEBUG, "Done processing bounces\n"); } diff --git a/citadel/modules/spam/serv_spam.c b/citadel/modules/spam/serv_spam.c index b8f3a6c96..5359a1a4b 100644 --- a/citadel/modules/spam/serv_spam.c +++ b/citadel/modules/spam/serv_spam.c @@ -80,8 +80,7 @@ int spam_assassin(struct CtdlMessage *msg) { char buf[SIZ]; int is_spam = 0; int sa; - char *msgtext; - size_t msglen; + StrBuf *msgtext; CitContext *CCC=CC; /* For users who have authenticated to this server we never want to @@ -118,18 +117,13 @@ int spam_assassin(struct CtdlMessage *msg) { sock_write(&sock, buf, strlen(buf)); /* Message */ - CCC->redirect_buffer = malloc(SIZ); - CCC->redirect_len = 0; - CCC->redirect_alloc = SIZ; + CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, 0); msgtext = CC->redirect_buffer; - msglen = CC->redirect_len; - CCC->redirect_buffer = NULL; - CCC->redirect_len = 0; - CCC->redirect_alloc = 0; + CC->redirect_buffer = NULL; - sock_write(&sock, msgtext, msglen); - free(msgtext); + sock_write(&sock, SKEY(msgtext)); + FreeStrBuf(&msgtext); /* Close one end of the socket connection; this tells SpamAssassin * that we're done. diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 838beb0b6..ee1ddf599 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -2768,7 +2768,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ char *hold_R, *hold_D; char *collected_addresses = NULL; struct addresses_to_be_filed *aptr = NULL; - char *saved_rfc822_version = NULL; + StrBuf *saved_rfc822_version = NULL; int qualified_for_journaling = 0; CitContext *CCC = CC; /* CachedCitContext - performance boost */ char bounce_to[1024] = ""; @@ -2919,15 +2919,11 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ CtdlLogPrintf(CTDL_ALERT, "CCC->redirect_buffer is not NULL during message submission!\n"); abort(); } - CCC->redirect_buffer = malloc(SIZ); - CCC->redirect_len = 0; - CCC->redirect_alloc = SIZ; + CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, QP_EADDR); - smi.meta_rfc822_length = CCC->redirect_len; + smi.meta_rfc822_length = StrLength(CCC->redirect_buffer); saved_rfc822_version = CCC->redirect_buffer; CCC->redirect_buffer = NULL; - CCC->redirect_len = 0; - CCC->redirect_alloc = 0; PutMetaData(&smi); diff --git a/citadel/sysdep.c b/citadel/sysdep.c index f183b4ac9..135e1c1ee 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -466,14 +466,8 @@ int client_write(const char *buf, int nbytes) // flush_client_inbuf(); Ctx = CC; if (Ctx->redirect_buffer != NULL) { - if ((Ctx->redirect_len + nbytes + 2) >= Ctx->redirect_alloc) { - Ctx->redirect_alloc = (Ctx->redirect_alloc * 2) + nbytes; - Ctx->redirect_buffer = realloc(Ctx->redirect_buffer, - Ctx->redirect_alloc); - } - memcpy(&Ctx->redirect_buffer[Ctx->redirect_len], buf, nbytes); - Ctx->redirect_len += nbytes; - Ctx->redirect_buffer[Ctx->redirect_len] = 0; + StrBufAppendBufPlain(Ctx->redirect_buffer, + buf, nbytes, 0); return 0; } -- 2.30.2