X-Git-Url: https://code.citadel.org/?p=citadel.git;a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=bf18da7447b0e2323e4cfbc74aad76235ad4f876;hp=c65eef1a664a32918a30912e280b2a74fb7277a4;hb=0387f48886a9395d89eaca01cd40ab751610426f;hpb=00159d60a19a36105161c420aeb6a4d33dbd6b5f diff --git a/citadel/msgbase.c b/citadel/msgbase.c index c65eef1a6..bf18da744 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1,7 +1,7 @@ /* * Implements the message store. * - * Copyright (c) 1987-2015 by the citadel.org team + * Copyright (c) 1987-2020 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. @@ -13,12 +13,12 @@ */ +#include +#include #include #include +#include #include - -#include "md5.h" - #include "ctdl_module.h" #include "citserver.h" #include "control.h" @@ -27,7 +27,6 @@ #include "genstamp.h" #include "room_ops.h" #include "user_ops.h" - #include "internet_addressing.h" #include "euidindex.h" #include "msgbase.h" @@ -35,12 +34,6 @@ struct addresses_to_be_filed *atbf = NULL; -/* This temp file holds the queue of operations for AdjRefCount() */ -static FILE *arcfp = NULL; -void AdjRefCountList(long *msgnum, long nmsg, int incr); - -int MessageDebugEnabled = 0; - /* * These are the four-character field headers we use when outputting * messages in Citadel format (as opposed to RFC822 format). @@ -55,34 +48,61 @@ char *msgkeys[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "from", /* A */ - NULL, /* B */ - NULL, /* C */ - NULL, /* D */ - "exti", /* E */ - "rfca", /* F */ - NULL, /* G */ - "hnod", /* H */ - "msgn", /* I */ - "jrnl", /* J */ - "rep2", /* K */ - "list", /* L */ - "text", /* M */ - "node", /* N */ - "room", /* O */ - "path", /* P */ - NULL, /* Q */ - "rcpt", /* R */ - "spec", /* S */ - "time", /* T */ - "subj", /* U */ - "nvto", /* V */ - "wefw", /* W */ - NULL, /* X */ - "cccc", /* Y */ - 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 + "locl", // N -> eOrigLocal + "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) +{ + void *v = NULL; + if (GetHash(msgKeyLookup, c, 4, &v)) { + *f = (eMsgField) v; + return 1; + } + return 0; +} + +void FillMsgKeyLookupTable(void) +{ + long i; + + msgKeyLookup = NewHash (1, FourHash); + + for (i=0; i < 91; i++) { + if (msgkeys[i] != NULL) { + Put(msgKeyLookup, msgkeys[i], 4, (void*)i, reference_free_handler); + } + } +} + + eMsgField FieldOrder[] = { /* Important fields */ emessageId , @@ -91,21 +111,17 @@ eMsgField FieldOrder[] = { eAuthor , erFc822Addr , eOriginalRoom, - eNodeName , - eHumanNode , eRecipient , - eDestination , /* Semi-important fields */ + eOrigLocal , 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 */ @@ -124,22 +140,28 @@ eMsgField FieldOrder[] = { static const long NDiskFields = sizeof(FieldOrder) / sizeof(eMsgField); + int CM_IsEmpty(struct CtdlMessage *Msg, eMsgField which) { - return !((Msg->cm_fields[which] != NULL) && - (Msg->cm_fields[which][0] != '\0')); + 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) { - if (Msg->cm_fields[which] != NULL) + 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'; Msg->cm_lengths[which] = length; } + void CM_SetFieldLONG(struct CtdlMessage *Msg, eMsgField which, long lvalue) { char buf[128]; @@ -147,6 +169,8 @@ void CM_SetFieldLONG(struct CtdlMessage *Msg, eMsgField which, long lvalue) 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) @@ -159,6 +183,7 @@ void CM_CutFieldAt(struct CtdlMessage *Msg, eMsgField WhichToCut, long maxlen) } } + void CM_FlushField(struct CtdlMessage *Msg, eMsgField which) { if (Msg->cm_fields[which] != NULL) @@ -166,35 +191,37 @@ void CM_FlushField(struct CtdlMessage *Msg, eMsgField which) Msg->cm_fields[which] = NULL; Msg->cm_lengths[which] = 0; } + + void CM_Flush(struct CtdlMessage *Msg) { int i; - if (CM_IsValidMsg(Msg) == 0) + if (CM_IsValidMsg(Msg) == 0) { return; + } - for (i = 0; i < 256; ++i) - { + for (i = 0; i < 256; ++i) { CM_FlushField(Msg, i); } } + void CM_CopyField(struct CtdlMessage *Msg, eMsgField WhichToPutTo, eMsgField WhichtToCopy) { long len; - if (Msg->cm_fields[WhichToPutTo] != NULL) + if (Msg->cm_fields[WhichToPutTo] != NULL) { free (Msg->cm_fields[WhichToPutTo]); + } - if (Msg->cm_fields[WhichtToCopy] != NULL) - { + if (Msg->cm_fields[WhichtToCopy] != NULL) { len = Msg->cm_lengths[WhichtToCopy]; Msg->cm_fields[WhichToPutTo] = malloc(len + 1); memcpy(Msg->cm_fields[WhichToPutTo], Msg->cm_fields[WhichtToCopy], len); Msg->cm_fields[WhichToPutTo][len] = '\0'; Msg->cm_lengths[WhichToPutTo] = len; } - else - { + else { Msg->cm_fields[WhichToPutTo] = NULL; Msg->cm_lengths[WhichToPutTo] = 0; } @@ -226,56 +253,66 @@ void CM_PrependToField(struct CtdlMessage *Msg, eMsgField which, const char *buf } } + void CM_SetAsField(struct CtdlMessage *Msg, eMsgField which, char **buf, long length) { - if (Msg->cm_fields[which] != NULL) + 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) { - if (Msg->cm_fields[which] != NULL) + if (Msg->cm_fields[which] != NULL) { free (Msg->cm_fields[which]); + } Msg->cm_lengths[which] = StrLength(*buf); Msg->cm_fields[which] = SmashStrBuf(buf); } + void CM_GetAsField(struct CtdlMessage *Msg, eMsgField which, char **ret, long *retlen) { - if (Msg->cm_fields[which] != NULL) - { + if (Msg->cm_fields[which] != NULL) { *retlen = Msg->cm_lengths[which]; *ret = Msg->cm_fields[which]; Msg->cm_fields[which] = NULL; Msg->cm_lengths[which] = 0; } - else - { + else { *ret = NULL; *retlen = 0; } } + /* * Returns 1 if the supplied pointer points to a valid Citadel message. * If the pointer is NULL or the magic number check fails, returns 0. */ int CM_IsValidMsg(struct CtdlMessage *msg) { - if (msg == NULL) + if (msg == NULL) { return 0; + } if ((msg->cm_magic) != CTDLMESSAGE_MAGIC) { - struct CitContext *CCC = CC; - MSGM_syslog(LOG_WARNING, "CM_IsValidMsg() -- self-check failed\n"); + syslog(LOG_WARNING, "msgbase: CM_IsValidMsg() self-check failed"); return 0; } return 1; } + void CM_FreeContents(struct CtdlMessage *msg) { int i; @@ -288,13 +325,14 @@ void CM_FreeContents(struct CtdlMessage *msg) msg->cm_magic = 0; /* just in case */ } + + /* * 'Destructor' for struct CtdlMessage */ void CM_Free(struct CtdlMessage *msg) { - if (CM_IsValidMsg(msg) == 0) - { + if (CM_IsValidMsg(msg) == 0) { if (msg != NULL) free (msg); return; } @@ -302,40 +340,42 @@ void CM_Free(struct CtdlMessage *msg) free(msg); } + 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); - if (NewMsg->cm_fields[i] == NULL) + if (NewMsg->cm_fields[i] == NULL) { return 0; + } memcpy(NewMsg->cm_fields[i], OrgMsg->cm_fields[i], len); NewMsg->cm_fields[i][len] = '\0'; NewMsg->cm_lengths[i] = len; return 1; } + struct CtdlMessage * CM_Duplicate(struct CtdlMessage *OrgMsg) { int i; struct CtdlMessage *NewMsg; - if (CM_IsValidMsg(OrgMsg) == 0) + if (CM_IsValidMsg(OrgMsg) == 0) { return NULL; + } NewMsg = (struct CtdlMessage *)malloc(sizeof(struct CtdlMessage)); - if (NewMsg == NULL) + if (NewMsg == NULL) { return NULL; + } memcpy(NewMsg, OrgMsg, sizeof(struct CtdlMessage)); memset(&NewMsg->cm_fields, 0, sizeof(char*) * 256); - for (i = 0; i < 256; ++i) - { - if (OrgMsg->cm_fields[i] != NULL) - { - if (!CM_DupField(i, OrgMsg, NewMsg)) - { + for (i = 0; i < 256; ++i) { + if (OrgMsg->cm_fields[i] != NULL) { + if (!CM_DupField(i, OrgMsg, NewMsg)) { CM_Free(NewMsg); return NULL; } @@ -346,9 +386,6 @@ struct CtdlMessage * CM_Duplicate(struct CtdlMessage *OrgMsg) } - - - /* Determine if a given message matches the fields in a message template. * Return 0 for a successful match. */ @@ -381,38 +418,36 @@ int CtdlMsgCmp(struct CtdlMessage *msg, struct CtdlMessage *template) { } - /* * Retrieve the "seen" message list for the current room. */ void CtdlGetSeen(char *buf, int which_set) { - struct CitContext *CCC = CC; visit vbuf; /* Learn about the user and room in question */ - CtdlGetRelationship(&vbuf, &CCC->user, &CCC->room); + CtdlGetRelationship(&vbuf, &CC->user, &CC->room); - if (which_set == ctdlsetseen_seen) + if (which_set == ctdlsetseen_seen) { safestrncpy(buf, vbuf.v_seen, SIZ); - if (which_set == ctdlsetseen_answered) + } + if (which_set == ctdlsetseen_answered) { safestrncpy(buf, vbuf.v_answered, SIZ); + } } - /* * Manipulate the "seen msgs" string (or other message set strings) */ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, int target_setting, int which_set, struct ctdluser *which_user, struct ctdlroom *which_room) { - struct CitContext *CCC = CC; struct cdbdata *cdbfr; int i, k; int is_seen = 0; int was_seen = 0; long lo = (-1L); - long hi = (-1L); /// TODO: we just write here. y? + long hi = (-1L); visit vbuf; long *msglist; int num_msgs = 0; @@ -430,15 +465,15 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, /* If no room was specified, we go with the current room. */ if (!which_room) { - which_room = &CCC->room; + which_room = &CC->room; } /* If no user was specified, we go with the current user. */ if (!which_user) { - which_user = &CCC->user; + which_user = &CC->user; } - MSG_syslog(LOG_DEBUG, "CtdlSetSeen(%d msgs starting with %ld, %s, %d) in <%s>\n", + syslog(LOG_DEBUG, "msgbase: CtdlSetSeen(%d msgs starting with %ld, %s, %d) in <%s>", num_target_msgnums, target_msgnums[0], (target_setting ? "SET" : "CLEAR"), which_set, @@ -475,18 +510,16 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, #if 0 /* This is a special diagnostic section. Do not allow it to run during normal operation. */ - MSG_syslog(LOG_DEBUG, "There are %d messages in the room.\n", num_msgs); + syslog(LOG_DEBUG, "There are %d messages in the room.\n", num_msgs); for (i=0; i 0) && (msglist[i] <= msglist[i-1])) abort(); } - MSG_syslog(LOG_DEBUG, "We are twiddling %d of them.\n", num_target_msgnums); + syslog(LOG_DEBUG, "We are twiddling %d of them.\n", num_target_msgnums); for (k=0; k 0) && (target_msgnums[k] <= target_msgnums[k-1])) abort(); } #endif - MSG_syslog(LOG_DEBUG, "before update: %s\n", ChrPtr(vset)); - /* Translate the existing sequence set into an array of booleans */ setstr = NewStrBuf(); lostr = NewStrBuf(); @@ -520,7 +553,6 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, FreeStrBuf(&lostr); FreeStrBuf(&histr); - /* Now translate the array of booleans back into a sequence set */ FlushStrBuf(vset); was_seen = 0; @@ -608,8 +640,6 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, vset = new_set; } - MSG_syslog(LOG_DEBUG, " after update: %s\n", ChrPtr(vset)); - /* Decide which message set we're manipulating */ switch (which_set) { case ctdlsetseen_seen: @@ -637,7 +667,6 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, ForEachMsgCallback CallBack, void *userdata) { - struct CitContext *CCC = CC; int a, i, j; visit vbuf; struct cdbdata *cdbfr; @@ -666,13 +695,13 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, if (need_to_free_re) regfree(&re); return -1; } - CtdlGetUser(&CCC->user, CCC->curr_user); + CtdlGetUser(&CC->user, CC->curr_user); if (server_shutting_down) { if (need_to_free_re) regfree(&re); return -1; } - CtdlGetRelationship(&vbuf, &CCC->user, &CCC->room); + CtdlGetRelationship(&vbuf, &CC->user, &CC->room); if (server_shutting_down) { if (need_to_free_re) regfree(&re); @@ -680,7 +709,7 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, } /* Load the message list */ - cdbfr = cdb_fetch(CDB_MSGLISTS, &CCC->room.QRnumber, sizeof(long)); + cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long)); if (cdbfr == NULL) { if (need_to_free_re) regfree(&re); return 0; /* No messages at all? No further action. */ @@ -738,7 +767,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; @@ -827,13 +856,16 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, || ((mode == MSGS_EQ) && (thismsg == ref)) ) ) { - if ((mode == MSGS_NEW) && (CCC->user.flags & US_LASTOLD) && (lastold > 0L) && (printed_lastold == 0) && (!is_seen)) { - if (CallBack) + if ((mode == MSGS_NEW) && (CC->user.flags & US_LASTOLD) && (lastold > 0L) && (printed_lastold == 0) && (!is_seen)) { + if (CallBack) { CallBack(lastold, userdata); + } printed_lastold = 1; ++num_processed; } - if (CallBack) CallBack(thismsg, userdata); + if (CallBack) { + CallBack(thismsg, userdata); + } ++num_processed; } } @@ -842,12 +874,12 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, /* * We cache the most recent msglist in order to do security checks later */ - if (CCC->client_socket > 0) { - if (CCC->cached_msglist != NULL) { - free(CCC->cached_msglist); + if (CC->client_socket > 0) { + if (CC->cached_msglist != NULL) { + free(CC->cached_msglist); } - CCC->cached_msglist = msglist; - CCC->cached_num_msgs = num_msgs; + CC->cached_msglist = msglist; + CC->cached_num_msgs = num_msgs; } else { free(msglist); @@ -857,7 +889,6 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, } - /* * memfmout() - Citadel text formatter and paginator. * Although the original purpose of this routine was to format @@ -869,7 +900,6 @@ void memfmout( char *mptr, /* where are we going to get our text from? */ const char *nl /* string to terminate lines with */ ) { - struct CitContext *CCC = CC; int column = 0; unsigned char ch = 0; char outbuf[1024]; @@ -881,15 +911,13 @@ void memfmout( while (ch=*(mptr++), ch != 0) { if (ch == '\n') { - if (client_write(outbuf, len) == -1) - { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + if (client_write(outbuf, len) == -1) { + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } len = 0; - if (client_write(nl, nllen) == -1) - { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + if (client_write(nl, nllen) == -1) { + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } column = 0; @@ -899,15 +927,13 @@ void memfmout( } else if (isspace(ch)) { if (column > 72) { /* Beyond 72 columns, break on the next space */ - if (client_write(outbuf, len) == -1) - { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + if (client_write(outbuf, len) == -1) { + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } len = 0; - if (client_write(nl, nllen) == -1) - { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + if (client_write(nl, nllen) == -1) { + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } column = 0; @@ -921,15 +947,13 @@ void memfmout( outbuf[len++] = ch; ++column; if (column > 1000) { /* Beyond 1000 columns, break anywhere */ - if (client_write(outbuf, len) == -1) - { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + if (client_write(outbuf, len) == -1) { + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } len = 0; - if (client_write(nl, nllen) == -1) - { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + if (client_write(nl, nllen) == -1) { + syslog(LOG_ERR, "msgbase: memfmout(): aborting due to write failure"); return; } column = 0; @@ -937,9 +961,8 @@ void memfmout( } } if (len) { - if (client_write(outbuf, len) == -1) - { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + if (client_write(outbuf, len) == -1) { + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } client_write(nl, nllen); @@ -948,7 +971,6 @@ void memfmout( } - /* * Callback function for mime parser that simply lists the part */ @@ -972,6 +994,7 @@ void list_this_part(char *name, char *filename, char *partnum, char *disp, } } + /* * Callback function for multipart prefix */ @@ -991,6 +1014,7 @@ void list_this_pref(char *name, char *filename, char *partnum, char *disp, } } + /* * Callback function for multipart sufffix */ @@ -1020,44 +1044,38 @@ void mime_download(char *name, char *filename, char *partnum, char *disp, char *encoding, char *cbid, void *cbuserdata) { int rv = 0; - CitContext *CCC = MyContext(); /* Silently go away if there's already a download open. */ - if (CCC->download_fp != NULL) + if (CC->download_fp != NULL) return; if ( - (!IsEmptyStr(partnum) && (!strcasecmp(CCC->download_desired_section, partnum))) - || (!IsEmptyStr(cbid) && (!strcasecmp(CCC->download_desired_section, cbid))) + (!IsEmptyStr(partnum) && (!strcasecmp(CC->download_desired_section, partnum))) + || (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid))) ) { - CCC->download_fp = tmpfile(); - if (CCC->download_fp == NULL) { - MSG_syslog(LOG_EMERG, "mime_download(): Couldn't write: %s\n", - strerror(errno)); - cprintf("%d cannot open temporary file: %s\n", - ERROR + INTERNAL_ERROR, strerror(errno)); + CC->download_fp = tmpfile(); + if (CC->download_fp == NULL) { + syslog(LOG_EMERG, "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, CCC->download_fp); + rv = fwrite(content, length, 1, CC->download_fp); if (rv <= 0) { - MSG_syslog(LOG_EMERG, "mime_download(): Couldn't write: %s\n", - strerror(errno)); - cprintf("%d unable to write tempfile.\n", - ERROR + TOO_BIG); - fclose(CCC->download_fp); - CCC->download_fp = NULL; + syslog(LOG_EMERG, "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; return; } - fflush(CCC->download_fp); - rewind(CCC->download_fp); + fflush(CC->download_fp); + rewind(CC->download_fp); OpenCmdResult(filename, cbtype); } } - /* * Callback function for mime parser that outputs a section all at once. * We can specify the desired section by part number *or* content-id. @@ -1084,9 +1102,9 @@ void mime_spew_section(char *name, char *filename, char *partnum, char *disp, } } + struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const char *Buffer, long Length) { - struct CitContext *CCC = CC; struct CtdlMessage *ret = NULL; const char *mptr; const char *upper_bound; @@ -1096,6 +1114,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. @@ -1104,7 +1125,7 @@ struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const cha */ ch = *mptr++; if (ch != 255) { - MSG_syslog(LOG_ERR, "Message %ld appears to be corrupted.\n", msgnum); + syslog(LOG_ERR, "msgbase: message %ld appears to be corrupted", msgnum); return NULL; } ret = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); @@ -1124,8 +1145,7 @@ struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const cha long len; /* work around possibly buggy messages: */ - while (field_header == '\0') - { + while (field_header == '\0') { if (mptr >= upper_bound) { break; } @@ -1152,24 +1172,22 @@ struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const cha * This is used by CtdlOutputMsg() and other fetch functions. * * NOTE: Caller is responsible for freeing the returned CtdlMessage struct - * using the CtdlMessageFree() function. + * 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 CitContext *CCC = CC; struct cdbdata *dmsgtext; struct CtdlMessage *ret = NULL; - MSG_syslog(LOG_DEBUG, "CtdlFetchMessage(%ld, %d)\n", msgnum, with_body); + syslog(LOG_DEBUG, "msgbase: CtdlFetchMessage(%ld, %d)", msgnum, with_body); dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long)); if (dmsgtext == NULL) { - MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Failed!\n", msgnum, with_body); + syslog(LOG_ERR, "msgbase: CtdlFetchMessage(%ld, %d) Failed!", msgnum, with_body); return NULL; } - if (dmsgtext->ptr[dmsgtext->len - 1] != '\0') - { - MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body); + if (dmsgtext->ptr[dmsgtext->len - 1] != '\0') { + syslog(LOG_ERR, "msgbase: CtdlFetchMessage(%ld, %d) Forcefully terminating message!!", msgnum, with_body); dmsgtext->ptr[dmsgtext->len - 1] = '\0'; } @@ -1197,17 +1215,10 @@ 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); } - /* * Pre callback function for multipart/alternative * @@ -1222,11 +1233,10 @@ void fixed_output_pre(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *cbuserdata) { - struct CitContext *CCC = CC; struct ma_info *ma; ma = (struct ma_info *)cbuserdata; - MSG_syslog(LOG_DEBUG, "fixed_output_pre() type=<%s>\n", cbtype); + syslog(LOG_DEBUG, "msgbase: fixed_output_pre() type=<%s>", cbtype); if (!strcasecmp(cbtype, "multipart/alternative")) { ++ma->is_ma; ma->did_print = 0; @@ -1236,6 +1246,7 @@ void fixed_output_pre(char *name, char *filename, char *partnum, char *disp, } } + /* * Post callback function for multipart/alternative */ @@ -1243,11 +1254,10 @@ void fixed_output_post(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *cbuserdata) { - struct CitContext *CCC = CC; struct ma_info *ma; ma = (struct ma_info *)cbuserdata; - MSG_syslog(LOG_DEBUG, "fixed_output_post() type=<%s>\n", cbtype); + syslog(LOG_DEBUG, "msgbase: fixed_output_post() type=<%s>", cbtype); if (!strcasecmp(cbtype, "multipart/alternative")) { --ma->is_ma; ma->did_print = 0; @@ -1257,6 +1267,7 @@ void fixed_output_post(char *name, char *filename, char *partnum, char *disp, } } + /* * Inline callback function for mime parser that wants to display text */ @@ -1264,7 +1275,6 @@ void fixed_output(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *cbuserdata) { - struct CitContext *CCC = CC; char *ptr; char *wptr; size_t wlen; @@ -1272,16 +1282,17 @@ void fixed_output(char *name, char *filename, char *partnum, char *disp, ma = (struct ma_info *)cbuserdata; - MSG_syslog(LOG_DEBUG, - "fixed_output() part %s: %s (%s) (%ld bytes)\n", - partnum, filename, cbtype, (long)length); + syslog(LOG_DEBUG, + "msgbase: fixed_output() part %s: %s (%s) (%ld bytes)", + partnum, filename, cbtype, (long)length + ); /* * If we're in the middle of a multipart/alternative scope and * we've already printed another section, skip this one. */ if ( (ma->is_ma) && (ma->did_print) ) { - MSG_syslog(LOG_DEBUG, "Skipping part %s (%s)\n", partnum, cbtype); + syslog(LOG_DEBUG, "msgbase: skipping part %s (%s)", partnum, cbtype); return; } ma->did_print = 1; @@ -1299,7 +1310,7 @@ void fixed_output(char *name, char *filename, char *partnum, char *disp, } if (!strcasecmp(cbtype, "text/html")) { - ptr = html_to_ascii(content, length, 80, 0); + ptr = html_to_ascii(content, length, 80); wlen = strlen(ptr); client_write(ptr, wlen); if ((wlen > 0) && (ptr[wlen-1] != '\n')) { @@ -1323,6 +1334,7 @@ void fixed_output(char *name, char *filename, char *partnum, char *disp, } } + /* * The client is elegant and sophisticated and wants to be choosy about * MIME content types, so figure out which multipart/alternative part @@ -1338,23 +1350,17 @@ void choose_preferred(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *cbuserdata) { - struct CitContext *CCC = CC; char buf[1024]; int i; struct ma_info *ma; ma = (struct ma_info *)cbuserdata; - // NOTE: REMOVING THIS CONDITIONAL FIXES BUG 220 - // http://bugzilla.citadel.org/show_bug.cgi?id=220 - // I don't know if there are any side effects! Please TEST TEST TEST - //if (ma->is_ma > 0) { - - for (i=0; ipreferred_formats, '|'); ++i) { - extract_token(buf, CCC->preferred_formats, i, '|', sizeof buf); + for (i=0; ipreferred_formats, '|'); ++i) { + extract_token(buf, CC->preferred_formats, i, '|', sizeof buf); if ( (!strcasecmp(buf, cbtype)) && (!ma->freeze) ) { if (i < ma->chosen_pref) { - MSG_syslog(LOG_DEBUG, "Setting chosen part: <%s>\n", partnum); + syslog(LOG_DEBUG, "msgbase: setting chosen part to <%s>", partnum); safestrncpy(ma->chosen_part, partnum, sizeof ma->chosen_part); ma->chosen_pref = i; } @@ -1362,6 +1368,7 @@ void choose_preferred(char *name, char *filename, char *partnum, char *disp, } } + /* * Now that we've chosen our preferred part, output it. */ @@ -1377,7 +1384,6 @@ void output_preferred(char *name, char *cbid, void *cbuserdata) { - struct CitContext *CCC = CC; int i; char buf[128]; int add_newline = 0; @@ -1395,8 +1401,8 @@ void output_preferred(char *name, /* If the content-type of this part is in our preferred formats * list, we can simply output it verbatim. */ - for (i=0; ipreferred_formats, '|'); ++i) { - extract_token(buf, CCC->preferred_formats, i, '|', sizeof buf); + for (i=0; ipreferred_formats, '|'); ++i) { + extract_token(buf, CC->preferred_formats, i, '|', sizeof buf); if (!strcasecmp(buf, cbtype)) { /* Yeah! Go! W00t!! */ if (ma->dont_decode == 0) @@ -1433,7 +1439,7 @@ void output_preferred(char *name, cprintf("\n"); if (client_write(text_content, length) == -1) { - MSGM_syslog(LOG_ERR, "output_preferred(): aborting due to write failure.\n"); + syslog(LOG_ERR, "msgbase: output_preferred() aborting due to write failure"); return; } if (add_newline) cprintf("\n"); @@ -1499,13 +1505,12 @@ void extract_encapsulated_message(char *name, char *filename, char *partnum, cha * (This is a security check) */ int check_cached_msglist(long msgnum) { - struct CitContext *CCC = CC; /* cases in which we skip the check */ - if (!CCC) return om_ok; /* not a session */ - if (CCC->client_socket <= 0) return om_ok; /* not a client session */ - if (CCC->cached_msglist == NULL) return om_access_denied; /* no msglist fetched */ - if (CCC->cached_num_msgs == 0) return om_access_denied; /* nothing to check */ + if (!CC) return om_ok; /* not a session */ + if (CC->client_socket <= 0) return om_ok; /* not a client session */ + if (CC->cached_msglist == NULL) return om_access_denied; /* no msglist fetched */ + if (CC->cached_num_msgs == 0) return om_access_denied; /* nothing to check */ /* Do a binary search within the cached_msglist for the requested msgnum */ @@ -1514,7 +1519,7 @@ int check_cached_msglist(long msgnum) { while (max >= min) { int middle = min + (max-min) / 2 ; - if (msgnum == CCC->cached_msglist[middle]) { + if (msgnum == CC->cached_msglist[middle]) { return om_ok; } if (msgnum > CC->cached_msglist[middle]) { @@ -1529,7 +1534,6 @@ int check_cached_msglist(long msgnum) { } - /* * Get a message off disk. (returns om_* values found in msgbase.h) * @@ -1545,13 +1549,12 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ char **Address, char **MessageID ) { - struct CitContext *CCC = CC; struct CtdlMessage *TheMessage = NULL; int retcode = CIT_OK; struct encapmsg encap; int r; - MSG_syslog(LOG_DEBUG, "CtdlOutputMsg(msgnum=%ld, mode=%d, section=%s)\n", + syslog(LOG_DEBUG, "msgbase: CtdlOutputMsg(msgnum=%ld, mode=%d, section=%s)", msg_num, mode, (section ? section : "<>") ); @@ -1579,8 +1582,8 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ r = check_cached_msglist(msg_num); } if (r != om_ok) { - MSG_syslog(LOG_DEBUG, "Security check fail: message %ld is not in %s\n", - msg_num, CCC->room.QRname + syslog(LOG_DEBUG, "msgbase: security check fail; message %ld is not in %s", + msg_num, CC->room.QRname ); if (do_proto) { if (r == om_access_denied) { @@ -1598,10 +1601,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) { @@ -1687,13 +1690,11 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ } - void OutputCtdlMsgHeaders( struct CtdlMessage *TheMessage, int do_proto) /* do Citadel protocol responses? */ { int i; - int suppress_f = 0; char buf[SIZ]; char display_name[256]; @@ -1720,16 +1721,6 @@ 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; @@ -1747,25 +1738,21 @@ void OutputCtdlMsgHeaders( msgkeys[Field], display_name); } - else if ((Field == erFc822Addr) && (suppress_f)) { - /* do nothing */ - } /* Masquerade display name if needed */ else { - if (do_proto) cprintf("%s=%s\n", - msgkeys[Field], - TheMessage->cm_fields[Field] - ); + if (do_proto) { + cprintf("%s=%s\n", msgkeys[Field], TheMessage->cm_fields[Field]); + } } } } } - } + 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, @@ -1816,27 +1803,17 @@ void OutputRFC822MsgHeaders( subject_found = 1; break; case emessageId: - safestrncpy(mid, mptr, sizeof_mid); /// TODO: detect @ here and copy @nodename in if not found. + safestrncpy(mid, mptr, sizeof_mid); break; case erFc822Addr: safestrncpy(fuser, mptr, sizeof_fuser); - /* case eOriginalRoom: - cprintf("X-Citadel-Room: %s%s", - mptr, nl) - break; - ; */ - case eNodeName: - safestrncpy(snode, mptr, sizeof_snode); - break; case eRecipient: - if (haschar(mptr, '@') == 0) - { + if (haschar(mptr, '@') == 0) { sanitize_truncated_recipient(mptr); cprintf("To: %s@%s", mptr, CtdlGetConfigStr("c_fqdn")); cprintf("%s", nl); } - else - { + else { if ((flags & QP_EADDR) != 0) { mptr = qp_encode_email_addrs(mptr); } @@ -1846,8 +1823,7 @@ void OutputRFC822MsgHeaders( } break; case eTimestamp: - datestring(datestamp, sizeof datestamp, - atol(mptr), DATESTRING_RFC822); + datestring(datestamp, sizeof datestamp, atol(mptr), DATESTRING_RFC822); cprintf("Date: %s%s", datestamp, nl); break; case eWeferences: @@ -1872,25 +1848,22 @@ 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: case eVltMsgNum: + case eOrigLocal: /* these don't map to mime message headers. */ break; - } - if (mptr != mpptr) + if (mptr != mpptr) { free (mptr); + } } } if (subject_found == 0) { @@ -1903,7 +1876,6 @@ void Dump_RFC822HeadersBody( struct CtdlMessage *TheMessage, 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; @@ -1917,7 +1889,6 @@ void Dump_RFC822HeadersBody( mptr = TheMessage->cm_fields[eMesageText]; - prev_ch = '\0'; while (*mptr != '\0') { if (*mptr == '\r') { @@ -1941,7 +1912,7 @@ void Dump_RFC822HeadersBody( ((headers_only == HEADERS_ONLY) && (mptr < StartOfText)) || ((headers_only != HEADERS_NONE) && (headers_only != HEADERS_ONLY)) - ) { + ) { if (*mptr == '\n') { memcpy(&outbuf[outlen], nl, nllen); outlen += nllen; @@ -1952,22 +1923,16 @@ void Dump_RFC822HeadersBody( } } } - if (flags & ESC_DOT) - { - if ((prev_ch == '\n') && - (*mptr == '.') && - ((*(mptr+1) == '\r') || (*(mptr+1) == '\n'))) - { + if (flags & ESC_DOT) { + if ((prev_ch == '\n') && (*mptr == '.') && ((*(mptr+1) == '\r') || (*(mptr+1) == '\n'))) { outbuf[outlen++] = '.'; } prev_ch = *mptr; } ++mptr; if (outlen > 1000) { - if (client_write(outbuf, outlen) == -1) - { - struct CitContext *CCC = CC; - MSGM_syslog(LOG_ERR, "Dump_RFC822HeadersBody(): aborting due to write failure.\n"); + if (client_write(outbuf, outlen) == -1) { + syslog(LOG_ERR, "msgbase: Dump_RFC822HeadersBody() aborting due to write failure"); return; } lfSent = (outbuf[outlen - 1] == '\n'); @@ -1983,7 +1948,6 @@ void Dump_RFC822HeadersBody( } - /* 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. @@ -2026,22 +1990,19 @@ void DumpFormatFixed( ch = '\r'; } } - /* if we reach the outer bounds of our buffer, - abort without respect what whe purge. */ - if (xlline && - ((isspace(ch)) || - (buflen > SIZ - nllen - 2))) + + /* 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'; + } if (ch == '\r') { memcpy (&buf[buflen], nl, nllen); buflen += nllen; buf[buflen] = '\0'; - if (client_write(buf, buflen) == -1) - { - struct CitContext *CCC = CC; - MSGM_syslog(LOG_ERR, "DumpFormatFixed(): aborting due to write failure.\n"); + if (client_write(buf, buflen) == -1) { + syslog(LOG_ERR, "msgbase: DumpFormatFixed() aborting due to write failure"); return; } *buf = '\0'; @@ -2053,10 +2014,12 @@ void DumpFormatFixed( } } buf[buflen] = '\0'; - if (!IsEmptyStr(buf)) + if (!IsEmptyStr(buf)) { cprintf("%s%s", buf, nl); + } } + /* * Get a message off disk. (returns om_* values found in msgbase.h) */ @@ -2068,7 +2031,6 @@ int CtdlOutputPreLoadedMsg( int crlf, /* Use CRLF newlines instead of LF? */ int flags /* should the bessage be exported clean? */ ) { - struct CitContext *CCC = CC; int i; const char *nl; /* newline string */ int nlen; @@ -2078,24 +2040,23 @@ 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]; - MSG_syslog(LOG_DEBUG, "CtdlOutputPreLoadedMsg(TheMessage=%s, %d, %d, %d, %d\n", + syslog(LOG_DEBUG, "msgbase: CtdlOutputPreLoadedMsg(TheMessage=%s, %d, %d, %d, %d", ((TheMessage == NULL) ? "NULL" : "not null"), - mode, headers_only, do_proto, crlf); + mode, headers_only, do_proto, crlf + ); strcpy(mid, "unknown"); nl = (crlf ? "\r\n" : "\n"); nlen = crlf ? 2 : 1; if (!CM_IsValidMsg(TheMessage)) { - MSGM_syslog(LOG_ERR, - "ERROR: invalid preloaded message for output\n"); - cit_backtrace (); + syslog(LOG_ERR, "msgbase: error; invalid preloaded message for output"); return(om_no_such_msg); } @@ -2112,7 +2073,7 @@ int CtdlOutputPreLoadedMsg( if (do_proto) cprintf("%d This is not a MIME message.\n", ERROR + ILLEGAL_VALUE); - } else if (CCC->download_fp != NULL) { + } else if (CC->download_fp != NULL) { if (do_proto) cprintf( "%d You already have a download open.\n", ERROR + RESOURCE_BUSY); @@ -2123,14 +2084,14 @@ int CtdlOutputPreLoadedMsg( /* If there's no file open by this time, the requested * section wasn't found, so print an error */ - if (CCC->download_fp == NULL) { + if (CC->download_fp == NULL) { if (do_proto) cprintf( "%d Section %s not found.\n", ERROR + FILE_NOT_FOUND, - CCC->download_desired_section); + CC->download_desired_section); } } - return((CCC->download_fp != NULL) ? om_ok : om_mime_error); + return((CC->download_fp != NULL) ? om_ok : om_mime_error); } /* MT_SPEW_SECTION is like MT_DOWNLOAD except it outputs the whole MIME part @@ -2153,10 +2114,10 @@ int CtdlOutputPreLoadedMsg( if (do_proto) cprintf( "%d Section %s not found.\n", ERROR + FILE_NOT_FOUND, - CCC->download_desired_section); + CC->download_desired_section); } } - return((CCC->download_fp != NULL) ? om_ok : om_mime_error); + return((CC->download_fp != NULL) ? om_ok : om_mime_error); } /* now for the user-mode message reading loops */ @@ -2186,7 +2147,7 @@ int CtdlOutputPreLoadedMsg( strcpy(suser, ""); strcpy(luser, ""); strcpy(fuser, ""); - memcpy(snode, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")) + 1); + strcpy(snode, ""); if (mode == MT_RFC822) OutputRFC822MsgHeaders( TheMessage, @@ -2206,12 +2167,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); } @@ -2301,7 +2258,7 @@ START_TEXT: ma.use_fo_hooks = 0; strcpy(ma.chosen_part, "1"); ma.chosen_pref = 9999; - ma.dont_decode = CCC->msg4_dont_decode; + ma.dont_decode = CC->msg4_dont_decode; mime_parser(CM_RANGE(TheMessage, eMesageText), *choose_preferred, *fixed_output_pre, *fixed_output_post, (void *)&ma, 1); @@ -2336,7 +2293,6 @@ DONE: /* now we're done */ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs, int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj ) { - struct CitContext *CCC = CC; int i, j, unique; char hold_rm[ROOMNAMELEN]; struct cdbdata *cdbfr; @@ -2350,12 +2306,12 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms long *msgs_to_be_merged = NULL; int num_msgs_to_be_merged = 0; - MSG_syslog(LOG_DEBUG, - "CtdlSaveMsgPointersInRoom(room=%s, num_msgs=%d, repl=%d, suppress_rca=%d)\n", - roomname, num_newmsgs, do_repl_check, suppress_refcount_adj + syslog(LOG_DEBUG, + "msgbase: CtdlSaveMsgPointersInRoom(room=%s, num_msgs=%d, repl=%d, suppress_rca=%d)", + roomname, num_newmsgs, do_repl_check, suppress_refcount_adj ); - strcpy(hold_rm, CCC->room.QRname); + strcpy(hold_rm, CC->room.QRname); /* Sanity checks */ if (newmsgidlist == NULL) return(ERROR + INTERNAL_ERROR); @@ -2363,10 +2319,10 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms if (num_newmsgs > 1) supplied_msg = NULL; /* Now the regular stuff */ - if (CtdlGetRoomLock(&CCC->room, - ((roomname != NULL) ? roomname : CCC->room.QRname) ) + if (CtdlGetRoomLock(&CC->room, + ((roomname != NULL) ? roomname : CC->room.QRname) ) != 0) { - MSG_syslog(LOG_ERR, "No such room <%s>\n", roomname); + syslog(LOG_ERR, "msgbase: no such room <%s>", roomname); return(ERROR + ROOM_NOT_FOUND); } @@ -2375,7 +2331,7 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms num_msgs_to_be_merged = 0; - cdbfr = cdb_fetch(CDB_MSGLISTS, &CCC->room.QRnumber, sizeof(long)); + cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long)); if (cdbfr == NULL) { msglist = NULL; num_msgs = 0; @@ -2403,14 +2359,14 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms } } - MSG_syslog(LOG_DEBUG, "%d unique messages to be merged\n", num_msgs_to_be_merged); + syslog(LOG_DEBUG, "msgbase: %d unique messages to be merged", num_msgs_to_be_merged); /* * Now merge the new messages */ msglist = realloc(msglist, (sizeof(long) * (num_msgs + num_msgs_to_be_merged)) ); if (msglist == NULL) { - MSGM_syslog(LOG_ALERT, "ERROR: can't realloc message list!\n"); + syslog(LOG_ALERT, "msgbase: ERROR; can't realloc message list!"); free(msgs_to_be_merged); return (ERROR + INTERNAL_ERROR); } @@ -2424,19 +2380,19 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms highest_msg = msglist[num_msgs - 1]; /* Write it back to disk. */ - cdb_store(CDB_MSGLISTS, &CCC->room.QRnumber, (int)sizeof(long), + cdb_store(CDB_MSGLISTS, &CC->room.QRnumber, (int)sizeof(long), msglist, (int)(num_msgs * sizeof(long))); /* Free up the memory we used. */ free(msglist); /* Update the highest-message pointer and unlock the room. */ - CCC->room.QRhighest = highest_msg; - CtdlPutRoomLock(&CCC->room); + CC->room.QRhighest = highest_msg; + CtdlPutRoomLock(&CC->room); /* Perform replication checks if necessary */ - if ( (DoesThisRoomNeedEuidIndexing(&CCC->room)) && (do_repl_check) ) { - MSGM_syslog(LOG_DEBUG, "CtdlSaveMsgPointerInRoom() doing repl checks\n"); + if ( (DoesThisRoomNeedEuidIndexing(&CC->room)) && (do_repl_check) ) { + syslog(LOG_DEBUG, "msgbase: CtdlSaveMsgPointerInRoom() doing repl checks"); for (i=0; icm_fields[eExclusiveID], &CCC->room, msgid); + index_message_by_euid(msg->cm_fields[eExclusiveID], &CC->room, msgid); } /* Free up the memory we may have allocated */ @@ -2466,14 +2422,17 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms } else { - MSGM_syslog(LOG_DEBUG, "CtdlSaveMsgPointerInRoom() skips repl checks\n"); + syslog(LOG_DEBUG, "msgbase: CtdlSaveMsgPointerInRoom() skips repl checks"); } /* Submit this room for processing by hooks */ - PerformRoomHooks(&CCC->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(&CCC->room, hold_rm); + CtdlGetRoom(&CC->room, hold_rm); /* Bump the reference count for all messages which were merged */ if (!suppress_refcount_adj) { @@ -2501,8 +2460,6 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, } - - /* * Message base operation to save a new message to the message store * (returns new message number) @@ -2512,7 +2469,6 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, * */ long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { - struct CitContext *CCC = CC; long retval; struct ser_ret smr; int is_bigmsg = 0; @@ -2523,8 +2479,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; @@ -2547,17 +2502,16 @@ long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { ERROR + INTERNAL_ERROR); } else { - MSGM_syslog(LOG_ERR, "CtdlSaveMessage() unable to serialize message"); + syslog(LOG_ERR, "msgbase: CtdlSaveMessage() unable to serialize message"); } return (-1L); } /* 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) { - MSG_syslog(LOG_ERR, "Can't store message %ld: %ld", msgid, retval); + syslog(LOG_ERR, "msgbase: can't store message %ld: %ld", msgid, retval); } else { if (is_bigmsg) { @@ -2568,8 +2522,7 @@ long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { (holdMLen + 1) ); if (retval < 0) { - MSG_syslog(LOG_ERR, "failed to store message body for msgid %ld: %ld", - msgid, retval); + syslog(LOG_ERR, "msgbase: failed to store message body for msgid %ld: %ld", msgid, retval); } } } @@ -2580,6 +2533,7 @@ long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { return(retval); } + long send_message(struct CtdlMessage *msg) { long newmsgid; long retval; @@ -2613,7 +2567,6 @@ long send_message(struct CtdlMessage *msg) { } - /* * Serialize a struct CtdlMessage into the format used on disk and network. * @@ -2624,7 +2577,6 @@ long send_message(struct CtdlMessage *msg) { void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ struct CtdlMessage *msg) /* unserialized msg */ { - struct CitContext *CCC = CC; size_t wlen; int i; @@ -2632,7 +2584,7 @@ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ * Check for valid message format */ if (CM_IsValidMsg(msg) == 0) { - MSGM_syslog(LOG_ERR, "CtdlSerializeMessage() aborting due to invalid message\n"); + syslog(LOG_ERR, "msgbase: CtdlSerializeMessage() aborting due to invalid message"); ret->len = 0; ret->ser = NULL; return; @@ -2645,8 +2597,7 @@ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ ret->ser = malloc(ret->len); if (ret->ser == NULL) { - MSG_syslog(LOG_ERR, "CtdlSerializeMessage() malloc(%ld) failed: %s\n", - (long)ret->len, strerror(errno)); + syslog(LOG_ERR, "msgbase: CtdlSerializeMessage() malloc(%ld) failed: %m", (long)ret->len); ret->len = 0; ret->ser = NULL; return; @@ -2657,9 +2608,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], @@ -2668,10 +2618,10 @@ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ wlen = wlen + msg->cm_lengths[FieldOrder[i]] + 1; } + } if (ret->len != wlen) { - MSG_syslog(LOG_ERR, "ERROR: len=%ld wlen=%ld\n", - (long)ret->len, (long)wlen); + syslog(LOG_ERR, "msgbase: ERROR; len=%ld wlen=%ld", (long)ret->len, (long)wlen); } return; @@ -2683,39 +2633,34 @@ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ * carry the same Exclusive ID as this one. If any are found, delete them. */ void ReplicationChecks(struct CtdlMessage *msg) { - struct CitContext *CCC = CC; long old_msgnum = (-1L); - if (DoesThisRoomNeedEuidIndexing(&CCC->room) == 0) return; + if (DoesThisRoomNeedEuidIndexing(&CC->room) == 0) return; - MSG_syslog(LOG_DEBUG, "Performing replication checks in <%s>\n", - CCC->room.QRname); + syslog(LOG_DEBUG, "msgbase: performing replication checks in <%s>", CC->room.QRname); /* No exclusive id? Don't do anything. */ if (msg == NULL) return; if (CM_IsEmpty(msg, eExclusiveID)) return; - /*MSG_syslog(LOG_DEBUG, "Exclusive ID: <%s> for room <%s>\n", - msg->cm_fields[eExclusiveID], CCC->room.QRname);*/ + /*syslog(LOG_DEBUG, "msgbase: exclusive ID: <%s> for room <%s>", + msg->cm_fields[eExclusiveID], CC->room.QRname);*/ - old_msgnum = CtdlLocateMessageByEuid(msg->cm_fields[eExclusiveID], &CCC->room); + old_msgnum = CtdlLocateMessageByEuid(msg->cm_fields[eExclusiveID], &CC->room); if (old_msgnum > 0L) { - MSG_syslog(LOG_DEBUG, "ReplicationChecks() replacing message %ld\n", old_msgnum); - CtdlDeleteMessages(CCC->room.QRname, &old_msgnum, 1, ""); + syslog(LOG_DEBUG, "msgbase: ReplicationChecks() replacing message %ld", old_msgnum); + CtdlDeleteMessages(CC->room.QRname, &old_msgnum, 1, ""); } } - /* * 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? */ - ) -{ + const char *force /* force a particular room? */ +) { char hold_rm[ROOMNAMELEN]; char actual_rm[ROOMNAMELEN]; char force_room[ROOMNAMELEN]; @@ -2732,9 +2677,8 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ struct addresses_to_be_filed *aptr = NULL; StrBuf *saved_rfc822_version = NULL; int qualified_for_journaling = 0; - CitContext *CCC = MyContext(); - MSGM_syslog(LOG_DEBUG, "CtdlSubmitMsg() called\n"); + syslog(LOG_DEBUG, "msgbase: CtdlSubmitMsg() called"); if (CM_IsValidMsg(msg) == 0) return(-1); /* self check */ /* If this message has no timestamp, we take the liberty of @@ -2769,7 +2713,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ /* Learn about what's inside, because it's what's inside that counts */ if (CM_IsEmpty(msg, eMesageText)) { - MSGM_syslog(LOG_ERR, "ERROR: attempt to save message with NULL body\n"); + syslog(LOG_ERR, "msgbase: ERROR; attempt to save message with NULL body"); return(-2); } @@ -2801,20 +2745,20 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } /* Goto the correct room */ - room = (recps) ? CCC->room.QRname : SENTITEMS; - MSG_syslog(LOG_DEBUG, "Selected room %s\n", room); - strcpy(hold_rm, CCC->room.QRname); - strcpy(actual_rm, CCC->room.QRname); + room = (recps) ? CC->room.QRname : SENTITEMS; + syslog(LOG_DEBUG, "msgbase: selected room %s", room); + strcpy(hold_rm, CC->room.QRname); + strcpy(actual_rm, CC->room.QRname); if (recps != NULL) { strcpy(actual_rm, SENTITEMS); } /* If the user is a twit, move to the twit room for posting */ if (TWITDETECT) { - if (CCC->user.axlevel == AxProbU) { + if (CC->user.axlevel == AxProbU) { strcpy(hold_rm, actual_rm); strcpy(actual_rm, CtdlGetConfigStr("c_twitroom")); - MSGM_syslog(LOG_DEBUG, "Diverting to twit room\n"); + syslog(LOG_DEBUG, "msgbase: diverting to twit room"); } } @@ -2823,33 +2767,33 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ strcpy(actual_rm, force_room); } - MSG_syslog(LOG_INFO, "Final selection: %s (%s)\n", actual_rm, room); - if (strcasecmp(actual_rm, CCC->room.QRname)) { - /* CtdlGetRoom(&CCC->room, actual_rm); */ + syslog(LOG_DEBUG, "msgbase: final selection: %s (%s)", actual_rm, room); + if (strcasecmp(actual_rm, CC->room.QRname)) { + /* CtdlGetRoom(&CC->room, actual_rm); */ CtdlUserGoto(actual_rm, 0, 1, NULL, NULL, NULL, NULL); } /* * If this message has no O (room) field, generate one. */ - if (CM_IsEmpty(msg, eOriginalRoom)) { - CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); + if (CM_IsEmpty(msg, eOriginalRoom) && !IsEmptyStr(CC->room.QRname)) { + CM_SetField(msg, eOriginalRoom, CC->room.QRname, -1); } /* Perform "before save" hooks (aborting if any return nonzero) */ - MSGM_syslog(LOG_DEBUG, "Performing before-save hooks\n"); + 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 (DoesThisRoomNeedEuidIndexing(&CCC->room)) { + if (DoesThisRoomNeedEuidIndexing(&CC->room)) { ReplicationChecks(msg); } /* Save it to disk */ - MSGM_syslog(LOG_DEBUG, "Saving to disk\n"); + syslog(LOG_DEBUG, "msgbase: saving to disk"); newmsgid = send_message(msg); if (newmsgid <= 0L) return(-5); @@ -2857,12 +2801,11 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ * be a critical section because nobody else knows about this message * yet. */ - MSGM_syslog(LOG_DEBUG, "Creating MetaData record\n"); + 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); + safestrncpy(smi.meta_content_type, content_type, sizeof smi.meta_content_type); /* * Measure how big this message will be when rendered as RFC822. @@ -2874,28 +2817,28 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ * 2. If journaling is enabled, we will need an RFC822 version of the * message to attach to the journalized copy. */ - if (CCC->redirect_buffer != NULL) { - MSGM_syslog(LOG_ALERT, "CCC->redirect_buffer is not NULL during message submission!\n"); + if (CC->redirect_buffer != NULL) { + syslog(LOG_ALERT, "msgbase: CC->redirect_buffer is not NULL during message submission!"); abort(); } - CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ); + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, QP_EADDR); - smi.meta_rfc822_length = StrLength(CCC->redirect_buffer); - saved_rfc822_version = CCC->redirect_buffer; - CCC->redirect_buffer = NULL; + smi.meta_rfc822_length = StrLength(CC->redirect_buffer); + saved_rfc822_version = CC->redirect_buffer; + CC->redirect_buffer = NULL; PutMetaData(&smi); /* Now figure out where to store the pointers */ - MSGM_syslog(LOG_DEBUG, "Storing pointers\n"); + 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 ((!CCC->internal_pgm) || (recps == NULL)) { + if ((!CC->internal_pgm) || (recps == NULL)) { if (CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 1, msg) != 0) { - MSGM_syslog(LOG_ERR, "ERROR saving message pointer!\n"); + syslog(LOG_ERR, "msgbase: ERROR saving message pointer!"); CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } @@ -2906,50 +2849,46 @@ 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); - MSG_syslog(LOG_DEBUG, "Delivering to room <%s>\n", recipient);///// xxxx + 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. */ - MSGM_syslog(LOG_DEBUG, "Updating user\n"); + syslog(LOG_DEBUG, "msgbase: updating user"); CtdlLockGetCurrentUser(); - CCC->user.posted = CCC->user.posted + 1; + CC->user.posted = CC->user.posted + 1; CtdlPutCurrentUserLock(); /* Decide where bounces need to be delivered */ - if ((recps != NULL) && (recps->bounce_to == NULL)) - { - if (CCC->logged_in) - snprintf(bounce_to, sizeof bounce_to, "%s@%s", - CCC->user.fullname, CtdlGetConfigStr("c_nodename")); - else - snprintf(bounce_to, sizeof bounce_to, "%s@%s", - msg->cm_fields[eAuthor], msg->cm_fields[eNodeName]); + if ((recps != NULL) && (recps->bounce_to == NULL)) { + if (CC->logged_in) { + strcpy(bounce_to, CC->user.fullname); + } + 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\n", recipient); + syslog(LOG_DEBUG, "msgbase: delivering private local mail to <%s>", recipient); if (CtdlGetUser(&userbuf, recipient) == 0) { CtdlMailboxName(actual_rm, sizeof actual_rm, &userbuf, MAILROOM); CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 0, msg); @@ -2957,7 +2896,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ PerformMessageHooks(msg, recps, EVT_AFTERUSRMBOXSAVE); } else { - MSG_syslog(LOG_DEBUG, "No user <%s>\n", recipient); + syslog(LOG_DEBUG, "msgbase: no user <%s>", recipient); CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } @@ -2965,28 +2904,27 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } /* Perform "after save" hooks */ - MSGM_syslog(LOG_DEBUG, "Performing after-save hooks\n"); + 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 */ - MSG_syslog(LOG_DEBUG, "Returning to original room %s\n", hold_rm); - if (strcasecmp(hold_rm, CCC->room.QRname)) + 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? */ - if ( (CCC->logged_in) && (recps != NULL) ) { + if ( (CC->logged_in) && (recps != NULL) ) { collected_addresses = harvest_collected_addresses(msg); } if (collected_addresses != NULL) { - aptr = (struct addresses_to_be_filed *) - malloc(sizeof(struct addresses_to_be_filed)); - CtdlMailboxName(actual_rm, sizeof actual_rm, - &CCC->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); @@ -3038,7 +2976,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ /* * Convenience function for generating small administrative messages. */ -void quickie_message(const char *from, +long quickie_message(const char *from, const char *fromaddr, const char *to, char *room, @@ -3055,12 +2993,12 @@ void quickie_message(const char *from, msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = format_type; - if (from != NULL) { - CM_SetField(msg, eAuthor, from, strlen(from)); + if (!IsEmptyStr(from)) { + CM_SetField(msg, eAuthor, from, -1); } - else if (fromaddr != NULL) { + 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]); @@ -3070,92 +3008,23 @@ void quickie_message(const char *from, msg->cm_fields[eAuthor] = strdup("Citadel"); } - if (fromaddr != NULL) CM_SetField(msg, erFc822Addr, fromaddr, strlen(fromaddr)); - if (room != NULL) CM_SetField(msg, eOriginalRoom, room, strlen(room)); - CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); - if (to != NULL) { - CM_SetField(msg, eRecipient, to, strlen(to)); + 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, -1); recp = validate_recipients(to, NULL, 0); } - if (subject != NULL) { - CM_SetField(msg, eMsgSubject, subject, strlen(subject)); + if (!IsEmptyStr(subject)) { + CM_SetField(msg, eMsgSubject, subject, -1); + } + if (!IsEmptyStr(text)) { + CM_SetField(msg, eMesageText, text, -1); } - CM_SetField(msg, eMesageText, text, strlen(text)); - CtdlSubmitMsg(msg, recp, room, 0); + long msgnum = CtdlSubmitMsg(msg, recp, room); CM_Free(msg); if (recp != NULL) free_recipients(recp); -} - -void flood_protect_quickie_message(const char *from, - const char *fromaddr, - const char *to, - char *room, - const char *text, - int format_type, - const char *subject, - int nCriterions, - const char **CritStr, - const long *CritStrLen, - long ccid, - long ioid, - time_t NOW) -{ - int i; - u_char rawdigest[MD5_DIGEST_LEN]; - struct MD5Context md5context; - StrBuf *guid; - char timestamp[64]; - long tslen; - static const time_t tsday = (8*60*60); /* just care for a day... */ - time_t seenstamp; - - tslen = snprintf(timestamp, sizeof(timestamp), "%ld", tsday); - MD5Init(&md5context); - - for (i = 0; i < nCriterions; i++) - MD5Update(&md5context, - (const unsigned char*)CritStr[i], CritStrLen[i]); - MD5Update(&md5context, - (const unsigned char*)timestamp, tslen); - MD5Final(rawdigest, &md5context); - - guid = NewStrBufPlain(NULL, - MD5_DIGEST_LEN * 2 + 12); - StrBufHexEscAppend(guid, NULL, rawdigest, MD5_DIGEST_LEN); - StrBufAppendBufPlain(guid, HKEY("_fldpt"), 0); - if (StrLength(guid) > 40) - StrBufCutAt(guid, 40, NULL); - - seenstamp = CheckIfAlreadySeen("FPAideMessage", - guid, - NOW, - tsday, - eUpdate, - ccid, - ioid); - if ((seenstamp > 0) && (seenstamp < tsday)) - { - FreeStrBuf(&guid); - /* yes, we did. flood protection kicks in. */ - syslog(LOG_DEBUG, - "not sending message again - %ld < %ld \n", seenstamp, tsday); - return; - } - else - { - syslog(LOG_DEBUG, - "sending message. %ld >= %ld", seenstamp, tsday); - FreeStrBuf(&guid); - /* no, this message isn't sent recently; go ahead. */ - quickie_message(from, - fromaddr, - to, - room, - text, - format_type, - subject); - } + return msgnum; } @@ -3167,10 +3036,8 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ size_t maxlen, /* maximum message length */ StrBuf *exist, /* if non-null, append to it; exist is ALWAYS freed */ - int crlf, /* CRLF newlines instead of LF */ - int *sock /* socket handle or 0 for this session's client socket */ - ) -{ + int crlf /* CRLF newlines instead of LF */ +) { StrBuf *Message; StrBuf *LineBuf; int flushing = 0; @@ -3192,18 +3059,12 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ /* read in the lines of message text one by one */ do { - if (sock != NULL) { - if ((CtdlSockGetLine(sock, LineBuf, 5) < 0) || - (*sock == -1)) - finished = 1; - } - else { - if (CtdlClientGetLine(LineBuf) < 0) finished = 1; + if (CtdlClientGetLine(LineBuf) < 0) { + finished = 1; } - if ((StrLength(LineBuf) == tlen) && - (!strcmp(ChrPtr(LineBuf), terminator))) + if ((StrLength(LineBuf) == tlen) && (!strcmp(ChrPtr(LineBuf), terminator))) { finished = 1; - + } if ( (!flushing) && (!finished) ) { if (crlf) { StrBufAppendBufPlain(LineBuf, HKEY("\r\n"), 0); @@ -3213,13 +3074,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); } @@ -3231,174 +3088,6 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ return Message; } -void DeleteAsyncMsg(ReadAsyncMsg **Msg) -{ - if (*Msg == NULL) - return; - FreeStrBuf(&(*Msg)->MsgBuf); - - free(*Msg); - *Msg = NULL; -} - -ReadAsyncMsg *NewAsyncMsg(const char *terminator, /* token signalling EOT */ - long tlen, - size_t maxlen, /* maximum message length */ - size_t expectlen, /* if we expect a message, how long should it be? */ - StrBuf *exist, /* if non-null, append to it; - exist is ALWAYS freed */ - long eLen, /* length of exist */ - int crlf /* CRLF newlines instead of LF */ - ) -{ - ReadAsyncMsg *NewMsg; - - NewMsg = (ReadAsyncMsg *)malloc(sizeof(ReadAsyncMsg)); - memset(NewMsg, 0, sizeof(ReadAsyncMsg)); - - if (exist == NULL) { - long len; - - if (expectlen == 0) { - len = 4 * SIZ; - } - else { - len = expectlen + 10; - } - NewMsg->MsgBuf = NewStrBufPlain(NULL, len); - } - else { - NewMsg->MsgBuf = NewStrBufDup(exist); - } - /* Do we need to change leading ".." to "." for SMTP escaping? */ - if ((tlen == 1) && (*terminator == '.')) { - NewMsg->dodot = 1; - } - - NewMsg->terminator = terminator; - NewMsg->tlen = tlen; - - NewMsg->maxlen = maxlen; - - NewMsg->crlf = crlf; - - return NewMsg; -} - -/* - * Back end function used by CtdlMakeMessage() and similar functions - */ -eReadState CtdlReadMessageBodyAsync(AsyncIO *IO) -{ - ReadAsyncMsg *ReadMsg; - int MsgFinished = 0; - eReadState Finished = eMustReadMore; - -#ifdef BIGBAD_IODBG - char fn [SIZ]; - FILE *fd; - const char *pch = ChrPtr(IO->SendBuf.Buf); - const char *pchh = IO->SendBuf.ReadWritePointer; - long nbytes; - - if (pchh == NULL) - pchh = pch; - - nbytes = StrLength(IO->SendBuf.Buf) - (pchh - pch); - snprintf(fn, SIZ, "/tmp/foolog_ev_%s.%d", - ((CitContext*)(IO->CitContext))->ServiceName, - IO->SendBuf.fd); - - fd = fopen(fn, "a+"); - if (fd == NULL) { - syslog(LOG_EMERG, "failed to open file %s: %s", fn, strerror(errno)); - cit_backtrace(); - exit(1); - } -#endif - - ReadMsg = IO->ReadMsg; - - /* read in the lines of message text one by one */ - do { - Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf); - - switch (Finished) { - case eMustReadMore: /// read new from socket... -#ifdef BIGBAD_IODBG - if (IO->RecvBuf.ReadWritePointer != NULL) { - nbytes = StrLength(IO->RecvBuf.Buf) - (IO->RecvBuf.ReadWritePointer - ChrPtr(IO->RecvBuf.Buf)); - fprintf(fd, "Read; Line unfinished: %ld Bytes still in buffer [", nbytes); - - fwrite(IO->RecvBuf.ReadWritePointer, nbytes, 1, fd); - - fprintf(fd, "]\n"); - } else { - fprintf(fd, "BufferEmpty! \n"); - } - fclose(fd); -#endif - return Finished; - break; - case eBufferNotEmpty: /* shouldn't happen... */ - case eReadSuccess: /// done for now... - break; - case eReadFail: /// WHUT? - ///todo: shut down! - break; - } - - - if ((StrLength(IO->IOBuf) == ReadMsg->tlen) && - (!strcmp(ChrPtr(IO->IOBuf), ReadMsg->terminator))) { - MsgFinished = 1; -#ifdef BIGBAD_IODBG - fprintf(fd, "found Terminator; Message Size: %d\n", StrLength(ReadMsg->MsgBuf)); -#endif - } - else if (!ReadMsg->flushing) { - -#ifdef BIGBAD_IODBG - fprintf(fd, "Read Line: [%d][%s]\n", StrLength(IO->IOBuf), ChrPtr(IO->IOBuf)); -#endif - - /* Unescape SMTP-style input of two dots at the beginning of the line */ - if ((ReadMsg->dodot) && - (StrLength(IO->IOBuf) == 2) && /* TODO: do we just unescape lines with two dots or any line? */ - (!strcmp(ChrPtr(IO->IOBuf), ".."))) - { -#ifdef BIGBAD_IODBG - fprintf(fd, "UnEscaped!\n"); -#endif - StrBufCutLeft(IO->IOBuf, 1); - } - - if (ReadMsg->crlf) { - StrBufAppendBufPlain(IO->IOBuf, HKEY("\r\n"), 0); - } - else { - StrBufAppendBufPlain(IO->IOBuf, HKEY("\n"), 0); - } - - StrBufAppendBuf(ReadMsg->MsgBuf, IO->IOBuf, 0); - } - - /* if we've hit the max msg length, flush the rest */ - if (StrLength(ReadMsg->MsgBuf) >= ReadMsg->maxlen) ReadMsg->flushing = 1; - - } while (!MsgFinished); - -#ifdef BIGBAD_IODBG - fprintf(fd, "Done with reading; %s.\n, ", - (MsgFinished)?"Message Finished": "FAILED"); - fclose(fd); -#endif - if (MsgFinished) - return eReadSuccess; - else - return eReadFail; -} - /* * Back end function used by CtdlMakeMessage() and similar functions @@ -3408,8 +3097,7 @@ char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */ size_t maxlen, /* maximum message length */ StrBuf *exist, /* if non-null, append to it; exist is ALWAYS freed */ - int crlf, /* CRLF newlines instead of LF */ - int *sock /* socket handle or 0 for this session's client socket */ + int crlf /* CRLF newlines instead of LF */ ) { StrBuf *Message; @@ -3418,14 +3106,15 @@ char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */ tlen, maxlen, exist, - crlf, - sock); + crlf + ); if (Message == NULL) return NULL; else return SmashStrBuf(&Message); } + struct CtdlMessage *CtdlMakeMessage( struct ctdluser *author, /* author's user structure */ char *recipient, /* NULL if it's not mail */ @@ -3439,8 +3128,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 */ @@ -3466,6 +3154,7 @@ struct CtdlMessage *CtdlMakeMessage( } + /* * Build a binary message to be saved on disk. * (NOTE: if you supply 'preformatted_text', the buffer you give it @@ -3473,7 +3162,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 */ @@ -3496,11 +3184,7 @@ struct CtdlMessage *CtdlMakeMessageLen( long textlen, char *references, /* Thread references */ long reflen - ) -{ - struct CitContext *CCC = CC; - /* Don't confuse the poor folks if it's not routed mail. * / - char dest_node[256] = "";*/ +) { long blen; char buf[1024]; struct CtdlMessage *msg; @@ -3520,8 +3204,8 @@ struct CtdlMessage *CtdlMakeMessageLen( if (myelen > 0) { CM_SetField(msg, eMessagePath, my_email, myelen); } - else { - CM_SetField(msg, eMessagePath, author->fullname, strlen(author->fullname)); + else if (!IsEmptyStr(author->fullname)) { + CM_SetField(msg, eMessagePath, author->fullname, -1); } convert_spaces_to_underscores(msg->cm_fields[eMessagePath]); @@ -3538,16 +3222,15 @@ struct CtdlMessage *CtdlMakeMessageLen( CM_SetAsFieldSB(msg, eAuthor, &FakeEncAuthor); FreeStrBuf(&FakeAuthor); - if (CCC->room.QRflags & QR_MAILBOX) { /* room */ - CM_SetField(msg, eOriginalRoom, &CCC->room.QRname[11], strlen(&CCC->room.QRname[11])); - } - else { - CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); + if (!!IsEmptyStr(CC->room.QRname)) { + if (CC->room.QRflags & QR_MAILBOX) { /* room */ + CM_SetField(msg, eOriginalRoom, &CC->room.QRname[11], -1); + } + else { + 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); } @@ -3558,8 +3241,8 @@ struct CtdlMessage *CtdlMakeMessageLen( if (myelen > 0) { CM_SetField(msg, erFc822Addr, my_email, myelen); } - else if ( (author == &CCC->user) && (!IsEmptyStr(CCC->cs_inet_email)) ) { - CM_SetField(msg, erFc822Addr, CCC->cs_inet_email, strlen(CCC->cs_inet_email)); + else if ( (author == &CC->user) && (!IsEmptyStr(CC->cs_inet_email)) ) { + CM_SetField(msg, erFc822Addr, CC->cs_inet_email, -1); } if (subject != NULL) { @@ -3598,7 +3281,7 @@ struct CtdlMessage *CtdlMakeMessageLen( } else { StrBuf *MsgBody; - MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0); + MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0); if (MsgBody != NULL) { CM_SetAsFieldSB(msg, eMesageText, &MsgBody); } @@ -3608,19 +3291,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. */ - ) -{ - struct CitContext *CCC = CC; +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; @@ -3638,15 +3317,13 @@ int CtdlDeleteMessages(const char *room_name, /* which room */ regcomp(&re, content_type, 0); need_to_free_re = 1; } - MSG_syslog(LOG_DEBUG, " CtdlDeleteMessages(%s, %d msgs, %s)\n", - room_name, num_dmsgnums, content_type); + syslog(LOG_DEBUG, "msgbase: CtdlDeleteMessages(%s, %d msgs, %s)", room_name, num_dmsgnums, content_type); /* get room record, obtaining a lock... */ if (CtdlGetRoomLock(&qrbuf, room_name) != 0) { - MSG_syslog(LOG_ERR, " CtdlDeleteMessages(): Room <%s> not found\n", - room_name); + 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 */ } cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf.QRnumber, sizeof(long)); @@ -3670,7 +3347,7 @@ int CtdlDeleteMessages(const char *room_name, /* which room */ StrBuf *dbg = NewStrBuf(); for (i = 0; i < num_dmsgnums; i++) StrBufAppendPrintf(dbg, ", %ld", dmsgnums[i]); - MSG_syslog(LOG_DEBUG, " Deleting before: %s", ChrPtr(dbg)); + syslog(LOG_DEBUG, "msgbase: Deleting before: %s", ChrPtr(dbg)); FreeStrBuf(&dbg); } */ @@ -3720,7 +3397,7 @@ int CtdlDeleteMessages(const char *room_name, /* which room */ StrBuf *dbg = NewStrBuf(); for (i = 0; i < num_deleted; i++) StrBufAppendPrintf(dbg, ", %ld", dellist[i]); - MSG_syslog(LOG_DEBUG, " Deleting: %s", ChrPtr(dbg)); + syslog(LOG_DEBUG, "msgbase: Deleting: %s", ChrPtr(dbg)); FreeStrBuf(&dbg); } */ @@ -3752,20 +3429,17 @@ int CtdlDeleteMessages(const char *room_name, /* which room */ /* Now free the memory we used, and go away. */ if (msglist != NULL) free(msglist); if (dellist != NULL) free(dellist); - MSG_syslog(LOG_DEBUG, " %d message(s) deleted.\n", num_deleted); + syslog(LOG_DEBUG, "msgbase: %d message(s) deleted", num_deleted); if (need_to_free_re) regfree(&re); return (num_deleted); } - - /* * GetMetaData() - Get the supplementary record for a message */ void GetMetaData(struct MetaData *smibuf, long msgnum) { - struct cdbdata *cdbsmi; long TheIndex; @@ -3778,11 +3452,12 @@ void GetMetaData(struct MetaData *smibuf, long msgnum) cdbsmi = cdb_fetch(CDB_MSGMAIN, &TheIndex, sizeof(long)); if (cdbsmi == NULL) { - return; /* record not found; go with defaults */ + return; /* record not found; leave it alone */ } memcpy(smibuf, cdbsmi->ptr, ((cdbsmi->len > sizeof(struct MetaData)) ? - sizeof(struct MetaData) : cdbsmi->len)); + sizeof(struct MetaData) : cdbsmi->len) + ); cdb_free(cdbsmi); return; } @@ -3800,184 +3475,29 @@ void PutMetaData(struct MetaData *smibuf) cdb_store(CDB_MSGMAIN, &TheIndex, (int)sizeof(long), - smibuf, (int)sizeof(struct MetaData)); - + smibuf, (int)sizeof(struct MetaData) + ); } + /* - * AdjRefCount - submit an adjustment to the reference count for a message. - * (These are just queued -- we actually process them later.) + * Convenience function to process a big block of AdjRefCount() operations */ -void AdjRefCount(long msgnum, int incr) -{ - struct CitContext *CCC = CC; - struct arcq new_arcq; - int rv = 0; - - MSG_syslog(LOG_DEBUG, "AdjRefCount() msg %ld ref count delta %+d\n", msgnum, incr); - - begin_critical_section(S_SUPPMSGMAIN); - if (arcfp == NULL) { - arcfp = fopen(file_arcq, "ab+"); - chown(file_arcq, CTDLUID, (-1)); - chmod(file_arcq, 0600); - } - end_critical_section(S_SUPPMSGMAIN); - - /* msgnum < 0 means that we're trying to close the file */ - if (msgnum < 0) { - MSGM_syslog(LOG_DEBUG, "Closing the AdjRefCount queue file\n"); - begin_critical_section(S_SUPPMSGMAIN); - if (arcfp != NULL) { - fclose(arcfp); - arcfp = NULL; - } - end_critical_section(S_SUPPMSGMAIN); - return; - } - - /* - * If we can't open the queue, perform the operation synchronously. - */ - if (arcfp == NULL) { - TDAP_AdjRefCount(msgnum, incr); - return; - } - - new_arcq.arcq_msgnum = msgnum; - new_arcq.arcq_delta = incr; - rv = fwrite(&new_arcq, sizeof(struct arcq), 1, arcfp); - if (rv == -1) { - MSG_syslog(LOG_EMERG, "Couldn't write Refcount Queue File %s: %s\n", - file_arcq, - strerror(errno)); - } - fflush(arcfp); - - return; -} - void AdjRefCountList(long *msgnum, long nmsg, int incr) { - struct CitContext *CCC = CC; - long i, the_size, offset; - struct arcq *new_arcq; - int rv = 0; - - MSG_syslog(LOG_DEBUG, "AdjRefCountList() msg %ld ref count delta %+d\n", nmsg, incr); - - begin_critical_section(S_SUPPMSGMAIN); - if (arcfp == NULL) { - arcfp = fopen(file_arcq, "ab+"); - chown(file_arcq, CTDLUID, (-1)); - chmod(file_arcq, 0600); - } - end_critical_section(S_SUPPMSGMAIN); + long i; - /* - * If we can't open the queue, perform the operation synchronously. - */ - if (arcfp == NULL) { - for (i = 0; i < nmsg; i++) - TDAP_AdjRefCount(msgnum[i], incr); - return; - } - - the_size = sizeof(struct arcq) * nmsg; - new_arcq = malloc(the_size); for (i = 0; i < nmsg; i++) { - new_arcq[i].arcq_msgnum = msgnum[i]; - new_arcq[i].arcq_delta = incr; - } - rv = 0; - offset = 0; - while ((rv >= 0) && (offset < the_size)) - { - rv = fwrite(new_arcq + offset, 1, the_size - offset, arcfp); - if (rv == -1) { - MSG_syslog(LOG_EMERG, "Couldn't write Refcount Queue File %s: %s\n", - file_arcq, - strerror(errno)); - } - else { - offset += rv; - } + AdjRefCount(msgnum[i], incr); } - free(new_arcq); - fflush(arcfp); - - return; } /* - * TDAP_ProcessAdjRefCountQueue() - * - * Process the queue of message count adjustments that was created by calls - * to AdjRefCount() ... by reading the queue and calling TDAP_AdjRefCount() - * for each one. This should be an "off hours" operation. + * AdjRefCount - adjust the reference count for a message. We need to delete from disk any message whose reference count reaches zero. */ -int TDAP_ProcessAdjRefCountQueue(void) -{ - struct CitContext *CCC = CC; - char file_arcq_temp[PATH_MAX]; - int r; - FILE *fp; - struct arcq arcq_rec; - int num_records_processed = 0; - - snprintf(file_arcq_temp, sizeof file_arcq_temp, "%s.%04x", file_arcq, rand()); - - begin_critical_section(S_SUPPMSGMAIN); - if (arcfp != NULL) { - fclose(arcfp); - arcfp = NULL; - } - - r = link(file_arcq, file_arcq_temp); - if (r != 0) { - MSG_syslog(LOG_CRIT, "%s: %s\n", file_arcq_temp, strerror(errno)); - end_critical_section(S_SUPPMSGMAIN); - return(num_records_processed); - } - - unlink(file_arcq); - end_critical_section(S_SUPPMSGMAIN); - - fp = fopen(file_arcq_temp, "rb"); - if (fp == NULL) { - MSG_syslog(LOG_CRIT, "%s: %s\n", file_arcq_temp, strerror(errno)); - return(num_records_processed); - } - - while (fread(&arcq_rec, sizeof(struct arcq), 1, fp) == 1) { - TDAP_AdjRefCount(arcq_rec.arcq_msgnum, arcq_rec.arcq_delta); - ++num_records_processed; - } - - fclose(fp); - r = unlink(file_arcq_temp); - if (r != 0) { - MSG_syslog(LOG_CRIT, "%s: %s\n", file_arcq_temp, strerror(errno)); - } - - return(num_records_processed); -} - - - -/* - * TDAP_AdjRefCount - adjust the reference count for a message. - * This one does it "for real" because it's called by - * the autopurger function that processes the queue - * created by AdjRefCount(). If a message's reference - * count becomes zero, we also delete the message from - * disk and de-index it. - */ -void TDAP_AdjRefCount(long msgnum, int incr) +void AdjRefCount(long msgnum, int incr) { - struct CitContext *CCC = CC; - struct MetaData smi; long delnum; @@ -3990,15 +3510,12 @@ void TDAP_AdjRefCount(long msgnum, int incr) smi.meta_refcount += incr; PutMetaData(&smi); end_critical_section(S_SUPPMSGMAIN); - MSG_syslog(LOG_DEBUG, "TDAP_AdjRefCount() msg %ld ref count delta %+d, is now %d\n", - msgnum, incr, smi.meta_refcount - ); + syslog(LOG_DEBUG, "msgbase: AdjRefCount() msg %ld ref count delta %+d, is now %d", msgnum, incr, smi.meta_refcount); - /* If the reference count is now zero, delete the message - * (and its supplementary record as well). + /* If the reference count is now zero, delete both the message and its metadata record. */ if (smi.meta_refcount == 0) { - MSG_syslog(LOG_DEBUG, "Deleting message <%ld>\n", msgnum); + syslog(LOG_DEBUG, "msgbase: deleting message <%ld>", msgnum); /* Call delete hooks with NULL room to show it has gone altogether */ PerformDeleteHooks(NULL, msgnum); @@ -4012,9 +3529,9 @@ void TDAP_AdjRefCount(long msgnum, int incr) delnum = (0L - msgnum); cdb_delete(CDB_MSGMAIN, &delnum, (int)sizeof(long)); } - } + /* * Write a generic object to this room * @@ -4023,15 +3540,13 @@ void TDAP_AdjRefCount(long msgnum, int incr) */ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ char *content_type, /* MIME type of this object */ - char *raw_message, /* Data to be written */ - off_t raw_length, /* Size of raw_message */ + char *raw_message, /* Data to be written */ + off_t raw_length, /* Size of raw_message */ struct ctdluser *is_mailbox, /* Mailbox room? */ int is_binary, /* Is encoding necessary? */ int is_unique, /* Del others of this type? */ - unsigned int flags /* Internal save flags */ - ) -{ - struct CitContext *CCC = CC; + unsigned int flags /* Internal save flags */ +) { struct ctdlroom qrbuf; char roomname[ROOMNAMELEN]; struct CtdlMessage *msg; @@ -4044,7 +3559,7 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ safestrncpy(roomname, req_room, sizeof(roomname)); } - MSG_syslog(LOG_DEBUG, "Raw length is %ld\n", (long)raw_length); + syslog(LOG_DEBUG, "msfbase: raw length is %ld", (long)raw_length); if (is_binary) { encoded_message = NewStrBufPlain(NULL, (size_t) (((raw_length * 134) / 100) + 4096 ) ); @@ -4071,54 +3586,46 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ StrBufAppendBufPlain(encoded_message, raw_message, raw_length, 0); } - MSGM_syslog(LOG_DEBUG, "Allocating\n"); + syslog(LOG_DEBUG, "msgbase: allocating"); 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; - CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->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); /* 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); + CtdlCreateRoom(roomname, ( (is_mailbox != NULL) ? 5 : 3 ), "", 0, 1, 0, VIEW_BBS); } /* If the caller specified this object as unique, delete all * other objects of this type that are currently in the room. */ if (is_unique) { - MSG_syslog(LOG_DEBUG, "Deleted %d other msgs of this type\n", + syslog(LOG_DEBUG, "msgbase: deleted %d other msgs of this type", CtdlDeleteMessages(roomname, NULL, 0, content_type) ); } /* Now write the data */ - CtdlSubmitMsg(msg, NULL, roomname, 0); + CtdlSubmitMsg(msg, NULL, roomname); CM_Free(msg); } +/************************************************************************/ +/* MODULE INITIALIZATION */ +/************************************************************************/ -/*****************************************************************************/ -/* MODULE INITIALIZATION STUFF */ -/*****************************************************************************/ -void SetMessageDebugEnabled(const int n) -{ - MessageDebugEnabled = n; -} CTDL_MODULE_INIT(msgbase) { if (!threading) { - CtdlRegisterDebugFlagHook(HKEY("messages"), SetMessageDebugEnabled, &MessageDebugEnabled); + FillMsgKeyLookupTable(); } - /* return our Subversion id for the Log */ + /* return our module id for the log */ return "msgbase"; }