Route all access to cm_fields[] through api functions
authorWilfried Goesgens <dothebart@citadel.org>
Sun, 1 Sep 2013 10:30:27 +0000 (12:30 +0200)
committerWilfried Goesgens <dothebart@citadel.org>
Sun, 1 Sep 2013 10:30:27 +0000 (12:30 +0200)
25 files changed:
citadel/internet_addressing.c
citadel/journaling.c
citadel/modules/blog/serv_blog.c
citadel/modules/calendar/serv_calendar.c
citadel/modules/clamav/serv_virus.c
citadel/modules/extnotify/extnotify_main.c
citadel/modules/imap/imap_misc.c
citadel/modules/instmsg/serv_instmsg.c
citadel/modules/network/netspool.h
citadel/modules/network/serv_netmail.c
citadel/modules/network/serv_netspool.c
citadel/modules/network/serv_network.c
citadel/modules/notes/serv_notes.c
citadel/modules/rssclient/rss_atom_parser.c
citadel/modules/rssclient/serv_rssclient.c
citadel/modules/sieve/serv_sieve.c
citadel/modules/smtp/serv_smtp.c
citadel/modules/smtp/serv_smtpeventclient.c
citadel/modules/smtp/serv_smtpqueue.c
citadel/modules/smtp/smtp_util.c
citadel/modules/spam/serv_spam.c
citadel/modules/vcard/serv_vcard.c
citadel/modules/wiki/serv_wiki.c
citadel/msgbase.c
citadel/msgbase.h

index b4663fc..14c9900 100644 (file)
@@ -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; i<strlen(msg->cm_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]);
        }
 
index 26c2736..d1daf5a 100644 (file)
@@ -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; i<jmsg->recps.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; i<jmsg->recps.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; i<jmsg->recps.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);
index 4424d46..a6513e7 100644 (file)
@@ -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);
 }
index 0d971d9..a70baad 100644 (file)
@@ -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);
                                }
                        }
 
index 6f2dd04..ae24461 100644 (file)
@@ -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);
index 826704c..6d86508 100644 (file)
@@ -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... */
index ede4b2f..be0fa51 100644 (file)
@@ -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));
            }
        }
 
index cb4101a..9a75e28 100644 (file)
@@ -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.
index d04a49f..8496c5c 100644 (file)
@@ -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);
index a8086b8..dd47f25 100644 (file)
@@ -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 */
index 3700ee4..dac6db4 100644 (file)
@@ -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) {
index 1f0a680..b2b296e 100644 (file)
@@ -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);
index bf1de8d..9c1c944 100644 (file)
@@ -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);
                }
        }
 
index 681cf8a..254b6e5 100644 (file)
@@ -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));
                }
        }
 
index 059cd1b..374d53d 100644 (file)
@@ -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);
                
index d7a5584..4a9fcbf 100644 (file)
@@ -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) {
index ad9137f..9559d1c 100644 (file)
@@ -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]);
index 5eddfc1..de7aafb 100644 (file)
@@ -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);
index 6ff9e35..685e2ca 100644 (file)
@@ -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) {
index dd4c807..6dcf95f 100644 (file)
@@ -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) {
index f27e224..c0ced7e 100644 (file)
@@ -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"));
                }
        }
 
index 10516c3..36fdb25 100644 (file)
@@ -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);
index 799a3f3..33d8563 100644 (file)
@@ -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 {
index be3a876..cc52aec 100644 (file)
@@ -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; i<num_tokens(recps->recp_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);
                                }
index d6b21b0..06c4261 100644 (file)
@@ -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 *);