X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=93c673faa3c1a245962136cd48c36ebdcdb5757d;hb=e86cae42a7b279758e7d5de8785793af5cdf689d;hp=9d4451309fd8e831bd3618b67779097a9b7efa8c;hpb=dbaf416c5e665af584ad1db3109cc5486fdfa96f;p=citadel.git diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 9d4451309..93c673faa 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-2015 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. @@ -22,6 +22,7 @@ #include "ctdl_module.h" #include "citserver.h" #include "control.h" +#include "config.h" #include "clientsocket.h" #include "genstamp.h" #include "room_ops.h" @@ -44,7 +45,7 @@ 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 +55,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 */ @@ -1765,7 +1791,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, @@ -1831,7 +1857,7 @@ void OutputRFC822MsgHeaders( 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 @@ -1903,7 +1929,7 @@ void Dump_RFC822HeadersBody( int headers_only, /* eschew the message body? */ int flags, /* should the bessage be exported clean? */ - const char *nl) + const char *nl, int nlen) { cit_uint8_t prev_ch; int eoh = 0; @@ -1912,6 +1938,7 @@ void Dump_RFC822HeadersBody( int outlen = 0; int nllen = strlen(nl); char *mptr; + int lfSent = 0; mptr = TheMessage->cm_fields[eMesageText]; @@ -1968,12 +1995,16 @@ void Dump_RFC822HeadersBody( MSGM_syslog(LOG_ERR, "Dump_RFC822HeadersBody(): aborting due to write failure.\n"); 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); } @@ -1985,13 +2016,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]; @@ -2066,6 +2096,7 @@ int CtdlOutputPreLoadedMsg( 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 @@ -2084,6 +2115,7 @@ int CtdlOutputPreLoadedMsg( strcpy(mid, "unknown"); nl = (crlf ? "\r\n" : "\n"); + nlen = crlf ? 2 : 1; if (!CM_IsValidMsg(TheMessage)) { MSGM_syslog(LOG_ERR, @@ -2179,12 +2211,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), @@ -2248,7 +2280,7 @@ START_TEXT: TheMessage, headers_only, flags, - nl); + nl, nlen); goto DONE; } } @@ -2266,7 +2298,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 @@ -2587,7 +2619,7 @@ long send_message(struct CtdlMessage *msg) { msgidbuflen = snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", (long unsigned int) time(NULL), (long unsigned int) newmsgid, - config.c_fqdn + CtdlGetConfigStr("c_fqdn") ); CM_SetField(msg, emessageId, msgidbuf, msgidbuflen); @@ -2806,7 +2838,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ if (TWITDETECT) { if (CCC->user.axlevel == AxProbU) { strcpy(hold_rm, actual_rm); - strcpy(actual_rm, config.c_twitroom); + strcpy(actual_rm, CtdlGetConfigStr("c_twitroom")); MSGM_syslog(LOG_DEBUG, "Diverting to twit room\n"); } } @@ -2825,7 +2857,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ /* * If this message has no O (room) field, generate one. */ - if (CM_IsEmpty(msg, eOriginalRoom)) { + if (CM_IsEmpty(msg, eOriginalRoom) && !IsEmptyStr(CCC->room.QRname)) { CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); } @@ -2889,7 +2921,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ if ((!CCC->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); + CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } @@ -2918,7 +2950,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ { if (CCC->logged_in) snprintf(bounce_to, sizeof bounce_to, "%s@%s", - CCC->user.fullname, config.c_nodename); + CCC->user.fullname, CtdlGetConfigStr("c_nodename")); else snprintf(bounce_to, sizeof bounce_to, "%s@%s", msg->cm_fields[eAuthor], msg->cm_fields[eNodeName]); @@ -2951,7 +2983,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } else { MSG_syslog(LOG_DEBUG, "No user <%s>\n", recipient); - CtdlSaveMsgPointerInRoom(config.c_aideroom, newmsgid, 0, msg); + CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg); } } recps->recp_local = pch; @@ -2996,13 +3028,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"); } } @@ -3048,10 +3080,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], '@'); @@ -3063,17 +3095,19 @@ 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); CM_Free(msg); @@ -3513,7 +3547,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]); @@ -3531,15 +3565,17 @@ 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(CCC->room.QRname)) { + 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)); + } } - 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); @@ -3591,7 +3627,7 @@ struct CtdlMessage *CtdlMakeMessageLen( } else { StrBuf *MsgBody; - MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); + MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0); if (MsgBody != NULL) { CM_SetAsFieldSB(msg, eMesageText, &MsgBody); } @@ -4072,8 +4108,8 @@ void CtdlWriteObject(char *req_room, /* Room to stuff it in */ 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, 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); @@ -4109,6 +4145,7 @@ void SetMessageDebugEnabled(const int n) CTDL_MODULE_INIT(msgbase) { if (!threading) { + FillMsgKeyLookupTable(); CtdlRegisterDebugFlagHook(HKEY("messages"), SetMessageDebugEnabled, &MessageDebugEnabled); }