X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fmessages.c;h=3c3c92f6dd2f3b1aced34d0a484c81cfeee63278;hb=9f86bcfb5f58af7d3d9378583ba493f125c530b0;hp=e891539ce500dbf4e6da49da42bc55f65f38318e;hpb=89406b8ce58376969b5f11c4f88d77eb15d3b7d2;p=citadel.git diff --git a/webcit/messages.c b/webcit/messages.c index e891539ce..3c3c92f6d 100644 --- a/webcit/messages.c +++ b/webcit/messages.c @@ -18,7 +18,6 @@ #include "calendar.h" HashList *MsgHeaderHandler = NULL; -HashList *MsgEvaluators = NULL; HashList *MimeRenderHandler = NULL; HashList *ReadLoopHandler = NULL; int dbg_analyze_msg = 0; @@ -31,12 +30,6 @@ void jsonMessageListHdr(void); void display_enter(void); -typedef void (*MsgPartEvaluatorFunc)(message_summary *Sum, StrBuf *Buf); - -typedef struct _MsgPartEvaluatorStruct { - MsgPartEvaluatorFunc f; -} MsgPartEvaluatorStruct; - void fixview() { /* workaround for json listview; its not useable directly */ @@ -178,7 +171,7 @@ int load_message(message_summary *Msg, * printable_view Nonzero to display a printable view * section Optional for encapsulated message/rfc822 submessage */ -int read_message(StrBuf *Target, const char *tmpl, long tmpllen, long msgnum, const StrBuf *PartNum, const StrBuf **OutMime) +int read_message(StrBuf *Target, const char *tmpl, long tmpllen, long msgnum, const StrBuf *PartNum, const StrBuf **OutMime, WCTemplputParams *TP) { StrBuf *Buf; StrBuf *FoundCharset; @@ -188,9 +181,13 @@ int read_message(StrBuf *Target, const char *tmpl, long tmpllen, long msgnum, co void *vHdr; long len; const char *Key; + WCTemplputParams SuperTP; WCTemplputParams SubTP; StrBuf *Error = NULL; + memset(&SuperTP, 0, sizeof(WCTemplputParams)); + memset(&SubTP, 0, sizeof(WCTemplputParams)); + Buf = NewStrBuf(); FoundCharset = NewStrBuf(); Msg = (message_summary *)malloc(sizeof(message_summary)); @@ -211,38 +208,46 @@ int read_message(StrBuf *Target, const char *tmpl, long tmpllen, long msgnum, co StrBufTrim(Buf); StrBufLowerCase(Buf); - /* Locate a renderer capable of converting this MIME part into HTML */ - if (GetHash(MimeRenderHandler, SKEY(Buf), &vHdr) && - (vHdr != NULL)) { - RenderMimeFuncStruct *Render; - Render = (RenderMimeFuncStruct*)vHdr; - Render->f(Msg->MsgBody, NULL, FoundCharset); - } - - if (StrLength(Msg->reply_references)> 0) { - /* Trim down excessively long lists of thread references. We eliminate the - * second one in the list so that the thread root remains intact. - */ - int rrtok = num_tokens(ChrPtr(Msg->reply_references), '|'); - int rrlen = StrLength(Msg->reply_references); - if ( ((rrtok >= 3) && (rrlen > 900)) || (rrtok > 10) ) { - StrBufRemove_token(Msg->reply_references, 1, '|'); + StackContext(TP, &SuperTP, Msg, CTX_MAILSUM, 0, NULL); + { + /* Locate a renderer capable of converting this MIME part into HTML */ + if (GetHash(MimeRenderHandler, SKEY(Buf), &vHdr) && + (vHdr != NULL)) { + RenderMimeFuncStruct *Render; + + StackContext(&SuperTP, &SubTP, Msg->MsgBody, CTX_MIME_ATACH, 0, NULL); + { + Render = (RenderMimeFuncStruct*)vHdr; + Render->f(Target, &SubTP, FoundCharset); + } + UnStackContext(&SubTP); + } + + if (StrLength(Msg->reply_references)> 0) { + /* Trim down excessively long lists of thread references. We eliminate the + * second one in the list so that the thread root remains intact. + */ + int rrtok = num_tokens(ChrPtr(Msg->reply_references), '|'); + int rrlen = StrLength(Msg->reply_references); + if ( ((rrtok >= 3) && (rrlen > 900)) || (rrtok > 10) ) { + StrBufRemove_token(Msg->reply_references, 1, '|'); + } } - } - /* now check if we need to translate some mimeparts, and remove the duplicate */ - it = GetNewHashPos(Msg->AllAttach, 0); - while (GetNextHashPos(Msg->AllAttach, it, &len, &Key, &vMime) && - (vMime != NULL)) { - wc_mime_attachment *Mime = (wc_mime_attachment*) vMime; - evaluate_mime_part(Msg, Mime); - } - DeleteHashPos(&it); - StackContext(NULL, &SubTP, Msg, CTX_MAILSUM, 0, NULL); - { - *OutMime = DoTemplate(tmpl, tmpllen, Target, &SubTP); + /* now check if we need to translate some mimeparts, and remove the duplicate */ + it = GetNewHashPos(Msg->AllAttach, 0); + while (GetNextHashPos(Msg->AllAttach, it, &len, &Key, &vMime) && + (vMime != NULL)) { + StackContext(&SuperTP, &SubTP, vMime, CTX_MIME_ATACH, 0, NULL); + { + evaluate_mime_part(Target, &SubTP); + } + UnStackContext(&SubTP); + } + DeleteHashPos(&it); + *OutMime = DoTemplate(tmpl, tmpllen, Target, &SuperTP); } - UnStackContext(&SubTP); + UnStackContext(&SuperTP); DestroyMessageSummary(Msg); FreeStrBuf(&FoundCharset); @@ -352,9 +357,9 @@ void handle_one_message(void) case ePOST: Tmpl = sbstr("template"); if (StrLength(Tmpl) > 0) - read_message(WCC->WBuf, SKEY(Tmpl), msgnum, NULL, &Mime); + read_message(WCC->WBuf, SKEY(Tmpl), msgnum, NULL, &Mime, NULL); else - read_message(WCC->WBuf, HKEY("view_message"), msgnum, NULL, &Mime); + read_message(WCC->WBuf, HKEY("view_message"), msgnum, NULL, &Mime, NULL); http_transmit_thing(ChrPtr(Mime), 0); break; case eDELETE: @@ -411,9 +416,9 @@ void embed_message(void) { case ePOST: Tmpl = sbstr("template"); if (StrLength(Tmpl) > 0) - read_message(WCC->WBuf, SKEY(Tmpl), msgnum, NULL, &Mime); + read_message(WCC->WBuf, SKEY(Tmpl), msgnum, NULL, &Mime, NULL); else - read_message(WCC->WBuf, HKEY("view_message"), msgnum, NULL, &Mime); + read_message(WCC->WBuf, HKEY("view_message"), msgnum, NULL, &Mime, NULL); http_transmit_thing(ChrPtr(Mime), 0); break; case eDELETE: @@ -450,7 +455,7 @@ void print_message(void) { begin_burst(); - read_message(WC->WBuf, HKEY("view_message_print"), msgnum, NULL, &Mime); + read_message(WC->WBuf, HKEY("view_message_print"), msgnum, NULL, &Mime, NULL); wDumpContent(0); } @@ -471,7 +476,7 @@ void display_headers(void) { PACKAGE_STRING); begin_burst(); - serv_printf("MSG2 %ld|3", msgnum); + serv_printf("MSG2 %ld|1", msgnum); serv_getln(buf, sizeof buf); if (buf[0] == '1') { while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { @@ -483,50 +488,6 @@ void display_headers(void) { } -message_summary *ReadOneMessageSummary(StrBuf *RawMessage, const char *DefaultSubject, long MsgNum) -{ - void *vEval; - MsgPartEvaluatorStruct *Eval; - message_summary *Msg; - StrBuf *Buf; - const char *buf; - const char *ebuf; - int nBuf; - long len; - - Buf = NewStrBuf(); - - serv_printf("MSG0 %ld|1", MsgNum); /* ask for headers only */ - - StrBuf_ServGetln(Buf); - if (GetServerStatus(Buf, NULL) == 1) { - FreeStrBuf(&Buf); - return NULL; - } - - Msg = (message_summary*)malloc(sizeof(message_summary)); - memset(Msg, 0, sizeof(message_summary)); - while (len = StrBuf_ServGetln(Buf), - (len >= 0) && - ((len != 3) || - strcmp(ChrPtr(Buf), "000"))) - { - buf = ChrPtr(Buf); - ebuf = strchr(ChrPtr(Buf), '='); - nBuf = ebuf - buf; - if (GetHash(MsgEvaluators, buf, nBuf, &vEval) && vEval != NULL) { - Eval = (MsgPartEvaluatorStruct*) vEval; - StrBufCutLeft(Buf, nBuf + 1); - Eval->f(Msg, Buf); - } - else syslog(1, "Don't know how to handle Message Headerline [%s]", ChrPtr(Buf)); - } - return Msg; -} - - - - /* * load message pointers from the server for a "read messages" operation @@ -638,10 +599,11 @@ int load_msg_ptrs(const char *servcmd, * \param MatchMSet MSet we want to flag * \param FlagToSet Flag to set on each BasicMsgStruct->Flags if in MSet */ -void SetFlagsFromMSet(HashList *ScanMe, MSet *MatchMSet, int FlagToSet, int Reverse) +long SetFlagsFromMSet(HashList *ScanMe, MSet *MatchMSet, int FlagToSet, int Reverse) { const char *HashKey; long HKLen; + long count = 0; HashPos *at; void *vMsg; message_summary *Msg; @@ -652,17 +614,21 @@ void SetFlagsFromMSet(HashList *ScanMe, MSet *MatchMSet, int FlagToSet, int Reve Msg = (message_summary*) vMsg; if (Reverse && IsInMSetList(MatchMSet, Msg->msgnum)) { Msg->Flags = Msg->Flags | FlagToSet; + count++; } else if (!Reverse && !IsInMSetList(MatchMSet, Msg->msgnum)) { Msg->Flags = Msg->Flags | FlagToSet; + count++; } } DeleteHashPos(&at); + return count; } -void load_seen_flags(void) +long load_seen_flags(void) { + long count = 0; StrBuf *OldMsg; wcsession *WCC = WC; MSet *MatchMSet; @@ -675,15 +641,16 @@ void load_seen_flags(void) } else { FreeStrBuf(&OldMsg); - return; + return 0; } if (ParseMSet(&MatchMSet, OldMsg)) { - SetFlagsFromMSet(WCC->summ, MatchMSet, MSGFLAG_READ, 0); + count = SetFlagsFromMSet(WCC->summ, MatchMSet, MSGFLAG_READ, 0); } DeleteMSet(&MatchMSet); FreeStrBuf(&OldMsg); + return count; } extern readloop_struct rlid[]; @@ -722,7 +689,7 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer) long HKLen; WCTemplputParams SubTP; SharedMessageStatus Stat; - void *ViewSpecific; + void *ViewSpecific = NULL; if (havebstr("is_summary") && (1 == (ibstr("is_summary")))) { WCC->CurRoom.view = VIEW_MAILBOX; @@ -802,7 +769,7 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer) Stat.startmsg = 0; } - if (Stat.load_seen) load_seen_flags(); + if (Stat.load_seen) Stat.numNewmsgs = load_seen_flags(); /* * Print any inforation above the message list... @@ -820,9 +787,13 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer) Foo = NewStrBuf (); StrBufPrintf(Foo, "%ld", Stat.nummsgs); - PutBstr(HKEY("__READLOOP:TOTALMSGS"), NewStrBufDup(Foo)); + PutBstr(HKEY("__READLOOP:TOTALMSGS"), NewStrBufDup(Foo)); // keep Foo! + + StrBufPrintf(Foo, "%ld", Stat.numNewmsgs); + PutBstr(HKEY("__READLOOP:NEWMSGS"), NewStrBufDup(Foo)); // keep Foo! + StrBufPrintf(Foo, "%ld", Stat.startmsg); - PutBstr(HKEY("__READLOOP:STARTMSG"), Foo); + PutBstr(HKEY("__READLOOP:STARTMSG"), Foo); // store Foo elsewhere, descope it here. } /* @@ -918,6 +889,7 @@ void post_mime_to_server(void) { /* Remember, serv_printf() appends an extra newline */ if (include_text_alt) { + StrBuf *Buf; serv_printf("Content-type: multipart/alternative; " "boundary=\"%s\"\n", alt_boundary); serv_printf("This is a multipart message in MIME format.\n"); @@ -927,18 +899,30 @@ void post_mime_to_server(void) { serv_puts("Content-Transfer-Encoding: quoted-printable"); serv_puts(""); txtmail = html_to_ascii(bstr("msgtext"), 0, 80, 0); - text_to_server_qp(txtmail); /* Transmit message in quoted-printable encoding */ + Buf = NewStrBufPlain(txtmail, -1); free(txtmail); + text_to_server_qp(Buf); /* Transmit message in quoted-printable encoding */ + FreeStrBuf(&Buf); serv_printf("\n--%s", alt_boundary); } - serv_puts("Content-type: text/html; charset=utf-8"); - serv_puts("Content-Transfer-Encoding: quoted-printable"); - serv_puts(""); - serv_puts("
\r\n"); - text_to_server_qp(bstr("msgtext")); /* Transmit message in quoted-printable encoding */ - serv_puts("\r\n"); + if (havebstr("markdown")) + { + serv_puts("Content-type: text/x-markdown; charset=utf-8"); + serv_puts("Content-Transfer-Encoding: quoted-printable"); + serv_puts(""); + text_to_server_qp(sbstr("msgtext")); /* Transmit message in quoted-printable encoding */ + } + else + { + serv_puts("Content-type: text/html; charset=utf-8"); + serv_puts("Content-Transfer-Encoding: quoted-printable"); + serv_puts(""); + serv_puts("\r\n"); + text_to_server_qp(sbstr("msgtext")); /* Transmit message in quoted-printable encoding */ + serv_puts("\r\n"); + } if (include_text_alt) { serv_printf("--%s--", alt_boundary); @@ -1042,7 +1026,7 @@ void post_message(void) StrBuf_ServGetln(Buf); if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) { /* You probably don't even have a dumb Drafts folder */ - syslog(9, "%s:%d: server save to drafts error: %s\n", __FILE__, __LINE__, ChrPtr(Buf) + 4); + syslog(LOG_DEBUG, "%s:%d: server save to drafts error: %s\n", __FILE__, __LINE__, ChrPtr(Buf) + 4); AppendImportantMessage(_("Saved to Drafts failed: "), -1); display_enter(); FreeStrBuf(&Buf); @@ -1116,7 +1100,7 @@ void post_message(void) } else { - syslog(9, "%s\n", ChrPtr(CmdBuf)); + syslog(LOG_DEBUG, "%s\n", ChrPtr(CmdBuf)); serv_puts(ChrPtr(CmdBuf)); FreeStrBuf(&CmdBuf); @@ -1153,7 +1137,7 @@ void post_message(void) } dont_post = lbstr("postseq"); } else { - syslog(9, "%s:%d: server post error: %s", __FILE__, __LINE__, ChrPtr(Buf) + 4); + syslog(LOG_DEBUG, "%s:%d: server post error: %s", __FILE__, __LINE__, ChrPtr(Buf) + 4); AppendImportantMessage(ChrPtr(Buf) + 4, StrLength(Buf) - 4); display_enter(); if (saving_to_drafts) gotoroom(WCC->CurRoom.name); @@ -1207,24 +1191,40 @@ void upload_attachment(void) { long newnlen; void *v; wc_mime_attachment *att; + const StrBuf *Tmpl = sbstr("template"); + const StrBuf *MimeType = NULL; + const StrBuf *UID; - syslog(9, "upload_attachment()\n"); - wc_printf("upload_attachment()