X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=30f9a6888b9c084a681e257656731a7b6ef4bbc0;hb=1a0e6bea859c26612782daf164e4062ef58a0cf4;hp=776680b6df7cd5dd04f16bd04979fe23cf07cff6;hpb=4e9952daf6d736348f34fa1e02f33a568d25d894;p=citadel.git diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 776680b6d..30f9a6888 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1,7 +1,7 @@ /* * Implements the message store. * - * Copyright (c) 1987-2012 by the citadel.org team + * Copyright (c) 1987-2018 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,20 +13,21 @@ */ +#include +#include #include #include +#include #include - #include "md5.h" - #include "ctdl_module.h" #include "citserver.h" #include "control.h" +#include "config.h" #include "clientsocket.h" #include "genstamp.h" #include "room_ops.h" #include "user_ops.h" - #include "internet_addressing.h" #include "euidindex.h" #include "msgbase.h" @@ -38,13 +39,11 @@ struct addresses_to_be_filed *atbf = NULL; 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). */ -char *msgkeys[] = { +char *msgkeys[91] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -54,33 +53,58 @@ 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 */ + "from", /* A -> eAuthor */ + NULL, /* B -> eBig_message */ + NULL, /* C -> eRemoteRoom */ + NULL, /* D -> eDestination */ + "exti", /* E -> eXclusivID */ + "rfca", /* F -> erFc822Addr */ NULL, /* G */ - "hnod", /* H */ - "msgn", /* I */ - "jrnl", /* J */ - "rep2", /* K */ - "list", /* L */ - "text", /* M */ - "node", /* N */ - "room", /* O */ - "path", /* P */ + "hnod", /* H -> eHumanNode */ + "msgn", /* I -> emessageId */ + "jrnl", /* J -> eJournal */ + "rep2", /* K -> eReplyTo */ + "list", /* L -> eListID */ + "text", /* M -> eMesageText */ + "node", /* N -> eNodeName */ + "room", /* O -> eOriginalRoom */ + "path", /* P -> eMessagePath */ NULL, /* Q */ - "rcpt", /* R */ - "spec", /* S */ - "time", /* T */ - "subj", /* U */ - "nvto", /* V */ - "wefw", /* W */ + "rcpt", /* R -> eRecipient */ + "spec", /* S -> eSpecialField */ + "time", /* T -> eTimestamp */ + "subj", /* U -> eMsgSubject */ + "nvto", /* V -> eenVelopeTo */ + "wefw", /* W -> eWeferences */ NULL, /* X */ - "cccc", /* Y */ - NULL /* Z */ + "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 */ @@ -268,8 +292,7 @@ int CM_IsValidMsg(struct CtdlMessage *msg) { 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; @@ -385,11 +408,10 @@ 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) safestrncpy(buf, vbuf.v_seen, SIZ); @@ -405,7 +427,6 @@ void CtdlGetSeen(char *buf, int which_set) { 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; @@ -429,15 +450,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, @@ -474,18 +495,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(); @@ -607,8 +626,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: @@ -636,7 +653,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; @@ -665,13 +681,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); @@ -679,7 +695,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. */ @@ -737,7 +753,7 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, free(msglist); return -1; } - msg = CtdlFetchMessage(msglist[a], 1); + msg = CtdlFetchMessage(msglist[a], 1, 1); if (msg != NULL) { if (CtdlMsgCmp(msg, compare)) { msglist[a] = 0L; @@ -826,7 +842,7 @@ 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 ((mode == MSGS_NEW) && (CC->user.flags & US_LASTOLD) && (lastold > 0L) && (printed_lastold == 0) && (!is_seen)) { if (CallBack) CallBack(lastold, userdata); printed_lastold = 1; @@ -841,12 +857,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); @@ -868,7 +884,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]; @@ -882,13 +897,13 @@ void memfmout( if (ch == '\n') { if (client_write(outbuf, len) == -1) { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + 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"); + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } column = 0; @@ -900,13 +915,13 @@ void memfmout( 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"); + 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"); + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } column = 0; @@ -922,13 +937,13 @@ void memfmout( 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"); + 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"); + syslog(LOG_ERR, "msgbase: memfmout(): aborting due to write failure"); return; } column = 0; @@ -938,7 +953,7 @@ void memfmout( if (len) { if (client_write(outbuf, len) == -1) { - MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n"); + syslog(LOG_ERR, "msgbase: memfmout() aborting due to write failure"); return; } client_write(nl, nllen); @@ -1019,37 +1034,32 @@ 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); } @@ -1083,33 +1093,17 @@ void mime_spew_section(char *name, char *filename, char *partnum, char *disp, } } - -/* - * Load a message from disk into memory. - * This is used by CtdlOutputMsg() and other fetch functions. - * - * NOTE: Caller is responsible for freeing the returned CtdlMessage struct - * using the CtdlMessageFree() function. - */ -struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) +struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const char *Buffer, long Length) { - struct CitContext *CCC = CC; - struct cdbdata *dmsgtext; struct CtdlMessage *ret = NULL; - char *mptr; - char *upper_bound; + const char *mptr; + const char *upper_bound; cit_uint8_t ch; cit_uint8_t field_header; eMsgField which; - MSG_syslog(LOG_DEBUG, "CtdlFetchMessage(%ld, %d)\n", 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); - return NULL; - } - mptr = dmsgtext->ptr; - upper_bound = mptr + dmsgtext->len; + mptr = Buffer; + upper_bound = Buffer + Length; /* Parse the three bytes that begin EVERY message on disk. * The first is always 0xFF, the on-disk magic number. @@ -1118,8 +1112,7 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) */ ch = *mptr++; if (ch != 255) { - MSG_syslog(LOG_ERR, "Message %ld appears to be corrupted.\n", msgnum); - cdb_free(dmsgtext); + syslog(LOG_ERR, "msgbase: message %ld appears to be corrupted", msgnum); return NULL; } ret = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); @@ -1135,21 +1128,66 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) * have just processed the 'M' (message text) field. */ do { + field_header = '\0'; long len; + + /* work around possibly buggy messages: */ + while (field_header == '\0') + { + if (mptr >= upper_bound) { + break; + } + field_header = *mptr++; + } if (mptr >= upper_bound) { break; } - field_header = *mptr++; which = field_header; len = strlen(mptr); + CM_SetField(ret, which, mptr, len); mptr += len + 1; /* advance to next field */ } while ((mptr < upper_bound) && (field_header != 'M')); + return (ret); +} + + +/* + * Load a message from disk into memory. + * This is used by CtdlOutputMsg() and other fetch functions. + * + * NOTE: Caller is responsible for freeing the returned CtdlMessage struct + * using the CM_Free(); function. + */ +struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body, int run_msg_hooks) +{ + struct cdbdata *dmsgtext; + struct CtdlMessage *ret = NULL; + + syslog(LOG_DEBUG, "msgbase: CtdlFetchMessage(%ld, %d)", msgnum, with_body); + dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long)); + if (dmsgtext == NULL) { + syslog(LOG_ERR, "msgbase: CtdlFetchMessage(%ld, %d) Failed!", msgnum, with_body); + return NULL; + } + + 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'; + } + + ret = CtdlDeserializeMessage(msgnum, with_body, dmsgtext->ptr, dmsgtext->len); + cdb_free(dmsgtext); + if (ret == NULL) { + return NULL; + } + /* Always make sure there's something in the msg text field. If * it's NULL, the message text is most likely stored separately, * so go ahead and fetch that. Failing that, just set a dummy @@ -1158,7 +1196,7 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) if ( (CM_IsEmpty(ret, eMesageText)) && (with_body) ) { dmsgtext = cdb_fetch(CDB_BIGMSGS, &msgnum, sizeof(long)); if (dmsgtext != NULL) { - CM_SetAsField(ret, eMesageText, &dmsgtext->ptr, dmsgtext->len); + CM_SetAsField(ret, eMesageText, &dmsgtext->ptr, dmsgtext->len - 1); cdb_free(dmsgtext); } } @@ -1167,7 +1205,7 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) } /* Perform "before read" hooks (aborting if any return nonzero) */ - if (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0) { + if (run_msg_hooks && (PerformMessageHooks(ret, NULL, EVT_BEFOREREAD) > 0)) { CM_Free(ret); return NULL; } @@ -1191,11 +1229,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; @@ -1212,11 +1249,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; @@ -1233,7 +1269,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; @@ -1241,16 +1276,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; @@ -1307,7 +1343,6 @@ 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; @@ -1319,11 +1354,11 @@ void choose_preferred(char *name, char *filename, char *partnum, char *disp, // 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; } @@ -1346,7 +1381,6 @@ void output_preferred(char *name, char *cbid, void *cbuserdata) { - struct CitContext *CCC = CC; int i; char buf[128]; int add_newline = 0; @@ -1364,8 +1398,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) @@ -1402,7 +1436,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"); @@ -1468,13 +1502,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 */ @@ -1483,7 +1516,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]) { @@ -1504,22 +1537,22 @@ int check_cached_msglist(long msgnum) { * */ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ - 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? */ - char *section, /* NULL or a message/rfc822 section */ - int flags, /* various flags; see msgbase.h */ - char **Author, - char **Address + 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? */ + char *section, /* NULL or a message/rfc822 section */ + int flags, /* various flags; see msgbase.h */ + char **Author, + 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 : "<>") ); @@ -1547,8 +1580,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) { @@ -1566,10 +1599,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); + TheMessage = CtdlFetchMessage(msg_num, 0, 1); } else { - TheMessage = CtdlFetchMessage(msg_num, 1); + TheMessage = CtdlFetchMessage(msg_num, 1, 1); } if (TheMessage == NULL) { @@ -1599,6 +1632,11 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ long len; CM_GetAsField(TheMessage, erFc822Addr, Address, &len); } + if ((MessageID != NULL) && (*MessageID == NULL)) + { + long len; + CM_GetAsField(TheMessage, emessageId, MessageID, &len); + } CM_Free(TheMessage); TheMessage = NULL; @@ -1638,6 +1676,11 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ long len; CM_GetAsField(TheMessage, erFc822Addr, Address, &len); } + if ((MessageID != NULL) && (*MessageID == NULL)) + { + long len; + CM_GetAsField(TheMessage, emessageId, MessageID, &len); + } CM_Free(TheMessage); @@ -1724,7 +1767,7 @@ void OutputCtdlMsgHeaders( void OutputRFC822MsgHeaders( struct CtdlMessage *TheMessage, int flags, /* should the bessage be exported clean */ - const char *nl, + const char *nl, int nlen, char *mid, long sizeof_mid, char *suser, long sizeof_suser, char *luser, long sizeof_luser, @@ -1739,28 +1782,28 @@ void OutputRFC822MsgHeaders( char *mpptr = NULL; char *hptr; - for (i = 0; i < 256; ++i) { - if (TheMessage->cm_fields[i]) { - mptr = mpptr = TheMessage->cm_fields[i]; - - if (i == eAuthor) { + for (i = 0; i < NDiskFields; ++i) { + if (TheMessage->cm_fields[FieldOrder[i]]) { + mptr = mpptr = TheMessage->cm_fields[FieldOrder[i]]; + switch (FieldOrder[i]) { + case eAuthor: safestrncpy(luser, mptr, sizeof_luser); safestrncpy(suser, mptr, sizeof_suser); - } - else if (i == 'Y') { + break; + case eCarbonCopY: if ((flags & QP_EADDR) != 0) { mptr = qp_encode_email_addrs(mptr); } sanitize_truncated_recipient(mptr); cprintf("CC: %s%s", mptr, nl); - } - else if (i == 'P') { + break; + case eMessagePath: cprintf("Return-Path: %s%s", mptr, nl); - } - else if (i == eListID) { + break; + case eListID: cprintf("List-ID: %s%s", mptr, nl); - } - else if (i == 'V') { + break; + case eenVelopeTo: if ((flags & QP_EADDR) != 0) mptr = qp_encode_email_addrs(mptr); hptr = mptr; @@ -1768,26 +1811,29 @@ void OutputRFC822MsgHeaders( hptr ++; if (!IsEmptyStr(hptr)) cprintf("Envelope-To: %s%s", hptr, nl); - } - else if (i == 'U') { + break; + case eMsgSubject: cprintf("Subject: %s%s", mptr, nl); subject_found = 1; - } - else if (i == 'I') + break; + case emessageId: safestrncpy(mid, mptr, sizeof_mid); /// TODO: detect @ here and copy @nodename in if not found. - else if (i == erFc822Addr) + break; + case erFc822Addr: safestrncpy(fuser, mptr, sizeof_fuser); - /* else if (i == 'O') + /* case eOriginalRoom: cprintf("X-Citadel-Room: %s%s", - mptr, nl); */ - else if (i == 'N') + mptr, nl) + break; + ; */ + case eNodeName: safestrncpy(snode, mptr, sizeof_snode); - else if (i == 'R') - { + break; + case eRecipient: if (haschar(mptr, '@') == 0) { sanitize_truncated_recipient(mptr); - cprintf("To: %s@%s", mptr, config.c_fqdn); + cprintf("To: %s@%s", mptr, CtdlGetConfigStr("c_fqdn")); cprintf("%s", nl); } else @@ -1799,13 +1845,13 @@ void OutputRFC822MsgHeaders( cprintf("To: %s", mptr); cprintf("%s", nl); } - } - else if (i == 'T') { + break; + case eTimestamp: datestring(datestamp, sizeof datestamp, atol(mptr), DATESTRING_RFC822); cprintf("Date: %s%s", datestamp, nl); - } - else if (i == 'W') { + break; + case eWeferences: cprintf("References: "); k = num_tokens(mptr, '|'); for (j=0; jcm_fields[eMesageText]; @@ -1902,16 +1967,19 @@ void Dump_RFC822HeadersBody( 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"); + syslog(LOG_ERR, "msgbase: Dump_RFC822HeadersBody() aborting due to write failure"); return; } + lfSent = (outbuf[outlen - 1] == '\n'); outlen = 0; } } if (outlen > 0) { client_write(outbuf, outlen); + lfSent = (outbuf[outlen - 1] == '\n'); } + if (!lfSent) + client_write(nl, nlen); } @@ -1923,13 +1991,12 @@ void Dump_RFC822HeadersBody( void DumpFormatFixed( struct CtdlMessage *TheMessage, int mode, /* how would you like that message? */ - const char *nl) + const char *nl, int nllen) { cit_uint8_t ch; char buf[SIZ]; int buflen; int xlline = 0; - int nllen = strlen (nl); char *mptr; mptr = TheMessage->cm_fields[eMesageText]; @@ -1973,8 +2040,7 @@ void DumpFormatFixed( if (client_write(buf, buflen) == -1) { - struct CitContext *CCC = CC; - MSGM_syslog(LOG_ERR, "DumpFormatFixed(): aborting due to write failure.\n"); + syslog(LOG_ERR, "msgbase: DumpFormatFixed() aborting due to write failure"); return; } *buf = '\0'; @@ -2001,9 +2067,9 @@ 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; struct ma_info ma; /* Buffers needed for RFC822 translation. These are all filled @@ -2016,17 +2082,17 @@ int CtdlOutputPreLoadedMsg( char snode[100]; char mid[100]; - 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); } @@ -2043,7 +2109,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); @@ -2054,14 +2120,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 @@ -2084,10 +2150,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 */ @@ -2117,12 +2183,12 @@ int CtdlOutputPreLoadedMsg( strcpy(suser, ""); strcpy(luser, ""); strcpy(fuser, ""); - memcpy(snode, CFG_KEY(c_nodename) + 1); + memcpy(snode, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")) + 1); if (mode == MT_RFC822) OutputRFC822MsgHeaders( TheMessage, flags, - nl, + nl, nlen, mid, sizeof(mid), suser, sizeof(suser), luser, sizeof(luser), @@ -2186,7 +2252,7 @@ START_TEXT: TheMessage, headers_only, flags, - nl); + nl, nlen); goto DONE; } } @@ -2204,7 +2270,7 @@ START_TEXT: DumpFormatFixed( TheMessage, mode, /* how would you like that message? */ - nl); + nl, nlen); /* If the message on disk is format 0 (Citadel vari-format), we * output using the formatter at 80 columns. This is the final output @@ -2232,7 +2298,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); @@ -2267,7 +2333,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; @@ -2281,12 +2346,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); @@ -2294,10 +2359,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); } @@ -2306,7 +2371,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; @@ -2334,14 +2399,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); } @@ -2355,19 +2420,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 */ @@ -2397,14 +2462,14 @@ 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); + PerformRoomHooks(&CC->room); /* 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) { @@ -2442,75 +2507,99 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, * called by server-side modules. * */ -long send_message(struct CtdlMessage *msg) { - struct CitContext *CCC = CC; - long newmsgid; +long CtdlSaveThisMessage(struct CtdlMessage *msg, long msgid, int Reply) { long retval; - char msgidbuf[256]; - long msgidbuflen; struct ser_ret smr; int is_bigmsg = 0; char *holdM = NULL; long holdMLen = 0; - /* Get a new message number */ - newmsgid = get_new_message_number(); - msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", - (long unsigned int) time(NULL), - (long unsigned int) newmsgid, - config.c_fqdn - ); - - /* Generate an ID if we don't have one already */ - if (CM_IsEmpty(msg, emessageId)) { - CM_SetField(msg, emessageId, msgidbuf, msgidbuflen); - } - - /* If the message is big, set its body aside for storage elsewhere */ - if (!CM_IsEmpty(msg, eMesageText)) { - if (msg->cm_lengths[eMesageText] > BIGMSG) { - is_bigmsg = 1; - holdM = msg->cm_fields[eMesageText]; - msg->cm_fields[eMesageText] = NULL; - holdMLen = msg->cm_lengths[eMesageText]; - msg->cm_lengths[eMesageText] = 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) + { + is_bigmsg = 1; + holdM = msg->cm_fields[eMesageText]; + msg->cm_fields[eMesageText] = NULL; + holdMLen = msg->cm_lengths[eMesageText]; + msg->cm_lengths[eMesageText] = 0; } /* Serialize our data structure for storage in the database */ CtdlSerializeMessage(&smr, msg); if (is_bigmsg) { + /* put the message body back into the message */ msg->cm_fields[eMesageText] = holdM; msg->cm_lengths[eMesageText] = holdMLen; } if (smr.len == 0) { - cprintf("%d Unable to serialize message\n", - ERROR + INTERNAL_ERROR); + if (Reply) { + 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 */ - if (cdb_store(CDB_MSGMAIN, &newmsgid, (int)sizeof(long), - smr.ser, smr.len) < 0) { - MSGM_syslog(LOG_ERR, "Can't store message\n"); - retval = 0L; - } else { + 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); + } + else { if (is_bigmsg) { - cdb_store(CDB_BIGMSGS, - &newmsgid, - (int)sizeof(long), - holdM, - (holdMLen + 1) + retval = cdb_store(CDB_BIGMSGS, + &msgid, + (int)sizeof(long), + holdM, + (holdMLen + 1) ); + if (retval < 0) { + syslog(LOG_ERR, "msgbase: failed to store message body for msgid %ld: %ld", msgid, retval); + } } - retval = newmsgid; } /* Free the memory we used for the serialized message */ free(smr.ser); + return(retval); +} + +long send_message(struct CtdlMessage *msg) { + long newmsgid; + long retval; + char msgidbuf[256]; + long msgidbuflen; + + /* Get a new message number */ + newmsgid = get_new_message_number(); + + /* 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") + ); + + CM_SetField(msg, emessageId, msgidbuf, msgidbuflen); + } + + retval = CtdlSaveThisMessage(msg, newmsgid, 1); + + if (retval == 0) { + retval = newmsgid; + } + /* Return the *local* message ID to the caller * (even if we're storing an incoming network message) */ @@ -2527,9 +2616,8 @@ long send_message(struct CtdlMessage *msg) { * 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 */ + struct CtdlMessage *msg) /* unserialized msg */ { - struct CitContext *CCC = CC; size_t wlen; int i; @@ -2537,7 +2625,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; @@ -2550,8 +2638,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; @@ -2575,8 +2662,7 @@ void CtdlSerializeMessage(struct ser_ret *ret, /* return values */ } 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; @@ -2588,25 +2674,23 @@ 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, ""); } } @@ -2637,9 +2721,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 @@ -2674,7 +2757,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); } @@ -2706,20 +2789,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, config.c_twitroom); - MSGM_syslog(LOG_DEBUG, "Diverting to twit room\n"); + strcpy(actual_rm, CtdlGetConfigStr("c_twitroom")); + syslog(LOG_DEBUG, "msgbase: diverting to twit room"); } } @@ -2728,33 +2811,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); */ - CtdlUserGoto(actual_rm, 0, 1, NULL, NULL); + 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, strlen(CC->room.QRname)); } /* 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); @@ -2762,7 +2845,7 @@ 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; @@ -2779,29 +2862,29 @@ 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"); - CtdlSaveMsgPointerInRoom(config.c_aideroom, newmsgid, 0, msg); + syslog(LOG_ERR, "msgbase: ERROR saving message pointer!"); + CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } @@ -2815,25 +2898,25 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ 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 + 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"); - CtdlGetUserLock(&CCC->user, CCC->curr_user); - CCC->user.posted = CCC->user.posted + 1; - CtdlPutUserLock(&CCC->user); + syslog(LOG_DEBUG, "msgbase: updating user"); + CtdlLockGetCurrentUser(); + 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, config.c_nodename); - else - snprintf(bounce_to, sizeof bounce_to, "%s@%s", - msg->cm_fields[eAuthor], msg->cm_fields[eNodeName]); + if (CC->logged_in) { + snprintf(bounce_to, sizeof bounce_to, "%s@%s", CC->user.fullname, CtdlGetConfigStr("c_nodename")); + } + else { + snprintf(bounce_to, sizeof bounce_to, "%s@%s", msg->cm_fields[eAuthor], msg->cm_fields[eNodeName]); + } recps->bounce_to = bounce_to; } @@ -2854,7 +2937,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ 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); @@ -2862,28 +2945,28 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ PerformMessageHooks(msg, recps, EVT_AFTERUSRMBOXSAVE); } else { - MSG_syslog(LOG_DEBUG, "No user <%s>\n", recipient); - CtdlSaveMsgPointerInRoom(config.c_aideroom, newmsgid, 0, msg); + syslog(LOG_DEBUG, "msgbase: no user <%s>", recipient); + CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } recps->recp_local = pch; } /* 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)) - CtdlUserGoto(hold_rm, 0, 1, NULL, NULL); + 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); } @@ -2891,7 +2974,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ aptr = (struct addresses_to_be_filed *) malloc(sizeof(struct addresses_to_be_filed)); CtdlMailboxName(actual_rm, sizeof actual_rm, - &CCC->user, USERCONTACTSROOM); + &CC->user, USERCONTACTSROOM); aptr->roomname = strdup(actual_rm); aptr->collected_addresses = collected_addresses; begin_critical_section(S_ATBF); @@ -2908,13 +2991,13 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } else { if (recps == NULL) { - qualified_for_journaling = config.c_journal_pubmsgs; + qualified_for_journaling = CtdlGetConfigInt("c_journal_pubmsgs"); } else if (recps->num_local + recps->num_ignet + recps->num_internet > 0) { - qualified_for_journaling = config.c_journal_email; + qualified_for_journaling = CtdlGetConfigInt("c_journal_email"); } else { - qualified_for_journaling = config.c_journal_pubmsgs; + qualified_for_journaling = CtdlGetConfigInt("c_journal_pubmsgs"); } } @@ -2943,7 +3026,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, @@ -2960,10 +3043,10 @@ void quickie_message(const char *from, msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = format_type; - if (from != NULL) { + if (!IsEmptyStr(from)) { CM_SetField(msg, eAuthor, from, strlen(from)); } - else if (fromaddr != NULL) { + else if (!IsEmptyStr(fromaddr)) { char *pAt; CM_SetField(msg, eAuthor, fromaddr, strlen(fromaddr)); pAt = strchr(msg->cm_fields[eAuthor], '@'); @@ -2975,85 +3058,24 @@ 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, CFG_KEY(c_nodename)); - if (to != NULL) { + if (!IsEmptyStr(fromaddr)) CM_SetField(msg, erFc822Addr, fromaddr, strlen(fromaddr)); + if (!IsEmptyStr(room)) CM_SetField(msg, eOriginalRoom, room, strlen(room)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + if (!IsEmptyStr(to)) { CM_SetField(msg, eRecipient, to, strlen(to)); recp = validate_recipients(to, NULL, 0); } - if (subject != NULL) { + if (!IsEmptyStr(subject)) { CM_SetField(msg, eMsgSubject, subject, strlen(subject)); } - CM_SetField(msg, eMesageText, text, strlen(text)); + if (!IsEmptyStr(text)) { + CM_SetField(msg, eMesageText, text, strlen(text)); + } - CtdlSubmitMsg(msg, recp, room, 0); + long msgnum = CtdlSubmitMsg(msg, recp, room, 0); 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, - 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; - time_t tsday = NOW / (8*60*60); /* just care for a day... */ - - 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); - - if (CheckIfAlreadySeen("FPAideMessage", - guid, - NOW, - tsday, - eUpdate, - ccid, - ioid)!= 0) - { - FreeStrBuf(&guid); - /* yes, we did. flood protection kicks in. */ - syslog(LOG_DEBUG, - "not sending message again\n"); - return; - } - FreeStrBuf(&guid); - /* no, this message isn't sent recently; go ahead. */ - quickie_message(from, - fromaddr, - to, - room, - text, - format_type, - subject); + return msgnum; } @@ -3065,8 +3087,7 @@ 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; @@ -3090,18 +3111,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); @@ -3129,169 +3144,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+"); -#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 eAbort; -} - /* * Back end function used by CtdlMakeMessage() and similar functions @@ -3301,8 +3153,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; @@ -3311,8 +3162,8 @@ char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */ tlen, maxlen, exist, - crlf, - sock); + crlf + ); if (Message == NULL) return NULL; else @@ -3391,7 +3242,6 @@ struct CtdlMessage *CtdlMakeMessageLen( long reflen ) { - struct CitContext *CCC = CC; /* Don't confuse the poor folks if it's not routed mail. * / char dest_node[256] = "";*/ long blen; @@ -3413,7 +3263,7 @@ struct CtdlMessage *CtdlMakeMessageLen( if (myelen > 0) { CM_SetField(msg, eMessagePath, my_email, myelen); } - else { + else if (!IsEmptyStr(author->fullname)) { CM_SetField(msg, eMessagePath, author->fullname, strlen(author->fullname)); } convert_spaces_to_underscores(msg->cm_fields[eMessagePath]); @@ -3429,16 +3279,19 @@ struct CtdlMessage *CtdlMakeMessageLen( } StrBufRFC2047encode(&FakeEncAuthor, FakeAuthor); 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], strlen(&CC->room.QRname[11])); + } + else { + CM_SetField(msg, eOriginalRoom, CC->room.QRname, strlen(CC->room.QRname)); + } } - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); - CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); + 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); @@ -3450,8 +3303,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, strlen(CC->cs_inet_email)); } if (subject != NULL) { @@ -3489,9 +3342,10 @@ struct CtdlMessage *CtdlMakeMessageLen( CM_SetField(msg, eMesageText, preformatted_text, textlen); } else { - preformatted_text = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); - if (preformatted_text != NULL) { - CM_SetField(msg, eMesageText, preformatted_text, strlen(preformatted_text)); + StrBuf *MsgBody; + MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0); + if (MsgBody != NULL) { + CM_SetAsFieldSB(msg, eMesageText, &MsgBody); } } @@ -3505,13 +3359,12 @@ struct CtdlMessage *CtdlMakeMessageLen( * API function to delete messages which match a set of criteria * (returns the actual number of messages deleted) */ -int CtdlDeleteMessages(char *room_name, /* which room */ +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; struct ctdlroom qrbuf; struct cdbdata *cdbfr; long *msglist = NULL; @@ -3529,15 +3382,13 @@ int CtdlDeleteMessages(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)); @@ -3561,7 +3412,7 @@ int CtdlDeleteMessages(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); } */ @@ -3611,7 +3462,7 @@ int CtdlDeleteMessages(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); } */ @@ -3643,7 +3494,7 @@ int CtdlDeleteMessages(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); } @@ -3701,11 +3552,10 @@ void PutMetaData(struct MetaData *smibuf) */ 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); + syslog(LOG_DEBUG, "msgbase: AdjRefCount() msg %ld ref count delta %+d", msgnum, incr); begin_critical_section(S_SUPPMSGMAIN); if (arcfp == NULL) { @@ -3717,7 +3567,7 @@ void AdjRefCount(long msgnum, int incr) /* msgnum < 0 means that we're trying to close the file */ if (msgnum < 0) { - MSGM_syslog(LOG_DEBUG, "Closing the AdjRefCount queue file\n"); + syslog(LOG_DEBUG, "msgbase: closing the AdjRefCount queue file"); begin_critical_section(S_SUPPMSGMAIN); if (arcfp != NULL) { fclose(arcfp); @@ -3739,9 +3589,7 @@ void AdjRefCount(long msgnum, int incr) 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)); + syslog(LOG_EMERG, "%s: %m", file_arcq); } fflush(arcfp); @@ -3750,13 +3598,10 @@ void AdjRefCount(long msgnum, int incr) 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+"); @@ -3777,6 +3622,7 @@ void AdjRefCountList(long *msgnum, long nmsg, int incr) the_size = sizeof(struct arcq) * nmsg; new_arcq = malloc(the_size); for (i = 0; i < nmsg; i++) { + syslog(LOG_DEBUG, "msgbase: AdjRefCountList() msg %ld ref count delta %+d", msgnum[i], incr); new_arcq[i].arcq_msgnum = msgnum[i]; new_arcq[i].arcq_delta = incr; } @@ -3786,9 +3632,7 @@ void AdjRefCountList(long *msgnum, long nmsg, int incr) { 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)); + syslog(LOG_ERR, "%s: %m", file_arcq); } else { offset += rv; @@ -3810,7 +3654,6 @@ void AdjRefCountList(long *msgnum, long nmsg, int incr) */ int TDAP_ProcessAdjRefCountQueue(void) { - struct CitContext *CCC = CC; char file_arcq_temp[PATH_MAX]; int r; FILE *fp; @@ -3827,7 +3670,7 @@ int TDAP_ProcessAdjRefCountQueue(void) r = link(file_arcq, file_arcq_temp); if (r != 0) { - MSG_syslog(LOG_CRIT, "%s: %s\n", file_arcq_temp, strerror(errno)); + syslog(LOG_ERR, "%s: %m", file_arcq_temp); end_critical_section(S_SUPPMSGMAIN); return(num_records_processed); } @@ -3837,7 +3680,7 @@ int TDAP_ProcessAdjRefCountQueue(void) fp = fopen(file_arcq_temp, "rb"); if (fp == NULL) { - MSG_syslog(LOG_CRIT, "%s: %s\n", file_arcq_temp, strerror(errno)); + syslog(LOG_ERR, "%s: %m", file_arcq_temp); return(num_records_processed); } @@ -3849,7 +3692,7 @@ int TDAP_ProcessAdjRefCountQueue(void) fclose(fp); r = unlink(file_arcq_temp); if (r != 0) { - MSG_syslog(LOG_CRIT, "%s: %s\n", file_arcq_temp, strerror(errno)); + syslog(LOG_ERR, "%s: %m", file_arcq_temp); } return(num_records_processed); @@ -3867,7 +3710,6 @@ int TDAP_ProcessAdjRefCountQueue(void) */ void TDAP_AdjRefCount(long msgnum, int incr) { - struct CitContext *CCC = CC; struct MetaData smi; long delnum; @@ -3881,7 +3723,7 @@ 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", + syslog(LOG_DEBUG, "msgbase: TDAP_AdjRefCount() msg %ld ref count delta %+d, is now %d", msgnum, incr, smi.meta_refcount ); @@ -3889,7 +3731,7 @@ void TDAP_AdjRefCount(long msgnum, int incr) * (and its supplementary record as well). */ 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); @@ -3922,7 +3764,6 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ unsigned int flags /* Internal save flags */ ) { - struct CitContext *CCC = CC; struct ctdlroom qrbuf; char roomname[ROOMNAMELEN]; struct CtdlMessage *msg; @@ -3935,7 +3776,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 ) ); @@ -3962,16 +3803,16 @@ 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, eAuthor, CC->user.fullname, strlen(CC->user.fullname)); CM_SetField(msg, eOriginalRoom, req_room, strlen(req_room)); - CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); - CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); msg->cm_flags = flags; CM_SetAsFieldSB(msg, eMesageText, &encoded_message); @@ -3986,7 +3827,7 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ * 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) ); } @@ -4000,14 +3841,11 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ /*****************************************************************************/ /* 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 */