X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=135fe0e39b7f53c73882e3f0bbe46859ae4a054b;hb=8357d67fb22adec3b854d61bdbd898dcfcc91959;hp=57eb0d21386380c0d6ff080d2830c21148c624b9;hpb=72cf2e7f757fd0d4e977be9154222be3af77b59c;p=citadel.git diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 57eb0d213..135fe0e39 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1129,19 +1129,36 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) ret->cm_anon_type = *mptr++; /* Anon type byte */ ret->cm_format_type = *mptr++; /* Format type byte */ + + if (dmsgtext->ptr[dmsgtext->len - 1] != '\0') + { + MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body); + dmsgtext->ptr[dmsgtext->len - 1] = '\0'; + } + /* * The rest is zero or more arbitrary fields. Load them in. * We're done when we encounter either a zero-length field or * 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 */ @@ -1158,7 +1175,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); } } @@ -1504,14 +1521,15 @@ 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; @@ -1599,6 +1617,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 +1661,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); @@ -1739,28 +1767,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,22 +1796,25 @@ 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); @@ -1799,13 +1830,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; jroom.QRname)) { /* CtdlGetRoom(&CCC->room, actual_rm); */ - CtdlUserGoto(actual_rm, 0, 1, NULL, NULL); + CtdlUserGoto(actual_rm, 0, 1, NULL, NULL, NULL, NULL); } /* @@ -2821,9 +2870,9 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ /* Bump this user's messages posted counter. */ MSGM_syslog(LOG_DEBUG, "Updating user\n"); - CtdlGetUserLock(&CCC->user, CCC->curr_user); + CtdlLockGetCurrentUser(); CCC->user.posted = CCC->user.posted + 1; - CtdlPutUserLock(&CCC->user); + CtdlPutCurrentUserLock(); /* Decide where bounces need to be delivered */ if ((recps != NULL) && (recps->bounce_to == NULL)) @@ -2878,7 +2927,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ /* 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); + CtdlUserGoto(hold_rm, 0, 1, NULL, NULL, NULL, NULL); /* * Any addresses to harvest for someone's address book? @@ -2977,7 +3026,7 @@ void quickie_message(const char *from, if (fromaddr != NULL) CM_SetField(msg, erFc822Addr, fromaddr, strlen(fromaddr)); if (room != NULL) CM_SetField(msg, eOriginalRoom, room, strlen(room)); - CM_SetField(msg, eNodeName, NODENAME, strlen(NODENAME)); + CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); if (to != NULL) { CM_SetField(msg, eRecipient, to, strlen(to)); recp = validate_recipients(to, NULL, 0); @@ -3012,7 +3061,8 @@ void flood_protect_quickie_message(const char *from, StrBuf *guid; char timestamp[64]; long tslen; - time_t tsday = NOW / (8*60*60); /* just care for a day... */ + static const time_t tsday = (8*60*60); /* just care for a day... */ + time_t seenstamp; tslen = snprintf(timestamp, sizeof(timestamp), "%ld", tsday); MD5Init(&md5context); @@ -3031,29 +3081,35 @@ void flood_protect_quickie_message(const char *from, if (StrLength(guid) > 40) StrBufCutAt(guid, 40, NULL); - if (CheckIfAlreadySeen("FPAideMessage", - guid, - NOW, - tsday, - eUpdate, - ccid, - ioid)!= 0) + seenstamp = CheckIfAlreadySeen("FPAideMessage", + guid, + NOW, + tsday, + eUpdate, + ccid, + ioid); + if (seenstamp < tsday) { FreeStrBuf(&guid); /* yes, we did. flood protection kicks in. */ syslog(LOG_DEBUG, - "not sending message again\n"); + "not sending message again - %ld < %ld \n", seenstamp, tsday); return; } - FreeStrBuf(&guid); - /* no, this message isn't sent recently; go ahead. */ - quickie_message(from, - fromaddr, - to, - room, - text, - format_type, - subject); + else + { + syslog(LOG_DEBUG, + "sending message. %ld >= %ld", seenstamp, tsday); + FreeStrBuf(&guid); + /* no, this message isn't sent recently; go ahead. */ + quickie_message(from, + fromaddr, + to, + room, + text, + format_type, + subject); + } } @@ -3208,6 +3264,11 @@ eReadState CtdlReadMessageBodyAsync(AsyncIO *IO) IO->SendBuf.fd); fd = fopen(fn, "a+"); + if (fd == NULL) { + syslog(LOG_EMERG, "failed to open file %s: %s", fn, strerror(errno)); + cit_backtrace(); + exit(1); + } #endif ReadMsg = IO->ReadMsg; @@ -3289,7 +3350,7 @@ eReadState CtdlReadMessageBodyAsync(AsyncIO *IO) if (MsgFinished) return eReadSuccess; else - return eAbort; + return eReadFail; } @@ -3429,6 +3490,7 @@ 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])); @@ -3437,8 +3499,8 @@ struct CtdlMessage *CtdlMakeMessageLen( CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); } - CM_SetField(msg, eNodeName, NODENAME, strlen(NODENAME)); - CM_SetField(msg, eHumanNode, HUMANNODE, strlen(HUMANNODE)); + CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); if (rcplen > 0) { CM_SetField(msg, eRecipient, recipient, rcplen); @@ -3489,9 +3551,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"), config.c_maxmsglen, NULL, 0, 0); + if (MsgBody != NULL) { + CM_SetAsFieldSB(msg, eMesageText, &MsgBody); } } @@ -3970,8 +4033,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, config.c_nodename, strlen(config.c_nodename)); - CM_SetField(msg, eHumanNode, config.c_humannode, strlen(config.c_humannode)); + CM_SetField(msg, eNodeName, CFG_KEY(c_nodename)); + CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode)); msg->cm_flags = flags; CM_SetAsFieldSB(msg, eMesageText, &encoded_message);