X-Git-Url: https://code.citadel.org/?p=citadel.git;a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=081be8980a2aba77e5dd44121e083e57f8e4027e;hp=7f6b7c9dabecf7477a213aecbea99a1f67e1af03;hb=79d6eafd2a8bb379b3e13ff071a000d9bf36771b;hpb=4f91d5d6e8ab40320421406d735eb72c8ff9575e diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 7f6b7c9da..081be8980 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1,7 +1,7 @@ /* * Implements the message store. * - * Copyright (c) 1987-2018 by the citadel.org team + * Copyright (c) 1987-2021 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3. @@ -19,7 +19,6 @@ #include #include #include -#include "md5.h" #include "ctdl_module.h" #include "citserver.h" #include "control.h" @@ -39,7 +38,7 @@ struct addresses_to_be_filed *atbf = NULL; * These are the four-character field headers we use when outputting * messages in Citadel format (as opposed to RFC822 format). */ -char *msgkeys[91] = { +char *msgkeys[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -49,34 +48,35 @@ char *msgkeys[91] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "from", /* A -> eAuthor */ - NULL, /* B -> eBig_message */ - NULL, /* C -> eRemoteRoom FIXME no more ignet */ - NULL, /* D -> eDestination FIXME no more ignet */ - "exti", /* E -> eXclusivID */ - "rfca", /* F -> erFc822Addr */ - NULL, /* G */ - "hnod", /* H -> eHumanNode FIXME no more ignet */ - "msgn", /* I -> emessageId */ - "jrnl", /* J -> eJournal */ - "rep2", /* K -> eReplyTo */ - "list", /* L -> eListID */ - "text", /* M -> eMesageText */ - "node", /* N -> eNodeName FIXME no more ignet */ - "room", /* O -> eOriginalRoom */ - "path", /* P -> eMessagePath */ - NULL, /* Q */ - "rcpt", /* R -> eRecipient */ - "spec", /* S -> eSpecialField FIXME we might not be using this anymore */ - "time", /* T -> eTimestamp */ - "subj", /* U -> eMsgSubject */ - "nvto", /* V -> eenVelopeTo */ - "wefw", /* W -> eWeferences */ - NULL, /* X */ - "cccc", /* Y -> eCarbonCopY */ - NULL /* Z */ - + "from", // A -> eAuthor + NULL, // B -> eBig_message + NULL, // C (formerly used as eRemoteRoom) + NULL, // D (formerly used as eDestination) + "exti", // E -> eXclusivID + "rfca", // F -> erFc822Addr + NULL, // G + "hnod", // H (formerly used as eHumanNode) + "msgn", // I -> emessageId + "jrnl", // J -> eJournal + "rep2", // K -> eReplyTo + "list", // L -> eListID + "text", // M -> eMesageText + NULL, // N (formerly used as eNodename) + "room", // O -> eOriginalRoom + "path", // P -> eMessagePath + NULL, // Q + "rcpt", // R -> eRecipient + NULL, // S (formerly used as eSpecialField) + "time", // T -> eTimestamp + "subj", // U -> eMsgSubject + "nvto", // V -> eenVelopeTo + "wefw", // W -> eWeferences + NULL, // X + "cccc", // Y -> eCarbonCopY + NULL // Z }; + + HashList *msgKeyLookup = NULL; int GetFieldFromMnemonic(eMsgField *f, const char* c) @@ -102,6 +102,7 @@ void FillMsgKeyLookupTable(void) } } + eMsgField FieldOrder[] = { /* Important fields */ emessageId , @@ -110,21 +111,16 @@ eMsgField FieldOrder[] = { eAuthor , erFc822Addr , eOriginalRoom, - eNodeName , - eHumanNode , eRecipient , - eDestination , /* Semi-important fields */ eBig_message , - eRemoteRoom , eExclusiveID , eWeferences , eJournal , -/* G is not used yet, may become virus signature*/ +/* G is not used yet */ eReplyTo , eListID , /* Q is not used yet */ - eSpecialField, eenVelopeTo , /* X is not used yet */ /* Z is not used yet */ @@ -144,17 +140,18 @@ eMsgField FieldOrder[] = { static const long NDiskFields = sizeof(FieldOrder) / sizeof(eMsgField); -int CM_IsEmpty(struct CtdlMessage *Msg, eMsgField which) -{ +int CM_IsEmpty(struct CtdlMessage *Msg, eMsgField which) { return !((Msg->cm_fields[which] != NULL) && (Msg->cm_fields[which][0] != '\0')); } -void CM_SetField(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]); } + if (length < 0) { // You can set the length to -1 to have CM_SetField measure it for you + length = strlen(buf); + } Msg->cm_fields[which] = malloc(length + 1); memcpy(Msg->cm_fields[which], buf, length); Msg->cm_fields[which][length] = '\0'; @@ -162,8 +159,7 @@ void CM_SetField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long } -void CM_SetFieldLONG(struct CtdlMessage *Msg, eMsgField which, long lvalue) -{ +void CM_SetFieldLONG(struct CtdlMessage *Msg, eMsgField which, long lvalue) { char buf[128]; long len; len = snprintf(buf, sizeof(buf), "%ld", lvalue); @@ -171,8 +167,7 @@ void CM_SetFieldLONG(struct CtdlMessage *Msg, eMsgField which, long lvalue) } -void CM_CutFieldAt(struct CtdlMessage *Msg, eMsgField WhichToCut, long maxlen) -{ +void CM_CutFieldAt(struct CtdlMessage *Msg, eMsgField WhichToCut, long maxlen) { if (Msg->cm_fields[WhichToCut] == NULL) return; @@ -184,8 +179,7 @@ void CM_CutFieldAt(struct CtdlMessage *Msg, eMsgField WhichToCut, long maxlen) } -void CM_FlushField(struct CtdlMessage *Msg, eMsgField which) -{ +void CM_FlushField(struct CtdlMessage *Msg, eMsgField which) { if (Msg->cm_fields[which] != NULL) free (Msg->cm_fields[which]); Msg->cm_fields[which] = NULL; @@ -193,8 +187,7 @@ void CM_FlushField(struct CtdlMessage *Msg, eMsgField which) } -void CM_Flush(struct CtdlMessage *Msg) -{ +void CM_Flush(struct CtdlMessage *Msg) { int i; if (CM_IsValidMsg(Msg) == 0) { @@ -207,8 +200,7 @@ void CM_Flush(struct CtdlMessage *Msg) } -void CM_CopyField(struct CtdlMessage *Msg, eMsgField WhichToPutTo, eMsgField WhichtToCopy) -{ +void CM_CopyField(struct CtdlMessage *Msg, eMsgField WhichToPutTo, eMsgField WhichtToCopy) { long len; if (Msg->cm_fields[WhichToPutTo] != NULL) { free (Msg->cm_fields[WhichToPutTo]); @@ -228,8 +220,7 @@ void CM_CopyField(struct CtdlMessage *Msg, eMsgField WhichToPutTo, eMsgField Whi } -void CM_PrependToField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length) -{ +void CM_PrependToField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length) { if (Msg->cm_fields[which] != NULL) { long oldmsgsize; long newmsgsize; @@ -254,20 +245,23 @@ void CM_PrependToField(struct CtdlMessage *Msg, eMsgField which, const char *buf } -void CM_SetAsField(struct CtdlMessage *Msg, eMsgField which, char **buf, long length) -{ +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; - Msg->cm_lengths[which] = length; + if (length < 0) { // You can set the length to -1 to have CM_SetField measure it for you + Msg->cm_lengths[which] = strlen(Msg->cm_fields[which]); + } + else { + Msg->cm_lengths[which] = length; + } } -void CM_SetAsFieldSB(struct CtdlMessage *Msg, eMsgField which, StrBuf **buf) -{ +void CM_SetAsFieldSB(struct CtdlMessage *Msg, eMsgField which, StrBuf **buf) { if (Msg->cm_fields[which] != NULL) { free (Msg->cm_fields[which]); } @@ -277,8 +271,7 @@ void CM_SetAsFieldSB(struct CtdlMessage *Msg, eMsgField which, StrBuf **buf) } -void CM_GetAsField(struct CtdlMessage *Msg, eMsgField which, char **ret, long *retlen) -{ +void CM_GetAsField(struct CtdlMessage *Msg, eMsgField which, char **ret, long *retlen) { if (Msg->cm_fields[which] != NULL) { *retlen = Msg->cm_lengths[which]; *ret = Msg->cm_fields[which]; @@ -308,8 +301,7 @@ int CM_IsValidMsg(struct CtdlMessage *msg) { } -void CM_FreeContents(struct CtdlMessage *msg) -{ +void CM_FreeContents(struct CtdlMessage *msg) { int i; for (i = 0; i < 256; ++i) @@ -325,8 +317,7 @@ void CM_FreeContents(struct CtdlMessage *msg) /* * 'Destructor' for struct CtdlMessage */ -void CM_Free(struct CtdlMessage *msg) -{ +void CM_Free(struct CtdlMessage *msg) { if (CM_IsValidMsg(msg) == 0) { if (msg != NULL) free (msg); return; @@ -336,8 +327,7 @@ void CM_Free(struct CtdlMessage *msg) } -int CM_DupField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg) -{ +int CM_DupField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg) { long len; len = OrgMsg->cm_lengths[i]; NewMsg->cm_fields[i] = malloc(len + 1); @@ -351,8 +341,7 @@ int CM_DupField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *New } -struct CtdlMessage * CM_Duplicate(struct CtdlMessage *OrgMsg) -{ +struct CtdlMessage *CM_Duplicate(struct CtdlMessage *OrgMsg) { int i; struct CtdlMessage *NewMsg; @@ -484,7 +473,8 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, cdbfr->ptr = NULL; /* CtdlSetSeen() now owns this memory */ num_msgs = cdbfr->len / sizeof(long); cdb_free(cdbfr); - } else { + } + else { return; /* No messages at all? No further action. */ } @@ -762,7 +752,7 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, free(msglist); return -1; } - msg = CtdlFetchMessage(msglist[a], 1, 1); + msg = CtdlFetchMessage(msglist[a], 1); if (msg != NULL) { if (CtdlMsgCmp(msg, compare)) { msglist[a] = 0L; @@ -1050,14 +1040,14 @@ void mime_download(char *name, char *filename, char *partnum, char *disp, ) { CC->download_fp = tmpfile(); if (CC->download_fp == NULL) { - syslog(LOG_EMERG, "msgbase: mime_download() couldn't write: %m"); + syslog(LOG_ERR, "msgbase: mime_download() couldn't write: %m"); cprintf("%d cannot open temporary file: %s\n", ERROR + INTERNAL_ERROR, strerror(errno)); return; } rv = fwrite(content, length, 1, CC->download_fp); if (rv <= 0) { - syslog(LOG_EMERG, "msgbase: mime_download() Couldn't write: %m"); + syslog(LOG_ERR, "msgbase: mime_download() Couldn't write: %m"); cprintf("%d unable to write tempfile.\n", ERROR + TOO_BIG); fclose(CC->download_fp); CC->download_fp = NULL; @@ -1109,6 +1099,9 @@ struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const cha mptr = Buffer; upper_bound = Buffer + Length; + if (msgnum <= 0) { + return NULL; + } /* Parse the three bytes that begin EVERY message on disk. * The first is always 0xFF, the on-disk magic number. @@ -1166,7 +1159,7 @@ struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const cha * NOTE: Caller is responsible for freeing the returned CtdlMessage struct * using the CM_Free(); function. */ -struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hooks) +struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) { struct cdbdata *dmsgtext; struct CtdlMessage *ret = NULL; @@ -1207,12 +1200,6 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hoo CM_SetField(ret, eMesageText, HKEY("\r\n\r\n (no text)\r\n")); } - /* Perform "before read" hooks (aborting if any return nonzero) */ - if (run_msg_hooks && (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0)) { - CM_Free(ret); - return NULL; - } - return (ret); } @@ -1599,10 +1586,10 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ * request that we don't even bother loading the body into memory. */ if (headers_only == HEADERS_FAST) { - TheMessage = CtdlFetchMessage(msg_num, 0, 1); + TheMessage = CtdlFetchMessage(msg_num, 0); } else { - TheMessage = CtdlFetchMessage(msg_num, 1, 1); + TheMessage = CtdlFetchMessage(msg_num, 1); } if (TheMessage == NULL) { @@ -1688,12 +1675,8 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ } -void OutputCtdlMsgHeaders( - struct CtdlMessage *TheMessage, - int do_proto) /* do Citadel protocol responses? */ -{ +void OutputCtdlMsgHeaders(struct CtdlMessage *TheMessage, int do_proto) { int i; - int suppress_f = 0; char buf[SIZ]; char display_name[256]; @@ -1720,39 +1703,34 @@ void OutputCtdlMsgHeaders( } } - /* Don't show Internet address for users on the - * local Citadel network. - */ - suppress_f = 0; - if (!CM_IsEmpty(TheMessage, eNodeName) && (haschar(TheMessage->cm_fields[eNodeName], '.') == 0)) { - suppress_f = 1; - } - /* Now spew the header fields in the order we like them. */ for (i=0; i< NDiskFields; ++i) { eMsgField Field; Field = FieldOrder[i]; if (Field != eMesageText) { - if ( (!CM_IsEmpty(TheMessage, Field)) - && (msgkeys[Field] != NULL) ) { - if ((Field == eenVelopeTo) || - (Field == eRecipient) || - (Field == eCarbonCopY)) { + if ( (!CM_IsEmpty(TheMessage, Field)) && (msgkeys[Field] != NULL) ) { + if ((Field == eenVelopeTo) || (Field == eRecipient) || (Field == eCarbonCopY)) { sanitize_truncated_recipient(TheMessage->cm_fields[Field]); } if (Field == eAuthor) { - if (do_proto) cprintf("%s=%s\n", - msgkeys[Field], - display_name); - } - else if ((Field == erFc822Addr) && (suppress_f)) { - /* do nothing */ + if (do_proto) { + cprintf("%s=%s\n", msgkeys[Field], display_name); + } } /* Masquerade display name if needed */ else { if (do_proto) { cprintf("%s=%s\n", msgkeys[Field], TheMessage->cm_fields[Field]); } + } + /* Give the client a hint about whether the message originated locally */ + if (Field == erFc822Addr) { + if (IsDirectory(TheMessage->cm_fields[Field] ,0)) { + cprintf("locl=yes\n"); // message originated locally. + } + + + } } } @@ -1762,7 +1740,7 @@ void OutputCtdlMsgHeaders( void OutputRFC822MsgHeaders( struct CtdlMessage *TheMessage, - int flags, /* should the bessage be exported clean */ + int flags, /* should the message be exported clean */ const char *nl, int nlen, char *mid, long sizeof_mid, char *suser, long sizeof_suser, @@ -1817,8 +1795,6 @@ void OutputRFC822MsgHeaders( break; case erFc822Addr: safestrncpy(fuser, mptr, sizeof_fuser); - case eNodeName: - safestrncpy(snode, mptr, sizeof_snode); break; case eRecipient: if (haschar(mptr, '@') == 0) { @@ -1861,15 +1837,11 @@ void OutputRFC822MsgHeaders( cprintf("Reply-To: %s%s", mptr, nl); break; - case eRemoteRoom: - case eDestination: case eExclusiveID: - case eHumanNode: case eJournal: case eMesageText: case eBig_message: case eOriginalRoom: - case eSpecialField: case eErrorMsg: case eSuppressIdx: case eExtnotify: @@ -2056,11 +2028,11 @@ int CtdlOutputPreLoadedMsg( * using functions that are bounds-checked, and therefore we can * make them substantially smaller than SIZ. */ - char suser[100]; - char luser[100]; - char fuser[100]; - char snode[100]; - char mid[100]; + char suser[1024]; + char luser[1024]; + char fuser[1024]; + char snode[1024]; + char mid[1024]; syslog(LOG_DEBUG, "msgbase: CtdlOutputPreLoadedMsg(TheMessage=%s, %d, %d, %d, %d", ((TheMessage == NULL) ? "NULL" : "not null"), @@ -2144,7 +2116,7 @@ int CtdlOutputPreLoadedMsg( /* Tell the client which format type we're using. */ if ( (mode == MT_CITADEL) && (do_proto) ) { - cprintf("type=%d\n", TheMessage->cm_format_type); + cprintf("type=%d\n", TheMessage->cm_format_type); // Tell the client which format type we're using. } /* nhdr=yes means that we're only displaying headers, no body */ @@ -2155,15 +2127,15 @@ int CtdlOutputPreLoadedMsg( cprintf("nhdr=yes\n"); } - if ((mode == MT_CITADEL) || (mode == MT_MIME)) + if ((mode == MT_CITADEL) || (mode == MT_MIME)) { OutputCtdlMsgHeaders(TheMessage, do_proto); - + } /* begin header processing loop for RFC822 transfer format */ strcpy(suser, ""); strcpy(luser, ""); strcpy(fuser, ""); - memcpy(snode, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")) + 1); + strcpy(snode, ""); if (mode == MT_RFC822) OutputRFC822MsgHeaders( TheMessage, @@ -2183,12 +2155,8 @@ int CtdlOutputPreLoadedMsg( } if (mode == MT_RFC822) { - if (!strcasecmp(snode, NODENAME)) { - safestrncpy(snode, FQDN, sizeof snode); - } - /* Construct a fun message id */ - cprintf("Message-ID: <%s", mid);/// todo: this possibly breaks threadding mails. + cprintf("Message-ID: <%s", mid); if (strchr(mid, '@')==NULL) { cprintf("@%s", snode); } @@ -2421,7 +2389,7 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms msg = supplied_msg; } else { - msg = CtdlFetchMessage(msgid, 0, 1); + msg = CtdlFetchMessage(msgid, 0); } if (msg != NULL) { @@ -2446,7 +2414,10 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms } /* Submit this room for processing by hooks */ - PerformRoomHooks(&CC->room); + int total_roomhook_errors = PerformRoomHooks(&CC->room); + if (total_roomhook_errors) { + syslog(LOG_WARNING, "msgbase: room hooks returned %d errors", total_roomhook_errors); + } /* Go back to the room we were in before we wandered here... */ CtdlGetRoom(&CC->room, hold_rm); @@ -2477,8 +2448,6 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, } - - /* * Message base operation to save a new message to the message store * (returns new message number) @@ -2498,8 +2467,7 @@ long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { * If the message is big, set its body aside for storage elsewhere * and we hide the message body from the serializer */ - if (!CM_IsEmpty(msg, eMesageText) && msg->cm_lengths[eMesageText] > BIGMSG) - { + if (!CM_IsEmpty(msg, eMesageText) && msg->cm_lengths[eMesageText] > BIGMSG) { is_bigmsg = 1; holdM = msg->cm_fields[eMesageText]; msg->cm_fields[eMesageText] = NULL; @@ -2529,8 +2497,7 @@ long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { } /* Write our little bundle of joy into the message base */ - retval = cdb_store(CDB_MSGMAIN, &msgid, (int)sizeof(long), - smr.ser, smr.len); + retval = cdb_store(CDB_MSGMAIN, &msgid, (int)sizeof(long), smr.ser, smr.len); if (retval < 0) { syslog(LOG_ERR, "msgbase: can't store message %ld: %ld", msgid, retval); } @@ -2554,6 +2521,7 @@ long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { return(retval); } + long send_message(struct CtdlMessage *msg) { long newmsgid; long retval; @@ -2587,9 +2555,8 @@ long send_message(struct CtdlMessage *msg) { } - /* - * Serialize a struct CtdlMessage into the format used on disk and network. + * Serialize a struct CtdlMessage into the format used on disk. * * This function loads up a "struct ser_ret" (defined in server.h) which * contains the length of the serialized message and a pointer to the @@ -2629,9 +2596,8 @@ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ ret->ser[2] = msg->cm_format_type; wlen = 3; - for (i=0; i < NDiskFields; ++i) - if (msg->cm_fields[FieldOrder[i]] != NULL) - { + for (i=0; i < NDiskFields; ++i) { + if (msg->cm_fields[FieldOrder[i]] != NULL) { ret->ser[wlen++] = (char)FieldOrder[i]; memcpy(&ret->ser[wlen], @@ -2640,6 +2606,7 @@ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ wlen = wlen + msg->cm_lengths[FieldOrder[i]] + 1; } + } if (ret->len != wlen) { syslog(LOG_ERR, "msgbase: ERROR; len=%ld wlen=%ld", (long)ret->len, (long)wlen); @@ -2675,16 +2642,13 @@ void ReplicationChecks(struct CtdlMessage *msg) { } - /* * Save a message to disk and submit it into the delivery system. */ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ - recptypes *recps, /* recipients (if mail) */ - const char *force, /* force a particular room? */ - int flags /* should the message be exported clean? */ - ) -{ + struct recptypes *recps, /* recipients (if mail) */ + const char *force /* force a particular room? */ +) { char hold_rm[ROOMNAMELEN]; char actual_rm[ROOMNAMELEN]; char force_room[ROOMNAMELEN]; @@ -2801,7 +2765,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ * If this message has no O (room) field, generate one. */ if (CM_IsEmpty(msg, eOriginalRoom) && !IsEmptyStr(CC->room.QRname)) { - CM_SetField(msg, eOriginalRoom, CC->room.QRname, strlen(CC->room.QRname)); + CM_SetField(msg, eOriginalRoom, CC->room.QRname, -1); } /* Perform "before save" hooks (aborting if any return nonzero) */ @@ -2829,8 +2793,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ memset(&smi, 0, sizeof(struct MetaData)); smi.meta_msgnum = newmsgid; smi.meta_refcount = 0; - safestrncpy(smi.meta_content_type, content_type, - sizeof smi.meta_content_type); + safestrncpy(smi.meta_content_type, content_type, sizeof smi.meta_content_type); /* * Measure how big this message will be when rendered as RFC822. @@ -2863,7 +2826,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ */ if ((!CC->internal_pgm) || (recps == NULL)) { if (CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 1, msg) != 0) { - syslog(LOG_ERR, "msgbase: ERROR saving message pointer!"); + syslog(LOG_ERR, "msgbase: ERROR saving message pointer %ld in %s", newmsgid, actual_rm); CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } @@ -2874,13 +2837,13 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } /* If other rooms are specified, drop them there too. */ - if ((recps != NULL) && (recps->num_room > 0)) + if ((recps != NULL) && (recps->num_room > 0)) { for (i=0; irecp_room, '|'); ++i) { - extract_token(recipient, recps->recp_room, i, - '|', sizeof recipient); + extract_token(recipient, recps->recp_room, i, '|', sizeof recipient); syslog(LOG_DEBUG, "msgbase: delivering to room <%s>", recipient); CtdlSaveMsgPointerInRoom(recipient, newmsgid, 0, msg); } + } /* Bump this user's messages posted counter. */ syslog(LOG_DEBUG, "msgbase: updating user"); @@ -2889,33 +2852,29 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ CtdlPutCurrentUserLock(); /* Decide where bounces need to be delivered */ - if ((recps != NULL) && (recps->bounce_to == NULL)) - { + if ((recps != NULL) && (recps->bounce_to == NULL)) { if (CC->logged_in) { - snprintf(bounce_to, sizeof bounce_to, "%s@%s", CC->user.fullname, CtdlGetConfigStr("c_nodename")); + strcpy(bounce_to, CC->user.fullname); } - else { - snprintf(bounce_to, sizeof bounce_to, "%s@%s", msg->cm_fields[eAuthor], msg->cm_fields[eNodeName]); + else if (!IsEmptyStr(msg->cm_fields[eAuthor])){ + strcpy(bounce_to, msg->cm_fields[eAuthor]); } recps->bounce_to = bounce_to; } CM_SetFieldLONG(msg, eVltMsgNum, newmsgid); - /* If this is private, local mail, make a copy in the * recipient's mailbox and bump the reference count. */ - if ((recps != NULL) && (recps->num_local > 0)) - { + if ((recps != NULL) && (recps->num_local > 0)) { char *pch; int ntokens; pch = recps->recp_local; recps->recp_local = recipient; ntokens = num_tokens(pch, '|'); - for (i=0; i", recipient); if (CtdlGetUser(&userbuf, recipient) == 0) { @@ -2940,8 +2899,9 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ /* Go back to the room we started from */ syslog(LOG_DEBUG, "msgbase: returning to original room %s", hold_rm); - if (strcasecmp(hold_rm, CC->room.QRname)) + if (strcasecmp(hold_rm, CC->room.QRname)) { CtdlUserGoto(hold_rm, 0, 1, NULL, NULL, NULL, NULL); + } /* * Any addresses to harvest for someone's address book? @@ -2951,10 +2911,8 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } if (collected_addresses != NULL) { - aptr = (struct addresses_to_be_filed *) - malloc(sizeof(struct addresses_to_be_filed)); - CtdlMailboxName(actual_rm, sizeof actual_rm, - &CC->user, USERCONTACTSROOM); + aptr = (struct addresses_to_be_filed *) malloc(sizeof(struct addresses_to_be_filed)); + CtdlMailboxName(actual_rm, sizeof actual_rm, &CC->user, USERCONTACTSROOM); aptr->roomname = strdup(actual_rm); aptr->collected_addresses = collected_addresses; begin_critical_section(S_ATBF); @@ -3015,7 +2973,7 @@ long quickie_message(const char *from, const char *subject) { struct CtdlMessage *msg; - recptypes *recp = NULL; + struct recptypes *recp = NULL; msg = malloc(sizeof(struct CtdlMessage)); memset(msg, 0, sizeof(struct CtdlMessage)); @@ -3024,11 +2982,11 @@ long quickie_message(const char *from, msg->cm_format_type = format_type; if (!IsEmptyStr(from)) { - CM_SetField(msg, eAuthor, from, strlen(from)); + CM_SetField(msg, eAuthor, from, -1); } else if (!IsEmptyStr(fromaddr)) { char *pAt; - CM_SetField(msg, eAuthor, fromaddr, strlen(fromaddr)); + CM_SetField(msg, eAuthor, fromaddr, -1); pAt = strchr(msg->cm_fields[eAuthor], '@'); if (pAt != NULL) { CM_CutFieldAt(msg, eAuthor, pAt - msg->cm_fields[eAuthor]); @@ -3038,21 +2996,20 @@ long quickie_message(const char *from, msg->cm_fields[eAuthor] = strdup("Citadel"); } - if (!IsEmptyStr(fromaddr)) CM_SetField(msg, erFc822Addr, fromaddr, strlen(fromaddr)); - if (!IsEmptyStr(room)) CM_SetField(msg, eOriginalRoom, room, strlen(room)); - CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + if (!IsEmptyStr(fromaddr)) CM_SetField(msg, erFc822Addr, fromaddr, -1); + if (!IsEmptyStr(room)) CM_SetField(msg, eOriginalRoom, room, -1); if (!IsEmptyStr(to)) { - CM_SetField(msg, eRecipient, to, strlen(to)); + CM_SetField(msg, eRecipient, to, -1); recp = validate_recipients(to, NULL, 0); } if (!IsEmptyStr(subject)) { - CM_SetField(msg, eMsgSubject, subject, strlen(subject)); + CM_SetField(msg, eMsgSubject, subject, -1); } if (!IsEmptyStr(text)) { - CM_SetField(msg, eMesageText, text, strlen(text)); + CM_SetField(msg, eMesageText, text, -1); } - long msgnum = CtdlSubmitMsg(msg, recp, room, 0); + long msgnum = CtdlSubmitMsg(msg, recp, room); CM_Free(msg); if (recp != NULL) free_recipients(recp); return msgnum; @@ -3068,8 +3025,7 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ StrBuf *exist, /* if non-null, append to it; exist is ALWAYS freed */ int crlf /* CRLF newlines instead of LF */ - ) -{ +) { StrBuf *Message; StrBuf *LineBuf; int flushing = 0; @@ -3106,13 +3062,9 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ } /* Unescape SMTP-style input of two dots at the beginning of the line */ - if ((dotdot) && - (StrLength(LineBuf) == 2) && - (!strcmp(ChrPtr(LineBuf), ".."))) - { + if ((dotdot) && (StrLength(LineBuf) > 1) && (ChrPtr(LineBuf)[0] == '.')) { StrBufCutLeft(LineBuf, 1); } - StrBufAppendBuf(Message, LineBuf, 0); } @@ -3150,6 +3102,7 @@ char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */ return SmashStrBuf(&Message); } + struct CtdlMessage *CtdlMakeMessage( struct ctdluser *author, /* author's user structure */ char *recipient, /* NULL if it's not mail */ @@ -3163,8 +3116,7 @@ struct CtdlMessage *CtdlMakeMessage( char *supplied_euid, /* ...or NULL if this is irrelevant */ char *preformatted_text, /* ...or NULL to read text from client */ char *references /* Thread references */ -) -{ +) { return CtdlMakeMessageLen( author, /* author's user structure */ recipient, /* NULL if it's not mail */ @@ -3190,6 +3142,7 @@ struct CtdlMessage *CtdlMakeMessage( } + /* * Build a binary message to be saved on disk. * (NOTE: if you supply 'preformatted_text', the buffer you give it @@ -3197,7 +3150,6 @@ struct CtdlMessage *CtdlMakeMessage( * responsible for managing that memory -- it will be freed along with * the rest of the fields when CM_Free() is called.) */ - struct CtdlMessage *CtdlMakeMessageLen( struct ctdluser *author, /* author's user structure */ char *recipient, /* NULL if it's not mail */ @@ -3220,10 +3172,7 @@ struct CtdlMessage *CtdlMakeMessageLen( long textlen, char *references, /* Thread references */ long reflen - ) -{ - /* Don't confuse the poor folks if it's not routed mail. * / - char dest_node[256] = "";*/ +) { long blen; char buf[1024]; struct CtdlMessage *msg; @@ -3244,7 +3193,7 @@ struct CtdlMessage *CtdlMakeMessageLen( CM_SetField(msg, eMessagePath, my_email, myelen); } else if (!IsEmptyStr(author->fullname)) { - CM_SetField(msg, eMessagePath, author->fullname, strlen(author->fullname)); + CM_SetField(msg, eMessagePath, author->fullname, -1); } convert_spaces_to_underscores(msg->cm_fields[eMessagePath]); @@ -3263,16 +3212,13 @@ struct CtdlMessage *CtdlMakeMessageLen( if (!!IsEmptyStr(CC->room.QRname)) { if (CC->room.QRflags & QR_MAILBOX) { /* room */ - CM_SetField(msg, eOriginalRoom, &CC->room.QRname[11], strlen(&CC->room.QRname[11])); + CM_SetField(msg, eOriginalRoom, &CC->room.QRname[11], -1); } else { - CM_SetField(msg, eOriginalRoom, CC->room.QRname, strlen(CC->room.QRname)); + CM_SetField(msg, eOriginalRoom, CC->room.QRname, -1); } } - CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); - CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); - if (rcplen > 0) { CM_SetField(msg, eRecipient, recipient, rcplen); } @@ -3284,7 +3230,7 @@ struct CtdlMessage *CtdlMakeMessageLen( CM_SetField(msg, erFc822Addr, my_email, myelen); } else if ( (author == &CC->user) && (!IsEmptyStr(CC->cs_inet_email)) ) { - CM_SetField(msg, erFc822Addr, CC->cs_inet_email, strlen(CC->cs_inet_email)); + CM_SetField(msg, erFc822Addr, CC->cs_inet_email, -1); } if (subject != NULL) { @@ -3333,18 +3279,15 @@ struct CtdlMessage *CtdlMakeMessageLen( } - - /* * API function to delete messages which match a set of criteria * (returns the actual number of messages deleted) */ -int CtdlDeleteMessages(const char *room_name, /* which room */ - long *dmsgnums, /* array of msg numbers to be deleted */ - int num_dmsgnums, /* number of msgs to be deleted, or 0 for "any" */ - char *content_type /* or "" for any. regular expressions expected. */ - ) -{ +int CtdlDeleteMessages(const char *room_name, // which room + long *dmsgnums, // array of msg numbers to be deleted + int num_dmsgnums, // number of msgs to be deleted, or 0 for "any" + char *content_type // or "" for any. regular expressions expected. +) { struct ctdlroom qrbuf; struct cdbdata *cdbfr; long *msglist = NULL; @@ -3591,8 +3534,7 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ int is_binary, /* Is encoding necessary? */ int is_unique, /* Del others of this type? */ unsigned int flags /* Internal save flags */ - ) -{ +) { struct ctdlroom qrbuf; char roomname[ROOMNAMELEN]; struct CtdlMessage *msg; @@ -3638,10 +3580,8 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ msg->cm_magic = CTDLMESSAGE_MAGIC; msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = 4; - CM_SetField(msg, eAuthor, CC->user.fullname, strlen(CC->user.fullname)); - CM_SetField(msg, eOriginalRoom, req_room, strlen(req_room)); - CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); - CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); + CM_SetField(msg, eAuthor, CC->user.fullname, -1); + CM_SetField(msg, eOriginalRoom, req_room, -1); msg->cm_flags = flags; CM_SetAsFieldSB(msg, eMesageText, &encoded_message); @@ -3659,7 +3599,7 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ ); } /* Now write the data */ - CtdlSubmitMsg(msg, NULL, roomname, 0); + CtdlSubmitMsg(msg, NULL, roomname); CM_Free(msg); }