From 848934c1722edc208c4df49c571586b72c3fc486 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Sun, 1 Sep 2013 12:30:27 +0200 Subject: [PATCH] Route all access to cm_fields[] through api functions --- citadel/internet_addressing.c | 72 ++++---- citadel/journaling.c | 151 +++++++++++------ citadel/modules/blog/serv_blog.c | 10 +- citadel/modules/calendar/serv_calendar.c | 58 +++---- citadel/modules/clamav/serv_virus.c | 5 +- citadel/modules/extnotify/extnotify_main.c | 4 +- citadel/modules/imap/imap_misc.c | 16 +- citadel/modules/instmsg/serv_instmsg.c | 13 +- citadel/modules/network/netspool.h | 2 +- citadel/modules/network/serv_netmail.c | 65 +++----- citadel/modules/network/serv_netspool.c | 44 +++-- citadel/modules/network/serv_network.c | 67 +++----- citadel/modules/notes/serv_notes.c | 27 +-- citadel/modules/rssclient/rss_atom_parser.c | 8 +- citadel/modules/rssclient/serv_rssclient.c | 27 ++- citadel/modules/sieve/serv_sieve.c | 5 +- citadel/modules/smtp/serv_smtp.c | 27 +-- citadel/modules/smtp/serv_smtpeventclient.c | 4 +- citadel/modules/smtp/serv_smtpqueue.c | 10 +- citadel/modules/smtp/smtp_util.c | 12 +- citadel/modules/spam/serv_spam.c | 26 ++- citadel/modules/vcard/serv_vcard.c | 72 ++++---- citadel/modules/wiki/serv_wiki.c | 176 +++++++++++--------- citadel/msgbase.c | 171 +++++++++++++++---- citadel/msgbase.h | 11 +- 25 files changed, 585 insertions(+), 498 deletions(-) diff --git a/citadel/internet_addressing.c b/citadel/internet_addressing.c index b4663fc36..14c9900df 100644 --- a/citadel/internet_addressing.c +++ b/citadel/internet_addressing.c @@ -553,7 +553,6 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) { int i; const char *colonpos = NULL; int processed = 0; - char buf[SIZ]; char user[1024]; char node[1024]; char name[1024]; @@ -589,44 +588,44 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) { if (!strcasecmp(key, "Date")) { parsed_date = parsedate(value); if (parsed_date < 0L) parsed_date = time(NULL); - snprintf(buf, sizeof buf, "%ld", (long)parsed_date ); + if (msg->cm_fields[eTimestamp] == NULL) - msg->cm_fields[eTimestamp] = strdup(buf); + CM_SetFieldLONG(msg, eTimestamp, parsed_date); processed = 1; } else if (!strcasecmp(key, "From")) { process_rfc822_addr(value, user, node, name); syslog(LOG_DEBUG, "Converted to <%s@%s> (%s)\n", user, node, name); - snprintf(addr, sizeof addr, "%s@%s", user, node); + snprintf(addr, sizeof(addr), "%s@%s", user, node); if (msg->cm_fields[eAuthor] == NULL) - msg->cm_fields[eAuthor] = strdup(name); + CM_SetField(msg, eAuthor, name, strlen(name)); if (msg->cm_fields[erFc822Addr] == NULL) - msg->cm_fields[erFc822Addr] = strdup(addr); + CM_SetField(msg, erFc822Addr, addr, strlen(addr)); processed = 1; } else if (!strcasecmp(key, "Subject")) { if (msg->cm_fields[eMsgSubject] == NULL) - msg->cm_fields[eMsgSubject] = strndup(value, valuelen); + CM_SetField(msg, eMsgSubject, value, valuelen); processed = 1; } else if (!strcasecmp(key, "List-ID")) { if (msg->cm_fields[eListID] == NULL) - msg->cm_fields[eListID] = strndup(value, valuelen); + CM_SetField(msg, eListID, value, valuelen); processed = 1; } else if (!strcasecmp(key, "To")) { if (msg->cm_fields[eRecipient] == NULL) - msg->cm_fields[eRecipient] = strndup(value, valuelen); + CM_SetField(msg, eRecipient, value, valuelen); processed = 1; } else if (!strcasecmp(key, "CC")) { if (msg->cm_fields[eCarbonCopY] == NULL) - msg->cm_fields[eCarbonCopY] = strndup(value, valuelen); + CM_SetField(msg, eCarbonCopY, value, valuelen); processed = 1; } @@ -634,18 +633,25 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) { if (msg->cm_fields[emessageId] != NULL) { syslog(LOG_WARNING, "duplicate message id\n"); } + else { + char *pValue; + long pValueLen; - if (msg->cm_fields[emessageId] == NULL) { - msg->cm_fields[emessageId] = strndup(value, valuelen); - + pValue = value; + pValueLen = valuelen; /* Strip angle brackets */ - while (haschar(msg->cm_fields[emessageId], '<') > 0) { - strcpy(&msg->cm_fields[emessageId][0], - &msg->cm_fields[emessageId][1]); + while (haschar(pValue, '<') > 0) { + pValue ++; + pValueLen --; } - for (i = 0; icm_fields[emessageId]); ++i) - if (msg->cm_fields[emessageId][i] == '>') - msg->cm_fields[emessageId][i] = 0; + + for (i = 0; i <= pValueLen; ++i) + if (pValue[i] == '>') { + pValueLen = i; + break; + } + + CM_SetField(msg, emessageId, pValue, pValueLen); } processed = 1; @@ -653,36 +659,29 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) { else if (!strcasecmp(key, "Return-Path")) { if (msg->cm_fields[eMessagePath] == NULL) - msg->cm_fields[eMessagePath] = strndup(value, valuelen); + CM_SetField(msg, eMessagePath, value, valuelen); processed = 1; } else if (!strcasecmp(key, "Envelope-To")) { if (msg->cm_fields[eenVelopeTo] == NULL) - msg->cm_fields[eenVelopeTo] = strndup(value, valuelen); + CM_SetField(msg, eenVelopeTo, value, valuelen); processed = 1; } else if (!strcasecmp(key, "References")) { - if (msg->cm_fields[eWeferences] != NULL) { - free(msg->cm_fields[eWeferences]); - } - msg->cm_fields[eWeferences] = strndup(value, valuelen); + CM_SetField(msg, eWeferences, value, valuelen); processed = 1; } else if (!strcasecmp(key, "Reply-To")) { - if (msg->cm_fields[eReplyTo] != NULL) { - free(msg->cm_fields[eReplyTo]); - } - msg->cm_fields[eReplyTo] = strndup(value, valuelen); + CM_SetField(msg, eReplyTo, value, valuelen); processed = 1; } else if (!strcasecmp(key, "In-reply-to")) { - if (msg->cm_fields[eWeferences] == NULL) { /* References: supersedes In-reply-to: */ - msg->cm_fields[eWeferences] = strndup(value, valuelen); - } + if (msg->cm_fields[eWeferences] == NULL) /* References: supersedes In-reply-to: */ + CM_SetField(msg, eWeferences, value, valuelen); processed = 1; } @@ -690,7 +689,7 @@ int convert_field(struct CtdlMessage *msg, const char *beg, const char *end) { /* Clean up and move on. */ free(key); /* Don't free 'value', it's actually the same buffer */ - return(processed); + return processed; } @@ -749,7 +748,6 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822) struct CtdlMessage *msg; const char *pos, *beg, *end, *totalend; int done, alldone = 0; - char buf[SIZ]; int converted; StrBuf *OtherHeaders; @@ -818,20 +816,20 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822) if (pos < totalend) StrBufAppendBufPlain(OtherHeaders, pos, totalend - pos, 0); FreeStrBuf(rfc822); - msg->cm_fields[eMesageText] = SmashStrBuf(&OtherHeaders); + CM_SetAsFieldSB(msg, eMesageText, &OtherHeaders); /* Follow-up sanity checks... */ /* If there's no timestamp on this message, set it to now. */ if (msg->cm_fields[eTimestamp] == NULL) { - snprintf(buf, sizeof buf, "%ld", (long)time(NULL)); - msg->cm_fields[eTimestamp] = strdup(buf); + CM_SetFieldLONG(msg, eTimestamp, time(NULL)); } /* If a W (references, or rather, Wefewences) field is present, we * have to convert it from RFC822 format to Citadel format. */ if (msg->cm_fields[eWeferences] != NULL) { + /// todo: API! convert_references_to_wefewences(msg->cm_fields[eWeferences]); } diff --git a/citadel/journaling.c b/citadel/journaling.c index 26c273694..d1daf5a7a 100644 --- a/citadel/journaling.c +++ b/citadel/journaling.c @@ -123,8 +123,10 @@ void JournalRunQueueMsg(struct jnlq *jmsg) { struct CtdlMessage *journal_msg = NULL; struct recptypes *journal_recps = NULL; - char *message_text = NULL; + StrBuf *message_text = NULL; char mime_boundary[256]; + long mblen; + long rfc822len; char recipient[256]; char inetemail[256]; static int seq = 0; @@ -150,14 +152,17 @@ void JournalRunQueueMsg(struct jnlq *jmsg) { journal_msg->cm_magic = CTDLMESSAGE_MAGIC; journal_msg->cm_anon_type = MES_NORMAL; journal_msg->cm_format_type = FMT_RFC822; - journal_msg->cm_fields[eJournal] = strdup("is journal"); - journal_msg->cm_fields[eAuthor] = jmsg->from; - journal_msg->cm_fields[eNodeName] = jmsg->node; - journal_msg->cm_fields[erFc822Addr] = jmsg->rfca; - journal_msg->cm_fields[eMsgSubject] = jmsg->subj; - - sprintf(mime_boundary, "--Citadel-Journal-%08lx-%04x--", time(NULL), ++seq); - message_text = malloc(strlen(jmsg->rfc822) + sizeof(struct recptypes) + 1024); + CM_SetField(journal_msg, eJournal, HKEY("is journal")); + CM_SetField(journal_msg, eAuthor, jmsg->from, strlen(jmsg->from)); + CM_SetField(journal_msg, eNodeName, jmsg->node, strlen(jmsg->node)); + CM_SetField(journal_msg, erFc822Addr, jmsg->rfca, strlen(jmsg->rfca)); + CM_SetField(journal_msg, eMsgSubject, jmsg->subj, strlen(jmsg->subj)); + + mblen = snprintf(mime_boundary, sizeof(mime_boundary), + "--Citadel-Journal-%08lx-%04x--", time(NULL), ++seq); + rfc822len = strlen(jmsg->rfc822); + + message_text = NewStrBufPlain(NULL, rfc822len + sizeof(struct recptypes) + 1024); /* * Here is where we begin to compose the journalized message. @@ -165,45 +170,69 @@ void JournalRunQueueMsg(struct jnlq *jmsg) { * requested by a paying customer, and yes, it is intentionally * spelled wrong. Do NOT remove or change it. */ - sprintf(message_text, - "Content-type: multipart/mixed; boundary=\"%s\"\r\n" - "Content-Identifer: ExJournalReport\r\n" - "MIME-Version: 1.0\r\n" - "\n" - "--%s\r\n" - "Content-type: text/plain\r\n" - "\r\n" - "Sender: %s " - , - mime_boundary, - mime_boundary, - ( journal_msg->cm_fields[eAuthor] ? journal_msg->cm_fields[eAuthor] : "(null)" ) - ); + StrBufAppendBufPlain( + message_text, + HKEY("Content-type: multipart/mixed; boundary=\""), 0); + + StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0); + + StrBufAppendBufPlain( + message_text, + HKEY("\"\r\n" + "Content-Identifer: ExJournalReport\r\n" + "MIME-Version: 1.0\r\n" + "\n" + "--"), 0); + + StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0); + + StrBufAppendBufPlain( + message_text, + HKEY("\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "Sender: "), 0); + + if (journal_msg->cm_fields[eAuthor]) + StrBufAppendBufPlain( + message_text, + journal_msg->cm_fields[eAuthor], -1, 0); + else + StrBufAppendBufPlain( + message_text, + HKEY("(null)"), 0); if (journal_msg->cm_fields[erFc822Addr]) { - sprintf(&message_text[strlen(message_text)], "<%s>", - journal_msg->cm_fields[erFc822Addr]); + StrBufAppendPrintf(message_text, " <%s>", + journal_msg->cm_fields[erFc822Addr]); } else if (journal_msg->cm_fields[eNodeName]) { - sprintf(&message_text[strlen(message_text)], "@ %s", - journal_msg->cm_fields[eNodeName]); + StrBufAppendPrintf(message_text, " @ %s", + journal_msg->cm_fields[eNodeName]); } - - sprintf(&message_text[strlen(message_text)], - "\r\n" - "Message-ID: <%s>\r\n" - "Recipients:\r\n" - , - jmsg->msgn - ); + else + StrBufAppendBufPlain( + message_text, + HKEY(" "), 0); + + StrBufAppendBufPlain( + message_text, + HKEY("\r\n" + "Message-ID: <"), 0); + + StrBufAppendBufPlain(message_text, jmsg->msgn, -1, 0); + StrBufAppendBufPlain( + message_text, + HKEY(">\r\n" + "Recipients:\r\n"), 0); if (jmsg->recps.num_local > 0) { for (i=0; irecps.num_local; ++i) { extract_token(recipient, jmsg->recps.recp_local, i, '|', sizeof recipient); local_to_inetemail(inetemail, recipient, sizeof inetemail); - sprintf(&message_text[strlen(message_text)], - " %s <%s>\r\n", recipient, inetemail); + StrBufAppendPrintf(message_text, + " %s <%s>\r\n", recipient, inetemail); } } @@ -211,8 +240,8 @@ void JournalRunQueueMsg(struct jnlq *jmsg) { for (i=0; irecps.num_ignet; ++i) { extract_token(recipient, jmsg->recps.recp_ignet, i, '|', sizeof recipient); - sprintf(&message_text[strlen(message_text)], - " %s\r\n", recipient); + StrBufAppendPrintf(message_text, + " %s\r\n", recipient); } } @@ -220,27 +249,41 @@ void JournalRunQueueMsg(struct jnlq *jmsg) { for (i=0; irecps.num_internet; ++i) { extract_token(recipient, jmsg->recps.recp_internet, i, '|', sizeof recipient); - sprintf(&message_text[strlen(message_text)], + StrBufAppendPrintf(message_text, " %s\r\n", recipient); } } - sprintf(&message_text[strlen(message_text)], - "\r\n" - "--%s\r\n" - "Content-type: message/rfc822\r\n" - "\r\n" - "%s" - "--%s--\r\n" - , - mime_boundary, - jmsg->rfc822, - mime_boundary - ); - - journal_msg->cm_fields[eMesageText] = message_text; + StrBufAppendBufPlain( + message_text, + HKEY("\r\n" + "--"), 0); + + StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0); + + StrBufAppendBufPlain( + message_text, + HKEY("\r\n" + "Content-type: message/rfc822\r\n" + "\r\n"), 0); + + StrBufAppendBufPlain(message_text, jmsg->rfc822, rfc822len, 0); + + StrBufAppendBufPlain( + message_text, + HKEY("--"), 0); + + StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0); + + StrBufAppendBufPlain( + message_text, + HKEY("--\r\n"), 0); + + CM_SetAsFieldSB(journal_msg, eMesageText, &message_text); free(jmsg->rfc822); free(jmsg->msgn); + jmsg->rfc822 = NULL; + jmsg->msgn = NULL; /* Submit journal message */ CtdlSubmitMsg(journal_msg, journal_recps, "", 0); diff --git a/citadel/modules/blog/serv_blog.c b/citadel/modules/blog/serv_blog.c index 4424d46b8..a6513e775 100644 --- a/citadel/modules/blog/serv_blog.c +++ b/citadel/modules/blog/serv_blog.c @@ -74,18 +74,16 @@ int blog_upload_beforesave(struct CtdlMessage *msg) { */ if (msg->cm_fields[eExclusiveID] == NULL) { - char uuid[BLOG_EUIDBUF_SIZE]; + char uuid[SIZ]; generate_uuid(uuid); - msg->cm_fields[eExclusiveID] = strdup(uuid); + CM_SetField(msg, eExclusiveID, uuid, strlen(uuid)); } /* * We also want to define a maximum length, whether we generated it or not. */ - else if (strlen(msg->cm_fields[eExclusiveID]) >= BLOG_EUIDBUF_SIZE) { - msg->cm_fields[eExclusiveID][BLOG_EUIDBUF_SIZE-1] = 0; - } - + CM_CutFieldAt(msg, eExclusiveID, BLOG_EUIDBUF_SIZE - 1); + /* Now allow the save to complete. */ return(0); } diff --git a/citadel/modules/calendar/serv_calendar.c b/citadel/modules/calendar/serv_calendar.c index 0d971d9d9..a70baada4 100644 --- a/citadel/modules/calendar/serv_calendar.c +++ b/citadel/modules/calendar/serv_calendar.c @@ -98,6 +98,7 @@ icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) { */ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { char *ser = NULL; + long serlen; icalcomponent *encaps = NULL; struct CtdlMessage *msg = NULL; icalcomponent *tmp=NULL; @@ -119,13 +120,15 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { ser = icalcomponent_as_ical_string_r(cal); if (ser == NULL) return; + serlen = strlen(ser); + /* If the caller supplied a user, write to that user's default calendar room */ if (u) { /* This handy API function does all the work for us. */ CtdlWriteObject(USERCALENDARROOM, /* which room */ "text/calendar", /* MIME type */ ser, /* data */ - strlen(ser)+1, /* length */ + serlen + 1, /* length */ u, /* which user */ 0, /* not binary */ 0, /* don't delete others of this type */ @@ -135,18 +138,24 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { /* If the caller did not supply a user, write to the currently selected room */ if (!u) { + struct CitContext *CCC = CC; + StrBuf *MsgBody; + msg = malloc(sizeof(struct CtdlMessage)); memset(msg, 0, sizeof(struct CtdlMessage)); msg->cm_magic = CTDLMESSAGE_MAGIC; msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = 4; - msg->cm_fields[eAuthor] = strdup(CC->user.fullname); - msg->cm_fields[eOriginalRoom] = strdup(CC->room.QRname); - msg->cm_fields[eNodeName] = strdup(config.c_nodename); - msg->cm_fields[eHumanNode] = strdup(config.c_humannode); - msg->cm_fields[eMesageText] = malloc(strlen(ser) + 40); - strcpy(msg->cm_fields[eMesageText], "Content-type: text/calendar\r\n\r\n"); - strcat(msg->cm_fields[eMesageText], ser); + CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); + CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); + CM_SetField(msg, eNodeName, config.c_nodename, strlen(config.c_nodename)); + CM_SetField(msg, eHumanNode, config.c_humannode, strlen(config.c_humannode)); + + MsgBody = NewStrBufPlain(NULL, serlen + 100); + StrBufAppendBufPlain(MsgBody, HKEY("Content-type: text/calendar\r\n\r\n"), 0); + StrBufAppendBufPlain(MsgBody, ser, serlen, 0); + + CM_SetAsFieldSB(msg, eMesageText, &MsgBody); /* Now write the data */ CtdlSubmitMsg(msg, NULL, "", QP_EADDR); @@ -183,7 +192,7 @@ void ical_send_a_reply(icalcomponent *request, char *action) { struct CtdlMessage *msg = NULL; struct recptypes *valid = NULL; - strcpy(organizer_string, ""); + *organizer_string = '\0'; strcpy(summary_string, "Calendar item"); if (request == NULL) { @@ -2285,10 +2294,10 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *cbuserdata) { + const char* pch; icalcomponent *cal, *nested_event, *nested_todo, *whole_cal; icalproperty *p; char new_uid[256] = ""; - char buf[1024] = ""; struct CtdlMessage *msg = (struct CtdlMessage *) cbuserdata; if (!msg) return; @@ -2334,13 +2343,10 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, p = ical_ctdl_get_subprop(cal, ICAL_UID_PROPERTY); } if (p != NULL) { - safestrncpy(buf, icalproperty_get_comment(p), sizeof buf); - if (!IsEmptyStr(buf)) { - if (msg->cm_fields[eExclusiveID] != NULL) { - free(msg->cm_fields[eExclusiveID]); - } - msg->cm_fields[eExclusiveID] = strdup(buf); - syslog(LOG_DEBUG, "Saving calendar UID <%s>\n", buf); + pch = icalproperty_get_comment(p); + if (!IsEmptyStr(pch)) { + CM_SetField(msg, eExclusiveID, pch, strlen(pch)); + syslog(LOG_DEBUG, "Saving calendar UID <%s>\n", pch); } } @@ -2348,12 +2354,12 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, p = ical_ctdl_get_subprop(cal, ICAL_SUMMARY_PROPERTY); if (p != NULL) { - safestrncpy(buf, icalproperty_get_comment(p), sizeof buf); - if (!IsEmptyStr(buf)) { - if (msg->cm_fields[eMsgSubject] != NULL) { - free(msg->cm_fields[eMsgSubject]); - } - msg->cm_fields[eMsgSubject] = rfc2047encode(buf, strlen(buf)); + pch = icalproperty_get_comment(p); + if (!IsEmptyStr(pch)) { + char *subj; + + subj = rfc2047encode(pch, strlen(pch)); + CM_SetAsField(msg, eMsgSubject, &subj, strlen(subj)); } } @@ -2364,11 +2370,7 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, time_t idtstart; idtstart = icaltime_as_timet(icalproperty_get_dtstart(p)); if (idtstart > 0) { - if (msg->cm_fields[eTimestamp] != NULL) { - free(msg->cm_fields[eTimestamp]); - } - msg->cm_fields[eTimestamp] = strdup("000000000000000000"); - sprintf(msg->cm_fields[eTimestamp], "%ld", idtstart); + CM_SetFieldLONG(msg, eTimestamp, idtstart); } } diff --git a/citadel/modules/clamav/serv_virus.c b/citadel/modules/clamav/serv_virus.c index 6f2dd0418..ae24461aa 100644 --- a/citadel/modules/clamav/serv_virus.c +++ b/citadel/modules/clamav/serv_virus.c @@ -180,10 +180,7 @@ int clamd(struct CtdlMessage *msg) { } if (is_virus) { - if (msg->cm_fields[eErrorMsg] != NULL) { - free(msg->cm_fields[eErrorMsg]); - } - msg->cm_fields[eErrorMsg] = strdup("message rejected by virus filter"); + CM_SetField(msg, eErrorMsg, HKEY("message rejected by virus filter")); } bail: close(sock); diff --git a/citadel/modules/extnotify/extnotify_main.c b/citadel/modules/extnotify/extnotify_main.c index 826704cf4..6d865082c 100644 --- a/citadel/modules/extnotify/extnotify_main.c +++ b/citadel/modules/extnotify/extnotify_main.c @@ -154,6 +154,7 @@ eNotifyType extNotify_getConfigMessage(char *username, int num_msgs = 0; int a; char *configMsg; + long clen; char *pch; // Get the user @@ -204,8 +205,7 @@ eNotifyType extNotify_getConfigMessage(char *username, // Do a simple string search to see if 'funambol' is selected as the // type. This string would be at the very top of the message contents. - configMsg = msg->cm_fields[eMesageText]; - msg->cm_fields[eMesageText] = NULL; + CM_GetAsField(msg, eMesageText, &configMsg, &clen); CtdlFreeMessage(msg); /* here we would find the pager number... */ diff --git a/citadel/modules/imap/imap_misc.c b/citadel/modules/imap/imap_misc.c index ede4b2fd7..be0fa51ed 100644 --- a/citadel/modules/imap/imap_misc.c +++ b/citadel/modules/imap/imap_misc.c @@ -371,7 +371,7 @@ void imap_append(int num_parms, ConstStr *Params) { * folder is selected, save its name so we can return there!!!!!) */ if (Imap->selected) { - strcpy(savedroom, CC->room.QRname); + strcpy(savedroom, CCC->room.QRname); } CtdlUserGoto(roomname, 0, 0, &msgs, &new); @@ -382,14 +382,12 @@ void imap_append(int num_parms, ConstStr *Params) { * For now, we allow "forgeries" if the room is one of the user's * private mailboxes. */ - if (CC->logged_in) { - if ( ((CC->room.QRflags & QR_MAILBOX) == 0) && (config.c_imap_keep_from == 0)) { - if (msg->cm_fields[eAuthor] != NULL) free(msg->cm_fields[eAuthor]); - if (msg->cm_fields[eNodeName] != NULL) free(msg->cm_fields[eNodeName]); - if (msg->cm_fields[eHumanNode] != NULL) free(msg->cm_fields[eHumanNode]); - msg->cm_fields[eAuthor] = strdup(CC->user.fullname); - msg->cm_fields[eNodeName] = strdup(config.c_nodename); - msg->cm_fields[eHumanNode] = strdup(config.c_humannode); + if (CCC->logged_in) { + if ( ((CCC->room.QRflags & QR_MAILBOX) == 0) && (config.c_imap_keep_from == 0)) { + + CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); + CM_SetField(msg, eNodeName, config.c_nodename, strlen(config.c_nodename)); + CM_SetField(msg, eHumanNode, config.c_humannode, strlen(config.c_humannode)); } } diff --git a/citadel/modules/instmsg/serv_instmsg.c b/citadel/modules/instmsg/serv_instmsg.c index cb4101a97..9a75e281c 100644 --- a/citadel/modules/instmsg/serv_instmsg.c +++ b/citadel/modules/instmsg/serv_instmsg.c @@ -459,16 +459,17 @@ void flush_individual_conversation(struct imlog *im) { msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = FMT_RFC822; if (!IsEmptyStr(im->usernames[0])) { - msg->cm_fields[eAuthor] = strdup(im->usernames[0]); + CM_SetField(msg, eAuthor, im->usernames[0], strlen(im->usernames[0])); } else { - msg->cm_fields[eAuthor] = strdup("Citadel"); + CM_SetField(msg, eAuthor, HKEY("Citadel")); } if (!IsEmptyStr(im->usernames[1])) { - msg->cm_fields[eRecipient] = strdup(im->usernames[1]); + CM_SetField(msg, eRecipient, im->usernames[1], strlen(im->usernames[1])); } - msg->cm_fields[eOriginalRoom] = strdup(PAGELOGROOM); - msg->cm_fields[eNodeName] = strdup(NODENAME); - msg->cm_fields[eMesageText] = SmashStrBuf(&im->conversation); /* we own this memory now */ + + CM_SetField(msg, eOriginalRoom, HKEY(PAGELOGROOM)); + CM_SetField(msg, eNodeName, NODENAME, strlen(NODENAME)); + CM_SetAsFieldSB(msg, eMesageText, &im->conversation); /* we own this memory now */ /* Start with usernums[1] because it's guaranteed to be higher than usernums[0], * so if there's only one party, usernums[0] will be zero but usernums[1] won't. diff --git a/citadel/modules/network/netspool.h b/citadel/modules/network/netspool.h index d04a49f1f..8496c5c5a 100644 --- a/citadel/modules/network/netspool.h +++ b/citadel/modules/network/netspool.h @@ -55,7 +55,7 @@ void InspectQueuedRoom(SpoolControl **pSC, int HaveSpoolConfig(OneRoomNetCfg* RNCfg); - +void Netmap_AddMe(struct CtdlMessage *msg, const char *defl, long defllen); void network_do_spoolin(HashList *working_ignetcfg, HashList *the_netmap, int *netmap_changed); void network_consolidate_spoolout(HashList *working_ignetcfg, HashList *the_netmap); void free_spoolcontrol_struct(SpoolControl **scc); diff --git a/citadel/modules/network/serv_netmail.c b/citadel/modules/network/serv_netmail.c index a8086b83b..dd47f2592 100644 --- a/citadel/modules/network/serv_netmail.c +++ b/citadel/modules/network/serv_netmail.c @@ -165,9 +165,7 @@ static void ListCalculateSubject(struct CtdlMessage *msg) StrBufRFC2047encode(&Subject, FlatSubject); } - if (msg->cm_fields[eMsgSubject] != NULL) - free (msg->cm_fields[eMsgSubject]); - msg->cm_fields[eMsgSubject] = SmashStrBuf(&Subject); + CM_SetAsFieldSB(msg, eMsgSubject, &Subject); FreeStrBuf(&FlatSubject); } @@ -177,7 +175,10 @@ static void ListCalculateSubject(struct CtdlMessage *msg) */ void network_deliver_digest(SpoolControl *sc) { + struct CitContext *CCC = CC; + long len; char buf[SIZ]; + char *pbuf; struct CtdlMessage *msg = NULL; long msglen; struct recptypes *valid; @@ -198,17 +199,16 @@ void network_deliver_digest(SpoolControl *sc) msg->cm_format_type = FMT_RFC822; msg->cm_anon_type = MES_NORMAL; - sprintf(buf, "%ld", time(NULL)); - msg->cm_fields[eTimestamp] = strdup(buf); - msg->cm_fields[eAuthor] = strdup(CC->room.QRname); - snprintf(buf, sizeof buf, "[%s]", CC->room.QRname); - msg->cm_fields[eMsgSubject] = strdup(buf); + CM_SetFieldLONG(msg, eTimestamp, time(NULL)); + CM_SetField(msg, eAuthor, CCC->room.QRname, strlen(CCC->room.QRname)); + len = snprintf(buf, sizeof buf, "[%s]", CCC->room.QRname); + CM_SetField(msg, eMsgSubject, buf, len); - CtdlMsgSetCM_Fields(msg, erFc822Addr, SKEY(sc->Users[roommailalias])); - CtdlMsgSetCM_Fields(msg, eRecipient, SKEY(sc->Users[roommailalias])); + CM_SetField(msg, erFc822Addr, SKEY(sc->Users[roommailalias])); + CM_SetField(msg, eRecipient, SKEY(sc->Users[roommailalias])); /* Set the 'List-ID' header */ - CtdlMsgSetCM_Fields(msg, eListID, SKEY(sc->ListID)); + CM_SetField(msg, eListID, SKEY(sc->ListID)); /* * Go fetch the contents of the digest @@ -216,11 +216,11 @@ void network_deliver_digest(SpoolControl *sc) fseek(sc->digestfp, 0L, SEEK_END); msglen = ftell(sc->digestfp); - msg->cm_fields[eMesageText] = malloc(msglen + 1); + pbuf = malloc(msglen + 1); fseek(sc->digestfp, 0L, SEEK_SET); - fread(msg->cm_fields[eMesageText], (size_t)msglen, 1, sc->digestfp); - msg->cm_fields[eMesageText][msglen] = '\0'; - + fread(pbuf, (size_t)msglen, 1, sc->digestfp); + pbuf[msglen] = '\0'; + CM_SetAsField(msg, eMesageText, &pbuf, msglen); fclose(sc->digestfp); sc->digestfp = NULL; @@ -327,7 +327,7 @@ void network_process_list(SpoolControl *sc, struct CtdlMessage *omsg, long *dele msg = CtdlDuplicateMessage(omsg); - CtdlMsgSetCM_Fields(msg, eListID, SKEY(sc->Users[roommailalias])); + CM_SetField(msg, eListID, SKEY(sc->Users[roommailalias])); /* if there is no other recipient, Set the recipient * of the list message to the email address of the @@ -336,11 +336,11 @@ void network_process_list(SpoolControl *sc, struct CtdlMessage *omsg, long *dele if ((msg->cm_fields[eRecipient] == NULL) || IsEmptyStr(msg->cm_fields[eRecipient])) { - CtdlMsgSetCM_Fields(msg, eRecipient, SKEY(sc->Users[roommailalias])); + CM_SetField(msg, eRecipient, SKEY(sc->Users[roommailalias])); } /* Set the 'List-ID' header */ - CtdlMsgSetCM_Fields(msg, eListID, SKEY(sc->ListID)); + CM_SetField(msg, eListID, SKEY(sc->ListID)); /* Prepend "[List name]" to the subject */ @@ -426,11 +426,11 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon * room itself, so the remote listserv doesn't * reject us. */ - CtdlMsgSetCM_Fields(msg, erFc822Addr, SKEY(sc->Users[roommailalias])); + CM_SetField(msg, erFc822Addr, SKEY(sc->Users[roommailalias])); valid = validate_recipients(ChrPtr(sc->Users[participate]) , NULL, 0); - CtdlMsgSetCM_Fields(msg, eRecipient, SKEY(sc->Users[roommailalias])); + CM_SetField(msg, eRecipient, SKEY(sc->Users[roommailalias])); CtdlSubmitMsg(msg, valid, "", 0); free_recipients(valid); } @@ -449,8 +449,6 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long char buf[SIZ]; char filename[PATH_MAX]; FILE *fp; - size_t newpath_len; - char *newpath = NULL; StrBuf *Buf = NULL; int i; int bang = 0; @@ -467,18 +465,8 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long /* Prepend our node name to the Path field whenever * sending a message to another IGnet node */ - if (msg->cm_fields[eMessagePath] == NULL) - { - msg->cm_fields[eMessagePath] = strdup("username"); - } - newpath_len = strlen(msg->cm_fields[eMessagePath]) + - strlen(config.c_nodename) + 2; - newpath = malloc(newpath_len); - snprintf(newpath, newpath_len, "%s!%s", - config.c_nodename, msg->cm_fields[eMessagePath]); - free(msg->cm_fields[eMessagePath]); - msg->cm_fields[eMessagePath] = newpath; - + Netmap_AddMe(msg, HKEY("username")); + /* * Determine if this message is set to be deleted * after sending out on the network @@ -545,16 +533,11 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long * room on the far end by setting the C field * correctly */ - if (msg->cm_fields[eRemoteRoom] != NULL) { - free(msg->cm_fields[eRemoteRoom]); - } if (StrLength(RemoteRoom) > 0) { - msg->cm_fields[eRemoteRoom] = - strdup(ChrPtr(RemoteRoom)); + CM_SetField(msg, eRemoteRoom, SKEY(RemoteRoom)); } else { - msg->cm_fields[eRemoteRoom] = - strdup(CC->room.QRname); + CM_SetField(msg, eRemoteRoom, CCC->room.QRname, strlen(CCC->room.QRname)); } /* serialize it for transmission */ diff --git a/citadel/modules/network/serv_netspool.c b/citadel/modules/network/serv_netspool.c index 3700ee42b..dac6db41c 100644 --- a/citadel/modules/network/serv_netspool.c +++ b/citadel/modules/network/serv_netspool.c @@ -160,7 +160,23 @@ int HaveSpoolConfig(OneRoomNetCfg* RNCfg) return interested; } +void Netmap_AddMe(struct CtdlMessage *msg, const char *defl, long defllen) +{ + long node_len; + char buf[SIZ]; + /* prepend our node to the path */ + if (msg->cm_fields[eMessagePath] == NULL) { + CM_SetField(msg, eMessagePath, defl, defllen); + } + node_len = strlen(config.c_nodename); + if (node_len >= SIZ) + node_len = SIZ - 1; + memcpy(buf, config.c_nodename, node_len); + buf[node_len] = '!'; + buf[node_len + 1] = '\0'; + CM_PrependToField(msg, eMessagePath, buf, node_len + 1); +} void InspectQueuedRoom(SpoolControl **pSC, RoomProcList *room_to_spool, @@ -408,7 +424,6 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg, struct recptypes *recp = NULL; char target_room[ROOMNAMELEN]; struct ser_ret sermsg; - char *oldpath = NULL; char filename[PATH_MAX]; FILE *fp; const StrBuf *nexthop = NULL; @@ -439,8 +454,7 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg, for (pos = 3; pos < size; ++pos) { field = buffer[pos]; len = strlen(buffer + pos + 1); - msg->cm_fields[field] = malloc(len + 1); - memcpy (msg->cm_fields[field], buffer+ pos + 1, len + 1); + CM_SetField(msg, field, buffer + pos + 1, len); pos = pos + len + 1; } @@ -456,19 +470,7 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg, working_ignetcfg, the_netmap) == 0) { - /* prepend our node to the path */ - if (msg->cm_fields[eMessagePath] != NULL) { - oldpath = msg->cm_fields[eMessagePath]; - msg->cm_fields[eMessagePath] = NULL; - } - else { - oldpath = strdup("unknown_user"); - } - size = strlen(oldpath) + SIZ; - msg->cm_fields[eMessagePath] = malloc(size); - snprintf(msg->cm_fields[eMessagePath], size, "%s!%s", - config.c_nodename, oldpath); - free(oldpath); + Netmap_AddMe(msg, HKEY("unknown_user")); /* serialize the message */ serialize_message(&sermsg, msg); @@ -562,14 +564,8 @@ void network_process_buffer(char *buffer, long size, HashList *working_ignetcfg, } /* Strip out fields that are only relevant during transit */ - if (msg->cm_fields[eDestination] != NULL) { - free(msg->cm_fields[eDestination]); - msg->cm_fields[eDestination] = NULL; - } - if (msg->cm_fields[eRemoteRoom] != NULL) { - free(msg->cm_fields[eRemoteRoom]); - msg->cm_fields[eRemoteRoom] = NULL; - } + CM_FlushField(msg, eDestination); + CM_FlushField(msg, eRemoteRoom); /* save the message into a room */ if (PerformNetprocHooks(msg, target_room) == 0) { diff --git a/citadel/modules/network/serv_network.c b/citadel/modules/network/serv_network.c index 1f0a680ca..b2b296ef8 100644 --- a/citadel/modules/network/serv_network.c +++ b/citadel/modules/network/serv_network.c @@ -348,14 +348,13 @@ void destroy_network_queue_room_locked (void) void network_bounce(struct CtdlMessage *msg, char *reason) { struct CitContext *CCC = CC; - char *oldpath = NULL; char buf[SIZ]; char bouncesource[SIZ]; char recipient[SIZ]; struct recptypes *valid = NULL; char force_room[ROOMNAMELEN]; static int serialnum = 0; - size_t size; + long len; QNM_syslog(LOG_DEBUG, "entering network_bounce()\n"); @@ -366,65 +365,37 @@ void network_bounce(struct CtdlMessage *msg, char *reason) /* * Give it a fresh message ID */ - if (msg->cm_fields[emessageId] != NULL) { - free(msg->cm_fields[emessageId]); - } - snprintf(buf, sizeof buf, "%ld.%04lx.%04x@%s", - (long)time(NULL), (long)getpid(), ++serialnum, config.c_fqdn); - msg->cm_fields[emessageId] = strdup(buf); + len = snprintf(buf, sizeof(buf), + "%ld.%04lx.%04x@%s", + (long)time(NULL), + (long)getpid(), + ++serialnum, + config.c_fqdn); + + CM_SetField(msg, emessageId, buf, len); /* * FIXME ... right now we're just sending a bounce; we really want to * include the text of the bounced message. */ - if (msg->cm_fields[eMesageText] != NULL) { - free(msg->cm_fields[eMesageText]); - } - msg->cm_fields[eMesageText] = strdup(reason); + CM_SetField(msg, eMesageText, reason, strlen(reason)); msg->cm_format_type = 0; /* * Turn the message around */ - if (msg->cm_fields[eRecipient] == NULL) { - free(msg->cm_fields[eRecipient]); - } - - if (msg->cm_fields[eDestination] == NULL) { - free(msg->cm_fields[eDestination]); - } - - snprintf(recipient, sizeof recipient, "%s@%s", - msg->cm_fields[eAuthor], msg->cm_fields[eNodeName]); + CM_FlushField(msg, eRecipient); + CM_FlushField(msg, eDestination); - if (msg->cm_fields[eAuthor] == NULL) { - free(msg->cm_fields[eAuthor]); - } - - if (msg->cm_fields[eNodeName] == NULL) { - free(msg->cm_fields[eNodeName]); - } - - if (msg->cm_fields[eMsgSubject] == NULL) { - free(msg->cm_fields[eMsgSubject]); - } + len = snprintf(recipient, sizeof(recipient), "%s@%s", + msg->cm_fields[eAuthor], + msg->cm_fields[eNodeName]); - msg->cm_fields[eAuthor] = strdup(BOUNCESOURCE); - msg->cm_fields[eNodeName] = strdup(config.c_nodename); - msg->cm_fields[eMsgSubject] = strdup("Delivery Status Notification (Failure)"); + CM_SetField(msg, eAuthor, HKEY(BOUNCESOURCE)); + CM_SetField(msg, eNodeName, config.c_nodename, strlen(config.c_nodename)); + CM_SetField(msg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); - /* prepend our node to the path */ - if (msg->cm_fields[eMessagePath] != NULL) { - oldpath = msg->cm_fields[eMessagePath]; - msg->cm_fields[eMessagePath] = NULL; - } - else { - oldpath = strdup("unknown_user"); - } - size = strlen(oldpath) + SIZ; - msg->cm_fields[eMessagePath] = malloc(size); - snprintf(msg->cm_fields[eMessagePath], size, "%s!%s", config.c_nodename, oldpath); - free(oldpath); + Netmap_AddMe(msg, HKEY("unknown_user")); /* Now submit the message */ valid = validate_recipients(recipient, NULL, 0); diff --git a/citadel/modules/notes/serv_notes.c b/citadel/modules/notes/serv_notes.c index bf1de8d06..9c1c944d9 100644 --- a/citadel/modules/notes/serv_notes.c +++ b/citadel/modules/notes/serv_notes.c @@ -120,16 +120,9 @@ int serv_notes_beforesave(struct CtdlMessage *msg) syslog(LOG_DEBUG, "UUID of note is: %s\n", uuid); if (!IsEmptyStr(uuid)) { + CM_SetField(msg, eExclusiveID, uuid, strlen(uuid)); - if (msg->cm_fields[eExclusiveID] != NULL) { - free(msg->cm_fields[eExclusiveID]); - } - msg->cm_fields[eExclusiveID] = strdup(uuid); - - if (msg->cm_fields[eMsgSubject] != NULL) { - free(msg->cm_fields[eMsgSubject]); - } - msg->cm_fields[eMsgSubject] = strdup(uuid); + CM_CopyField(msg, eMsgSubject, eExclusiveID); } } p++; @@ -149,23 +142,19 @@ int serv_notes_beforesave(struct CtdlMessage *msg) /* Set the message EUID to the vNote UID */ - if (v->uid) if (!IsEmptyStr(v->uid)) { + if ((v->uid) && (!IsEmptyStr(v->uid))) { syslog(LOG_DEBUG, "UID of vNote is: %s\n", v->uid); - if (msg->cm_fields[eExclusiveID] != NULL) { - free(msg->cm_fields[eExclusiveID]); - } - msg->cm_fields[eExclusiveID] = strdup(v->uid); + CM_SetField(msg, eExclusiveID, v->uid, strlen(v->uid)); } /* Set the message Subject to the vNote Summary */ - if (v->summary) if (!IsEmptyStr(v->summary)) { - if (msg->cm_fields[eMsgSubject] != NULL) { - free(msg->cm_fields[eMsgSubject]); - } - msg->cm_fields[eMsgSubject] = strdup(v->summary); + if ((v->summary) && (!IsEmptyStr(v->summary))) { + CM_SetField(msg, eMsgSubject, v->summary, strlen(v->summary)); + if (strlen(msg->cm_fields[eMsgSubject]) > 72) { strcpy(&msg->cm_fields[eMsgSubject][68], "..."); + CM_CutFieldAt(msg, eMsgSubject, 72); } } diff --git a/citadel/modules/rssclient/rss_atom_parser.c b/citadel/modules/rssclient/rss_atom_parser.c index 681cf8a14..254b6e5d7 100644 --- a/citadel/modules/rssclient/rss_atom_parser.c +++ b/citadel/modules/rssclient/rss_atom_parser.c @@ -675,7 +675,7 @@ void rss_remember_item(rss_item *ri, rss_aggregator *RSSAggr) /* gather the cheaply computed information now... */ if (ri->guid != NULL) { - SaveMsg->Msg.cm_fields[eExclusiveID] = strdup(ChrPtr(ri->guid)); + CM_SetField(&SaveMsg->Msg, eExclusiveID, SKEY(ri->guid)); } SaveMsg->MsgGUID = guid; @@ -683,12 +683,10 @@ void rss_remember_item(rss_item *ri, rss_aggregator *RSSAggr) if (ri->pubdate <= 0) { ri->pubdate = time(NULL); /// TODO: use event time! } - SaveMsg->Msg.cm_fields[eTimestamp] = malloc(64); - snprintf(SaveMsg->Msg.cm_fields[eTimestamp], 64, "%ld", ri->pubdate); + CM_SetFieldLONG(&SaveMsg->Msg, eTimestamp, ri->pubdate); if (ri->channel_title != NULL) { if (StrLength(ri->channel_title) > 0) { - SaveMsg->Msg.cm_fields[eOriginalRoom] = - strdup(ChrPtr(ri->channel_title)); + CM_SetField(&SaveMsg->Msg, eOriginalRoom, SKEY(ri->channel_title)); } } diff --git a/citadel/modules/rssclient/serv_rssclient.c b/citadel/modules/rssclient/serv_rssclient.c index 059cd1b47..374d53d4c 100644 --- a/citadel/modules/rssclient/serv_rssclient.c +++ b/citadel/modules/rssclient/serv_rssclient.c @@ -307,36 +307,31 @@ int rss_format_item(AsyncIO *IO, networker_save_message *SaveMsg) if (!FromAt && StrLength (SaveMsg->author_email) > 0) { StrBufRFC2047encode(&Encoded, SaveMsg->author_or_creator); - SaveMsg->Msg.cm_fields[eAuthor] = SmashStrBuf(&Encoded); - SaveMsg->Msg.cm_fields[eMessagePath] = - SmashStrBuf(&SaveMsg->author_email); + CM_SetAsFieldSB(&SaveMsg->Msg, eAuthor, &Encoded); + CM_SetAsFieldSB(&SaveMsg->Msg, eMessagePath, &SaveMsg->author_email); } else { if (FromAt) { - SaveMsg->Msg.cm_fields[eAuthor] = - SmashStrBuf(&SaveMsg->author_or_creator); - SaveMsg->Msg.cm_fields[eMessagePath] = - strdup(SaveMsg->Msg.cm_fields[eAuthor]); + CM_SetAsFieldSB(&SaveMsg->Msg, eAuthor, &SaveMsg->author_or_creator); + CM_CopyField(&SaveMsg->Msg, eMessagePath, eAuthor); } else { StrBufRFC2047encode(&Encoded, SaveMsg->author_or_creator); - SaveMsg->Msg.cm_fields[eAuthor] = - SmashStrBuf(&Encoded); - SaveMsg->Msg.cm_fields[eMessagePath] = - strdup("rss@localhost"); + CM_SetAsFieldSB(&SaveMsg->Msg, eAuthor, &Encoded); + CM_SetField(&SaveMsg->Msg, eMessagePath, HKEY("rss@localhost")); } } } else { - SaveMsg->Msg.cm_fields[eAuthor] = strdup("rss"); + CM_SetField(&SaveMsg->Msg, eAuthor, HKEY("rss")); } - SaveMsg->Msg.cm_fields[eNodeName] = strdup(NODENAME); + CM_SetField(&SaveMsg->Msg, eNodeName, NODENAME, strlen(NODENAME)); if (SaveMsg->title != NULL) { long len; char *Sbj; @@ -358,7 +353,7 @@ int rss_format_item(AsyncIO *IO, networker_save_message *SaveMsg) StrBufTrim(Encoded); StrBufRFC2047encode(&QPEncoded, Encoded); - SaveMsg->Msg.cm_fields[eMsgSubject] = SmashStrBuf(&QPEncoded); + CM_SetAsFieldSB(&SaveMsg->Msg, eMsgSubject, &QPEncoded); FreeStrBuf(&Encoded); } if (SaveMsg->link == NULL) @@ -398,8 +393,8 @@ eNextState RSSSaveMessage(AsyncIO *IO) if (rss_format_item(IO, RSSAggr->ThisMsg)) { - RSSAggr->ThisMsg->Msg.cm_fields[eMesageText] = - SmashStrBuf(&RSSAggr->ThisMsg->Message); + CM_SetAsFieldSB(&RSSAggr->ThisMsg->Msg, eMesageText, + &RSSAggr->ThisMsg->Message); CtdlSubmitMsg(&RSSAggr->ThisMsg->Msg, &RSSAggr->recp, NULL, 0); diff --git a/citadel/modules/sieve/serv_sieve.c b/citadel/modules/sieve/serv_sieve.c index d7a558472..4a9fcbf0f 100644 --- a/citadel/modules/sieve/serv_sieve.c +++ b/citadel/modules/sieve/serv_sieve.c @@ -746,6 +746,7 @@ void get_sieve_config_backend(long msgnum, void *userdata) { struct sdm_userdata *u = (struct sdm_userdata *) userdata; struct CtdlMessage *msg; char *conf; + long conflen; u->config_msgnum = msgnum; msg = CtdlFetchMessage(msgnum, 1); @@ -754,8 +755,8 @@ void get_sieve_config_backend(long msgnum, void *userdata) { return; } - conf = msg->cm_fields[eMesageText]; - msg->cm_fields[eMesageText] = NULL; + CM_GetAsField(msg, eMesageText, &conf, &conflen); + CtdlFreeMessage(msg); if (conf != NULL) { diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index ad9137ff3..9559d1c5a 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -839,32 +839,21 @@ void smtp_data(long offset, long flags) return; } - if (msg->cm_fields[eAuthor] != NULL) free(msg->cm_fields[eAuthor]); - if (msg->cm_fields[eNodeName] != NULL) free(msg->cm_fields[eNodeName]); - if (msg->cm_fields[eHumanNode] != NULL) free(msg->cm_fields[eHumanNode]); - if (msg->cm_fields[eOriginalRoom] != NULL) free(msg->cm_fields[eOriginalRoom]); - msg->cm_fields[eAuthor] = strdup(CCC->user.fullname); - msg->cm_fields[eNodeName] = strdup(config.c_nodename); - msg->cm_fields[eHumanNode] = strdup(config.c_humannode); - msg->cm_fields[eOriginalRoom] = strdup(MAILROOM); + CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); + CM_SetField(msg, eNodeName, config.c_nodename, strlen(config.c_nodename)); + CM_SetField(msg, eHumanNode, config.c_humannode, strlen(config.c_humannode)); + CM_SetField(msg, eOriginalRoom, HKEY(MAILROOM)); if (!validemail) { - if (msg->cm_fields[erFc822Addr] != NULL) free(msg->cm_fields[erFc822Addr]); - msg->cm_fields[erFc822Addr] = strdup(CCC->cs_inet_email); + CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email)); } } /* Set the "envelope from" address */ - if (msg->cm_fields[eMessagePath] != NULL) { - free(msg->cm_fields[eMessagePath]); - } - msg->cm_fields[eMessagePath] = strdup(ChrPtr(sSMTP->from)); + CM_SetField(msg, eMessagePath, SKEY(sSMTP->from)); /* Set the "envelope to" address */ - if (msg->cm_fields[eenVelopeTo] != NULL) { - free(msg->cm_fields[eenVelopeTo]); - } - msg->cm_fields[eenVelopeTo] = strdup(ChrPtr(sSMTP->recipients)); + CM_SetField(msg, eenVelopeTo, SKEY(sSMTP->recipients)); /* Submit the message into the Citadel system. */ valid = validate_recipients( @@ -887,7 +876,7 @@ void smtp_data(long offset, long flags) if (scan_errors > 0) { /* We don't want this message! */ if (msg->cm_fields[eErrorMsg] == NULL) { - msg->cm_fields[eErrorMsg] = strdup("Message rejected by filter"); + CM_SetField(msg, eErrorMsg, HKEY("Message rejected by filter")); } StrBufPrintf(sSMTP->OneRcpt, "550 %s\r\n", msg->cm_fields[eErrorMsg]); diff --git a/citadel/modules/smtp/serv_smtpeventclient.c b/citadel/modules/smtp/serv_smtpeventclient.c index 5eddfc1b6..de7aafb7e 100644 --- a/citadel/modules/smtp/serv_smtpeventclient.c +++ b/citadel/modules/smtp/serv_smtpeventclient.c @@ -222,8 +222,8 @@ eNextState FinalizeMessageSend_DB(AsyncIO *IO) msg->cm_magic = CTDLMESSAGE_MAGIC; msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = FMT_RFC822; - msg->cm_fields[eMesageText] = SmashStrBuf(&Msg->QMsgData); - msg->cm_fields[eMsgSubject] = strdup("QMSG"); + CM_SetAsFieldSB(msg, eMesageText, &Msg->QMsgData); + CM_SetField(msg, eMsgSubject, HKEY("QMSG")); Msg->MyQItem->QueMsgID = CtdlSubmitMsg(msg, NULL, SMTP_SPOOLOUT_ROOM, QP_EADDR); EVS_syslog(LOG_DEBUG, "%ld", Msg->MyQItem->QueMsgID); diff --git a/citadel/modules/smtp/serv_smtpqueue.c b/citadel/modules/smtp/serv_smtpqueue.c index 6ff9e35c8..685e2ca76 100644 --- a/citadel/modules/smtp/serv_smtpqueue.c +++ b/citadel/modules/smtp/serv_smtpqueue.c @@ -700,11 +700,11 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay) bmsg->cm_anon_type = MES_NORMAL; bmsg->cm_format_type = FMT_RFC822; - bmsg->cm_fields[eOriginalRoom] = strdup(MAILROOM); - bmsg->cm_fields[eAuthor] = strdup("Citadel"); - bmsg->cm_fields[eNodeName] = strdup(config.c_nodename); - bmsg->cm_fields[eMsgSubject] = strdup("Delivery Status Notification (Failure)"); - bmsg->cm_fields[eMesageText] = SmashStrBuf(&BounceMB); + CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM)); + CM_SetField(bmsg, eAuthor, HKEY("Citadel")); + CM_SetField(bmsg, eNodeName, config.c_nodename, strlen(config.c_nodename)); + CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); + CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB); /* First try the user who sent the message */ if (StrLength(MyQItem->BounceTo) == 0) { diff --git a/citadel/modules/smtp/smtp_util.c b/citadel/modules/smtp/smtp_util.c index dd4c80751..6dcf95fb0 100644 --- a/citadel/modules/smtp/smtp_util.c +++ b/citadel/modules/smtp/smtp_util.c @@ -161,10 +161,10 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) bmsg->cm_magic = CTDLMESSAGE_MAGIC; bmsg->cm_anon_type = MES_NORMAL; bmsg->cm_format_type = FMT_RFC822; - bmsg->cm_fields[eAuthor] = strdup("Citadel"); - bmsg->cm_fields[eOriginalRoom] = strdup(MAILROOM); - bmsg->cm_fields[eNodeName] = strdup(config.c_nodename); - bmsg->cm_fields[eMsgSubject] = strdup("Delivery Status Notification (Failure)"); + CM_SetField(bmsg, eAuthor, HKEY("Citadel")); + CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM)); + CM_SetField(bmsg, eNodeName, config.c_nodename, strlen(config.c_nodename)); + CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); StrBufAppendBufPlain( BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0); @@ -286,9 +286,7 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0); - if (bmsg->cm_fields[eAuthor] != NULL) - free(bmsg->cm_fields[eAuthor]); - bmsg->cm_fields[eAuthor] = SmashStrBuf(&BounceMB); + CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB); /* Deliver the bounce if there's anything worth mentioning */ syslog(LOG_DEBUG, "num_bounces = %d\n", num_bounces); if (num_bounces > 0) { diff --git a/citadel/modules/spam/serv_spam.c b/citadel/modules/spam/serv_spam.c index f27e22441..c0ced7eeb 100644 --- a/citadel/modules/spam/serv_spam.c +++ b/citadel/modules/spam/serv_spam.c @@ -143,35 +143,31 @@ int spam_assassin(struct CtdlMessage *msg) { syslog(LOG_DEBUG, "<%s\n", buf); syslog(LOG_DEBUG, "c_spam_flag_only setting %d\n", config.c_spam_flag_only); if (config.c_spam_flag_only) { - syslog(LOG_DEBUG, "flag spam code used"); int headerlen; - int newmsgsize; - int oldmsgsize; - + char *cur; char sastatus[10]; char sascore[10]; char saoutof[10]; int numscore; + syslog(LOG_DEBUG, "flag spam code used"); + extract_token(sastatus, buf, 1, ' ', sizeof sastatus); extract_token(sascore, buf, 3, ' ', sizeof sascore); extract_token(saoutof, buf, 5, ' ', sizeof saoutof); - sprintf(buf,"X-Spam-Level: "); - char *cur = buf + 14; + memcpy(buf, HKEY("X-Spam-Level: ")); + cur = buf + 14; for (numscore = atoi(sascore); numscore>0; numscore--) *(cur++) = '*'; *cur = '\0'; - sprintf(cur,"\r\nX-Spam-Status: %s, score=%s required=%s\r\n", sastatus, sascore, saoutof); - headerlen = strlen(buf); - oldmsgsize = strlen(msg->cm_fields[eMesageText]) + 1; - newmsgsize = headerlen + oldmsgsize; - - msg->cm_fields[eMesageText] = realloc(msg->cm_fields[eMesageText], newmsgsize); + headerlen = cur - buf; + headerlen += snprintf(cur, (sizeof(buf) - headerlen), + "\r\nX-Spam-Status: %s, score=%s required=%s\r\n", + sastatus, sascore, saoutof); - memmove(msg->cm_fields[eMesageText]+headerlen,msg->cm_fields[eMesageText],oldmsgsize); - memcpy(msg->cm_fields[eMesageText],buf,headerlen); + CM_PrependToField(msg, eMesageText, buf, headerlen); } else { syslog(LOG_DEBUG, "reject spam code used"); @@ -183,7 +179,7 @@ int spam_assassin(struct CtdlMessage *msg) { if (msg->cm_fields[eErrorMsg] != NULL) { free(msg->cm_fields[eErrorMsg]); } - msg->cm_fields[eErrorMsg] = strdup("message rejected by spam filter"); + CM_SetField(msg, eErrorMsg, HKEY("message rejected by spam filter")); } } diff --git a/citadel/modules/vcard/serv_vcard.c b/citadel/modules/vcard/serv_vcard.c index 10516c3fd..36fdb257d 100644 --- a/citadel/modules/vcard/serv_vcard.c +++ b/citadel/modules/vcard/serv_vcard.c @@ -425,10 +425,7 @@ int vcard_upload_beforesave(struct CtdlMessage *msg) { CtdlDeleteMessages(CCC->room.QRname, NULL, 0, "[Tt][Ee][Xx][Tt]/.*[Vv][Cc][Aa][Rr][Dd]$"); /* Make the author of the message the name of the user. */ - if (msg->cm_fields[eAuthor] != NULL) { - free(msg->cm_fields[eAuthor]); - } - msg->cm_fields[eAuthor] = strdup(usbuf.fullname); + CM_SetField(msg, eAuthor, usbuf.fullname, strlen(usbuf.fullname)); } /* Insert or replace RFC2739-compliant free/busy URL */ @@ -458,16 +455,13 @@ int vcard_upload_beforesave(struct CtdlMessage *msg) { /* * Set the EUID of the message to the UID of the vCard. */ - if (msg->cm_fields[eExclusiveID] != NULL) - { - free(msg->cm_fields[eExclusiveID]); - msg->cm_fields[eExclusiveID] = NULL; - } + CM_FlushField(msg, eExclusiveID); + s = vcard_get_prop(v, "UID", 1, 0, 0); if (s != NULL) { - msg->cm_fields[eExclusiveID] = strdup(s); + CM_SetField(msg, eExclusiveID, s, strlen(s)); if (msg->cm_fields[eMsgSubject] == NULL) { - msg->cm_fields[eMsgSubject] = strdup(s); + CM_CopyField(msg, eMsgSubject, eExclusiveID); } } @@ -479,19 +473,22 @@ int vcard_upload_beforesave(struct CtdlMessage *msg) { s = vcard_get_prop(v, "N", 1, 0, 0); } if (s != NULL) { - if (msg->cm_fields[eMsgSubject] != NULL) { - free(msg->cm_fields[eMsgSubject]); - } - msg->cm_fields[eMsgSubject] = strdup(s); + CM_SetField(msg, eMsgSubject, s, strlen(s)); } /* Re-serialize it back into the msg body */ ser = vcard_serialize(v); if (ser != NULL) { - msg->cm_fields[eMesageText] = realloc(msg->cm_fields[eMesageText], strlen(ser) + 1024); - sprintf(msg->cm_fields[eMesageText], - "Content-type: " VCARD_MIME_TYPE - "\r\n\r\n%s\r\n", ser); + StrBuf *buf; + long serlen; + + serlen = strlen(ser); + buf = NewStrBufPlain(NULL, serlen + 1024); + + StrBufAppendBufPlain(buf, HKEY("Content-type: " VCARD_MIME_TYPE "\r\n\r\n"), 0); + StrBufAppendBufPlain(buf, ser, serlen, 0); + StrBufAppendBufPlain(buf, HKEY("\r\n"), 0); + CM_SetAsFieldSB(msg, eMesageText, &buf); free(ser); } @@ -897,6 +894,7 @@ void vcard_newuser(struct ctdluser *usbuf) { void vcard_purge(struct ctdluser *usbuf) { struct CtdlMessage *msg; char buf[SIZ]; + long len; msg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); if (msg == NULL) return; @@ -905,16 +903,16 @@ void vcard_purge(struct ctdluser *usbuf) { msg->cm_magic = CTDLMESSAGE_MAGIC; msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = 0; - msg->cm_fields[eAuthor] = strdup(usbuf->fullname); - msg->cm_fields[eOriginalRoom] = strdup(ADDRESS_BOOK_ROOM); - msg->cm_fields[eNodeName] = strdup(NODENAME); - msg->cm_fields[eMesageText] = strdup("Purge this vCard\n"); + CM_SetField(msg, eAuthor, usbuf->fullname, strlen(usbuf->fullname)); + CM_SetField(msg, eOriginalRoom, HKEY(ADDRESS_BOOK_ROOM)); + CM_SetField(msg, eNodeName, NODENAME, strlen(NODENAME)); + CM_SetField(msg, eMesageText, HKEY("Purge this vCard\n")); - snprintf(buf, sizeof buf, VCARD_EXT_FORMAT, - msg->cm_fields[eAuthor], NODENAME); - msg->cm_fields[eExclusiveID] = strdup(buf); + len = snprintf(buf, sizeof buf, VCARD_EXT_FORMAT, + msg->cm_fields[eAuthor], NODENAME); + CM_SetField(msg, eExclusiveID, buf, len); - msg->cm_fields[eSpecialField] = strdup("CANCEL"); + CM_SetField(msg, eSpecialField, HKEY("CANCEL")); CtdlSubmitMsg(msg, NULL, ADDRESS_BOOK_ROOM, QP_EADDR); CtdlFreeMessage(msg); @@ -1372,19 +1370,27 @@ void store_this_ha(struct addresses_to_be_filed *aptr) { striplt(recipient); v = vcard_new_from_rfc822_addr(recipient); if (v != NULL) { + const char *s; vmsg = malloc(sizeof(struct CtdlMessage)); memset(vmsg, 0, sizeof(struct CtdlMessage)); vmsg->cm_magic = CTDLMESSAGE_MAGIC; vmsg->cm_anon_type = MES_NORMAL; vmsg->cm_format_type = FMT_RFC822; - vmsg->cm_fields[eAuthor] = strdup("Citadel"); - vmsg->cm_fields[eExclusiveID] = strdup(vcard_get_prop(v, "UID", 1, 0, 0)); + CM_SetField(vmsg, eAuthor, HKEY("Citadel")); + s = vcard_get_prop(v, "UID", 1, 0, 0); + CM_SetField(vmsg, eExclusiveID, s, strlen(s)); ser = vcard_serialize(v); if (ser != NULL) { - vmsg->cm_fields[eMesageText] = malloc(strlen(ser) + 1024); - sprintf(vmsg->cm_fields[eMesageText], - "Content-type: " VCARD_MIME_TYPE - "\r\n\r\n%s\r\n", ser); + StrBuf *buf; + long serlen; + + serlen = strlen(ser); + buf = NewStrBufPlain(NULL, serlen + 1024); + + StrBufAppendBufPlain(buf, HKEY("Content-type: " VCARD_MIME_TYPE "\r\n\r\n"), 0); + StrBufAppendBufPlain(buf, ser, serlen, 0); + StrBufAppendBufPlain(buf, HKEY("\r\n"), 0); + CM_SetAsFieldSB(vmsg, eMesageText, &buf); free(ser); } vcard_free(v); diff --git a/citadel/modules/wiki/serv_wiki.c b/citadel/modules/wiki/serv_wiki.c index 799a3f322..33d856310 100644 --- a/citadel/modules/wiki/serv_wiki.c +++ b/citadel/modules/wiki/serv_wiki.c @@ -82,6 +82,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { FILE *fp; int rv; char history_page[1024]; + long history_page_len; char boundary[256]; char prefixed_boundary[258]; char buf[1024]; @@ -102,7 +103,8 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { /* If there's no EUID we can't do this. Reject the post. */ if (msg->cm_fields[eExclusiveID] == NULL) return(1); - snprintf(history_page, sizeof history_page, "%s_HISTORY_", msg->cm_fields[eExclusiveID]); + history_page_len = snprintf(history_page, sizeof history_page, + "%s_HISTORY_", msg->cm_fields[eExclusiveID]); /* Make sure we're saving a real wiki page rather than a wiki history page. * This is important in order to avoid recursing infinitely into this hook. @@ -118,10 +120,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { if (msg->cm_fields[eMesageText] == NULL) return(0); /* Set the message subject identical to the page name */ - if (msg->cm_fields[eMsgSubject] != NULL) { - free(msg->cm_fields[eMsgSubject]); - } - msg->cm_fields[eMsgSubject] = strdup(msg->cm_fields[eExclusiveID]); + CM_CopyField(msg, eMsgSubject, eExclusiveID); /* See if we can retrieve the previous version. */ old_msgnum = CtdlLocateMessageByEuid(msg->cm_fields[eExclusiveID], &CCC->room); @@ -183,7 +182,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { fseek(fp, 0L, SEEK_SET); diffbuf = malloc(diffbuf_len + 1); fread(diffbuf, diffbuf_len, 1, fp); - diffbuf[diffbuf_len] = 0; + diffbuf[diffbuf_len] = '\0'; fclose(fp); } @@ -212,27 +211,30 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { /* Create a new history message if necessary */ if (history_msg == NULL) { + char *buf; + long len; + history_msg = malloc(sizeof(struct CtdlMessage)); memset(history_msg, 0, sizeof(struct CtdlMessage)); history_msg->cm_magic = CTDLMESSAGE_MAGIC; history_msg->cm_anon_type = MES_NORMAL; history_msg->cm_format_type = FMT_RFC822; - history_msg->cm_fields[eAuthor] = strdup("Citadel"); - history_msg->cm_fields[eRecipient] = strdup(CCC->room.QRname); - history_msg->cm_fields[eExclusiveID] = strdup(history_page); - history_msg->cm_fields[eMsgSubject] = strdup(history_page); - history_msg->cm_fields[eSuppressIdx] = strdup("1"); /* suppress full text indexing */ + CM_SetField(history_msg, eAuthor, HKEY("Citadel")); + CM_SetField(history_msg, eRecipient, CCC->room.QRname, strlen(CCC->room.QRname)); + CM_SetField(history_msg, eExclusiveID, history_page, history_page_len); + CM_SetField(history_msg, eMsgSubject, history_page, history_page_len); + CM_SetField(history_msg, eSuppressIdx, HKEY("1")); /* suppress full text indexing */ snprintf(boundary, sizeof boundary, "Citadel--Multipart--%04x--%08lx", getpid(), time(NULL)); - history_msg->cm_fields[eMesageText] = malloc(1024); - snprintf(history_msg->cm_fields[eMesageText], 1024, - "Content-type: multipart/mixed; boundary=\"%s\"\n\n" - "This is a Citadel wiki history encoded as multipart MIME.\n" - "Each part is comprised of a diff script representing one change set.\n" - "\n" - "--%s--\n" - , - boundary, boundary + buf = (char*) malloc(1024); + len = snprintf(buf, 1024, + "Content-type: multipart/mixed; boundary=\"%s\"\n\n" + "This is a Citadel wiki history encoded as multipart MIME.\n" + "Each part is comprised of a diff script representing one change set.\n" + "\n" + "--%s--\n", + boundary, boundary ); + CM_SetAsField(history_msg, eMesageText, &buf, len); } /* Update the history message (regardless of whether it's new or existing) */ @@ -240,15 +242,12 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { /* Remove the Message-ID from the old version of the history message. This will cause a brand * new one to be generated, avoiding an uninitentional hit of the loop zapper when we replicate. */ - if (history_msg->cm_fields[emessageId] != NULL) { - free(history_msg->cm_fields[emessageId]); - history_msg->cm_fields[emessageId] = NULL; - } + CM_FlushField(history_msg, emessageId); /* Figure out the boundary string. We do this even when we generated the * boundary string in the above code, just to be safe and consistent. */ - strcpy(boundary, ""); + *boundary = '\0'; ptr = history_msg->cm_fields[eMesageText]; do { @@ -279,44 +278,62 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { * Now look for the first boundary. That is where we need to insert our fun. */ if (!IsEmptyStr(boundary)) { - snprintf(prefixed_boundary, sizeof prefixed_boundary, "--%s", boundary); - history_msg->cm_fields[eMesageText] = realloc(history_msg->cm_fields[eMesageText], - strlen(history_msg->cm_fields[eMesageText]) + strlen(diffbuf) + 1024 - ); - ptr = bmstrcasestr(history_msg->cm_fields[eMesageText], prefixed_boundary); + char *MsgText; + long MsgTextLen; + time_t Now = time(NULL); + + snprintf(prefixed_boundary, sizeof(prefixed_boundary), "--%s", boundary); + + CM_GetAsField(history_msg, eMesageText, &MsgText, &MsgTextLen); + + ptr = bmstrcasestr(MsgText, prefixed_boundary); if (ptr != NULL) { - char *the_rest_of_it = strdup(ptr); + StrBuf *NewMsgText; char uuid[64]; char memo[512]; + long memolen; char encoded_memo[1024]; + + NewMsgText = NewStrBufPlain(NULL, MsgTextLen + diffbuf_len + 1024); + generate_uuid(uuid); - snprintf(memo, sizeof memo, "%s|%ld|%s|%s", - uuid, - time(NULL), - CCC->user.fullname, - config.c_nodename - ); - CtdlEncodeBase64(encoded_memo, memo, strlen(memo), 0); - sprintf(ptr, "--%s\n" - "Content-type: text/plain\n" - "Content-Disposition: inline; filename=\"%s\"\n" - "Content-Transfer-Encoding: 8bit\n" - "\n" - "%s\n" - "%s" - , - boundary, - encoded_memo, - diffbuf, - the_rest_of_it - ); - free(the_rest_of_it); + memolen = snprintf(memo, sizeof(memo), "%s|%ld|%s|%s", + uuid, + Now, + CCC->user.fullname, + config.c_nodename); + + memolen = CtdlEncodeBase64(encoded_memo, memo, memolen, 0); + + StrBufAppendBufPlain(NewMsgText, HKEY("--"), 0); + StrBufAppendBufPlain(NewMsgText, boundary, -1, 0); + StrBufAppendBufPlain( + NewMsgText, + HKEY("\n" + "Content-type: text/plain\n" + "Content-Disposition: inline; filename=\""), 0); + + StrBufAppendBufPlain(NewMsgText, encoded_memo, memolen, 0); + + StrBufAppendBufPlain( + NewMsgText, + HKEY("\"\n" + "Content-Transfer-Encoding: 8bit\n" + "\n"), 0); + + StrBufAppendBufPlain(NewMsgText, diffbuf, diffbuf_len, 0); + StrBufAppendBufPlain(NewMsgText, HKEY("\n"), 0); + + StrBufAppendBufPlain(NewMsgText, ptr, MsgTextLen - (ptr - MsgText), 0); + free(MsgText); + CM_SetAsFieldSB(history_msg, eMesageText, &NewMsgText); } - - history_msg->cm_fields[eTimestamp] = realloc(history_msg->cm_fields[eTimestamp], 32); - if (history_msg->cm_fields[eTimestamp] != NULL) { - snprintf(history_msg->cm_fields[eTimestamp], 32, "%ld", time(NULL)); + else + { + CM_SetAsField(history_msg, eMesageText, &MsgText, MsgTextLen); } + + CM_SetFieldLONG(history_msg, eTimestamp, Now); CtdlSubmitMsg(history_msg, NULL, "", 0); } @@ -325,7 +342,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) { } free(diffbuf); - free(history_msg); + CtdlFreeMessage(history_msg); return(0); } @@ -468,11 +485,11 @@ void wiki_rev_callback(char *name, char *filename, char *partnum, char *disp, */ void wiki_rev(char *pagename, char *rev, char *operation) { + struct CitContext *CCC = CC; int r; char history_page_name[270]; long msgnum; char temp[PATH_MAX]; - char timestamp[64]; struct CtdlMessage *msg; FILE *fp; struct HistoryEraserCallBackData hecbd; @@ -501,7 +518,7 @@ void wiki_rev(char *pagename, char *rev, char *operation) /* Begin by fetching the current version of the page. We're going to patch * backwards through the diffs until we get the one we want. */ - msgnum = CtdlLocateMessageByEuid(pagename, &CC->room); + msgnum = CtdlLocateMessageByEuid(pagename, &CCC->room); if (msgnum > 0L) { msg = CtdlFetchMessage(msgnum, 1); } @@ -535,7 +552,7 @@ void wiki_rev(char *pagename, char *rev, char *operation) /* Get the revision history */ snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename); - msgnum = CtdlLocateMessageByEuid(history_page_name, &CC->room); + msgnum = CtdlLocateMessageByEuid(history_page_name, &CCC->room); if (msgnum > 0L) { msg = CtdlFetchMessage(msgnum, 1); } @@ -582,20 +599,22 @@ void wiki_rev(char *pagename, char *rev, char *operation) msg->cm_format_type = FMT_RFC822; fp = fopen(temp, "r"); if (fp) { + char *msgbuf; fseek(fp, 0L, SEEK_END); len = ftell(fp); fseek(fp, 0L, SEEK_SET); - msg->cm_fields[eMesageText] = malloc(len + 1); - rv = fread(msg->cm_fields[eMesageText], len, 1, fp); + msgbuf = malloc(len + 1); + rv = fread(msgbuf, len, 1, fp); syslog(LOG_DEBUG, "did %d blocks of %ld bytes\n", rv, len); - msg->cm_fields[eMesageText][len] = 0; + msgbuf[len] = '\0'; + CM_SetAsField(msg, eMesageText, &msgbuf, len); fclose(fp); } if (len <= 0) { msgnum = (-1L); } else if (!strcasecmp(operation, "fetch")) { - msg->cm_fields[eAuthor] = strdup("Citadel"); + CM_SetField(msg, eAuthor, HKEY("Citadel")); CtdlCreateRoom(wwm, 5, "", 0, 1, 1, VIEW_BBS); /* Not an error if already exists */ msgnum = CtdlSubmitMsg(msg, NULL, wwm, 0); /* Store the revision here */ @@ -605,26 +624,25 @@ void wiki_rev(char *pagename, char *rev, char *operation) * but only if the client fetches the message we just generated immediately * without first trying to perform other fetch operations. */ - if (CC->cached_msglist != NULL) { - free(CC->cached_msglist); - CC->cached_msglist = NULL; - CC->cached_num_msgs = 0; + if (CCC->cached_msglist != NULL) { + free(CCC->cached_msglist); + CCC->cached_msglist = NULL; + CCC->cached_num_msgs = 0; } - CC->cached_msglist = malloc(sizeof(long)); - if (CC->cached_msglist != NULL) { - CC->cached_num_msgs = 1; - CC->cached_msglist[0] = msgnum; + CCC->cached_msglist = malloc(sizeof(long)); + if (CCC->cached_msglist != NULL) { + CCC->cached_num_msgs = 1; + CCC->cached_msglist[0] = msgnum; } } else if (!strcasecmp(operation, "revert")) { - snprintf(timestamp, sizeof timestamp, "%ld", time(NULL)); - msg->cm_fields[eTimestamp] = strdup(timestamp); - msg->cm_fields[eAuthor] = strdup(CC->user.fullname); - msg->cm_fields[erFc822Addr] = strdup(CC->cs_inet_email); - msg->cm_fields[eOriginalRoom] = strdup(CC->room.QRname); - msg->cm_fields[eNodeName] = strdup(NODENAME); - msg->cm_fields[eExclusiveID] = strdup(pagename); + CM_SetFieldLONG(msg, eTimestamp, time(NULL)); + CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); + CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email)); + CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); + CM_SetField(msg, eNodeName, NODENAME, strlen(NODENAME)); + CM_SetField(msg, eExclusiveID, pagename, strlen(pagename)); msgnum = CtdlSubmitMsg(msg, NULL, "", 0); /* Replace the current revision */ } else { diff --git a/citadel/msgbase.c b/citadel/msgbase.c index be3a87628..cc52aec73 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -156,7 +156,7 @@ eMsgField FieldOrder[] = { }; static const long NDiskFields = sizeof(FieldOrder) / sizeof(eMsgField); -void CtdlMsgSetCM_Fields(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length) +void CM_SetField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length) { if (Msg->cm_fields[which] != NULL) free (Msg->cm_fields[which]); @@ -165,6 +165,102 @@ void CtdlMsgSetCM_Fields(struct CtdlMessage *Msg, eMsgField which, const char *b Msg->cm_fields[which][length] = '\0'; } +void CM_SetFieldLONG(struct CtdlMessage *Msg, eMsgField which, long lvalue) +{ + char buf[128]; + long len; + len = snprintf(buf, sizeof(buf), "%ld", lvalue); + CM_SetField(Msg, which, buf, len); +} +void CM_CutFieldAt(struct CtdlMessage *Msg, eMsgField WhichToCut, long maxlen) +{ + if (Msg->cm_fields[WhichToCut] == NULL) + return; + + if (strlen(Msg->cm_fields[WhichToCut]) > maxlen) + Msg->cm_fields[WhichToCut][maxlen] = '\0'; +} + +void CM_FlushField(struct CtdlMessage *Msg, eMsgField which) +{ + if (Msg->cm_fields[which] != NULL) + free (Msg->cm_fields[which]); + Msg->cm_fields[which] = NULL; +} + +void CM_CopyField(struct CtdlMessage *Msg, eMsgField WhichToPutTo, eMsgField WhichtToCopy) +{ + long len; + if (Msg->cm_fields[WhichToPutTo] != NULL) + free (Msg->cm_fields[WhichToPutTo]); + + if (Msg->cm_fields[WhichtToCopy] != NULL) + { + len = strlen(Msg->cm_fields[WhichtToCopy]); + Msg->cm_fields[WhichToPutTo] = malloc(len + 1); + memcpy(Msg->cm_fields[WhichToPutTo], Msg->cm_fields[WhichToPutTo], len); + Msg->cm_fields[WhichToPutTo][len] = '\0'; + } + else + Msg->cm_fields[WhichToPutTo] = NULL; +} + + +void CM_PrependToField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length) +{ + if (Msg->cm_fields[which] != NULL) { + long oldmsgsize; + long newmsgsize; + char *new; + + oldmsgsize = strlen(Msg->cm_fields[which]) + 1; + newmsgsize = length + oldmsgsize; + + new = malloc(newmsgsize); + memcpy(new, buf, length); + memcpy(new + length, Msg->cm_fields[which], oldmsgsize); + free(Msg->cm_fields[which]); + Msg->cm_fields[which] = new; + } + else { + Msg->cm_fields[which] = malloc(length + 1); + memcpy(Msg->cm_fields[which], buf, length); + Msg->cm_fields[which][length] = '\0'; + } +} + +void CM_SetAsField(struct CtdlMessage *Msg, eMsgField which, char **buf, long length) +{ + if (Msg->cm_fields[which] != NULL) + free (Msg->cm_fields[which]); + + Msg->cm_fields[which] = *buf; + *buf = NULL; +} + +void CM_SetAsFieldSB(struct CtdlMessage *Msg, eMsgField which, StrBuf **buf) +{ + if (Msg->cm_fields[which] != NULL) + free (Msg->cm_fields[which]); + + Msg->cm_fields[which] = SmashStrBuf(buf); +} + +void CM_GetAsField(struct CtdlMessage *Msg, eMsgField which, char **ret, long *retlen) +{ + if (Msg->cm_fields[which] != NULL) + { + *retlen = strlen(Msg->cm_fields[which]); + *ret = Msg->cm_fields[which]; + Msg->cm_fields[which] = NULL; + } + else + { + *ret = NULL; + *retlen = 0; + } +} + /* * This function is self explanatory. * (What can I say, I'm in a weird mood today...) @@ -943,12 +1039,12 @@ void cmd_msgs(char *cmdbuf) template->cm_anon_type = MES_NORMAL; while(client_getln(buf, sizeof buf) >= 0 && strcmp(buf,"000")) { + long tValueLen; extract_token(tfield, buf, 0, '|', sizeof tfield); - extract_token(tvalue, buf, 1, '|', sizeof tvalue); + tValueLen = extract_token(tvalue, buf, 1, '|', sizeof tvalue); for (i='A'; i<='Z'; ++i) if (msgkeys[i]!=NULL) { if (!strcasecmp(tfield, msgkeys[i])) { - template->cm_fields[i] = - strdup(tvalue); + CM_SetField(template, i, tvalue, tValueLen); } } } @@ -1283,13 +1379,15 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) * have just processed the 'M' (message text) field. */ do { + long len; if (mptr >= upper_bound) { break; } field_header = *mptr++; - ret->cm_fields[field_header] = strdup(mptr); + len = strlen(mptr); + CM_SetField(ret, field_header, mptr, len); - while (*mptr++ != 0); /* advance to next field */ + mptr += len + 1; /* advance to next field */ } while ((mptr < upper_bound) && (field_header != 'M')); @@ -1303,13 +1401,12 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) if ( (ret->cm_fields[eMesageText] == NULL) && (with_body) ) { dmsgtext = cdb_fetch(CDB_BIGMSGS, &msgnum, sizeof(long)); if (dmsgtext != NULL) { - ret->cm_fields[eMesageText] = dmsgtext->ptr; - dmsgtext->ptr = NULL; + CM_SetAsField(ret, eMesageText, &dmsgtext->ptr, dmsgtext->len); cdb_free(dmsgtext); } } if (ret->cm_fields[eMesageText] == NULL) { - ret->cm_fields[eMesageText] = strdup("\r\n\r\n (no text)\r\n"); + CM_SetField(ret, eMesageText, HKEY("\r\n\r\n (no text)\r\n")); } /* Perform "before read" hooks (aborting if any return nonzero) */ @@ -1362,7 +1459,7 @@ void CtdlFreeMessage(struct CtdlMessage *msg) free(msg); } -int DupCMField(int i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg) +int DupCMField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg) { long len; len = strlen(OrgMsg->cm_fields[i]); @@ -1856,7 +1953,6 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ * encapsulated message instead of the top-level * message. Isn't that neat? */ - } else { if (do_proto) { @@ -2981,21 +3077,22 @@ long send_message(struct CtdlMessage *msg) { long newmsgid; long retval; char msgidbuf[256]; + long msgidbuflen; struct ser_ret smr; int is_bigmsg = 0; char *holdM = NULL; /* Get a new message number */ newmsgid = get_new_message_number(); - snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", - (long unsigned int) time(NULL), - (long unsigned int) newmsgid, - config.c_fqdn + msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", + (long unsigned int) time(NULL), + (long unsigned int) newmsgid, + config.c_fqdn ); /* Generate an ID if we don't have one already */ if (msg->cm_fields[emessageId]==NULL) { - msg->cm_fields[emessageId] = strdup(msgidbuf); + CM_SetField(msg, emessageId, msgidbuf, msgidbuflen); } /* If the message is big, set its body aside for storage elsewhere */ @@ -3158,7 +3255,6 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ ) { char submit_filename[128]; - char generated_timestamp[32]; char hold_rm[ROOMNAMELEN]; char actual_rm[ROOMNAMELEN]; char force_room[ROOMNAMELEN]; @@ -3192,15 +3288,14 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ * giving it one, right now. */ if (msg->cm_fields[eTimestamp] == NULL) { - snprintf(generated_timestamp, sizeof generated_timestamp, "%ld", (long)time(NULL)); - msg->cm_fields[eTimestamp] = strdup(generated_timestamp); + CM_SetFieldLONG(msg, eTimestamp, time(NULL)); } /* If this message has no path, we generate one. */ if (msg->cm_fields[eMessagePath] == NULL) { if (msg->cm_fields[eAuthor] != NULL) { - msg->cm_fields[eMessagePath] = strdup(msg->cm_fields[eAuthor]); + CM_CopyField(msg, eMessagePath, eAuthor); for (a=0; !IsEmptyStr(&msg->cm_fields[eMessagePath][a]); ++a) { if (isspace(msg->cm_fields[eMessagePath][a])) { msg->cm_fields[eMessagePath][a] = ' '; @@ -3208,12 +3303,12 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } } else { - msg->cm_fields[eMessagePath] = strdup("unknown"); + CM_SetField(msg,eMessagePath, HKEY("unknown")); } } if (force == NULL) { - strcpy(force_room, ""); + force_room[0] = '\0'; } else { strcpy(force_room, force); @@ -3285,7 +3380,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ * If this message has no O (room) field, generate one. */ if (msg->cm_fields[eOriginalRoom] == NULL) { - msg->cm_fields[eOriginalRoom] = strdup(CCC->room.QRname); + CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); } /* Perform "before save" hooks (aborting if any return nonzero) */ @@ -3388,8 +3483,10 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ */ if ((recps != NULL) && (recps->num_local > 0)) for (i=0; irecp_local, '|'); ++i) { - extract_token(recipient, recps->recp_local, i, - '|', sizeof recipient); + long recipientlen; + recipientlen = extract_token(recipient, + recps->recp_local, i, + '|', sizeof recipient); MSG_syslog(LOG_DEBUG, "Delivering private local mail to <%s>\n", recipient); if (CtdlGetUser(&userbuf, recipient) == 0) { @@ -3400,13 +3497,17 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ /* Generate a instruction message for the Funambol notification * server, in the same style as the SMTP queue */ + long instrlen; instr_alloc = 1024; instr = malloc(instr_alloc); - snprintf(instr, instr_alloc, - "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n" - "bounceto|%s\n", - SPOOLMIME, newmsgid, (long)time(NULL), - bounce_to + instrlen = snprintf( + instr, instr_alloc, + "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n" + "bounceto|%s\n", + SPOOLMIME, + newmsgid, + (long)time(NULL), //todo: time() is expensive! + bounce_to ); imsg = malloc(sizeof(struct CtdlMessage)); @@ -3414,11 +3515,11 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ imsg->cm_magic = CTDLMESSAGE_MAGIC; imsg->cm_anon_type = MES_NORMAL; imsg->cm_format_type = FMT_RFC822; - imsg->cm_fields[eMsgSubject] = strdup("QMSG"); - imsg->cm_fields[eAuthor] = strdup("Citadel"); - imsg->cm_fields[eJournal] = strdup("do not journal"); - imsg->cm_fields[eMesageText] = instr; /* imsg owns this memory now */ - imsg->cm_fields[eExtnotify] = strdup(recipient); + CM_SetField(imsg, eMsgSubject, HKEY("QMSG")); + CM_SetField(imsg, eAuthor, HKEY("Citadel")); + CM_SetField(imsg, eJournal, HKEY("do not journal")); + CM_SetAsField(imsg, eMesageText, &instr, instrlen); + CM_SetField(imsg, eExtnotify, recipient, recipientlen); CtdlSubmitMsg(imsg, NULL, FNBL_QUEUE_ROOM, 0); CtdlFreeMessage(imsg); } diff --git a/citadel/msgbase.h b/citadel/msgbase.h index d6b21b094..06c426174 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -164,7 +164,16 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ ); struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body); struct CtdlMessage * CtdlDuplicateMessage(struct CtdlMessage *OrgMsg); -void CtdlMsgSetCM_Fields(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length); +void CM_SetField (struct CtdlMessage *Msg, eMsgField which, const char *buf, long length); +void CM_SetFieldLONG (struct CtdlMessage *Msg, eMsgField which, long lvalue); +void CM_CopyField (struct CtdlMessage *Msg, eMsgField WhichToPutTo, eMsgField WhichtToCopy); +void CM_CutFieldAt (struct CtdlMessage *Msg, eMsgField WhichToCut, long maxlen); +void CM_FlushField (struct CtdlMessage *Msg, eMsgField which); +void CM_SetAsField (struct CtdlMessage *Msg, eMsgField which, char **buf, long length); +void CM_SetAsFieldSB (struct CtdlMessage *Msg, eMsgField which, StrBuf **buf); +void CM_GetAsField (struct CtdlMessage *Msg, eMsgField which, char **ret, long *retlen); +void CM_PrependToField (struct CtdlMessage *Msg, eMsgField which, const char *buf, long length); + void CtdlFreeMessage(struct CtdlMessage *msg); void CtdlFreeMessageContents(struct CtdlMessage *msg); void serialize_message(struct ser_ret *, struct CtdlMessage *); -- 2.30.2