int i;
const char *colonpos = NULL;
int processed = 0;
- char buf[SIZ];
char user[1024];
char node[1024];
char name[1024];
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;
}
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;
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;
}
/* Clean up and move on. */
free(key); /* Don't free 'value', it's actually the same buffer */
- return(processed);
+ return processed;
}
struct CtdlMessage *msg;
const char *pos, *beg, *end, *totalend;
int done, alldone = 0;
- char buf[SIZ];
int converted;
StrBuf *OtherHeaders;
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]);
}
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;
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.
* 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);
}
}
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);
}
}
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);
*/
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);
}
*/
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;
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 */
/* 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);
struct CtdlMessage *msg = NULL;
struct recptypes *valid = NULL;
- strcpy(organizer_string, "");
+ *organizer_string = '\0';
strcpy(summary_string, "Calendar item");
if (request == NULL) {
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;
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);
}
}
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));
}
}
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);
}
}
}
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);
int num_msgs = 0;
int a;
char *configMsg;
+ long clen;
char *pch;
// Get the user
// 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... */
* 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);
* 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));
}
}
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.
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);
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);
}
*/
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;
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
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;
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
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 */
* 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);
}
char buf[SIZ];
char filename[PATH_MAX];
FILE *fp;
- size_t newpath_len;
- char *newpath = NULL;
StrBuf *Buf = NULL;
int i;
int bang = 0;
/* 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
* 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 */
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,
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;
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;
}
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);
}
/* 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) {
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");
/*
* 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);
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++;
/* 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);
}
}
/* 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;
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));
}
}
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;
StrBufTrim(Encoded);
StrBufRFC2047encode(&QPEncoded, Encoded);
- SaveMsg->Msg.cm_fields[eMsgSubject] = SmashStrBuf(&QPEncoded);
+ CM_SetAsFieldSB(&SaveMsg->Msg, eMsgSubject, &QPEncoded);
FreeStrBuf(&Encoded);
}
if (SaveMsg->link == NULL)
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);
struct sdm_userdata *u = (struct sdm_userdata *) userdata;
struct CtdlMessage *msg;
char *conf;
+ long conflen;
u->config_msgnum = msgnum;
msg = CtdlFetchMessage(msgnum, 1);
return;
}
- conf = msg->cm_fields[eMesageText];
- msg->cm_fields[eMesageText] = NULL;
+ CM_GetAsField(msg, eMesageText, &conf, &conflen);
+
CtdlFreeMessage(msg);
if (conf != NULL) {
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(
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]);
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);
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) {
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);
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) {
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");
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"));
}
}
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 */
/*
* 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);
}
}
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);
}
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;
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);
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);
FILE *fp;
int rv;
char history_page[1024];
+ long history_page_len;
char boundary[256];
char prefixed_boundary[258];
char buf[1024];
/* 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.
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);
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);
}
/* 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) */
/* 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 {
* 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);
}
}
free(diffbuf);
- free(history_msg);
+ CtdlFreeMessage(history_msg);
return(0);
}
*/
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;
/* 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);
}
/* 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);
}
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 */
* 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 {
};
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]);
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...)
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);
}
}
}
* 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'));
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) */
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]);
* encapsulated message instead of the top-level
* message. Isn't that neat?
*/
-
}
else {
if (do_proto) {
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 */
)
{
char submit_filename[128];
- char generated_timestamp[32];
char hold_rm[ROOMNAMELEN];
char actual_rm[ROOMNAMELEN];
char force_room[ROOMNAMELEN];
* 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] = ' ';
}
}
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);
* 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) */
*/
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) {
/* 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));
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);
}
);
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 *);