// Implements the message store.
//
-// Copyright (c) 1987-2023 by the citadel.org team
+// Copyright (c) 1987-2024 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.
+// This program is open source software. Use, duplication, or disclosure
+// is subject to the terms of the GNU General Public License version 3.
#include <stdlib.h>
#include <unistd.h>
"jrnl", // J -> eJournal
"rep2", // K -> eReplyTo
"list", // L -> eListID
- "text", // M -> eMesageText
+ "text", // M -> eMessageText
NULL, // N (formerly used as eNodename)
"room", // O -> eOriginalRoom
"path", // P -> eMessagePath
eMsgField FieldOrder[] = {
-/* Important fields */
+// Important fields
emessageId ,
eMessagePath ,
eTimestamp ,
erFc822Addr ,
eOriginalRoom,
eRecipient ,
-/* Semi-important fields */
+// Semi-important fields
eBig_message ,
eExclusiveID ,
eWeferences ,
eJournal ,
-/* G is not used yet */
+// G is not used yet
eReplyTo ,
eListID ,
-/* Q is not used yet */
+// Q is not used yet
eenVelopeTo ,
-/* X is not used yet */
-/* Z is not used yet */
+// X is not used yet
+// Z is not used yet
eCarbonCopY ,
eMsgSubject ,
-/* internal only */
+// internal only
eErrorMsg ,
eSuppressIdx ,
eExtnotify ,
-/* Message text (MUST be last) */
- eMesageText
-/* Not saved to disk:
- eVltMsgNum
-*/
+// Message text (MUST be last)
+ eMessageText
+// Not saved to disk:
+// eVltMsgNum
+//
};
static const long NDiskFields = sizeof(FieldOrder) / sizeof(eMsgField);
}
}
- /* If a search string was specified, get a message list from
- * the full text index and remove messages which aren't on both
- * lists.
- *
- * How this works:
- * Since the lists are sorted and strictly ascending, and the
- * output list is guaranteed to be shorter than or equal to the
- * input list, we overwrite the bottom of the input list. This
- * eliminates the need to memmove big chunks of the list over and
- * over again.
- */
+ // If a search string was specified, get a message list from
+ // the full text index and remove messages which aren't on both
+ // lists.
+ //
+ // How this works:
+ // Since the lists are sorted and strictly ascending, and the
+ // output list is guaranteed to be shorter than or equal to the
+ // input list, we overwrite the bottom of the input list. This
+ // eliminates the need to memmove big chunks of the list over and
+ // over again.
if ( (num_msgs > 0) && (mode == MSGS_SEARCH) && (search_string) ) {
- /* Call search module via hook mechanism.
- * NULL means use any search function available.
- * otherwise replace with a char * to name of search routine
- */
+ // Call search module via hook mechanism.
+ // NULL means use any search function available.
+ // otherwise replace with a char * to name of search routine
search = CtdlFullTextSearch(search_string);
if (array_len(search) > 0) {
}
}
else {
- num_msgs = 0; /* No messages qualify */
+ num_msgs = 0; // No messages qualify
}
if (search != NULL) array_free(search);
- /* Now that we've purged messages which don't contain the search
- * string, treat a MSGS_SEARCH just like a MSGS_ALL from this
- * point on.
- */
+ // Now that we've purged messages which don't contain the search
+ // string, treat a MSGS_SEARCH just like a MSGS_ALL from this
+ // point on.
mode = MSGS_ALL;
}
- /*
- * Now iterate through the message list, according to the
- * criteria supplied by the caller.
- */
+ // Now iterate through the message list, according to the
+ // criteria supplied by the caller.
if (num_msgs > 0)
for (a = 0; a < num_msgs; ++a) {
if (server_shutting_down) {
}
if (need_to_free_re) regfree(&re);
- /*
- * We cache the most recent msglist in order to do security checks later
- */
+ // We cache the most recent msglist in order to do security checks later
if (CC->client_socket > 0) {
if (CC->cached_msglist != NULL) {
free(CC->cached_msglist);
}
-/*
- * memfmout() - Citadel text formatter and paginator.
- * Although the original purpose of this routine was to format
- * text to the reader's screen width, all we're really using it
- * for here is to format text out to 80 columns before sending it
- * to the client. The client software may reformat it again.
- */
+// memfmout() - Citadel text formatter and paginator.
+// Although the original purpose of this routine was to format
+// text to the reader's screen width, all we're really using it
+// for here is to format text out to 80 columns before sending it
+// to the client. The client software MAY reformat it again.
void memfmout(
- char *mptr, /* where are we going to get our text from? */
- const char *nl /* string to terminate lines with */
+ char *mptr, // where are we going to get our text from?
+ const char *nl // string to terminate lines with
) {
int column = 0;
unsigned char ch = 0;
column = 0;
}
else if (ch == '\r') {
- /* Ignore carriage returns. Newlines are always LF or CRLF but never CR. */
+ // Ignore carriage returns. Newlines are always LF or CRLF but never CR.
}
else if (isspace(ch)) {
- if (column > 72) { /* Beyond 72 columns, break on the next space */
+ if (column > 72) { // Beyond 72 columns, break on the next space
if (client_write(outbuf, len) == -1) {
syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure");
return;
else {
outbuf[len++] = ch;
++column;
- if (column > 1000) { /* Beyond 1000 columns, break anywhere */
+ if (column > 1000) { // Beyond 1000 columns, break anywhere
if (client_write(outbuf, len) == -1) {
syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure");
return;
}
-/*
- * Callback function for mime parser that simply lists the part
- */
+// Callback function for mime parser that simply lists the part
void list_this_part(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
char *cbid, void *cbuserdata)
}
-/*
- * Callback function for multipart prefix
- */
+// Callback function for multipart prefix
void list_this_pref(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
char *cbid, void *cbuserdata)
}
-/*
- * Callback function for multipart sufffix
- */
+// Callback function for multipart sufffix
void list_this_suff(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length, char *encoding,
char *cbid, void *cbuserdata)
}
-/*
- * Callback function for mime parser that opens a section for downloading
- * we use serv_files function here:
- */
+// Callback function for mime parser that opens a section for downloading
+// we use serv_files function here:
extern void OpenCmdResult(char *filename, const char *mime_type);
void mime_download(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
{
int rv = 0;
- /* Silently go away if there's already a download open. */
+ // Silently go away if there's already a download open.
if (CC->download_fp != NULL)
return;
}
-/*
- * Callback function for mime parser that outputs a section all at once.
- * We can specify the desired section by part number *or* content-id.
- */
+// Callback function for mime parser that outputs a section all at once.
+// We can specify the desired section by part number *or* content-id.
void mime_spew_section(char *name, char *filename, char *partnum, char *disp,
void *content, char *cbtype, char *cbcharset, size_t length,
char *encoding, char *cbid, void *cbuserdata)
// so go ahead and fetch that. Failing that, just set a dummy
// body so other code doesn't barf.
//
- if ( (CM_IsEmpty(ret, eMesageText)) && (with_body) ) {
+ if ( (CM_IsEmpty(ret, eMessageText)) && (with_body) ) {
dmsgtext = cdb_fetch(CDB_BIGMSGS, &msgnum, sizeof(long));
if (dmsgtext.ptr != NULL) {
- CM_SetField(ret, eMesageText, dmsgtext.ptr);
+ CM_SetField(ret, eMessageText, dmsgtext.ptr);
}
}
- if (CM_IsEmpty(ret, eMesageText)) {
- CM_SetField(ret, eMesageText, "\r\n\r\n (no text)\r\n");
+ if (CM_IsEmpty(ret, eMessageText)) {
+ CM_SetField(ret, eMessageText, "\r\n\r\n (no text)\r\n");
}
return (ret);
for (i=0; i<num_tokens(CC->preferred_formats, '|'); ++i) {
extract_token(buf, CC->preferred_formats, i, '|', sizeof buf);
if (!strcasecmp(buf, cbtype)) {
- /* Yeah! Go! W00t!! */
+ // Yeah! Go! W00t!!
if (ma->dont_decode == 0)
rc = mime_decode_now (content,
length,
return(r);
}
- /*
- * Check to make sure the message is actually IN this room
- */
+ // Check to make sure the message is actually IN this room
r = check_cached_msglist(msg_num);
if (r == om_access_denied) {
- /* Not in the cache? We get ONE shot to check it again. */
+ // Not in the cache? We get ONE shot to check it again.
CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, NULL, NULL);
r = check_cached_msglist(msg_num);
}
return(r);
}
- /*
- * Fetch the message from disk. If we're in HEADERS_FAST mode,
- * request that we don't even bother loading the body into memory.
- */
+ // Fetch the message from disk. If we're in HEADERS_FAST mode, request that we don't even bother loading the body into memory.
if (headers_only == HEADERS_FAST) {
TheMessage = CtdlFetchMessage(msg_num, 0);
}
return(om_no_such_msg);
}
- /* Here is the weird form of this command, to process only an
- * encapsulated message/rfc822 section.
- */
+ // Here is the weird form of this command, to process only an encapsulated message/rfc822 section.
if (section) if (!IsEmptyStr(section)) if (strcmp(section, "0")) {
memset(&encap, 0, sizeof encap);
safestrncpy(encap.desired_section, section, sizeof encap.desired_section);
- mime_parser(CM_RANGE(TheMessage, eMesageText),
+ mime_parser(CM_RANGE(TheMessage, eMessageText),
*extract_encapsulated_message,
NULL, NULL, (void *)&encap, 0
);
- if ((Author != NULL) && (*Author == NULL))
- {
+ if ((Author != NULL) && (*Author == NULL)) {
long len;
CM_GetAsField(TheMessage, eAuthor, Author, &len);
}
- if ((Address != NULL) && (*Address == NULL))
- {
+ if ((Address != NULL) && (*Address == NULL)) {
long len;
CM_GetAsField(TheMessage, erFc822Addr, Address, &len);
}
- if ((MessageID != NULL) && (*MessageID == NULL))
- {
+ if ((MessageID != NULL) && (*MessageID == NULL)) {
long len;
CM_GetAsField(TheMessage, emessageId, MessageID, &len);
}
if (encap.msg) {
encap.msg[encap.msglen] = 0;
TheMessage = convert_internet_message(encap.msg);
- encap.msg = NULL; /* no free() here, TheMessage owns it now */
+ encap.msg = NULL; // no free() here, TheMessage owns it now
- /* Now we let it fall through to the bottom of this
- * function, because TheMessage now contains the
- * encapsulated message instead of the top-level
- * message. Isn't that neat?
- */
+ // Now we let it fall through to the bottom of this function, because TheMessage now contains the
+ // encapsulated message instead of the top-level message. Isn't that neat?
}
else {
if (do_proto) {
- cprintf("%d msg %ld has no part %s\n",
- ERROR + MESSAGE_NOT_FOUND,
- msg_num,
- section);
+ cprintf("%d msg %ld has no part %s\n", ERROR + MESSAGE_NOT_FOUND, msg_num, section);
}
retcode = om_no_such_msg;
}
}
- /* Ok, output the message now */
- if (retcode == CIT_OK)
+ // Ok, output the message now
+ if (retcode == CIT_OK) {
retcode = CtdlOutputPreLoadedMsg(TheMessage, mode, headers_only, do_proto, crlf, flags);
- if ((Author != NULL) && (*Author == NULL))
- {
+ }
+ if ((Author != NULL) && (*Author == NULL)) {
long len;
CM_GetAsField(TheMessage, eAuthor, Author, &len);
}
- if ((Address != NULL) && (*Address == NULL))
- {
+ if ((Address != NULL) && (*Address == NULL)) {
long len;
CM_GetAsField(TheMessage, erFc822Addr, Address, &len);
}
- if ((MessageID != NULL) && (*MessageID == NULL))
- {
+ if ((MessageID != NULL) && (*MessageID == NULL)) {
long len;
CM_GetAsField(TheMessage, emessageId, MessageID, &len);
}
char buf[SIZ];
char display_name[256];
- /* begin header processing loop for Citadel message format */
+ // begin header processing loop for Citadel message format
safestrncpy(display_name, "<unknown>", sizeof display_name);
if (!CM_IsEmpty(TheMessage, eAuthor)) {
strcpy(buf, TheMessage->cm_fields[eAuthor]);
}
}
- /* Now spew the header fields in the order we like them. */
+ // 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 (Field != eMessageText) {
if ( (!CM_IsEmpty(TheMessage, Field)) && (msgkeys[Field] != NULL) ) {
if ((Field == eenVelopeTo) || (Field == eRecipient) || (Field == eCarbonCopY)) {
sanitize_truncated_recipient(TheMessage->cm_fields[Field]);
cprintf("%s=%s\n", msgkeys[Field], display_name);
}
}
- /* Masquerade display name if needed */
+ // 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 */
+ // 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.
void OutputRFC822MsgHeaders(
struct CtdlMessage *TheMessage,
- int flags, /* should the message 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,
case eExclusiveID:
case eJournal:
- case eMesageText:
+ case eMessageText:
case eBig_message:
case eOriginalRoom:
case eErrorMsg:
case eSuppressIdx:
case eExtnotify:
case eVltMsgNum:
- /* these don't map to mime message headers. */
+ // these don't map to mime message headers.
break;
}
if (mptr != mpptr) {
void Dump_RFC822HeadersBody(
struct CtdlMessage *TheMessage,
- int headers_only, /* eschew the message body? */
- int flags, /* should the bessage be exported clean? */
+ int headers_only, // eschew the message body?
+ int flags, // should the bessage be exported clean?
const char *nl, int nlen)
{
cit_uint8_t prev_ch;
char *mptr;
int lfSent = 0;
- mptr = TheMessage->cm_fields[eMesageText];
+ mptr = TheMessage->cm_fields[eMessageText];
prev_ch = '\0';
while (*mptr != '\0') {
if (*mptr == '\r') {
- /* do nothing */
+ // do nothing
}
else {
if ((!eoh) &&
}
-/* If the format type on disk is 1 (fixed-format), then we want
- * everything to be output completely literally ... regardless of
- * what message transfer format is in use.
- */
+// If the format type on disk is 1 (fixed-format), then we want
+// everything to be output completely literally ... regardless of
+// what message transfer format is in use.
void DumpFormatFixed(
struct CtdlMessage *TheMessage,
- int mode, /* how would you like that message? */
+ int mode, // how would you like that message?
const char *nl, int nllen)
{
cit_uint8_t ch;
int xlline = 0;
char *mptr;
- mptr = TheMessage->cm_fields[eMesageText];
+ mptr = TheMessage->cm_fields[eMessageText];
if (mode == MT_MIME) {
cprintf("Content-type: text/plain\n\n");
}
}
- /* if we reach the outer bounds of our buffer, abort without respect for what we purge. */
+ // if we reach the outer bounds of our buffer, abort without respect for what we purge.
if (xlline && ((isspace(ch)) || (buflen > SIZ - nllen - 2))) {
ch = '\r';
}
}
-/*
- * Get a message off disk. (returns om_* values found in msgbase.h)
- */
+// Get a message off disk. (returns om_* values found in msgbase.h)
int CtdlOutputPreLoadedMsg(
struct CtdlMessage *TheMessage,
- int mode, /* how would you like that message? */
- int headers_only, /* eschew the message body? */
- int do_proto, /* do Citadel protocol responses? */
- int crlf, /* Use CRLF newlines instead of LF? */
- int flags /* should the bessage be exported clean? */
+ int mode, // how would you like that message?
+ int headers_only, // eschew the message body?
+ int do_proto, // do Citadel protocol responses?
+ int crlf, // Use CRLF newlines instead of LF?
+ int flags // should the bessage be exported clean?
) {
int i;
- const char *nl; /* newline string */
+ const char *nl; // newline string
int nlen;
struct ma_info ma;
- /* Buffers needed for RFC822 translation. These are all filled
- * using functions that are bounds-checked, and therefore we can
- * make them substantially smaller than SIZ.
- */
+ // Buffers needed for RFC822 translation. These are all filled
+ // using functions that are bounds-checked, and therefore we can
+ // make them substantially smaller than SIZ.
char suser[1024];
char luser[1024];
char fuser[1024];
return(om_no_such_msg);
}
- /* Suppress envelope recipients if required to avoid disclosing BCC addresses.
- * Pad it with spaces in order to avoid changing the RFC822 length of the message.
- */
+ // Suppress envelope recipients if required to avoid disclosing BCC addresses.
+ // Pad it with spaces in order to avoid changing the RFC822 length of the message.
if ( (flags & SUPPRESS_ENV_TO) && (!CM_IsEmpty(TheMessage, eenVelopeTo)) ) {
memset(TheMessage->cm_fields[eenVelopeTo], ' ', TheMessage->cm_lengths[eenVelopeTo]);
}
- /* Are we downloading a MIME component? */
+ // Are we downloading a MIME component?
if (mode == MT_DOWNLOAD) {
if (TheMessage->cm_format_type != FMT_RFC822) {
- if (do_proto)
- cprintf("%d This is not a MIME message.\n",
- ERROR + ILLEGAL_VALUE);
- } else if (CC->download_fp != NULL) {
- if (do_proto) cprintf(
- "%d You already have a download open.\n",
- ERROR + RESOURCE_BUSY);
- } else {
- /* Parse the message text component */
- mime_parser(CM_RANGE(TheMessage, eMesageText),
- *mime_download, NULL, NULL, NULL, 0);
- /* If there's no file open by this time, the requested
- * section wasn't found, so print an error
- */
+ if (do_proto) {
+ cprintf("%d This is not a MIME message.\n", ERROR + ILLEGAL_VALUE);
+ }
+ }
+ else if (CC->download_fp != NULL) {
+ if (do_proto) {
+ cprintf( "%d You already have a download open.\n", ERROR + RESOURCE_BUSY);
+ }
+ }
+ else {
+ // Parse the message text component
+ mime_parser(CM_RANGE(TheMessage, eMessageText), *mime_download, NULL, NULL, NULL, 0);
+
+ // If there's no file open by this time, the requested * section wasn't found, so print an error
if (CC->download_fp == NULL) {
- if (do_proto) cprintf(
- "%d Section %s not found.\n",
- ERROR + FILE_NOT_FOUND,
- CC->download_desired_section);
+ if (do_proto) {
+ cprintf( "%d Section %s not found.\n", ERROR + FILE_NOT_FOUND, CC->download_desired_section);
+ }
}
}
return((CC->download_fp != NULL) ? om_ok : om_mime_error);
else {
// Locate and parse the component specified by the caller
int found_it = 0;
- mime_parser(CM_RANGE(TheMessage, eMesageText), *mime_spew_section, NULL, NULL, (void *)&found_it, 0);
+ mime_parser(CM_RANGE(TheMessage, eMessageText), *mime_spew_section, NULL, NULL, (void *)&found_it, 0);
// If section wasn't found, print an error
if (!found_it) {
strcpy(luser, "");
strcpy(fuser, "");
strcpy(snode, "");
- if (mode == MT_RFC822)
+ if (mode == MT_RFC822) {
OutputRFC822MsgHeaders(
TheMessage,
flags,
luser, sizeof(luser),
fuser, sizeof(fuser),
snode, sizeof(snode)
- );
-
+ );
+ }
for (i=0; !IsEmptyStr(&suser[i]); ++i) {
suser[i] = tolower(suser[i]);
}
if (mode == MT_RFC822) {
- /* Construct a fun message id */
+ // Construct a fun message id
cprintf("Message-ID: <%s", mid);
if (strchr(mid, '@')==NULL) {
cprintf("@%s", snode);
cprintf("From: \"%s\" <%s@%s>%s", luser, suser, snode, nl);
}
- /* Blank line signifying RFC822 end-of-headers */
+ // Blank line signifying RFC822 end-of-headers
if (TheMessage->cm_format_type != FMT_RFC822) {
cprintf("%s", nl);
}
if (TheMessage->cm_format_type == FMT_RFC822) {
if ( (mode == MT_CITADEL) || (mode == MT_MIME) ) {
memset(&ma, 0, sizeof(struct ma_info));
- mime_parser(CM_RANGE(TheMessage, eMesageText),
+ mime_parser(CM_RANGE(TheMessage, eMessageText),
(do_proto ? *list_this_part : NULL),
(do_proto ? *list_this_pref : NULL),
(do_proto ? *list_this_suff : NULL),
if (mode == MT_MIME) {
cprintf("Content-type: text/x-citadel-variformat\n\n");
}
- memfmout(TheMessage->cm_fields[eMesageText], nl);
+ memfmout(TheMessage->cm_fields[eMessageText], nl);
}
// If the message on disk is format 4 (MIME), we've gotta hand it
strcpy(ma.chosen_part, "1");
ma.chosen_pref = 9999;
ma.dont_decode = CC->msg4_dont_decode;
- mime_parser(CM_RANGE(TheMessage, eMesageText),
+ mime_parser(CM_RANGE(TheMessage, eMessageText),
*choose_preferred, *fixed_output_pre,
*fixed_output_post, (void *)&ma, 1);
- mime_parser(CM_RANGE(TheMessage, eMesageText),
+ mime_parser(CM_RANGE(TheMessage, eMessageText),
*output_preferred, NULL, NULL, (void *)&ma, 1);
}
else {
ma.use_fo_hooks = 1;
- mime_parser(CM_RANGE(TheMessage, eMesageText),
+ mime_parser(CM_RANGE(TheMessage, eMessageText),
*fixed_output, *fixed_output_pre,
*fixed_output_post, (void *)&ma, 0);
}
}
-DONE: /* now we're done */
+DONE: // now we're done
if (do_proto) cprintf("000\n");
return(om_ok);
}
strcpy(hold_rm, CC->room.QRname);
- /* Sanity checks */
+ // Sanity checks
if (newmsgidlist == NULL) return(ERROR + INTERNAL_ERROR);
if (num_newmsgs < 1) return(ERROR + INTERNAL_ERROR);
if (num_newmsgs > 1) supplied_msg = NULL;
- /* Now the regular stuff */
+ // Now the regular stuff
if (CtdlGetRoomLock(&CC->room, ((roomname != NULL) ? roomname : CC->room.QRname) ) != 0) {
syslog(LOG_ERR, "msgbase: no such room <%s>", roomname);
return(ERROR + ROOM_NOT_FOUND);
num_msgs_to_be_merged = 0;
num_msgs = CtdlFetchMsgList(CC->room.QRnumber, &msglist);
- /* Create a list of msgid's which were supplied by the caller, but do
- * not already exist in the target room. It is absolutely taboo to
- * have more than one reference to the same message in a room.
- */
+ // Create a list of msgid's which were supplied by the caller, but do
+ // not already exist in the target room. It is absolutely taboo to
+ // have more than one reference to the same message in a room.
for (i=0; i<num_newmsgs; ++i) {
unique = 1;
if (num_msgs > 0) for (j=0; j<num_msgs; ++j) {
syslog(LOG_DEBUG, "msgbase: %d unique messages to be merged", num_msgs_to_be_merged);
- /*
- * Now merge the new messages
- */
+ // Now merge the new messages
msglist = realloc(msglist, (sizeof(long) * (num_msgs + num_msgs_to_be_merged)) );
if (msglist == NULL) {
syslog(LOG_ALERT, "msgbase: ERROR; can't realloc message list!");
free(msgs_to_be_merged);
- abort(); // FIXME FIXME FOOFOO
+ abort(); // FIXME
return (ERROR + INTERNAL_ERROR);
}
memcpy(&msglist[num_msgs], msgs_to_be_merged, (sizeof(long) * num_msgs_to_be_merged) );
num_msgs += num_msgs_to_be_merged;
- /* Sort the message list, so all the msgid's are in order */
+ // Sort the message list, so all the msgid's are in order
num_msgs = sort_msglist(msglist, num_msgs);
- /* Determine the highest message number */
+ // Determine the highest message number
highest_msg = msglist[num_msgs - 1];
- /* Write it back to disk. */
+ // Write it back to disk.
cdb_store(CDB_MSGLISTS, &CC->room.QRnumber, (int)sizeof(long), msglist, (int)(num_msgs * sizeof(long)));
- /* Free up the memory we used. */
+ // Free up the memory we used.
free(msglist);
- /* Update the highest-message pointer and unlock the room. */
+ // Update the highest-message pointer and unlock the room.
CC->room.QRhighest = highest_msg;
CtdlPutRoomLock(&CC->room);
- /* Perform replication checks if necessary */
+ // Perform replication checks if necessary
if ( (DoesThisRoomNeedEuidIndexing(&CC->room)) && (do_repl_check) ) {
syslog(LOG_DEBUG, "msgbase: CtdlSaveMsgPointerInRoom() doing repl checks");
if (msg != NULL) {
ReplicationChecks(msg);
- /* If the message has an Exclusive ID, index that... */
+ // If the message has an Exclusive ID, index that...
if (!CM_IsEmpty(msg, eExclusiveID)) {
index_message_by_euid(msg->cm_fields[eExclusiveID], &CC->room, msgid);
}
- /* Free up the memory we may have allocated */
+ // Free up the memory we may have allocated
if (msg != supplied_msg) {
CM_Free(msg);
}
syslog(LOG_DEBUG, "msgbase: CtdlSaveMsgPointerInRoom() skips repl checks");
}
- /* Submit this room for processing by hooks */
+ // Submit this room for processing by hooks
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... */
+ // Go back to the room we were in before we wandered here...
CtdlGetRoom(&CC->room, hold_rm);
- /* Bump the reference count for all messages which were merged */
+ // Bump the reference count for all messages which were merged
if (!suppress_refcount_adj) {
AdjRefCountList(msgs_to_be_merged, num_msgs_to_be_merged, +1);
}
- /* Free up memory... */
+ // Free up memory...
if (msgs_to_be_merged != NULL) {
free(msgs_to_be_merged);
}
- /* Return success. */
+ // Return success.
return (0);
}
-/*
- * This is the same as CtdlSaveMsgPointersInRoom() but it only accepts
- * a single message.
- */
+// This is the same as CtdlSaveMsgPointersInRoom() but it only accepts a single message.
int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check, struct CtdlMessage *supplied_msg) {
return CtdlSaveMsgPointersInRoom(roomname, &msgid, 1, do_repl_check, supplied_msg, 0);
}
-/*
- * Message base operation to save a new message to the message store
- * (returns new message number)
- *
- * This is the back end for CtdlSubmitMsg() and should not be directly
- * called by server-side modules.
- *
- */
+// Message base operation to save a new message to the message store
+// (returns new message number)
+//
+// This is the back end for CtdlSubmitMsg() and should not be directly
+// called by server-side modules.
long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) {
long retval;
- struct ser_ret smr;
int is_bigmsg = 0;
char *holdM = NULL;
long holdMLen = 0;
- /*
- * 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 the message is big, set its body aside for storage elsewhere and we hide the message body from the serializer
+ if (!CM_IsEmpty(msg, eMessageText) && msg->cm_lengths[eMessageText] > BIGMSG) {
is_bigmsg = 1;
- holdM = msg->cm_fields[eMesageText];
- msg->cm_fields[eMesageText] = NULL;
- holdMLen = msg->cm_lengths[eMesageText];
- msg->cm_lengths[eMesageText] = 0;
+ holdM = msg->cm_fields[eMessageText];
+ msg->cm_fields[eMessageText] = NULL;
+ holdMLen = msg->cm_lengths[eMessageText];
+ msg->cm_lengths[eMessageText] = 0;
}
- /* Serialize our data structure for storage in the database */
- CtdlSerializeMessage(&smr, msg);
+ // Serialize our data structure for storage in the database
+ struct ser_ret smr = CtdlSerializeMessage(msg);
if (is_bigmsg) {
- /* put the message body back into the message */
- msg->cm_fields[eMesageText] = holdM;
- msg->cm_lengths[eMesageText] = holdMLen;
+ // put the message body back into the message
+ msg->cm_fields[eMessageText] = holdM;
+ msg->cm_lengths[eMessageText] = holdMLen;
}
if (smr.len == 0) {
if (Reply) {
- cprintf("%d Unable to serialize message\n",
- ERROR + INTERNAL_ERROR);
+ cprintf("%d Unable to serialize message\n", ERROR + INTERNAL_ERROR);
}
else {
syslog(LOG_ERR, "msgbase: CtdlSaveMessage() unable to serialize message");
-
}
return (-1L);
}
- /* Write our little bundle of joy into the message base */
+ // Write our little bundle of joy into the message base
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);
}
}
- /* Free the memory we used for the serialized message */
+ // Free the memory we used for the serialized message
free(smr.ser);
return(retval);
}
char msgidbuf[256];
long msgidbuflen;
- /* Get a new message number */
+ // Get a new message number
newmsgid = get_new_message_number();
- /* Generate an ID if we don't have one already */
+ // Generate an ID if we don't have one already
if (CM_IsEmpty(msg, emessageId)) {
msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s",
- (long unsigned int) time(NULL),
- (long unsigned int) newmsgid,
- CtdlGetConfigStr("c_fqdn")
- );
-
+ (long unsigned int) time(NULL),
+ (long unsigned int) newmsgid,
+ CtdlGetConfigStr("c_fqdn")
+ );
CM_SetField(msg, emessageId, msgidbuf);
}
retval = newmsgid;
}
- /* Return the *local* message ID to the caller
- * (even if we're storing an incoming network message)
- */
+ // Return the *local* message ID to the caller (even if we're storing a remotely originated message)
return(retval);
}
-/*
- * 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
- * serialized message in memory. THE LATTER MUST BE FREED BY THE CALLER.
- */
-void CtdlSerializeMessage(struct ser_ret *ret, /* return values */
- struct CtdlMessage *msg) /* unserialized msg */
-{
+// Serialize a struct CtdlMessage into the format used on disk.
+//
+// This function returns a "struct ser_ret" (defined in server.h) which
+// contains the length of the serialized message and a pointer to the
+// serialized message in memory. THE LATTER MUST BE FREED BY THE CALLER.
+struct ser_ret CtdlSerializeMessage(struct CtdlMessage *msg) {
+ struct ser_ret ret;
size_t wlen;
int i;
- /*
- * Check for valid message format
- */
+ // Check for valid message format
if (CM_IsValidMsg(msg) == 0) {
syslog(LOG_ERR, "msgbase: CtdlSerializeMessage() aborting due to invalid message");
- ret->len = 0;
- ret->ser = NULL;
- return;
+ ret.len = 0;
+ ret.ser = NULL;
+ return(ret);
}
- ret->len = 3;
- for (i=0; i < NDiskFields; ++i)
- if (msg->cm_fields[FieldOrder[i]] != NULL)
- ret->len += msg->cm_lengths[FieldOrder[i]] + 2;
+ ret.len = 3;
+ assert(FieldOrder[NDiskFields-1] == eMessageText); // Message text MUST be last!
+ for (i=0; i < NDiskFields; ++i) {
+ if (msg->cm_fields[FieldOrder[i]] != NULL) {
+ ret.len += msg->cm_lengths[FieldOrder[i]] + 2;
+ }
+ }
- ret->ser = malloc(ret->len);
- if (ret->ser == NULL) {
- syslog(LOG_ERR, "msgbase: CtdlSerializeMessage() malloc(%ld) failed: %m", (long)ret->len);
- ret->len = 0;
- ret->ser = NULL;
- return;
+ ret.ser = malloc(ret.len);
+ if (ret.ser == NULL) {
+ syslog(LOG_ERR, "msgbase: CtdlSerializeMessage() malloc(%ld) failed: %m", (long)ret.len);
+ ret.len = 0;
+ ret.ser = NULL;
+ return(ret);
}
- ret->ser[0] = 0xFF;
- ret->ser[1] = msg->cm_anon_type;
- ret->ser[2] = msg->cm_format_type;
+ ret.ser[0] = 0xFF;
+ ret.ser[1] = msg->cm_anon_type;
+ ret.ser[2] = msg->cm_format_type;
wlen = 3;
for (i=0; i < NDiskFields; ++i) {
if (msg->cm_fields[FieldOrder[i]] != NULL) {
- ret->ser[wlen++] = (char)FieldOrder[i];
-
- memcpy(&ret->ser[wlen],
- msg->cm_fields[FieldOrder[i]],
- msg->cm_lengths[FieldOrder[i]] + 1);
-
+ // future improvement: do the bigmsg check right here
+ ret.ser[wlen++] = (char)FieldOrder[i];
+ memcpy(&ret.ser[wlen], msg->cm_fields[FieldOrder[i]], msg->cm_lengths[FieldOrder[i]] + 1);
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);
- }
-
- return;
+ assert(ret.len == wlen); // Make sure we measured it correctly
+ return(ret);
}
-/*
- * Check to see if any messages already exist in the current room which
- * carry the same Exclusive ID as this one. If any are found, delete them.
- */
+// Check to see if any messages already exist in the current room which
+// carry the same Exclusive ID as this one. If any are found, delete them.
void ReplicationChecks(struct CtdlMessage *msg) {
long old_msgnum = (-1L);
syslog(LOG_DEBUG, "msgbase: performing replication checks in <%s>", CC->room.QRname);
- /* No exclusive id? Don't do anything. */
+ // No exclusive id? Don't do anything.
if (msg == NULL) return;
if (CM_IsEmpty(msg, eExclusiveID)) return;
- /*syslog(LOG_DEBUG, "msgbase: exclusive ID: <%s> for room <%s>",
- msg->cm_fields[eExclusiveID], CC->room.QRname);*/
-
old_msgnum = CtdlLocateMessageByEuid(msg->cm_fields[eExclusiveID], &CC->room);
if (old_msgnum > 0L) {
syslog(LOG_DEBUG, "msgbase: ReplicationChecks() replacing message %ld", old_msgnum);
}
-/*
- * Save a message to disk and submit it into the delivery system.
- */
-long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */
- struct recptypes *recps, /* recipients (if mail) */
- const char *force /* force a particular room? */
+// Save a message to disk and submit it into the delivery system.
+long CtdlSubmitMsg(struct CtdlMessage *msg, // message to save
+ 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];
- char content_type[SIZ]; /* We have to learn this */
+ char content_type[SIZ]; // We have to learn this
char recipient[SIZ];
char bounce_to[1024];
const char *room;
int qualified_for_journaling = 0;
syslog(LOG_DEBUG, "msgbase: CtdlSubmitMsg() called");
- if (CM_IsValidMsg(msg) == 0) return(-1); /* self check */
+ if (CM_IsValidMsg(msg) == 0) return(-1); // self check
- /* If this message has no timestamp, we take the liberty of
- * giving it one, right now.
- */
+ // If this message has no timestamp, we take the liberty of giving it one, right now.
if (CM_IsEmpty(msg, eTimestamp)) {
CM_SetFieldLONG(msg, eTimestamp, time(NULL));
}
- /* If this message has no path, we generate one.
- */
+ // If this message has no path, we generate one.
if (CM_IsEmpty(msg, eMessagePath)) {
if (!CM_IsEmpty(msg, eAuthor)) {
CM_CopyField(msg, eMessagePath, eAuthor);
strcpy(force_room, force);
}
- /* Learn about what's inside, because it's what's inside that counts */
- if (CM_IsEmpty(msg, eMesageText)) {
+ // Learn about what's inside, because it's what's inside that counts
+ if (CM_IsEmpty(msg, eMessageText)) {
syslog(LOG_ERR, "msgbase: ERROR; attempt to save message with NULL body");
return(-2);
}
break;
case 4:
strcpy(content_type, "text/plain");
- mptr = bmstrcasestr(msg->cm_fields[eMesageText], "Content-type:");
+ mptr = bmstrcasestr(msg->cm_fields[eMessageText], "Content-type:");
if (mptr != NULL) {
char *aptr;
safestrncpy(content_type, &mptr[13], sizeof content_type);
string_trim(content_type);
aptr = content_type;
while (!IsEmptyStr(aptr)) {
- if ((*aptr == ';')
- || (*aptr == ' ')
- || (*aptr == 13)
- || (*aptr == 10)) {
+ if ( (*aptr == ';')
+ || (*aptr == ' ')
+ || (*aptr == 13)
+ || (*aptr == 10)
+ ) {
*aptr = 0;
}
- else aptr++;
+ else {
+ aptr++;
+ }
}
}
}
- /* Goto the correct room */
+ // Goto the correct room
room = (recps) ? CC->room.QRname : SENTITEMS;
syslog(LOG_DEBUG, "msgbase: selected room %s", room);
strcpy(hold_rm, CC->room.QRname);
strcpy(actual_rm, SENTITEMS);
}
- /* If the user is a twit, move to the twit room for posting */
+ // If the user is a twit, move to the twit room for posting
if (TWITDETECT) {
if (CC->user.axlevel == AxProbU) {
strcpy(hold_rm, actual_rm);
}
}
- /* ...or if this message is destined for Aide> then go there. */
+ // ...or if this message is destined for Aide> then go there.
if (!IsEmptyStr(force_room)) {
strcpy(actual_rm, force_room);
}
CtdlUserGoto(actual_rm, 0, 1, NULL, NULL, NULL, NULL);
}
- /*
- * If this message has no O (room) field, generate one.
- */
+ // 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);
}
- /* Perform "before save" hooks (aborting if any return nonzero) */
+ // Perform "before save" hooks (aborting if any return nonzero)
syslog(LOG_DEBUG, "msgbase: performing before-save hooks");
if (PerformMessageHooks(msg, recps, EVT_BEFORESAVE) > 0) return(-3);
- /*
- * If this message has an Exclusive ID, and the room is replication
- * checking enabled, then do replication checks.
- */
+ // If this message has an Exclusive ID, and the room is replication
+ // checking enabled, then do replication checks.
if (DoesThisRoomNeedEuidIndexing(&CC->room)) {
ReplicationChecks(msg);
}
- /* Save it to disk */
+ // Save it to disk
syslog(LOG_DEBUG, "msgbase: saving to disk");
newmsgid = send_message(msg);
if (newmsgid <= 0L) return(-5);
- /* Write a supplemental message info record. This doesn't have to
- * be a critical section because nobody else knows about this message
- * yet.
- */
+ // Write a supplemental message info record. This doesn't have to be
+ // a critical section because nobody else knows about this message yet.
syslog(LOG_DEBUG, "msgbase: creating metadata record");
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);
- /*
- * Measure how big this message will be when rendered as RFC822.
- * We do this for two reasons:
- * 1. We need the RFC822 length for the new metadata record, so the
- * POP and IMAP services don't have to calculate message lengths
- * while the user is waiting (multiplied by potentially hundreds
- * or thousands of messages).
- * 2. If journaling is enabled, we will need an RFC822 version of the
- * message to attach to the journalized copy.
- */
+ // Measure how big this message will be when rendered as RFC822.
+ // We do this for two reasons:
+ // 1. We need the RFC822 length for the new metadata record, so the
+ // POP and IMAP services don't have to calculate message lengths
+ // while the user is waiting (multiplied by potentially hundreds
+ // or thousands of messages).
+ // 2. If journaling is enabled, we will need an RFC822 version of the
+ // message to attach to the journalized copy.
if (CC->redirect_buffer != NULL) {
syslog(LOG_ALERT, "msgbase: CC->redirect_buffer is not NULL during message submission!");
exit(CTDLEXIT_REDIRECT);
PutMetaData(&smi);
- /* Now figure out where to store the pointers */
+ // Now figure out where to store the pointers
syslog(LOG_DEBUG, "msgbase: storing pointers");
- /* If this is being done by the networker delivering a private
- * message, we want to BYPASS saving the sender's copy (because there
- * is no local sender; it would otherwise go to the Trashcan).
- */
+ // If this is being done by the networker delivering a private
+ // message, we want to BYPASS saving the sender's copy (because there
+ // is no local sender; it would otherwise go to the Trashcan).
if ((!CC->internal_pgm) || (recps == NULL)) {
if (CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 1, msg) != 0) {
syslog(LOG_ERR, "msgbase: ERROR saving message pointer %ld in %s", newmsgid, actual_rm);
}
}
- /* For internet mail, drop a copy in the outbound queue room */
+ // For internet mail, drop a copy in the outbound queue room
if ((recps != NULL) && (recps->num_internet > 0)) {
CtdlSaveMsgPointerInRoom(SMTP_SPOOLOUT_ROOM, newmsgid, 0, msg);
}
- /* If other rooms are specified, drop them there too. */
+ // If other rooms are specified, drop them there too.
if ((recps != NULL) && (recps->num_room > 0)) {
for (i=0; i<num_tokens(recps->recp_room, '|'); ++i) {
extract_token(recipient, recps->recp_room, i, '|', sizeof recipient);
}
}
- /* Decide where bounces need to be delivered */
+ // Decide where bounces need to be delivered
if ((recps != NULL) && (recps->bounce_to == NULL)) {
if (CC->logged_in) {
strcpy(bounce_to, CC->user.fullname);
recps->recp_local = pch;
}
- /* Perform "after save" hooks */
+ // Perform "after save" hooks
syslog(LOG_DEBUG, "msgbase: performing after-save hooks");
PerformMessageHooks(msg, recps, EVT_AFTERSAVE);
CM_FlushField(msg, eVltMsgNum);
- /* Go back to the room we started from */
+ // 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)) {
CtdlUserGoto(hold_rm, 0, 1, NULL, NULL, NULL, NULL);
}
- /*
- * Any addresses to harvest for someone's address book?
- */
+ // Any addresses to harvest for someone's address book?
if ( (CC->logged_in) && (recps != NULL) ) {
collected_addresses = harvest_collected_addresses(msg);
}
end_critical_section(S_ATBF);
}
- /*
- * Determine whether this message qualifies for journaling.
- */
+ // Determine whether this message qualifies for journaling.
if (!CM_IsEmpty(msg, eJournal)) {
qualified_for_journaling = 0;
}
}
}
- /*
- * Do we have to perform journaling? If so, hand off the saved
- * RFC822 version will be handed off to the journaler for background
- * submit. Otherwise, we have to free the memory ourselves.
- */
+ // Do we have to perform journaling? If so, hand off the saved
+ // RFC822 version will be handed off to the journaler for background
+ // submit. Otherwise, we have to free the memory ourselves.
if (saved_rfc822_version != NULL) {
if (qualified_for_journaling) {
JournalBackgroundSubmit(msg, saved_rfc822_version, recps);
if ((recps != NULL) && (recps->bounce_to == bounce_to))
recps->bounce_to = NULL;
- /* Done. */
+ // Done.
return(newmsgid);
}
-/*
- * Convenience function for generating small administrative messages.
- */
+// Convenience function for generating small administrative messages.
long quickie_message(char *from,
char *fromaddr,
char *to,
CM_SetField(msg, eMsgSubject, subject);
}
if (!IsEmptyStr(text)) {
- CM_SetField(msg, eMesageText, text);
+ CM_SetField(msg, eMessageText, text);
}
long msgnum = CtdlSubmitMsg(msg, recp, room);
}
-/*
- * Back end function used by CtdlMakeMessage() and similar functions
- */
+// Back end function used by CtdlMakeMessage() and similar functions
StrBuf *CtdlReadMessageBodyBuf(char *terminator, // token signalling EOT
long tlen,
size_t maxlen, // maximum message length
Message = NewStrBufDup(exist);
}
- /* Do we need to change leading ".." to "." for SMTP escaping? */
+ // Do we need to change leading ".." to "." for SMTP escaping?
if ((tlen == 1) && (*terminator == '.')) {
dotdot = 1;
}
- /* read in the lines of message text one by one */
+ // read in the lines of message text one by one
do {
if (CtdlClientGetLine(LineBuf) < 0) {
finished = 1;
StrBufAppendBufPlain(LineBuf, HKEY("\n"), 0);
}
- /* Unescape SMTP-style input of two dots at the beginning of the line */
+ // Unescape SMTP-style input of two dots at the beginning of the line
if ((dotdot) && (StrLength(LineBuf) > 1) && (ChrPtr(LineBuf)[0] == '.')) {
StrBufCutLeft(LineBuf, 1);
}
StrBufAppendBuf(Message, LineBuf, 0);
}
- /* if we've hit the max msg length, flush the rest */
+ // if we've hit the max msg length, flush the rest
if (StrLength(Message) >= maxlen) {
flushing = 1;
}
struct CtdlMessage *CtdlMakeMessage(
- struct ctdluser *author, /* author's user structure */
- char *recipient, /* NULL if it's not mail */
- char *recp_cc, /* NULL if it's not mail */
- char *room, /* room where it's going */
- int type, /* see MES_ types in header file */
- int format_type, /* variformat, plain text, MIME... */
- char *fake_name, /* who we're masquerading as */
- char *my_email, /* which of my email addresses to use (empty is ok) */
- char *subject, /* Subject (optional) */
- char *supplied_euid, /* ...or NULL if this is irrelevant */
- char *preformatted_text, /* ...or NULL to read text from client */
- char *references /* Thread references */
+ struct ctdluser *author, // author's user structure
+ char *recipient, // NULL if it's not mail
+ char *recp_cc, // NULL if it's not mail
+ char *room, // room where it's going
+ int type, // see MES_ types in header file
+ int format_type, // variformat, plain text, MIME...
+ char *fake_name, // who we're masquerading as
+ char *my_email, // which of my email addresses to use (empty is ok)
+ char *subject, // Subject (optional)
+ 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 */
+ author, // author's user structure
+ recipient, // NULL if it's not mail
(recipient)?strlen(recipient) : 0,
- recp_cc, /* NULL if it's not mail */
+ recp_cc, // NULL if it's not mail
(recp_cc)?strlen(recp_cc): 0,
- room, /* room where it's going */
+ room, // room where it's going
(room)?strlen(room): 0,
- type, /* see MES_ types in header file */
- format_type, /* variformat, plain text, MIME... */
- fake_name, /* who we're masquerading as */
+ type, // see MES_ types in header file
+ format_type, // variformat, plain text, MIME...
+ fake_name, // who we're masquerading as
(fake_name)?strlen(fake_name): 0,
- my_email, /* which of my email addresses to use (empty is ok) */
+ my_email, // which of my email addresses to use (empty is ok)
(my_email)?strlen(my_email): 0,
- subject, /* Subject (optional) */
+ subject, // Subject (optional)
(subject)?strlen(subject): 0,
- supplied_euid, /* ...or NULL if this is irrelevant */
+ supplied_euid, // ...or NULL if this is irrelevant
(supplied_euid)?strlen(supplied_euid):0,
- preformatted_text, /* ...or NULL to read text from client */
+ preformatted_text, // ...or NULL to read text from client
(preformatted_text)?strlen(preformatted_text) : 0,
- references, /* Thread references */
+ references, // Thread references
(references)?strlen(references):0);
}
-/*
- * Build a binary message to be saved on disk.
- * (NOTE: if you supply 'preformatted_text', the buffer you give it
- * will become part of the message. This means you are no longer
- * responsible for managing that memory -- it will be freed along with
- * the rest of the fields when CM_Free() is called.)
- */
+// Build a binary message to be saved on disk.
+// (NOTE: if you supply 'preformatted_text', the buffer you give it
+// will become part of the message. This means you are no longer
+// 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 */
+ struct ctdluser *author, // author's user structure
+ char *recipient, // NULL if it's not mail
long rcplen,
- char *recp_cc, /* NULL if it's not mail */
+ char *recp_cc, // NULL if it's not mail
long cclen,
- char *room, /* room where it's going */
+ char *room, // room where it's going
long roomlen,
- int type, /* see MES_ types in header file */
- int format_type, /* variformat, plain text, MIME... */
- char *fake_name, /* who we're masquerading as */
+ int type, // see MES_ types in header file
+ int format_type, // variformat, plain text, MIME...
+ char *fake_name, // who we're masquerading as
long fnlen,
- char *my_email, /* which of my email addresses to use (empty is ok) */
+ char *my_email, // which of my email addresses to use (empty is ok)
long myelen,
- char *subject, /* Subject (optional) */
+ char *subject, // Subject (optional)
long subjlen,
- char *supplied_euid, /* ...or NULL if this is irrelevant */
+ char *supplied_euid, // ...or NULL if this is irrelevant
long euidlen,
- char *preformatted_text, /* ...or NULL to read text from client */
+ char *preformatted_text, // ...or NULL to read text from client
long textlen,
- char *references, /* Thread references */
+ char *references, // Thread references
long reflen
) {
long blen;
if (recipient != NULL) rcplen = string_trim(recipient);
if (recp_cc != NULL) cclen = string_trim(recp_cc);
- /* Path or Return-Path */
+ // Path or Return-Path
if (myelen > 0) {
CM_SetField(msg, eMessagePath, my_email);
}
FreeStrBuf(&FakeAuthor);
if (!!IsEmptyStr(CC->room.QRname)) {
- if (CC->room.QRflags & QR_MAILBOX) { /* room */
+ if (CC->room.QRflags & QR_MAILBOX) { // room
CM_SetField(msg, eOriginalRoom, &CC->room.QRname[11]);
}
else {
long IsAscii;
IsAscii = -1;
i = 0;
- while ((subject[i] != '\0') &&
- (IsAscii = isascii(subject[i]) != 0 ))
+ while ((subject[i] != '\0') && (IsAscii = isascii(subject[i]) != 0 )) {
i++;
- if (IsAscii != 0)
+ }
+ if (IsAscii != 0) {
CM_SetField(msg, eMsgSubject, subject);
- else /* ok, we've got utf8 in the string. */
- {
+ }
+ else { // ok, we've got utf8 in the string.
char *rfc2047Subj;
rfc2047Subj = rfc2047encode(subject, length);
CM_SetAsField(msg, eMsgSubject, &rfc2047Subj, strlen(rfc2047Subj));
}
if (preformatted_text != NULL) {
- CM_SetField(msg, eMesageText, preformatted_text);
+ CM_SetField(msg, eMessageText, preformatted_text);
}
else {
StrBuf *MsgBody;
MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0);
if (MsgBody != NULL) {
- CM_SetAsFieldSB(msg, eMesageText, &MsgBody);
+ CM_SetAsFieldSB(msg, eMessageText, &MsgBody);
}
}
}
-/*
- * API function to delete messages which match a set of criteria
- * (returns the actual number of messages deleted)
- */
+// 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"
}
syslog(LOG_DEBUG, "msgbase: CtdlDeleteMessages(%s, %d msgs, %s)", room_name, num_dmsgnums, content_type);
- /* get room record, obtaining a lock... */
+ // get room record, obtaining a lock...
if (CtdlGetRoomLock(&qrbuf, room_name) != 0) {
syslog(LOG_ERR, "msgbase: CtdlDeleteMessages(): Room <%s> not found", room_name);
if (need_to_free_re) regfree(&re);
- return(0); /* room not found */
+ return(0); // room not found
}
num_msgs = CtdlFetchMsgList(qrbuf.QRnumber, &msglist);
while ((i < num_msgs) && (have_more_del)) {
delete_this = 0x00;
- /* Set/clear a bit for each criterion */
+ // Set/clear a bit for each criterion
- /* 0 messages in the list or a null list means that we are
- * interested in deleting any messages which meet the other criteria.
- */
+ // 0 messages in the list or a null list means that we are
+ // interested in deleting any messages which meet the other criteria.
if (have_delmsgs) {
delete_this |= 0x01;
}
if (regexec(&re, smi.meta_content_type, 1, &pm, 0) == 0) {
delete_this |= 0x02;
}
- } else {
+ }
+ else {
delete_this |= 0x02;
}
- /* Delete message only if all bits are set */
+ // Delete message only if all bits are set
if (delete_this == 0x03) {
dellist[num_deleted++] = msglist[i];
msglist[i] = 0L;
}
CtdlPutRoomLock(&qrbuf);
- /* Go through the messages we pulled out of the index, and decrement
- * their reference counts by 1. If this is the only room the message
- * was in, the reference count will reach zero and the message will
- * automatically be deleted from the database. We do this in a
- * separate pass because there might be plug-in hooks getting called,
- * and we don't want that happening during an S_ROOMS critical
- * section.
- */
+ // Go through the messages we pulled out of the index, and decrement
+ // their reference counts by 1. If this is the only room the message
+ // was in, the reference count will reach zero and the message will
+ // automatically be deleted from the database. We do this in a
+ // separate pass because there might be plug-in hooks getting called,
+ // and we don't want that happening during an S_ROOMS critical section.
if (num_deleted) {
for (i=0; i<num_deleted; ++i) {
PerformDeleteHooks(qrbuf.QRname, dellist[i]);
}
AdjRefCountList(dellist, num_deleted, -1);
}
- /* Now free the memory we used, and go away. */
+ // Now free the memory we used, and go away.
if (msglist != NULL) free(msglist);
if (dellist != NULL) free(dellist);
syslog(LOG_DEBUG, "msgbase: %d message(s) deleted", num_deleted);
}
-/*
- * GetMetaData() - Get the supplementary record for a message
- */
+// GetMetaData() - Get the supplementary record for a message
void GetMetaData(struct MetaData *smibuf, long msgnum) {
struct cdbdata cdbsmi;
long TheIndex;
memset(smibuf, 0, sizeof(struct MetaData));
smibuf->meta_msgnum = msgnum;
- smibuf->meta_refcount = 1; /* Default reference count is 1 */
+ smibuf->meta_refcount = 1; // Default reference count is 1
- /* Use the negative of the message number for its supp record index */
+ // Use the negative of the message number for its supp record index
TheIndex = (0L - msgnum);
cdbsmi = cdb_fetch(CDB_MSGMAIN, &TheIndex, sizeof(long));
if (cdbsmi.ptr == NULL) {
- return; /* record not found; leave it alone */
+ return; // record not found; leave it alone
}
memcpy(smibuf, cdbsmi.ptr, ((cdbsmi.len > sizeof(struct MetaData)) ? sizeof(struct MetaData) : cdbsmi.len));
return;
}
-/*
- * PutMetaData() - (re)write supplementary record for a message
- */
-void PutMetaData(struct MetaData *smibuf)
-{
+// PutMetaData() - (re)write supplementary record for a message
+void PutMetaData(struct MetaData *smibuf) {
long TheIndex;
- /* Use the negative of the message number for the metadata db index */
+ // Use the negative of the message number for the metadata db index
TheIndex = (0L - smibuf->meta_msgnum);
-
- cdb_store(CDB_MSGMAIN,
- &TheIndex, (int)sizeof(long),
- smibuf, (int)sizeof(struct MetaData)
- );
+ cdb_store(CDB_MSGMAIN, &TheIndex, (int)sizeof(long), smibuf, (int)sizeof(struct MetaData));
}
CM_SetField(msg, eOriginalRoom, req_room);
msg->cm_flags = flags;
- CM_SetAsFieldSB(msg, eMesageText, &encoded_message);
+ CM_SetAsFieldSB(msg, eMessageText, &encoded_message);
- /* Create the requested room if we have to. */
+ // Create the requested room if we have to.
if (CtdlGetRoom(&qrbuf, roomname) != 0) {
CtdlCreateRoom(roomname, ( (is_mailbox != NULL) ? 5 : 3 ), "", 0, 1, 0, VIEW_BBS);
}
- /* Now write the data */
+ // Now write the data
long new_msgnum = CtdlSubmitMsg(msg, NULL, roomname);
CM_Free(msg);
return new_msgnum;
}
-/************************************************************************/
-/* MODULE INITIALIZATION */
-/************************************************************************/
+// ************************************************************************/
+// * MODULE INITIALIZATION */
+// ************************************************************************/
char *ctdl_module_init_msgbase(void) {
if (!threading) {
FillMsgKeyLookupTable();
}
- /* return our module id for the log */
+ // return our module id for the log
return "msgbase";
}