5 CtxType CTX_MAILSUM = CTX_NONE;
6 CtxType CTX_MIME_ATACH = CTX_NONE;
8 HashList *MsgHeaderHandler = NULL;
9 HashList *DflMsgHeaderHandler = NULL;
10 HashList *DflEnumMsgHeaderHandler = NULL;
13 static inline void CheckConvertBufs(struct wcsession *WCC)
15 if (WCC->ConvertBuf1 == NULL)
16 WCC->ConvertBuf1 = NewStrBuf();
17 if (WCC->ConvertBuf2 == NULL)
18 WCC->ConvertBuf2 = NewStrBuf();
22 * message index functions
26 void DestroyMimeParts(wc_mime_attachment *Mime)
28 FreeStrBuf(&Mime->Name);
29 FreeStrBuf(&Mime->FileName);
30 FreeStrBuf(&Mime->PartNum);
31 FreeStrBuf(&Mime->Disposition);
32 FreeStrBuf(&Mime->ContentType);
33 FreeStrBuf(&Mime->Charset);
34 FreeStrBuf(&Mime->Data);
37 void DestroyMime(void *vMime)
39 wc_mime_attachment *Mime = (wc_mime_attachment*)vMime;
40 DestroyMimeParts(Mime);
44 void DestroyMessageSummary(void *vMsg)
46 message_summary *Msg = (message_summary*) vMsg;
48 FreeStrBuf(&Msg->from);
50 FreeStrBuf(&Msg->subj);
51 FreeStrBuf(&Msg->reply_inreplyto);
52 FreeStrBuf(&Msg->reply_references);
53 FreeStrBuf(&Msg->cccc);
54 FreeStrBuf(&Msg->ReplyTo);
55 FreeStrBuf(&Msg->AllRcpt);
56 FreeStrBuf(&Msg->Room);
57 FreeStrBuf(&Msg->Rfca);
58 FreeStrBuf(&Msg->EnvTo);
59 DeleteHash(&Msg->Attachments); /* list of Attachments */
60 DeleteHash(&Msg->Submessages);
61 DeleteHash(&Msg->AttachLinks);
62 DeleteHash(&Msg->AllAttach);
66 int EvaluateMsgHdrEnum(eMessageField f, message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
69 headereval* Hdr = NULL;
70 if (GetHash(DflEnumMsgHeaderHandler, IKEY(f), &vHdr) &&
72 Hdr = (headereval*)vHdr;
76 Hdr->evaluator(Msg, HdrLine, FoundCharset);
80 int EvaluateMsgHdr(const char *HeaderName, long HdrNLen, message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
83 headereval* Hdr = NULL;
85 if (GetHash(DflMsgHeaderHandler, HeaderName, HdrNLen, &vHdr) &&
87 Hdr = (headereval*)vHdr;
90 if (Hdr == NULL && GetHash(MsgHeaderHandler, HeaderName, HdrNLen, &vHdr) &&
92 Hdr = (headereval*)vHdr;
96 Hdr->evaluator(Msg, HdrLine, FoundCharset);
100 void RegisterMsgHdr(const char *HeaderName, long HdrNLen, ExamineMsgHeaderFunc evaluator, int type)
103 ev = (headereval*) malloc(sizeof(headereval));
104 ev->evaluator = evaluator;
109 if (GetFieldFromMnemonic(&f, HeaderName)) {
110 Put(DflMsgHeaderHandler, HeaderName, HdrNLen, ev, NULL);
111 Put(DflEnumMsgHeaderHandler, IKEY(f), ev, reference_free_handler);
115 Put(MsgHeaderHandler, HeaderName, HdrNLen, ev, NULL);
118 void RegisterMimeRenderer(const char *HeaderName, long HdrNLen,
119 RenderMimeFunc MimeRenderer,
120 int InlineRenderable,
123 RenderMimeFuncStruct *f;
125 f = (RenderMimeFuncStruct*) malloc(sizeof(RenderMimeFuncStruct));
127 Put(MimeRenderHandler, HeaderName, HdrNLen, f, NULL);
128 if (InlineRenderable)
129 RegisterEmbeddableMimeType(HeaderName, HdrNLen, 10000 - Priority);
132 /*----------------------------------------------------------------------------*/
135 * comparator for two longs in descending order.
137 int longcmp_r(const void *s1, const void *s2) {
141 l1 = *(long *)GetSearchPayload(s1);
142 l2 = *(long *)GetSearchPayload(s2);
144 if (l1 > l2) return(-1);
145 if (l1 < l2) return(+1);
150 * comparator for longs; descending order.
152 int qlongcmp_r(const void *s1, const void *s2) {
156 if (l1 > l2) return(-1);
157 if (l1 < l2) return(+1);
163 * comparator for message summary structs by ascending subject.
165 int summcmp_subj(const void *s1, const void *s2) {
166 message_summary *summ1;
167 message_summary *summ2;
169 summ1 = (message_summary *)GetSearchPayload(s1);
170 summ2 = (message_summary *)GetSearchPayload(s2);
171 return strcasecmp(ChrPtr(summ1->subj), ChrPtr(summ2->subj));
175 * comparator for message summary structs by descending subject.
177 int summcmp_rsubj(const void *s1, const void *s2) {
178 message_summary *summ1;
179 message_summary *summ2;
181 summ1 = (message_summary *)GetSearchPayload(s1);
182 summ2 = (message_summary *)GetSearchPayload(s2);
183 return strcasecmp(ChrPtr(summ2->subj), ChrPtr(summ1->subj));
186 * comparator for message summary structs by descending subject.
188 int groupchange_subj(const void *s1, const void *s2) {
189 message_summary *summ1;
190 message_summary *summ2;
192 summ1 = (message_summary *)s1;
193 summ2 = (message_summary *)s2;
194 return ChrPtr(summ2->subj)[0] != ChrPtr(summ1->subj)[0];
198 * comparator for message summary structs by ascending sender.
200 int summcmp_sender(const void *s1, const void *s2) {
201 message_summary *summ1;
202 message_summary *summ2;
204 summ1 = (message_summary *)GetSearchPayload(s1);
205 summ2 = (message_summary *)GetSearchPayload(s2);
206 return strcasecmp(ChrPtr(summ1->from), ChrPtr(summ2->from));
210 * comparator for message summary structs by descending sender.
212 int summcmp_rsender(const void *s1, const void *s2) {
213 message_summary *summ1;
214 message_summary *summ2;
216 summ1 = (message_summary *)GetSearchPayload(s1);
217 summ2 = (message_summary *)GetSearchPayload(s2);
218 return strcasecmp(ChrPtr(summ2->from), ChrPtr(summ1->from));
221 * comparator for message summary structs by descending sender.
223 int groupchange_sender(const void *s1, const void *s2) {
224 message_summary *summ1;
225 message_summary *summ2;
227 summ1 = (message_summary *)s1;
228 summ2 = (message_summary *)s2;
229 return strcasecmp(ChrPtr(summ2->from), ChrPtr(summ1->from)) != 0;
234 * comparator for message summary structs by ascending date.
236 int summcmp_date(const void *s1, const void *s2) {
237 message_summary *summ1;
238 message_summary *summ2;
240 summ1 = (message_summary *)GetSearchPayload(s1);
241 summ2 = (message_summary *)GetSearchPayload(s2);
243 if (summ1->date < summ2->date) return -1;
244 else if (summ1->date > summ2->date) return +1;
249 * comparator for message summary structs by descending date.
251 int summcmp_rdate(const void *s1, const void *s2) {
252 message_summary *summ1;
253 message_summary *summ2;
255 summ1 = (message_summary *)GetSearchPayload(s1);
256 summ2 = (message_summary *)GetSearchPayload(s2);
258 if (summ1->date < summ2->date) return +1;
259 else if (summ1->date > summ2->date) return -1;
264 * comparator for message summary structs by descending date.
266 const long DAYSECONDS = 24 * 60 * 60;
267 int groupchange_date(const void *s1, const void *s2) {
268 message_summary *summ1;
269 message_summary *summ2;
271 summ1 = (message_summary *)s1;
272 summ2 = (message_summary *)s2;
274 return (summ1->date % DAYSECONDS) != (summ2->date %DAYSECONDS);
278 /* Stub handlers for MIME parser */
279 void examine_pref(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {return;}
280 void examine_suff(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {return;}
281 void examine_path(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {return;}
283 void examine_content_encoding(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
285 /* nothing to do here */
289 void examine_exti(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
291 /* nothing to do here */
294 void examine_nhdr(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
297 if (!strncasecmp(ChrPtr(HdrLine), "yes", 8))
300 int Conditional_ANONYMOUS_MESSAGE(StrBuf *Target, WCTemplputParams *TP)
302 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
303 return Msg->nhdr != 0;
306 void examine_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
308 Msg->format_type = StrToi(HdrLine);
312 void examine_from(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
314 CheckConvertBufs(WC);
315 FreeStrBuf(&Msg->from);
316 Msg->from = NewStrBufPlain(NULL, StrLength(HdrLine));
317 StrBuf_RFC822_2_Utf8(Msg->from,
324 void tmplput_MAIL_SUMM_FROM(StrBuf *Target, WCTemplputParams *TP)
326 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
327 StrBufAppendTemplate(Target, TP, Msg->from, 0);
330 void examine_subj(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
332 CheckConvertBufs(WC);
333 FreeStrBuf(&Msg->subj);
334 Msg->subj = NewStrBufPlain(NULL, StrLength(HdrLine));
335 StrBuf_RFC822_2_Utf8(Msg->subj,
342 void tmplput_MAIL_SUMM_SUBJECT(StrBuf *Target, WCTemplputParams *TP)
344 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
346 if (TP->Tokens->nParameters == 4)
351 GetTemplateTokenString(Target, TP, 3, &pch, &len);
353 (strstr(ChrPtr(Msg->subj), pch) == NULL))
355 GetTemplateTokenString(Target, TP, 2, &pch, &len);
356 StrBufAppendBufPlain(Target, pch, len, 0);
359 StrBufAppendTemplate(Target, TP, Msg->subj, 0);
363 * Conditional returns true if the message has a Subject and it is nonzero in length
365 int Conditional_MAIL_SUMM_SUBJECT(StrBuf *Target, WCTemplputParams *TP) {
366 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
367 return StrLength(Msg->subj) > 0;
372 * Conditional returns true if the message originated on the local system
374 int Conditional_MAIL_LOCAL(StrBuf *Target, WCTemplputParams *TP) {
375 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
376 return (Msg->is_local ? 1 : 0);
380 void examine_msgn(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
384 CheckConvertBufs(WC);
385 FreeStrBuf(&Msg->reply_inreplyto);
386 Msg->reply_inreplyto = NewStrBufPlain(NULL, StrLength(HdrLine));
387 pOffset = strchr(ChrPtr(HdrLine), '/');
388 if (pOffset != NULL) {
389 Offset = pOffset - ChrPtr(HdrLine);
391 Msg->reply_inreplyto_hash = ThreadIdHashOffset(HdrLine, Offset);
392 StrBuf_RFC822_2_Utf8(Msg->reply_inreplyto,
401 void tmplput_MAIL_SUMM_INREPLYTO(StrBuf *Target, WCTemplputParams *TP) {
402 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
403 StrBufAppendTemplate(Target, TP, Msg->reply_inreplyto, 0);
407 int Conditional_MAIL_SUMM_UNREAD(StrBuf *Target, WCTemplputParams *TP) {
408 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
409 return (Msg->Flags & MSGFLAG_READ) != 0;
413 void examine_wefw(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
418 CheckConvertBufs(WCC);
419 FreeStrBuf(&Msg->reply_references);
420 Msg->reply_references = NewStrBufPlain(NULL, StrLength(HdrLine));
421 pOffset = strchr(ChrPtr(HdrLine), '/');
422 if (pOffset != NULL) {
423 Offset = pOffset - ChrPtr(HdrLine);
425 Msg->reply_references_hash = ThreadIdHashOffset(HdrLine, Offset);
426 StrBuf_RFC822_2_Utf8(Msg->reply_references,
435 void tmplput_MAIL_SUMM_REFIDS(StrBuf *Target, WCTemplputParams *TP) {
436 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
437 StrBufAppendTemplate(Target, TP, Msg->reply_references, 0);
441 void examine_replyto(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
444 CheckConvertBufs(WCC);
445 FreeStrBuf(&Msg->ReplyTo);
446 Msg->ReplyTo = NewStrBufPlain(NULL, StrLength(HdrLine));
447 StrBuf_RFC822_2_Utf8(Msg->ReplyTo,
453 if (Msg->AllRcpt == NULL)
454 Msg->AllRcpt = NewStrBufPlain(NULL, StrLength(HdrLine));
455 if (StrLength(Msg->AllRcpt) > 0) {
456 StrBufAppendBufPlain(Msg->AllRcpt, HKEY(", "), 0);
458 StrBufAppendBuf(Msg->AllRcpt, Msg->ReplyTo, 0);
462 void tmplput_MAIL_SUMM_REPLYTO(StrBuf *Target, WCTemplputParams *TP) {
463 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
464 StrBufAppendTemplate(Target, TP, Msg->ReplyTo, 0);
468 void examine_cccc(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
471 CheckConvertBufs(WCC);
472 FreeStrBuf(&Msg->cccc);
473 Msg->cccc = NewStrBufPlain(NULL, StrLength(HdrLine));
474 StrBuf_RFC822_2_Utf8(Msg->cccc,
480 if (Msg->AllRcpt == NULL)
481 Msg->AllRcpt = NewStrBufPlain(NULL, StrLength(HdrLine));
482 if (StrLength(Msg->AllRcpt) > 0) {
483 StrBufAppendBufPlain(Msg->AllRcpt, HKEY(", "), 0);
485 StrBufAppendBuf(Msg->AllRcpt, Msg->cccc, 0);
489 void tmplput_MAIL_SUMM_CCCC(StrBuf *Target, WCTemplputParams *TP) {
490 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
491 StrBufAppendTemplate(Target, TP, Msg->cccc, 0);
495 void examine_room(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
496 if ((StrLength(HdrLine) > 0) &&
497 (strcasecmp(ChrPtr(HdrLine), ChrPtr(WC->CurRoom.name)))) {
498 FreeStrBuf(&Msg->Room);
499 Msg->Room = NewStrBufDup(HdrLine);
504 void tmplput_MAIL_SUMM_ORGROOM(StrBuf *Target, WCTemplputParams *TP) {
505 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
506 StrBufAppendTemplate(Target, TP, Msg->Room, 0);
510 void examine_rfca(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
511 FreeStrBuf(&Msg->Rfca);
512 Msg->Rfca = NewStrBufDup(HdrLine);
516 void examine_locl(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
521 void tmplput_MAIL_SUMM_RFCA(StrBuf *Target, WCTemplputParams *TP) {
522 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
523 StrBufAppendTemplate(Target, TP, Msg->Rfca, 0);
527 int Conditional_MAIL_SUMM_RFCA(StrBuf *Target, WCTemplputParams *TP) {
528 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
529 return StrLength(Msg->Rfca) > 0;
533 int Conditional_MAIL_SUMM_CCCC(StrBuf *Target, WCTemplputParams *TP) {
534 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
535 return StrLength(Msg->cccc) > 0;
539 int Conditional_MAIL_SUMM_REPLYTO(StrBuf *Target, WCTemplputParams *TP) {
540 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
541 return StrLength(Msg->ReplyTo) > 0;
545 void examine_nvto(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
548 CheckConvertBufs(WCC);
549 FreeStrBuf(&Msg->EnvTo);
550 Msg->EnvTo = NewStrBufPlain(NULL, StrLength(HdrLine));
551 StrBuf_RFC822_2_Utf8(Msg->EnvTo,
560 void examine_rcpt(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
563 CheckConvertBufs(WCC);
564 FreeStrBuf(&Msg->to);
565 Msg->to = NewStrBufPlain(NULL, StrLength(HdrLine));
566 StrBuf_RFC822_2_Utf8(Msg->to,
572 if (Msg->AllRcpt == NULL)
573 Msg->AllRcpt = NewStrBufPlain(NULL, StrLength(HdrLine));
574 if (StrLength(Msg->AllRcpt) > 0) {
575 StrBufAppendBufPlain(Msg->AllRcpt, HKEY(", "), 0);
577 StrBufAppendBuf(Msg->AllRcpt, Msg->to, 0);
581 void tmplput_MAIL_SUMM_TO(StrBuf *Target, WCTemplputParams *TP) {
582 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
583 StrBufAppendTemplate(Target, TP, Msg->to, 0);
587 int Conditional_MAIL_SUMM_TO(StrBuf *Target, WCTemplputParams *TP) {
588 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
589 return StrLength(Msg->to) != 0;
593 int Conditional_MAIL_SUMM_SUBJ(StrBuf *Target, WCTemplputParams *TP) {
594 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
595 return StrLength(Msg->subj) != 0;
599 void tmplput_MAIL_SUMM_ALLRCPT(StrBuf *Target, WCTemplputParams *TP) {
600 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
601 StrBufAppendTemplate(Target, TP, Msg->AllRcpt, 0);
605 void tmplput_SUMM_COUNT(StrBuf *Target, WCTemplputParams *TP) {
606 StrBufAppendPrintf(Target, "%d", GetCount( WC->summ));
610 HashList *iterate_get_mailsumm_All(StrBuf *Target, WCTemplputParams *TP) {
615 void examine_time(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {
616 Msg->date = StrTol(HdrLine);
620 void tmplput_MAIL_SUMM_DATE_BRIEF(StrBuf *Target, WCTemplputParams *TP)
623 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
624 webcit_fmt_date(datebuf, 64, Msg->date, DATEFMT_BRIEF);
625 StrBufAppendBufPlain(Target, datebuf, -1, 0);
628 void tmplput_MAIL_SUMM_EUID(StrBuf *Target, WCTemplputParams *TP)
630 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
631 StrBufAppendTemplate(Target, TP, Msg->euid, 0);
634 void tmplput_MAIL_SUMM_DATE_FULL(StrBuf *Target, WCTemplputParams *TP)
637 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
638 webcit_fmt_date(datebuf, 64, Msg->date, DATEFMT_FULL);
639 StrBufAppendBufPlain(Target, datebuf, -1, 0);
641 void tmplput_MAIL_SUMM_DATE_NO(StrBuf *Target, WCTemplputParams *TP)
643 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
644 StrBufAppendPrintf(Target, "%ld", Msg->date, 0);
649 void render_MAIL(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
651 wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
652 const StrBuf *TemplateMime;
654 if (Mime->Data == NULL)
655 Mime->Data = NewStrBufPlain(NULL, Mime->length);
657 FlushStrBuf(Mime->Data);
658 read_message(Mime->Data, HKEY("view_submessage"), Mime->msgnum, Mime->PartNum, &TemplateMime, TP);
660 if ( (!IsEmptyStr(mime_submessages)) && (!section[0]) ) {
661 for (i=0; i<num_tokens(mime_submessages, '|'); ++i) {
662 extract_token(buf, mime_submessages, i, '|', sizeof buf);
663 / ** use printable_view to suppress buttons * /
664 wc_printf("<blockquote>");
665 read_message(Mime->msgnum, 1, ChrPtr(Mime->Section));
666 wc_printf("</blockquote>");
672 void render_MIME_ICS(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
674 wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
675 if (StrLength(Mime->Data) == 0) {
678 if (StrLength(Mime->Data) > 0) {
679 cal_process_attachment(Mime);
685 void examine_mime_part(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
687 const char *Ptr = NULL;
688 wc_mime_attachment *Mime;
692 CheckConvertBufs(WCC);
693 Mime = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment));
694 memset(Mime, 0, sizeof(wc_mime_attachment));
695 Mime->msgnum = Msg->msgnum;
698 Mime->Name = NewStrBuf();
699 StrBufExtract_NextToken(Buf, HdrLine, &Ptr, '|');
700 StrBuf_RFC822_2_Utf8(Mime->Name,
706 StrBufTrim(Mime->Name);
708 StrBufExtract_NextToken(Buf, HdrLine, &Ptr, '|');
709 Mime->FileName = NewStrBuf();
710 StrBuf_RFC822_2_Utf8(Mime->FileName,
716 StrBufTrim(Mime->FileName);
718 Mime->PartNum = NewStrBuf();
719 StrBufExtract_NextToken(Mime->PartNum, HdrLine, &Ptr, '|');
720 StrBufTrim(Mime->PartNum);
721 if (strchr(ChrPtr(Mime->PartNum), '.') != NULL)
726 Mime->Disposition = NewStrBuf();
727 StrBufExtract_NextToken(Mime->Disposition, HdrLine, &Ptr, '|');
729 Mime->ContentType = NewStrBuf();
730 StrBufExtract_NextToken(Mime->ContentType, HdrLine, &Ptr, '|');
731 StrBufTrim(Mime->ContentType);
732 StrBufLowerCase(Mime->ContentType);
733 if (!strcmp(ChrPtr(Mime->ContentType), "application/octet-stream")) {
734 StrBufPlain(Mime->ContentType,
735 GuessMimeByFilename(SKEY(Mime->FileName)), -1);
738 Mime->length = StrBufExtractNext_int(HdrLine, &Ptr, '|');
740 StrBufSkip_NTokenS(HdrLine, &Ptr, '|', 1); /* cbid?? */
742 Mime->Charset = NewStrBuf();
743 StrBufExtract_NextToken(Mime->Charset, HdrLine, &Ptr, '|');
746 if ( (StrLength(Mime->FileName) == 0) && (StrLength(Mime->Name) > 0) ) {
747 StrBufAppendBuf(Mime->FileName, Mime->Name, 0);
750 if (StrLength(Msg->PartNum) > 0) {
752 StrBufPrintf(Buf, "%s.%s", ChrPtr(Msg->PartNum), ChrPtr(Mime->PartNum));
758 if (Msg->AllAttach == NULL)
759 Msg->AllAttach = NewHash(1,NULL);
760 Put(Msg->AllAttach, SKEY(Mime->PartNum), Mime, DestroyMime);
765 void evaluate_mime_part(StrBuf *Target, WCTemplputParams *TP)
767 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
768 wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
771 /* just print the root-node */
772 if ((Mime->level >= 1) &&
773 GetHash(MimeRenderHandler, SKEY(Mime->ContentType), &vMimeRenderer) &&
774 vMimeRenderer != NULL)
776 Mime->Renderer = (RenderMimeFuncStruct*) vMimeRenderer;
777 if (Msg->Submessages == NULL)
778 Msg->Submessages = NewHash(1,NULL);
779 Put(Msg->Submessages, SKEY(Mime->PartNum), Mime, reference_free_handler);
781 else if ((Mime->level >= 1) &&
782 (!strcasecmp(ChrPtr(Mime->Disposition), "inline"))
783 && (!strncasecmp(ChrPtr(Mime->ContentType), "image/", 6)) ){
784 if (Msg->AttachLinks == NULL)
785 Msg->AttachLinks = NewHash(1,NULL);
786 Put(Msg->AttachLinks, SKEY(Mime->PartNum), Mime, reference_free_handler);
788 else if ((Mime->level >= 1) &&
789 (StrLength(Mime->ContentType) > 0) &&
790 ( (!strcasecmp(ChrPtr(Mime->Disposition), "attachment"))
791 || (!strcasecmp(ChrPtr(Mime->Disposition), "inline"))
792 || (!strcasecmp(ChrPtr(Mime->Disposition), ""))))
794 if (Msg->AttachLinks == NULL)
795 Msg->AttachLinks = NewHash(1,NULL);
796 Put(Msg->AttachLinks, SKEY(Mime->PartNum), Mime, reference_free_handler);
797 if ((strcasecmp(ChrPtr(Mime->ContentType), "application/octet-stream") == 0) &&
798 (StrLength(Mime->FileName) > 0)) {
799 FlushStrBuf(Mime->ContentType);
800 StrBufAppendBufPlain(Mime->ContentType,
801 GuessMimeByFilename(SKEY(Mime->FileName)),
807 void tmplput_MAIL_SUMM_NATTACH(StrBuf *Target, WCTemplputParams *TP)
809 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
810 StrBufAppendPrintf(Target, "%ld", GetCount(Msg->Attachments));
813 void examine_text(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
815 if (Msg->MsgBody->Data == NULL)
816 Msg->MsgBody->Data = NewStrBufPlain(NULL, SIZ);
818 FlushStrBuf(Msg->MsgBody->Data);
821 void examine_msg4_partnum(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
823 Msg->MsgBody->PartNum = NewStrBufDup(HdrLine);
824 StrBufTrim(Msg->MsgBody->PartNum);
827 void examine_content_lengh(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
829 Msg->MsgBody->length = StrTol(HdrLine);
830 Msg->MsgBody->size_known = 1;
833 void examine_content_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
841 Msg->MsgBody->ContentType = NewStrBufDup(HdrLine);
842 sem = strchr(ChrPtr(HdrLine), ';');
845 Token = NewStrBufPlain(NULL, StrLength(HdrLine));
846 Value = NewStrBufPlain(NULL, StrLength(HdrLine));
847 len = sem - ChrPtr(HdrLine);
848 StrBufCutAt(Msg->MsgBody->ContentType, len, NULL);
849 while (sem != NULL) {
850 while (isspace(*(sem + 1)))
852 StrBufCutLeft(HdrLine, sem - ChrPtr(HdrLine));
853 sem = strchr(ChrPtr(HdrLine), ';');
855 len = sem - ChrPtr(HdrLine);
857 len = StrLength(HdrLine);
860 StrBufAppendBufPlain(Token, ChrPtr(HdrLine), len, 0);
861 eq = strchr(ChrPtr(Token), '=');
863 len = eq - ChrPtr(Token);
864 StrBufAppendBufPlain(Value, eq + 1, StrLength(Token) - len - 1, 0);
865 StrBufCutAt(Token, len, NULL);
870 if (EvaluateMsgHdr(SKEY(Token), Msg, Value, FoundCharset) < 0)
871 syslog(LOG_WARNING, "don't know how to handle content type sub-header[%s]\n", ChrPtr(Token));
879 int ReadOneMessageSummary(message_summary *Msg, StrBuf *FoundCharset, StrBuf *Buf)
886 serv_printf("MSG0 %ld|1", Msg->msgnum); /* ask for headers only */
888 StrBuf_ServGetln(Buf);
889 if (GetServerStatus(Buf, NULL) != 1) {
893 while (len = StrBuf_ServGetln(Buf),
896 strcmp(ChrPtr(Buf), "000")))
899 ebuf = strchr(ChrPtr(Buf), '=');
902 if (EvaluateMsgHdr(buf, nBuf, Msg, Buf, FoundCharset) < 0)
903 syslog(LOG_INFO, "Don't know how to handle Message Headerline [%s]", ChrPtr(Buf));
908 void tmplput_MAIL_SUMM_N(StrBuf *Target, WCTemplputParams *TP)
910 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
911 StrBufAppendPrintf(Target, "%ld", Msg->msgnum);
915 void tmplput_MAIL_SUMM_PERMALINK(StrBuf *Target, WCTemplputParams *TP)
917 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
921 perma_link = NewStrBufPlain(HKEY("/readfwd?go="));
922 StrBufUrlescAppend(perma_link, WC->CurRoom.name, NULL);
923 View = sbstr("view");
925 StrBufAppendBufPlain(perma_link, HKEY("?view="), 0);
926 StrBufAppendBuf(perma_link, View, 0);
928 StrBufAppendBufPlain(perma_link, HKEY("?start_reading_at="), 0);
929 StrBufAppendPrintf(perma_link, "%ld#%ld", Msg->msgnum, Msg->msgnum);
930 StrBufAppendBuf(Target, perma_link, 0);
931 FreeStrBuf(&perma_link);
935 int Conditional_MAIL_MIME_ALL(StrBuf *Target, WCTemplputParams *TP)
937 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
938 return GetCount(Msg->Attachments) > 0;
941 int Conditional_MAIL_MIME_SUBMESSAGES(StrBuf *Target, WCTemplputParams *TP)
943 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
944 return GetCount(Msg->Submessages) > 0;
947 int Conditional_MAIL_MIME_ATTACHLINKS(StrBuf *Target, WCTemplputParams *TP)
949 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
950 return GetCount(Msg->AttachLinks) > 0;
953 int Conditional_MAIL_MIME_ATTACH(StrBuf *Target, WCTemplputParams *TP)
955 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
956 return GetCount(Msg->AllAttach) > 0;
959 void tmplput_QUOTED_MAIL_BODY(StrBuf *Target, WCTemplputParams *TP)
965 MsgNum = LBstr(TKEY(0));
967 read_message(Buf, HKEY("view_message_replyquote"), MsgNum, NULL, &Mime, TP);
968 StrBufAppendTemplate(Target, TP, Buf, 1);
972 void tmplput_EDIT_MAIL_BODY(StrBuf *Target, WCTemplputParams *TP)
978 MsgNum = LBstr(TKEY(0));
980 read_message(Buf, HKEY("view_message_edit"), MsgNum, NULL, &Mime, TP);
981 StrBufAppendTemplate(Target, TP, Buf, 1);
985 void tmplput_EDIT_WIKI_BODY(StrBuf *Target, WCTemplputParams *TP)
991 /* Insert the existing content of the wiki page into the editor. But we only want
992 * to do this the first time -- if the user is uploading an attachment we don't want
995 if (!havebstr("attach_button")) {
996 StrBuf *wikipage = NewStrBufDup(sbstr("page"));
997 putbstr("format", NewStrBufPlain(HKEY("plain")));
998 str_wiki_index(wikipage);
999 msgnum = locate_message_by_uid(ChrPtr(wikipage));
1000 FreeStrBuf(&wikipage);
1003 read_message(Buf, HKEY("view_message_wikiedit"), msgnum, NULL, &Mime, TP);
1004 StrBufAppendTemplate(Target, TP, Buf, 1);
1010 void tmplput_MAIL_BODY(StrBuf *Target, WCTemplputParams *TP)
1012 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
1013 StrBufAppendTemplate(Target, TP, Msg->MsgBody->Data, 0);
1017 void render_MAIL_variformat(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
1019 /* Messages in legacy Citadel variformat get handled thusly... */
1020 wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
1021 StrBuf *TTarget = NewStrBufPlain(NULL, StrLength(Mime->Data));
1022 FmOut(TTarget, "JUSTIFY", Mime->Data);
1023 FreeStrBuf(&Mime->Data);
1024 Mime->Data = TTarget;
1027 void render_MAIL_text_plain(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
1029 wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
1030 const char *ptr, *pte;
1031 const char *BufPtr = NULL;
1045 iconv_t ic = (iconv_t)(-1) ;
1048 if ((StrLength(Mime->Data) == 0) && (Mime->length > 0)) {
1049 FreeStrBuf(&Mime->Data);
1055 if (StrLength(Mime->Charset) != 0)
1057 else if (StrLength(FoundCharset) > 0)
1059 else if (StrLength(WC->DefaultCharset) > 0)
1060 cs = WC->DefaultCharset;
1064 else if (!strcasecmp(ChrPtr(cs), "utf-8")) {
1067 else if (!strcasecmp(ChrPtr(cs), "us-ascii")) {
1071 ctdl_iconv_open("UTF-8", ChrPtr(cs), &ic);
1072 if (ic == (iconv_t)(-1) ) {
1073 syslog(LOG_WARNING, "%s:%d iconv_open(UTF-8, %s) failed: %s\n",
1074 __FILE__, __LINE__, ChrPtr(Mime->Charset), strerror(errno));
1079 Line = NewStrBufPlain(NULL, SIZ);
1080 Line1 = NewStrBufPlain(NULL, SIZ);
1081 Line2 = NewStrBufPlain(NULL, SIZ);
1082 TTarget = NewStrBufPlain(NULL, StrLength(Mime->Data));
1085 if (StrLength(Mime->Data) > 0)
1088 StrBufSipLine(Line, Mime->Data, &BufPtr);
1092 len = StrLength(Line);
1095 while ((ptr < pte) &&
1104 if (i > 0) StrBufCutLeft(Line, i);
1106 if (StrLength(Line) == 0) {
1109 StrBufAppendBufPlain(TTarget, HKEY("<tt></tt><br>\n"), 0);
1115 for (i = bn; i < bq; i++)
1116 StrBufAppendBufPlain(TTarget, HKEY("<blockquote>"), 0);
1117 for (i = bq; i < bn; i++)
1118 StrBufAppendBufPlain(TTarget, HKEY("</blockquote>"), 0);
1121 StrBufConvert(Line, Line1, &ic);
1124 StrBufAppendBufPlain(TTarget, HKEY("<tt>"), 0);
1125 UrlizeText(Line1, Line, Line2);
1127 StrEscAppend(TTarget, Line1, NULL, 0, 0);
1128 StrBufAppendBufPlain(TTarget, HKEY("</tt><br>\n"), 0);
1132 while ((BufPtr != StrBufNOTNULL) &&
1135 if (nEmptyLines > 0)
1136 StrBufCutRight(TTarget, nEmptyLines * (sizeof ("<tt></tt><br>\n") - 1));
1137 for (i = 0; i < bn; i++)
1138 StrBufAppendBufPlain(TTarget, HKEY("</blockquote>"), 0);
1140 StrBufAppendBufPlain(TTarget, HKEY("</i><br>"), 0);
1142 if (ic != (iconv_t)(-1) ) {
1147 FreeStrBuf(&Mime->Data);
1148 Mime->Data = TTarget;
1149 FlushStrBuf(Mime->ContentType);
1150 StrBufAppendBufPlain(Mime->ContentType, HKEY("text/html"), 0);
1151 FlushStrBuf(Mime->Charset);
1152 StrBufAppendBufPlain(Mime->Charset, HKEY("UTF-8"), 0);
1158 void render_MAIL_html(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
1160 wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
1163 if (StrLength(Mime->Data) == 0)
1166 Buf = NewStrBufPlain(NULL, StrLength(Mime->Data));
1168 /* HTML is fun, but we've got to strip it first */
1169 output_html(ChrPtr(Mime->Charset),
1170 (WC->CurRoom.view == VIEW_WIKI ? 1 : 0),
1173 FreeStrBuf(&Mime->Data);
1178 void render_MAIL_UNKNOWN(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
1180 wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
1181 /* Unknown weirdness */
1182 FlushStrBuf(Mime->Data);
1183 StrBufAppendBufPlain(Mime->Data, _("I don't know how to display "), -1, 0);
1184 StrBufAppendBuf(Mime->Data, Mime->ContentType, 0);
1185 StrBufAppendBufPlain(Mime->Data, HKEY("<br>\n"), 0);
1189 HashList *iterate_get_mime_All(StrBuf *Target, WCTemplputParams *TP)
1191 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
1192 return Msg->Attachments;
1194 HashList *iterate_get_mime_Submessages(StrBuf *Target, WCTemplputParams *TP)
1196 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
1197 return Msg->Submessages;
1199 HashList *iterate_get_mime_AttachLinks(StrBuf *Target, WCTemplputParams *TP)
1201 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
1202 return Msg->AttachLinks;
1204 HashList *iterate_get_mime_Attachments(StrBuf *Target, WCTemplputParams *TP)
1206 message_summary *Msg = (message_summary*) CTX(CTX_MAILSUM);
1207 return Msg->AllAttach;
1210 void tmplput_MIME_Name(StrBuf *Target, WCTemplputParams *TP)
1212 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1213 StrBufAppendTemplate(Target, TP, mime->Name, 0);
1216 void tmplput_MIME_FileName(StrBuf *Target, WCTemplputParams *TP)
1218 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1219 StrBufAppendTemplate(Target, TP, mime->FileName, 0);
1222 void tmplput_MIME_PartNum(StrBuf *Target, WCTemplputParams *TP)
1224 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1225 StrBufAppendTemplate(Target, TP, mime->PartNum, 0);
1228 void tmplput_MIME_MsgNum(StrBuf *Target, WCTemplputParams *TP)
1230 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1231 StrBufAppendPrintf(Target, "%ld", mime->msgnum);
1234 void tmplput_MIME_Disposition(StrBuf *Target, WCTemplputParams *TP)
1236 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1237 StrBufAppendTemplate(Target, TP, mime->Disposition, 0);
1240 void tmplput_MIME_ContentType(StrBuf *Target, WCTemplputParams *TP)
1242 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1243 StrBufAppendTemplate(Target, TP, mime->ContentType, 0);
1246 void examine_charset(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
1248 Msg->MsgBody->Charset = NewStrBufDup(HdrLine);
1251 void tmplput_MIME_Charset(StrBuf *Target, WCTemplputParams *TP)
1253 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1254 StrBufAppendTemplate(Target, TP, mime->Charset, 0);
1257 void tmplput_MIME_Data(StrBuf *Target, WCTemplputParams *TP)
1259 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1260 if (mime->Renderer != NULL)
1261 mime->Renderer->f(Target, TP, NULL);
1262 StrBufAppendTemplate(Target, TP, mime->Data, 0);
1263 /* TODO: check whether we need to load it now? */
1266 void tmplput_MIME_LoadData(StrBuf *Target, WCTemplputParams *TP)
1268 wcsession *WCC = WC;
1269 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1270 wc_mime_attachment *att;
1272 if (( (!strcasecmp(ChrPtr(mime->Disposition), "inline"))||
1273 (!strcasecmp(ChrPtr(mime->Disposition), "attachment"))) &&
1274 (strcasecmp(ChrPtr(mime->ContentType), "application/ms-tnef")!=0))
1279 /* steal this mime part... */
1280 att = malloc(sizeof(wc_mime_attachment));
1281 memcpy(att, mime, sizeof(wc_mime_attachment));
1282 memset(mime, 0, sizeof(wc_mime_attachment));
1284 if (att->Data == NULL)
1287 if (WCC->attachments == NULL)
1288 WCC->attachments = NewHash(1, NULL);
1289 /* And add it to the list. */
1290 n = snprintf(N, sizeof N, "%d", GetCount(WCC->attachments) + 1);
1291 Put(WCC->attachments, N, n, att, DestroyMime);
1295 void tmplput_MIME_Length(StrBuf *Target, WCTemplputParams *TP)
1297 wc_mime_attachment *mime = (wc_mime_attachment*) CTX(CTX_MIME_ATACH);
1298 StrBufAppendPrintf(Target, "%ld", mime->length);
1301 HashList *iterate_get_registered_Attachments(StrBuf *Target, WCTemplputParams *TP)
1303 return WC->attachments;
1306 void get_registered_Attachments_Count(StrBuf *Target, WCTemplputParams *TP)
1308 StrBufAppendPrintf(Target, "%ld", GetCount (WC->attachments));
1311 void servcmd_do_search(char *buf, long bufsize)
1313 snprintf(buf, bufsize, "MSGS SEARCH|%s", bstr("query"));
1316 void servcmd_headers(char *buf, long bufsize)
1318 snprintf(buf, bufsize, "MSGS ALL");
1321 void servcmd_readfwd(char *buf, long bufsize)
1323 snprintf(buf, bufsize, "MSGS ALL");
1326 void servcmd_readgt(char *buf, long bufsize)
1328 snprintf(buf, bufsize, "MSGS GT|%s", bstr("gt"));
1331 void servcmd_readlt(char *buf, long bufsize)
1333 snprintf(buf, bufsize, "MSGS LT|%s", bstr("lt"));
1336 void servcmd_readnew(char *buf, long bufsize)
1338 snprintf(buf, bufsize, "MSGS NEW");
1341 void servcmd_readold(char *buf, long bufsize)
1343 snprintf(buf, bufsize, "MSGS OLD");
1347 /* DO NOT REORDER OR REMOVE ANY OF THESE */
1348 readloop_struct rlid[] = {
1349 { {HKEY("do_search")}, servcmd_do_search },
1350 { {HKEY("headers")}, servcmd_headers },
1351 { {HKEY("readfwd")}, servcmd_readfwd },
1352 { {HKEY("readnew")}, servcmd_readnew },
1353 { {HKEY("readold")}, servcmd_readold },
1354 { {HKEY("readgt")}, servcmd_readgt },
1355 { {HKEY("readlt")}, servcmd_readlt }
1359 /* I think these are supposed to align with _eMessageField in messages.h
1360 * So if you change one you have to change the other.
1361 * TODO: figure out who did this and beat them with a wet noodle.
1363 const char *fieldMnemonics[] = {
1364 "from", /* A -> eAuthor */
1365 "exti", /* E -> eXclusivID */
1366 "rfca", /* F -> erFc822Addr */
1367 "msgn", /* I -> emessageId */
1368 "jrnl", /* J -> eJournal */
1369 "rep2", /* K -> eReplyTo */
1370 "list", /* L -> eListID */
1371 "text", /* M -> eMessageText */
1372 "locl", /* eIsLocal */
1373 "path", /* P -> eMessagePath */
1374 "rcpt", /* R -> eRecipient */
1375 "spec", /* S -> eSpecialField */
1376 "time", /* T -> eTimestamp */
1377 "subj", /* U -> eMsgSubject */
1378 "nvto", /* V -> eenVelopeTo */
1379 "wefw", /* W -> eWeferences */
1380 "cccc", /* Y -> eCarbonCopY */
1381 "nhdr", /* eHeaderOnly */
1382 "type", /* eFormatType */
1383 "part", /* eMessagePart */
1384 "suff" /* eSubFolder */
1386 HashList *msgKeyLookup = NULL;
1389 int GetFieldFromMnemonic(eMessageField *f, const char *c) {
1391 if (GetHash(msgKeyLookup, c, 4, &v)) {
1392 *f = (eMessageField) v;
1399 void FillMsgKeyLookupTable(void) {
1402 msgKeyLookup = NewHash (1, FourHash);
1403 for (i=0; i<eLastHeader; ++i) {
1404 if (fieldMnemonics[i] != NULL) {
1405 Put(msgKeyLookup, fieldMnemonics[i], 4, (void*)i, reference_free_handler);
1412 InitModule_MSGRENDERERS
1415 RegisterCTX(CTX_MAILSUM);
1416 RegisterCTX(CTX_MIME_ATACH);
1418 RegisterSortFunc(HKEY("date"),
1424 RegisterSortFunc(HKEY("subject"),
1430 RegisterSortFunc(HKEY("sender"),
1437 RegisterNamespace("SUMM:COUNT", 0, 0, tmplput_SUMM_COUNT, NULL, CTX_NONE);
1439 /* iterate over all known mails in WC->summ */
1440 RegisterIterator("MAIL:SUMM:MSGS", 0, NULL, iterate_get_mailsumm_All, NULL,NULL, CTX_MAILSUM, CTX_NONE, IT_NOFLAG);
1442 RegisterNamespace("MAIL:SUMM:EUID", 0, 1, tmplput_MAIL_SUMM_EUID, NULL, CTX_MAILSUM);
1443 RegisterNamespace("MAIL:SUMM:DATEBRIEF", 0, 0, tmplput_MAIL_SUMM_DATE_BRIEF, NULL, CTX_MAILSUM);
1444 RegisterNamespace("MAIL:SUMM:DATEFULL", 0, 0, tmplput_MAIL_SUMM_DATE_FULL, NULL, CTX_MAILSUM);
1445 RegisterNamespace("MAIL:SUMM:DATENO", 0, 0, tmplput_MAIL_SUMM_DATE_NO, NULL, CTX_MAILSUM);
1446 RegisterNamespace("MAIL:SUMM:N", 0, 0, tmplput_MAIL_SUMM_N, NULL, CTX_MAILSUM);
1447 RegisterNamespace("MAIL:SUMM:PERMALINK", 0, 0, tmplput_MAIL_SUMM_PERMALINK, NULL, CTX_MAILSUM);
1448 RegisterNamespace("MAIL:SUMM:FROM", 0, 2, tmplput_MAIL_SUMM_FROM, NULL, CTX_MAILSUM);
1449 RegisterNamespace("MAIL:SUMM:TO", 0, 2, tmplput_MAIL_SUMM_TO, NULL, CTX_MAILSUM);
1450 RegisterNamespace("MAIL:SUMM:SUBJECT", 0, 4, tmplput_MAIL_SUMM_SUBJECT, NULL, CTX_MAILSUM);
1451 RegisterNamespace("MAIL:SUMM:NTATACH", 0, 0, tmplput_MAIL_SUMM_NATTACH, NULL, CTX_MAILSUM);
1452 RegisterNamespace("MAIL:SUMM:CCCC", 0, 2, tmplput_MAIL_SUMM_CCCC, NULL, CTX_MAILSUM);
1453 RegisterNamespace("MAIL:SUMM:REPLYTO", 0, 2, tmplput_MAIL_SUMM_REPLYTO, NULL, CTX_MAILSUM);
1454 RegisterNamespace("MAIL:SUMM:ALLRCPT", 0, 2, tmplput_MAIL_SUMM_ALLRCPT, NULL, CTX_MAILSUM);
1455 RegisterNamespace("MAIL:SUMM:ORGROOM", 0, 2, tmplput_MAIL_SUMM_ORGROOM, NULL, CTX_MAILSUM);
1456 RegisterNamespace("MAIL:SUMM:RFCA", 0, 2, tmplput_MAIL_SUMM_RFCA, NULL, CTX_MAILSUM);
1457 RegisterNamespace("MAIL:SUMM:REFIDS", 0, 1, tmplput_MAIL_SUMM_REFIDS, NULL, CTX_MAILSUM);
1458 RegisterNamespace("MAIL:SUMM:INREPLYTO", 0, 2, tmplput_MAIL_SUMM_INREPLYTO, NULL, CTX_MAILSUM);
1459 RegisterNamespace("MAIL:BODY", 0, 2, tmplput_MAIL_BODY, NULL, CTX_MAILSUM);
1460 RegisterNamespace("MAIL:QUOTETEXT", 1, 2, tmplput_QUOTED_MAIL_BODY, NULL, CTX_NONE);
1461 RegisterNamespace("MAIL:EDITTEXT", 1, 2, tmplput_EDIT_MAIL_BODY, NULL, CTX_NONE);
1462 RegisterNamespace("MAIL:EDITWIKI", 1, 2, tmplput_EDIT_WIKI_BODY, NULL, CTX_NONE);
1463 RegisterConditional("COND:MAIL:SUMM:RFCA", 0, Conditional_MAIL_SUMM_RFCA, CTX_MAILSUM);
1464 RegisterConditional("COND:MAIL:SUMM:CCCC", 0, Conditional_MAIL_SUMM_CCCC, CTX_MAILSUM);
1465 RegisterConditional("COND:MAIL:SUMM:REPLYTO", 0, Conditional_MAIL_SUMM_REPLYTO, CTX_MAILSUM);
1466 RegisterConditional("COND:MAIL:SUMM:UNREAD", 0, Conditional_MAIL_SUMM_UNREAD, CTX_MAILSUM);
1467 RegisterConditional("COND:MAIL:SUMM:SUBJECT", 0, Conditional_MAIL_SUMM_SUBJECT, CTX_MAILSUM);
1468 RegisterConditional("COND:MAIL:ANON", 0, Conditional_ANONYMOUS_MESSAGE, CTX_MAILSUM);
1469 RegisterConditional("COND:MAIL:TO", 0, Conditional_MAIL_SUMM_TO, CTX_MAILSUM);
1470 RegisterConditional("COND:MAIL:SUBJ", 0, Conditional_MAIL_SUMM_SUBJ, CTX_MAILSUM);
1471 RegisterConditional("COND:MAIL:LOCAL", 0, Conditional_MAIL_LOCAL, CTX_MAILSUM);
1473 /* do we have mimetypes to iterate over? */
1474 RegisterConditional("COND:MAIL:MIME:ATTACH", 0, Conditional_MAIL_MIME_ALL, CTX_MAILSUM);
1475 RegisterConditional("COND:MAIL:MIME:ATTACH:SUBMESSAGES", 0, Conditional_MAIL_MIME_SUBMESSAGES, CTX_MAILSUM);
1476 RegisterConditional("COND:MAIL:MIME:ATTACH:LINKS", 0, Conditional_MAIL_MIME_ATTACHLINKS, CTX_MAILSUM);
1477 RegisterConditional("COND:MAIL:MIME:ATTACH:ATT", 0, Conditional_MAIL_MIME_ATTACH, CTX_MAILSUM);
1478 RegisterIterator("MAIL:MIME:ATTACH", 0, NULL, iterate_get_mime_All, NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM, IT_NOFLAG);
1479 RegisterIterator("MAIL:MIME:ATTACH:SUBMESSAGES", 0, NULL, iterate_get_mime_Submessages, NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM, IT_NOFLAG);
1480 RegisterIterator("MAIL:MIME:ATTACH:LINKS", 0, NULL, iterate_get_mime_AttachLinks, NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM, IT_NOFLAG);
1481 RegisterIterator("MAIL:MIME:ATTACH:ATT", 0, NULL, iterate_get_mime_Attachments, NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM, IT_NOFLAG);
1483 /* Parts of a mime attachent */
1484 RegisterNamespace("MAIL:MIME:NAME", 0, 2, tmplput_MIME_Name, NULL, CTX_MIME_ATACH);
1485 RegisterNamespace("MAIL:MIME:FILENAME", 0, 2, tmplput_MIME_FileName, NULL, CTX_MIME_ATACH);
1486 RegisterNamespace("MAIL:MIME:PARTNUM", 0, 2, tmplput_MIME_PartNum, NULL, CTX_MIME_ATACH);
1487 RegisterNamespace("MAIL:MIME:MSGNUM", 0, 2, tmplput_MIME_MsgNum, NULL, CTX_MIME_ATACH);
1488 RegisterNamespace("MAIL:MIME:DISPOSITION", 0, 2, tmplput_MIME_Disposition, NULL, CTX_MIME_ATACH);
1489 RegisterNamespace("MAIL:MIME:CONTENTTYPE", 0, 2, tmplput_MIME_ContentType, NULL, CTX_MIME_ATACH);
1490 RegisterNamespace("MAIL:MIME:CHARSET", 0, 2, tmplput_MIME_Charset, NULL, CTX_MIME_ATACH);
1491 RegisterNamespace("MAIL:MIME:LENGTH", 0, 2, tmplput_MIME_Length, NULL, CTX_MIME_ATACH);
1492 RegisterNamespace("MAIL:MIME:DATA", 0, 2, tmplput_MIME_Data, NULL, CTX_MIME_ATACH);
1494 /* load the actual attachment into WC->attachments; no output!!! */
1495 RegisterNamespace("MAIL:MIME:LOADDATA", 0, 0, tmplput_MIME_LoadData, NULL, CTX_MIME_ATACH);
1497 /* iterate the WC->attachments; use the above tokens for their contents */
1498 RegisterIterator("MSG:ATTACHNAMES", 0, NULL, iterate_get_registered_Attachments, NULL, NULL, CTX_MIME_ATACH, CTX_NONE, IT_NOFLAG);
1499 RegisterNamespace("MSG:NATTACH", 0, 0, get_registered_Attachments_Count, NULL, CTX_NONE);
1501 /* mime renderers translate an attachment into webcit viewable html text */
1502 RegisterMimeRenderer(HKEY("message/rfc822"), render_MAIL, 0, 150);
1504 RegisterMimeRenderer(HKEY("text/calendar"), render_MIME_ICS, 1, 501);
1505 RegisterMimeRenderer(HKEY("application/ics"), render_MIME_ICS, 1, 500);
1507 RegisterMimeRenderer(HKEY("text/x-citadel-variformat"), render_MAIL_variformat, 1, 2);
1508 RegisterMimeRenderer(HKEY("text/plain"), render_MAIL_text_plain, 1, 3);
1509 RegisterMimeRenderer(HKEY("text"), render_MAIL_text_plain, 1, 1);
1510 RegisterMimeRenderer(HKEY("text/x-markdown"), render_MAIL_text_plain, 1, 1);
1511 RegisterMimeRenderer(HKEY("text/html"), render_MAIL_html, 1, 100);
1512 RegisterMimeRenderer(HKEY(""), render_MAIL_UNKNOWN, 0, 0);
1514 /* these headers are citserver replies to MSG4 and friends. one evaluator for each */
1515 RegisterMsgHdr(HKEY("nhdr"), examine_nhdr, 0);
1516 RegisterMsgHdr(HKEY("exti"), examine_exti, 0);
1517 RegisterMsgHdr(HKEY("type"), examine_type, 0);
1518 RegisterMsgHdr(HKEY("from"), examine_from, 0);
1519 RegisterMsgHdr(HKEY("subj"), examine_subj, 0);
1520 RegisterMsgHdr(HKEY("msgn"), examine_msgn, 0);
1521 RegisterMsgHdr(HKEY("wefw"), examine_wefw, 0);
1522 RegisterMsgHdr(HKEY("cccc"), examine_cccc, 0);
1523 RegisterMsgHdr(HKEY("rep2"), examine_replyto, 0);
1524 RegisterMsgHdr(HKEY("room"), examine_room, 0);
1525 RegisterMsgHdr(HKEY("rfca"), examine_rfca, 0);
1526 RegisterMsgHdr(HKEY("rcpt"), examine_rcpt, 0);
1527 RegisterMsgHdr(HKEY("nvto"), examine_nvto, 0);
1528 RegisterMsgHdr(HKEY("time"), examine_time, 0);
1529 RegisterMsgHdr(HKEY("part"), examine_mime_part, 0);
1530 RegisterMsgHdr(HKEY("locl"), examine_locl, 0);
1531 RegisterMsgHdr(HKEY("text"), examine_text, 1);
1533 /* these are the content-type headers we get in front of a message; put it into the same hash since it doesn't clash. */
1534 RegisterMsgHdr(HKEY("X-Citadel-MSG4-Partnum"), examine_msg4_partnum, 0);
1535 RegisterMsgHdr(HKEY("Content-type"), examine_content_type, 0);
1536 RegisterMsgHdr(HKEY("Content-length"), examine_content_lengh, 0);
1537 RegisterMsgHdr(HKEY("Content-transfer-encoding"), examine_content_encoding, 0); /* do we care? */
1538 RegisterMsgHdr(HKEY("charset"), examine_charset, 0);
1540 /* Don't care about these... */
1541 RegisterMsgHdr(HKEY("pref"), examine_pref, 0);
1542 RegisterMsgHdr(HKEY("suff"), examine_suff, 0);
1543 RegisterMsgHdr(HKEY("path"), examine_path, 0);
1547 InitModule2_MSGRENDERERS
1550 /* and finalize the anouncement to the server... */
1554 ServerStartModule_MSGRENDERERS
1557 DflMsgHeaderHandler = NewHash (1, FourHash);
1558 DflEnumMsgHeaderHandler = NewHash (1, Flathash);
1559 MsgHeaderHandler = NewHash(1, NULL);
1560 MimeRenderHandler = NewHash(1, NULL);
1561 ReadLoopHandler = NewHash(1, NULL);
1562 FillMsgKeyLookupTable();
1566 ServerShutdownModule_MSGRENDERERS
1569 DeleteHash(&DflMsgHeaderHandler);
1570 DeleteHash(&DflEnumMsgHeaderHandler);
1573 DeleteHash(&MsgHeaderHandler);
1574 DeleteHash(&MimeRenderHandler);
1575 DeleteHash(&ReadLoopHandler);
1576 DeleteHash(&msgKeyLookup);
1580 SessionDestroyModule_MSGRENDERERS
1583 DeleteHash(&sess->attachments);
1584 FreeStrBuf(&sess->ConvertBuf1);
1585 FreeStrBuf(&sess->ConvertBuf2);