X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=568cefb2e06f6c57175510351cbf1b05acf5b049;hb=0b0f8a2280a8f22877baccd2355d7b41b863bfa0;hp=134c3c100b7cddc8a3b5c256ecc6fe00a0ba6c73;hpb=d2fbe9d0eeadfaa1054e959031d6859164dfa78e;p=citadel.git diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 134c3c100..568cefb2e 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -38,6 +38,9 @@ #include #include #include + +#include "md5.h" + #include #include "citadel.h" #include "server.h" @@ -93,7 +96,7 @@ char *msgkeys[] = { "hnod", "msgn", "jrnl", - NULL, + "rep2", "list", "text", "node", @@ -370,7 +373,7 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, int is_seen = 0; int was_seen = 0; long lo = (-1L); - long hi = (-1L); + long hi = (-1L); /// TODO: we just write here. y? visit vbuf; long *msglist; int num_msgs = 0; @@ -1654,11 +1657,13 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ 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 */ + int flags, /* various flags; see msgbase.h */ + char **Author, + char **Address ) { struct CitContext *CCC = CC; struct CtdlMessage *TheMessage = NULL; - int retcode = om_no_such_msg; + int retcode = CIT_OK; struct encapmsg encap; int r; @@ -1732,6 +1737,17 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ *extract_encapsulated_message, NULL, NULL, (void *)&encap, 0 ); + + if ((Author != NULL) && (*Author == NULL)) + { + *Author = TheMessage->cm_fields['A']; + TheMessage->cm_fields['A'] = NULL; + } + if ((Address != NULL) && (*Address == NULL)) + { + *Address = TheMessage->cm_fields['F']; + TheMessage->cm_fields['F'] = NULL; + } CtdlFreeMessage(TheMessage); TheMessage = NULL; @@ -1748,15 +1764,31 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ } else { - if (do_proto) cprintf("%d msg %ld has no part %s\n", - ERROR + MESSAGE_NOT_FOUND, msg_num, section); + if (do_proto) { + cprintf("%d msg %ld has no part %s\n", + ERROR + MESSAGE_NOT_FOUND, + msg_num, + section); + } retcode = om_no_such_msg; } } /* Ok, output the message now */ - retcode = CtdlOutputPreLoadedMsg(TheMessage, mode, headers_only, do_proto, crlf, flags); + if (retcode == CIT_OK) + retcode = CtdlOutputPreLoadedMsg(TheMessage, mode, headers_only, do_proto, crlf, flags); + if ((Author != NULL) && (*Author == NULL)) + { + *Author = TheMessage->cm_fields['A']; + TheMessage->cm_fields['A'] = NULL; + } + if ((Address != NULL) && (*Address == NULL)) + { + *Address = TheMessage->cm_fields['F']; + TheMessage->cm_fields['F'] = NULL; + } + CtdlFreeMessage(TheMessage); return(retcode); @@ -1784,7 +1816,7 @@ char *qp_encode_email_addrs(char *source) if (source == NULL) return source; if (IsEmptyStr(source)) return source; - cit_backtrace(); + if (MessageDebugEnabled != 0) cit_backtrace(); MSG_syslog(LOG_DEBUG, "qp_encode_email_addrs: [%s]\n", source); AddrPtr = malloc (sizeof (long) * nAddrPtrMax); @@ -2178,7 +2210,6 @@ void Dump_RFC822HeadersBody( } if (outlen > 0) { client_write(outbuf, outlen); - outlen = 0; } } @@ -2537,7 +2568,7 @@ void cmd_msg0(char *cmdbuf) msgid = extract_long(cmdbuf, 0); headers_only = extract_int(cmdbuf, 1); - CtdlOutputMsg(msgid, MT_CITADEL, headers_only, 1, 0, NULL, 0); + CtdlOutputMsg(msgid, MT_CITADEL, headers_only, 1, 0, NULL, 0, NULL, NULL); return; } @@ -2553,7 +2584,7 @@ void cmd_msg2(char *cmdbuf) msgid = extract_long(cmdbuf, 0); headers_only = extract_int(cmdbuf, 1); - CtdlOutputMsg(msgid, MT_RFC822, headers_only, 1, 1, NULL, 0); + CtdlOutputMsg(msgid, MT_RFC822, headers_only, 1, 1, NULL, 0, NULL, NULL); } @@ -2607,7 +2638,7 @@ void cmd_msg4(char *cmdbuf) msgid = extract_long(cmdbuf, 0); extract_token(section, cmdbuf, 1, '|', sizeof section); - CtdlOutputMsg(msgid, MT_MIME, 0, 1, 0, (section[0] ? section : NULL) , 0); + CtdlOutputMsg(msgid, MT_MIME, 0, 1, 0, (section[0] ? section : NULL) , 0, NULL, NULL); } @@ -2640,7 +2671,7 @@ void cmd_opna(char *cmdbuf) extract_token(desired_section, cmdbuf, 1, '|', sizeof desired_section); safestrncpy(CC->download_desired_section, desired_section, sizeof CC->download_desired_section); - CtdlOutputMsg(msgid, MT_DOWNLOAD, 0, 1, 1, NULL, 0); + CtdlOutputMsg(msgid, MT_DOWNLOAD, 0, 1, 1, NULL, 0, NULL, NULL); } @@ -2656,8 +2687,8 @@ void cmd_dlat(char *cmdbuf) extract_token(desired_section, cmdbuf, 1, '|', sizeof desired_section); safestrncpy(CC->download_desired_section, desired_section, sizeof CC->download_desired_section); - CtdlOutputMsg(msgid, MT_SPEW_SECTION, 0, 1, 1, NULL, 0); -} + CtdlOutputMsg(msgid, MT_SPEW_SECTION, 0, 1, 1, NULL, 0, NULL, NULL); +} /* @@ -2749,6 +2780,8 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms 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"); + free(msgs_to_be_merged); + return (ERROR + INTERNAL_ERROR); } memcpy(&msglist[num_msgs], msgs_to_be_merged, (sizeof(long) * num_msgs_to_be_merged) ); num_msgs += num_msgs_to_be_merged; @@ -2978,47 +3011,6 @@ void serialize_message(struct ser_ret *ret, /* return values */ } -/* - * Serialize a struct CtdlMessage into the format used on disk and network. - * - * This function loads up a "struct ser_ret" (defined in server.h) which - * contains the length of the serialized message and a pointer to the - * serialized message in memory. THE LATTER MUST BE FREED BY THE CALLER. - */ -void dump_message(struct CtdlMessage *msg, /* unserialized msg */ - long Siz) /* how many chars ? */ -{ - int i; - static char *forder = FORDER; - char *buf; - - /* - * Check for valid message format - */ - if (is_valid_message(msg) == 0) { - struct CitContext *CCC = CC; - MSGM_syslog(LOG_ERR, "dump_message() aborting due to invalid message\n"); - return; - } - - buf = (char*) malloc (Siz + 1); - - for (i=0; i<26; ++i) if (msg->cm_fields[(int)forder[i]] != NULL) { - snprintf (buf, Siz, " msg[%c] = %s ...\n", (char) forder[i], - msg->cm_fields[(int)forder[i]]); - if (client_write (buf, strlen(buf)) == -1) - { - struct CitContext *CCC = CC; - MSGM_syslog(LOG_ERR, "dump_message(): aborting due to write failure.\n"); - return; - } - } - - return; -} - - - /* * Check to see if any messages already exist in the current room which * carry the same Exclusive ID as this one. If any are found, delete them. @@ -3500,18 +3492,16 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } - -void aide_message (char *text, char *subject) -{ - quickie_message("Citadel",NULL,NULL,AIDEROOM,text,FMT_CITADEL,subject); -} - - /* * Convenience function for generating small administrative messages. */ -void quickie_message(const char *from, const char *fromaddr, char *to, char *room, const char *text, - int format_type, const char *subject) +void quickie_message(const char *from, + const char *fromaddr, + char *to, + char *room, + const char *text, + int format_type, + const char *subject) { struct CtdlMessage *msg; struct recptypes *recp = NULL; @@ -3552,6 +3542,72 @@ void quickie_message(const char *from, const char *fromaddr, char *to, char *roo if (recp != NULL) free_recipients(recp); } +void flood_protect_quickie_message(const char *from, + const char *fromaddr, + char *to, + char *room, + const char *text, + int format_type, + const char *subject, + int nCriterions, + const char **CritStr, + long *CritStrLen) +{ + int i; + struct UseTable ut; + u_char rawdigest[MD5_DIGEST_LEN]; + struct MD5Context md5context; + StrBuf *guid; + struct cdbdata *cdbut; + char timestamp[64]; + long tslen; + time_t ts = time(NULL); + time_t tsday = ts / (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); + /* Find out if we've already sent a similar message */ + memcpy(ut.ut_msgid, SKEY(guid)); + ut.ut_timestamp = ts; + + cdbut = cdb_fetch(CDB_USETABLE, SKEY(guid)); + + if (cdbut != NULL) { + /* yes, we did. flood protection kicks in. */ + syslog(LOG_DEBUG, + "not sending message again\n"); + cdb_free(cdbut); + } + + /* rewrite the record anyway, to update the timestamp */ + cdb_store(CDB_USETABLE, + SKEY(guid), + &ut, sizeof(struct UseTable) ); + + if (cdbut != NULL) return; + /* no, this message isn't sent recently; go ahead. */ + quickie_message(from, + fromaddr, + to, + room, + text, + format_type, + subject); +} /* @@ -4048,7 +4104,7 @@ int CtdlCheckInternetMailPermission(struct ctdluser *who) { /* User flagged ok? */ if (who->flags & US_INTERNET) return(2); - /* Aide level access? */ + /* Admin level access? */ if (who->axlevel >= AxAideU) return(3); /* No mail for you! */ @@ -4157,11 +4213,11 @@ struct recptypes *validate_recipients(const char *supplied_recipients, ++num_recps; strcpy(org_recp, this_recp); + alias(this_recp); + alias(this_recp); mailtype = alias(this_recp); - mailtype = alias(this_recp); - mailtype = alias(this_recp); - j = 0; - for (j=0; !IsEmptyStr(&this_recp[j]); ++j) { + + for (j = 0; !IsEmptyStr(&this_recp[j]); ++j) { if (this_recp[j]=='_') { this_recp_cooked[j] = ' '; } @@ -4374,7 +4430,6 @@ void cmd_ent0(char *entargs) char subject[SIZ]; int subject_required = 0; int do_confirm = 0; - int verbose_reply = 0; long msgnum; int i, j; char buf[256]; @@ -4393,7 +4448,6 @@ void cmd_ent0(char *entargs) do_confirm = extract_int(entargs, 6); extract_token(cc, entargs, 7, '|', sizeof cc); extract_token(bcc, entargs, 8, '|', sizeof bcc); - verbose_reply = extract_int(entargs, 9); switch(CC->room.QRdefaultview) { case VIEW_NOTES: case VIEW_WIKI: @@ -4646,25 +4700,19 @@ void cmd_ent0(char *entargs) if (msg != NULL) { msgnum = CtdlSubmitMsg(msg, valid, "", QP_EADDR); - if (verbose_reply) - { - if (StrLength(CCC->StatusMessage)>0) - { - StrBufAppendBufPlain(CCC->StatusMessage, HKEY("\n000\n"), 0); - cputbuf(CCC->StatusMessage); - } - else - client_write(HKEY("\n000\n")); - } - if (do_confirm) { cprintf("%ld\n", msgnum); - if (msgnum >= 0L) { + + if (StrLength(CCC->StatusMessage) > 0) { + cprintf("%s\n", ChrPtr(CCC->StatusMessage)); + } + else if (msgnum >= 0L) { client_write(HKEY("Message accepted.\n")); } else { client_write(HKEY("Internal error.\n")); } + if (msg->cm_fields['E'] != NULL) { cprintf("%s\n", msg->cm_fields['E']); } else { @@ -4731,7 +4779,7 @@ int CtdlDeleteMessages(char *room_name, /* which room */ cdb_free(cdbfr); } if (num_msgs > 0) { - int have_contenttype = !IsEmptyStr(content_type); + int have_contenttype = (content_type != NULL) && !IsEmptyStr(content_type); int have_delmsgs = (num_dmsgnums == 0) || (dmsgnums == NULL); int have_more_del = 1; @@ -4939,7 +4987,7 @@ void cmd_move(char *args) */ permit = 0; - /* Aides can move/copy */ + /* Admins can move/copy */ if (CC->user.axlevel >= AxAideU) permit = 1; /* Room aides can move/copy */