/*
* Implements the message store.
*
- * Copyright (c) 1987-2020 by the citadel.org team
+ * Copyright (c) 1987-2021 by the citadel.org team
*
* This program is open source software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
"rep2", // K -> eReplyTo
"list", // L -> eListID
"text", // M -> eMesageText
- "locl", // N -> eOrigLocal
+ NULL, // N (formerly used as eNodename)
"room", // O -> eOriginalRoom
"path", // P -> eMessagePath
NULL, // Q
eOriginalRoom,
eRecipient ,
/* Semi-important fields */
- eOrigLocal ,
eBig_message ,
eExclusiveID ,
eWeferences ,
static const long NDiskFields = sizeof(FieldOrder) / sizeof(eMsgField);
-int CM_IsEmpty(struct CtdlMessage *Msg, eMsgField which)
-{
+int CM_IsEmpty(struct CtdlMessage *Msg, eMsgField which) {
return !((Msg->cm_fields[which] != NULL) && (Msg->cm_fields[which][0] != '\0'));
}
-void CM_SetField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length)
-{
+void CM_SetField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length) {
if (Msg->cm_fields[which] != NULL) {
free (Msg->cm_fields[which]);
}
}
-void CM_SetFieldLONG(struct CtdlMessage *Msg, eMsgField which, long lvalue)
-{
+void CM_SetFieldLONG(struct CtdlMessage *Msg, eMsgField which, long lvalue) {
char buf[128];
long len;
len = snprintf(buf, sizeof(buf), "%ld", lvalue);
}
-void CM_CutFieldAt(struct CtdlMessage *Msg, eMsgField WhichToCut, long maxlen)
-{
+void CM_CutFieldAt(struct CtdlMessage *Msg, eMsgField WhichToCut, long maxlen) {
if (Msg->cm_fields[WhichToCut] == NULL)
return;
}
-void CM_FlushField(struct CtdlMessage *Msg, eMsgField which)
-{
+void CM_FlushField(struct CtdlMessage *Msg, eMsgField which) {
if (Msg->cm_fields[which] != NULL)
free (Msg->cm_fields[which]);
Msg->cm_fields[which] = NULL;
}
-void CM_Flush(struct CtdlMessage *Msg)
-{
+void CM_Flush(struct CtdlMessage *Msg) {
int i;
if (CM_IsValidMsg(Msg) == 0) {
}
-void CM_CopyField(struct CtdlMessage *Msg, eMsgField WhichToPutTo, eMsgField WhichtToCopy)
-{
+void CM_CopyField(struct CtdlMessage *Msg, eMsgField WhichToPutTo, eMsgField WhichtToCopy) {
long len;
if (Msg->cm_fields[WhichToPutTo] != NULL) {
free (Msg->cm_fields[WhichToPutTo]);
}
-void CM_PrependToField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length)
-{
+void CM_PrependToField(struct CtdlMessage *Msg, eMsgField which, const char *buf, long length) {
if (Msg->cm_fields[which] != NULL) {
long oldmsgsize;
long newmsgsize;
}
-void CM_SetAsField(struct CtdlMessage *Msg, eMsgField which, char **buf, long length)
-{
+void CM_SetAsField(struct CtdlMessage *Msg, eMsgField which, char **buf, long length) {
if (Msg->cm_fields[which] != NULL) {
free (Msg->cm_fields[which]);
}
}
-void CM_SetAsFieldSB(struct CtdlMessage *Msg, eMsgField which, StrBuf **buf)
-{
+void CM_SetAsFieldSB(struct CtdlMessage *Msg, eMsgField which, StrBuf **buf) {
if (Msg->cm_fields[which] != NULL) {
free (Msg->cm_fields[which]);
}
}
-void CM_GetAsField(struct CtdlMessage *Msg, eMsgField which, char **ret, long *retlen)
-{
+void CM_GetAsField(struct CtdlMessage *Msg, eMsgField which, char **ret, long *retlen) {
if (Msg->cm_fields[which] != NULL) {
*retlen = Msg->cm_lengths[which];
*ret = Msg->cm_fields[which];
}
-void CM_FreeContents(struct CtdlMessage *msg)
-{
+void CM_FreeContents(struct CtdlMessage *msg) {
int i;
for (i = 0; i < 256; ++i)
/*
* 'Destructor' for struct CtdlMessage
*/
-void CM_Free(struct CtdlMessage *msg)
-{
+void CM_Free(struct CtdlMessage *msg) {
if (CM_IsValidMsg(msg) == 0) {
if (msg != NULL) free (msg);
return;
}
-int CM_DupField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg)
-{
+int CM_DupField(eMsgField i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg) {
long len;
len = OrgMsg->cm_lengths[i];
NewMsg->cm_fields[i] = malloc(len + 1);
}
-struct CtdlMessage * CM_Duplicate(struct CtdlMessage *OrgMsg)
-{
+struct CtdlMessage *CM_Duplicate(struct CtdlMessage *OrgMsg) {
int i;
struct CtdlMessage *NewMsg;
cdbfr->ptr = NULL; /* CtdlSetSeen() now owns this memory */
num_msgs = cdbfr->len / sizeof(long);
cdb_free(cdbfr);
- } else {
+ }
+ else {
return; /* No messages at all? No further action. */
}
) {
CC->download_fp = tmpfile();
if (CC->download_fp == NULL) {
- syslog(LOG_EMERG, "msgbase: mime_download() couldn't write: %m");
+ syslog(LOG_ERR, "msgbase: mime_download() couldn't write: %m");
cprintf("%d cannot open temporary file: %s\n", ERROR + INTERNAL_ERROR, strerror(errno));
return;
}
rv = fwrite(content, length, 1, CC->download_fp);
if (rv <= 0) {
- syslog(LOG_EMERG, "msgbase: mime_download() Couldn't write: %m");
+ syslog(LOG_ERR, "msgbase: mime_download() Couldn't write: %m");
cprintf("%d unable to write tempfile.\n", ERROR + TOO_BIG);
fclose(CC->download_fp);
CC->download_fp = NULL;
}
-void OutputCtdlMsgHeaders(
- struct CtdlMessage *TheMessage,
- int do_proto) /* do Citadel protocol responses? */
-{
+void OutputCtdlMsgHeaders(struct CtdlMessage *TheMessage, int do_proto) {
int i;
char buf[SIZ];
char display_name[256];
eMsgField Field;
Field = FieldOrder[i];
if (Field != eMesageText) {
- if ( (!CM_IsEmpty(TheMessage, Field))
- && (msgkeys[Field] != NULL) ) {
- if ((Field == eenVelopeTo) ||
- (Field == eRecipient) ||
- (Field == eCarbonCopY)) {
+ if ( (!CM_IsEmpty(TheMessage, Field)) && (msgkeys[Field] != NULL) ) {
+ if ((Field == eenVelopeTo) || (Field == eRecipient) || (Field == eCarbonCopY)) {
sanitize_truncated_recipient(TheMessage->cm_fields[Field]);
}
if (Field == eAuthor) {
- if (do_proto) cprintf("%s=%s\n",
- msgkeys[Field],
- display_name);
+ if (do_proto) {
+ cprintf("%s=%s\n", msgkeys[Field], display_name);
+ }
}
/* Masquerade display name if needed */
else {
if (do_proto) {
cprintf("%s=%s\n", msgkeys[Field], TheMessage->cm_fields[Field]);
}
+ }
+ /* Give the client a hint about whether the message originated locally */
+ if (Field == erFc822Addr) {
+ if (IsDirectory(TheMessage->cm_fields[Field] ,0)) {
+ cprintf("locl=yes\n"); // message originated locally.
+ }
+
+
+
}
}
}
break;
case erFc822Addr:
safestrncpy(fuser, mptr, sizeof_fuser);
+ break;
case eRecipient:
if (haschar(mptr, '@') == 0) {
sanitize_truncated_recipient(mptr);
case eSuppressIdx:
case eExtnotify:
case eVltMsgNum:
- case eOrigLocal:
/* these don't map to mime message headers. */
break;
}
/* Tell the client which format type we're using. */
if ( (mode == MT_CITADEL) && (do_proto) ) {
- cprintf("type=%d\n", TheMessage->cm_format_type);
+ cprintf("type=%d\n", TheMessage->cm_format_type); // Tell the client which format type we're using.
}
/* nhdr=yes means that we're only displaying headers, no body */
cprintf("nhdr=yes\n");
}
- if ((mode == MT_CITADEL) || (mode == MT_MIME))
+ if ((mode == MT_CITADEL) || (mode == MT_MIME)) {
OutputCtdlMsgHeaders(TheMessage, do_proto);
-
+ }
/* begin header processing loop for RFC822 transfer format */
strcpy(suser, "");
* Save a message to disk and submit it into the delivery system.
*/
long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */
- recptypes *recps, /* recipients (if mail) */
- const char *force, /* force a particular room? */
- int flags /* should the message be exported clean? */
+ struct recptypes *recps, /* recipients (if mail) */
+ const char *force /* force a particular room? */
) {
char hold_rm[ROOMNAMELEN];
char actual_rm[ROOMNAMELEN];
*/
if ((!CC->internal_pgm) || (recps == NULL)) {
if (CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 1, msg) != 0) {
- syslog(LOG_ERR, "msgbase: ERROR saving message pointer!");
+ syslog(LOG_ERR, "msgbase: ERROR saving message pointer %ld in %s", newmsgid, actual_rm);
CtdlSaveMsgPointerInRoom(CtdlGetConfigStr("c_aideroom"), newmsgid, 0, msg);
}
}
const char *subject)
{
struct CtdlMessage *msg;
- recptypes *recp = NULL;
+ struct recptypes *recp = NULL;
msg = malloc(sizeof(struct CtdlMessage));
memset(msg, 0, sizeof(struct CtdlMessage));
CM_SetField(msg, eMesageText, text, -1);
}
- long msgnum = CtdlSubmitMsg(msg, recp, room, 0);
+ long msgnum = CtdlSubmitMsg(msg, recp, room);
CM_Free(msg);
if (recp != NULL) free_recipients(recp);
return msgnum;
);
}
/* Now write the data */
- CtdlSubmitMsg(msg, NULL, roomname, 0);
+ CtdlSubmitMsg(msg, NULL, roomname);
CM_Free(msg);
}