webcit: webserver.o context_loop.o ical_dezonify.o \
cookie_conversion.o locate_host.o floors.o summary.o \
webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o \
- roomops.o messages.o userlist.o paging.o sysmsgs.o useredit.o \
- vcard_edit.o preferences.o html2html.o listsub.o \
+ roomops.o messages.o msg_renderers.o userlist.o paging.o sysmsgs.o \
+ useredit.o vcard_edit.o preferences.o html2html.o listsub.o \
graphics.o netconf.o siteconfig.o subst.o rss.o \
calendar.o calendar_tools.o calendar_view.o event.o smtpqueue.o \
availability.o iconbar.o crypto.o inetconf.o notes.o wiki.o \
$(CC) $(LDFLAGS) $(LIBOBJS) $(LIBS) \
webserver.o context_loop.o cookie_conversion.o \
webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o listsub.o \
- roomops.o messages.o userlist.o paging.o sysmsgs.o useredit.o \
- locate_host.o siteconfig.o subst.o vcard_edit.o floors.o \
+ roomops.o messages.o msg_renderers.o userlist.o paging.o sysmsgs.o \
+ useredit.o locate_host.o siteconfig.o subst.o vcard_edit.o floors.o \
graphics.o netconf.o preferences.o html2html.o rss.o openid.o \
summary.o calendar.o calendar_tools.o calendar_view.o event.o wiki.o \
availability.o ical_dezonify.o iconbar.o crypto.o inetconf.o notes.o \
#define SENDER_COL_WIDTH_PCT 30 /**< Mailbox view column width */
#define DATE_PLUS_BUTTONS_WIDTH_PCT 20 /**< Mailbox view column width */
-void display_vcard(StrBuf *Target, const char *vcard_source, char alpha, int full, char *storename, long msgnum);
void display_enter(void);
typedef void (*MsgPartEvaluatorFunc)(message_summary *Sum, StrBuf *Buf);
-struct attach_link {
- char partnum[32];
- char html[1024];
-};
-
-
-
-typedef struct _headereval {
- ExamineMsgHeaderFunc evaluator;
- int Type;
-} headereval;
-
-
-
-enum {
- eUp,
- eDown,
- eNone
-};
const char* SortIcons[3] = {
"static/up_pointer.gif",
-
-/*
- * Address book entry (keep it short and sweet, it's just a quickie lookup
- * which we can use to get to the real meat and bones later)
- */
-struct addrbookent {
- char ab_name[64]; /**< name string */
- long ab_msgnum; /**< message number of address book entry */
-};
-
/*----------------------------------------------------------------------------*/
/*
-/*----------------------------------------------------------------------------*/
-
-/**
- * message index functions
- */
-
-void DestroyMimeParts(wc_mime_attachment *Mime)
-{
- FreeStrBuf(&Mime->Name);
- FreeStrBuf(&Mime->FileName);
- FreeStrBuf(&Mime->PartNum);
- FreeStrBuf(&Mime->Disposition);
- FreeStrBuf(&Mime->ContentType);
- FreeStrBuf(&Mime->Charset);
- FreeStrBuf(&Mime->Data);
-}
-
-void DestroyMime(void *vMime)
-{
- wc_mime_attachment *Mime = (wc_mime_attachment*)vMime;
- DestroyMimeParts(Mime);
- free(Mime);
-}
-
-void DestroyMessageSummary(void *vMsg)
-{
- message_summary *Msg = (message_summary*) vMsg;
-
- FreeStrBuf(&Msg->from);
- FreeStrBuf(&Msg->to);
- FreeStrBuf(&Msg->subj);
- FreeStrBuf(&Msg->reply_inreplyto);
- FreeStrBuf(&Msg->reply_references);
- FreeStrBuf(&Msg->cccc);
- FreeStrBuf(&Msg->hnod);
- FreeStrBuf(&Msg->AllRcpt);
- FreeStrBuf(&Msg->Room);
- FreeStrBuf(&Msg->Rfca);
- FreeStrBuf(&Msg->OtherNode);
-
- FreeStrBuf(&Msg->reply_to);
-
- DeleteHash(&Msg->Attachments); /**< list of Accachments */
- DeleteHash(&Msg->Submessages);
- DeleteHash(&Msg->AttachLinks);
- DeleteHash(&Msg->AllAttach);
-
- DestroyMimeParts(&Msg->MsgBody);
-
- free(Msg);
-}
-
-
-
-void RegisterMsgHdr(const char *HeaderName, long HdrNLen, ExamineMsgHeaderFunc evaluator, int type)
-{
- headereval *ev;
- ev = (headereval*) malloc(sizeof(headereval));
- ev->evaluator = evaluator;
- ev->Type = type;
- Put(MsgHeaderHandler, HeaderName, HdrNLen, ev, NULL);
-}
-
-void RegisterMimeRenderer(const char *HeaderName, long HdrNLen, RenderMimeFunc MimeRenderer)
-{
- Put(MimeRenderHandler, HeaderName, HdrNLen, MimeRenderer, reference_free_handler);
-
-}
-
-/*----------------------------------------------------------------------------*/
-
-
-void examine_nhdr(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- Msg->nhdr = 0;
- if (!strncasecmp(ChrPtr(HdrLine), "yes", 8))
- Msg->nhdr = 1;
-}
-int Conditional_ANONYMOUS_MESSAGE(WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return Msg->nhdr != 0;
-}
-
-
-void examine_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- Msg->format_type = StrToi(HdrLine);
-
-}
-
-void examine_from(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- FreeStrBuf(&Msg->from);
- Msg->from = NewStrBufPlain(NULL, StrLength(HdrLine));
- StrBuf_RFC822_to_Utf8(Msg->from, HdrLine, WC->DefaultCharset, FoundCharset);
-}
-void tmplput_MAIL_SUMM_FROM(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->from, 0);
- lprintf(1,"%s", ChrPtr(Msg->from));
-}
-
-
-
-void examine_subj(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- FreeStrBuf(&Msg->subj);
- Msg->subj = NewStrBufPlain(NULL, StrLength(HdrLine));
- StrBuf_RFC822_to_Utf8(Msg->subj, HdrLine, WC->DefaultCharset, FoundCharset);
- lprintf(1,"%s", ChrPtr(Msg->subj));
-}
-void tmplput_MAIL_SUMM_SUBJECT(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{/////TODO: Fwd: and RE: filter!!
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->subj, 0);
-}
-
-
-void examine_msgn(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- FreeStrBuf(&Msg->reply_inreplyto);
- Msg->reply_inreplyto = NewStrBufPlain(NULL, StrLength(HdrLine));
- StrBuf_RFC822_to_Utf8(Msg->reply_inreplyto, HdrLine, WC->DefaultCharset, FoundCharset);
-}
-void tmplput_MAIL_SUMM_INREPLYTO(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->reply_inreplyto, 0);
-}
-
-int Conditional_MAIL_SUMM_UNREAD(WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return Msg->is_new != 0;
-}
-
-void examine_wefw(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- FreeStrBuf(&Msg->reply_references);
- Msg->reply_references = NewStrBufPlain(NULL, StrLength(HdrLine));
- StrBuf_RFC822_to_Utf8(Msg->reply_references, HdrLine, WC->DefaultCharset, FoundCharset);
-}
-void tmplput_MAIL_SUMM_REFIDS(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->reply_references, 0);
-}
-
-
-void examine_cccc(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- FreeStrBuf(&Msg->cccc);
- Msg->cccc = NewStrBufPlain(NULL, StrLength(HdrLine));
- StrBuf_RFC822_to_Utf8(Msg->cccc, HdrLine, WC->DefaultCharset, FoundCharset);
- if (Msg->AllRcpt == NULL)
- Msg->AllRcpt = NewStrBufPlain(NULL, StrLength(HdrLine));
- if (StrLength(Msg->AllRcpt) > 0) {
- StrBufAppendBufPlain(Msg->AllRcpt, HKEY(", "), 0);
- }
- StrBufAppendBuf(Msg->AllRcpt, Msg->cccc, 0);
-}
-void tmplput_MAIL_SUMM_CCCC(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->cccc, 0);
-}
-
-
-
-
-void examine_room(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- if ((StrLength(HdrLine) > 0) &&
- (strcasecmp(ChrPtr(HdrLine), WC->wc_roomname))) {
- FreeStrBuf(&Msg->Room);
- Msg->Room = NewStrBufDup(HdrLine);
- }
-}
-void tmplput_MAIL_SUMM_ORGROOM(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->Room, 0);
-}
-
-
-void examine_rfca(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- FreeStrBuf(&Msg->Rfca);
- Msg->Rfca = NewStrBufDup(HdrLine);
-}
-void tmplput_MAIL_SUMM_RFCA(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->Rfca, 0);
-}
-
-
-void examine_node(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- if ( (StrLength(HdrLine) > 0) &&
- ((WC->room_flags & QR_NETWORK)
- || ((strcasecmp(ChrPtr(HdrLine), serv_info.serv_nodename)
- && (strcasecmp(ChrPtr(HdrLine), serv_info.serv_fqdn)))))) {
- FreeStrBuf(&Msg->OtherNode);
- Msg->OtherNode = NewStrBufDup(HdrLine);
- }
-}
-void tmplput_MAIL_SUMM_OTHERNODE(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->OtherNode, 0);
-}
-int Conditional_MAIL_SUMM_OTHERNODE(WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return StrLength(Msg->OtherNode) > 0;
-}
-
-
-void examine_rcpt(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- FreeStrBuf(&Msg->to);
- Msg->to = NewStrBufPlain(NULL, StrLength(HdrLine));
- StrBuf_RFC822_to_Utf8(Msg->to, HdrLine, WC->DefaultCharset, FoundCharset);
- if (Msg->AllRcpt == NULL)
- Msg->AllRcpt = NewStrBufPlain(NULL, StrLength(HdrLine));
- if (StrLength(Msg->AllRcpt) > 0) {
- StrBufAppendBufPlain(Msg->AllRcpt, HKEY(", "), 0);
- }
- StrBufAppendBuf(Msg->AllRcpt, Msg->to, 0);
-}
-void tmplput_MAIL_SUMM_TO(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->to, 0);
-}
-void tmplput_MAIL_SUMM_ALLRCPT(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->AllRcpt, 0);
-}
-
-
-
-void examine_time(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- Msg->date = StrTol(HdrLine);
-}
-void tmplput_MAIL_SUMM_DATE_STR(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- char datebuf[64];
- message_summary *Msg = (message_summary*) Context;
- webcit_fmt_date(datebuf, Msg->date, 1);
- StrBufAppendBufPlain(Target, datebuf, -1, 0);
-}
-void tmplput_MAIL_SUMM_DATE_NO(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendPrintf(Target, "%ld", Msg->date, 0);
-}
-
-
-
-void render_MAIL(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
-{
-}
-
-void render_MIME_VCard(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
-{
- MimeLoadData(Mime);
- if (StrLength(Mime->Data) > 0) {
- StrBuf *Buf;
- Buf = NewStrBuf();
- /** If it's my vCard I can edit it */
- if ( (!strcasecmp(WC->wc_roomname, USERCONFIGROOM))
- || (!strcasecmp(&WC->wc_roomname[11], USERCONFIGROOM))
- || (WC->wc_view == VIEW_ADDRESSBOOK)
- ) {
- StrBufAppendPrintf(Buf, "<a href=\"edit_vcard?msgnum=%ld&partnum=%s\">",
- Mime->msgnum, ChrPtr(Mime->PartNum));
- StrBufAppendPrintf(Buf, "[%s]</a>", _("edit"));
- }
-
- /* In all cases, display the full card */
- display_vcard(Buf, ChrPtr(Mime->Data), 0, 1, NULL, Mime->msgnum);
- FreeStrBuf(&Mime->Data);
- Mime->Data = Buf;
- }
-
-}
-void render_MIME_ICS(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
-{
- MimeLoadData(Mime);
- if (StrLength(Mime->Data) > 0) {
- cal_process_attachment(Mime);
- }
-}
-
-
-
-void examine_mime_part(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- wc_mime_attachment *mime;
- StrBuf *Buf;
- void *vMimeRenderer;
-
- mime = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment));
- memset(mime, 0, sizeof(wc_mime_attachment));
- mime->msgnum = Msg->msgnum;
- Buf = NewStrBuf();
-
- mime->Name = NewStrBuf();
- StrBufExtract_token(mime->Name, HdrLine, 0, '|');
-
- StrBufExtract_token(Buf, HdrLine, 1, '|');
- mime->FileName = NewStrBuf();
- StrBuf_RFC822_to_Utf8(mime->FileName, Buf, WC->DefaultCharset, FoundCharset);
-
- mime->PartNum = NewStrBuf();
- StrBufExtract_token(mime->PartNum, HdrLine, 2, '|');
-
- mime->Disposition = NewStrBuf();
- StrBufExtract_token(mime->Disposition, HdrLine, 3, '|');
-
- mime->ContentType = NewStrBuf();
- StrBufExtract_token(mime->ContentType, HdrLine, 4, '|');
-
- mime->length = StrBufExtract_int(HdrLine, 5, '|');
-
- StrBufTrim(mime->Name);
- StrBufTrim(mime->FileName);
-
- if ( (StrLength(mime->FileName) == 0) && (StrLength(mime->Name) > 0) ) {
- StrBufAppendBuf(mime->FileName, mime->Name, 0);
- }
-
- if (Msg->AllAttach == NULL)
- Msg->AllAttach = NewHash(1,NULL);
- Put(Msg->AllAttach, SKEY(mime->PartNum), mime, DestroyMime);
-
-
- if (GetHash(MimeRenderHandler, SKEY(mime->ContentType), &vMimeRenderer) &&
- vMimeRenderer != NULL)
- {
- mime->Renderer = (RenderMimeFunc) vMimeRenderer;
- if (Msg->Submessages == NULL)
- Msg->Submessages = NewHash(1,NULL);
- Put(Msg->Submessages, SKEY(mime->PartNum), mime, reference_free_handler);
- }
- else if ((!strcasecmp(ChrPtr(mime->Disposition), "inline"))
- && (!strncasecmp(ChrPtr(mime->ContentType), "image/", 6)) ){
- if (Msg->AttachLinks == NULL)
- Msg->AttachLinks = NewHash(1,NULL);
- Put(Msg->AttachLinks, SKEY(mime->PartNum), mime, reference_free_handler);
- }
- else if ((StrLength(mime->ContentType) > 0) &&
- ( (!strcasecmp(ChrPtr(mime->Disposition), "attachment"))
- || (!strcasecmp(ChrPtr(mime->Disposition), "inline"))
- || (!strcasecmp(ChrPtr(mime->Disposition), ""))))
- {
- if (Msg->AttachLinks == NULL)
- Msg->AttachLinks = NewHash(1,NULL);
- Put(Msg->AttachLinks, SKEY(mime->PartNum), mime, reference_free_handler);
- if (strcasecmp(ChrPtr(mime->ContentType), "application/octet-stream") == 0) {
- FlushStrBuf(mime->ContentType);
- StrBufAppendBufPlain(mime->ContentType,
- GuessMimeByFilename(SKEY(mime->FileName)),
- -1, 0);
- }
- }
-
- FreeStrBuf(&Buf);
-}
-
-void tmplput_MAIL_SUMM_NATTACH(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendPrintf(Target, "%ld", GetCount(Msg->Attachments));
-}
-
-
-
-
-
-
-
-void examine_hnod(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- FreeStrBuf(&Msg->hnod);
- Msg->hnod = NewStrBufPlain(NULL, StrLength(HdrLine));
- StrBuf_RFC822_to_Utf8(Msg->hnod, HdrLine, WC->DefaultCharset, FoundCharset);
-}
-void tmplput_MAIL_SUMM_H_NODE(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->hnod, 0);
-}
-int Conditional_MAIL_SUMM_H_NODE(WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return StrLength(Msg->hnod) > 0;
-}
-
-
-
-void examine_text(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{////TODO: read messages here
- Msg->MsgBody.Data = NewStrBuf();
-}
-
-void examine_msg4_partnum(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- Msg->MsgBody.PartNum = NewStrBufDup(HdrLine);
- StrBufTrim(Msg->MsgBody.PartNum);/////TODO: striplt == trim?
-}
-
-void examine_content_encoding(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
-////TODO: do we care?
-}
-
-void examine_content_lengh(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{
- Msg->MsgBody.length = StrTol(HdrLine);
- Msg->MsgBody.size_known = 1;
-}
-
-void examine_content_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
-{////TODO
- int len, i;
- Msg->MsgBody.ContentType = NewStrBufDup(HdrLine);
- StrBufTrim(Msg->MsgBody.ContentType);/////todo==striplt?
- len = StrLength(Msg->MsgBody.ContentType);
- for (i=0; i<len; ++i) {
- if (!strncasecmp(ChrPtr(Msg->MsgBody.ContentType) + i, "charset=", 8)) {/// TODO: WHUT?
-// safestrncpy(mime_charset, &mime_content_type[i+8],
- /// sizeof mime_charset);
- }
- }/****
- for (i=0; i<len; ++i) {
- if (mime_content_type[i] == ';') {
- mime_content_type[i] = 0;
- len = i - 1;
- }
- }
- len = strlen(mime_charset);
- for (i=0; i<len; ++i) {
- if (mime_charset[i] == ';') {
- mime_charset[i] = 0;
- len = i - 1;
- }
- }
- */
-}
-
-void tmplput_MAIL_SUMM_N(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendPrintf(Target, "%ld", Msg->msgnum);
-}
-
-
-
-int Conditional_MAIL_MIME_ALL(WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return GetCount(Msg->Attachments) > 0;
-}
-
-int Conditional_MAIL_MIME_SUBMESSAGES(WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return GetCount(Msg->Submessages) > 0;
-}
-
-int Conditional_MAIL_MIME_ATTACHLINKS(WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return GetCount(Msg->AttachLinks) > 0;
-}
-
-int Conditional_MAIL_MIME_ATTACH(WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return GetCount(Msg->AllAttach) > 0;
-}
-
-
-
-/*----------------------------------------------------------------------------*/
-
-
-void tmplput_MAIL_BODY(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- StrBufAppendBuf(Target, Msg->MsgBody.Data, 0);
-}
-
-
-void render_MAIL_variformat(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
-{
- /* Messages in legacy Citadel variformat get handled thusly... */
- StrBuf *Target = NewStrBufPlain(NULL, StrLength(Mime->Data));
- FmOut(Target, "JUSTIFY", Mime->Data);
- FreeStrBuf(&Mime->Data);
- Mime->Data = Target;
-}
-
-void render_MAIL_text_plain(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
-{
- StrBuf *cs = NULL;
- const char *ptr, *pte;
- const char *BufPtr = NULL;
- StrBuf *Line = NewStrBuf();
- StrBuf *Line1 = NewStrBuf();
- StrBuf *Line2 = NewStrBuf();
- StrBuf *Target = NewStrBufPlain(NULL, StrLength(Mime->Data));
- int ConvertIt = 1;
- int bn = 0;
- int bq = 0;
- int i, n, done = 0;
- long len;
-#ifdef HAVE_ICONV
- iconv_t ic = (iconv_t)(-1) ;
-#endif
-
- /* Boring old 80-column fixed format text gets handled this way... */
- if ((strcasecmp(ChrPtr(Mime->Charset), "us-ascii") == 0) &&
- (strcasecmp(ChrPtr(Mime->Charset), "UTF-8") == 0))
- ConvertIt = 0;
-
-#ifdef HAVE_ICONV
- if (ConvertIt) {
- if (StrLength(Mime->Charset) != 0)
- cs = Mime->Charset;
- else if (StrLength(FoundCharset) > 0)
- cs = FoundCharset;
- else if (StrLength(WC->DefaultCharset) > 0)
- cs = WC->DefaultCharset;
- if (cs == 0) {
- ConvertIt = 0;
- }
- else {
- ctdl_iconv_open("UTF-8", ChrPtr(cs), &ic);
- if (ic == (iconv_t)(-1) ) {
- lprintf(5, "%s:%d iconv_open(UTF-8, %s) failed: %s\n",
- __FILE__, __LINE__, ChrPtr(Mime->Charset), strerror(errno));
- }
- }
- }
-#endif
-
- while ((n = StrBufSipLine(Line, Mime->Data, &BufPtr), n >= 0) && !done)
- {
- done = n == 0;
- bq = 0;
- i = 0;
- ptr = ChrPtr(Line);
- len = StrLength(Line);
- pte = ptr + len;
-
- while ((ptr < pte) &&
- ((*ptr == '>') ||
- isspace(*ptr)))
- {
- if (*ptr == '>')
- bq++;
- ptr ++;
- i++;
- }
- if (i > 0) StrBufCutLeft(Line, i);
-
- if (StrLength(Line) == 0)
- continue;
-
- for (i = bn; i < bq; i++)
- StrBufAppendBufPlain(Target, HKEY("<blockquote>"), 0);
- for (i = bq; i < bn; i++)
- StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
-
- if (ConvertIt == 1) {
- StrBufConvert(Line, Line1, &ic);
- }
-
- StrBufAppendBufPlain(Target, HKEY("<tt>"), 0);
- UrlizeText(Line1, Line, Line2);
-
- StrEscAppend(Target, Line1, NULL, 0, 0);
- StrBufAppendBufPlain(Target, HKEY("</tt><br />\n"), 0);
- bn = bq;
- }
-
- for (i = 0; i < bn; i++)
- StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
-
- StrBufAppendBufPlain(Target, HKEY("</i><br />"), 0);
-#ifdef HAVE_ICONV
- if (ic != (iconv_t)(-1) ) {
- iconv_close(ic);
- }
-#endif
- FreeStrBuf(&Mime->Data);
- Mime->Data = Target;
- FreeStrBuf(&Line);
- FreeStrBuf(&Line1);
- FreeStrBuf(&Line2);
-}
-
-void render_MAIL_html(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
-{
- StrBuf *Buf;
- /* HTML is fun, but we've got to strip it first */
- Buf = NewStrBufPlain(NULL, StrLength(Mime->Data));
- output_html(ChrPtr(Mime->Charset),
- (WC->wc_view == VIEW_WIKI ? 1 : 0),
- StrToi(Mime->PartNum),
- Mime->Data, Buf);
- FreeStrBuf(&Mime->Data);
- Mime->Data = Buf;
-}
-
-void render_MAIL_UNKNOWN(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
-{
- /* Unknown weirdness */
- FlushStrBuf(Mime->Data);
- StrBufAppendBufPlain(Mime->Data, _("I don't know how to display "), -1, 0);
- StrBufAppendBuf(Mime->Data, Mime->ContentType, 0);
- StrBufAppendBufPlain(Mime->Data, HKEY("<br />\n"), 0);
-}
-
-
-
-
-
-
-HashList *iterate_get_mime_All(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return Msg->Attachments;
-}
-HashList *iterate_get_mime_Submessages(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return Msg->Submessages;
-}
-HashList *iterate_get_mime_AttachLinks(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return Msg->AttachLinks;
-}
-HashList *iterate_get_mime_Attachments(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
-{
- message_summary *Msg = (message_summary*) Context;
- return Msg->AllAttach;
-}
-
-void tmplput_MIME_Name(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- StrBufAppendBuf(Target, mime->Name, 0);
-}
-
-void tmplput_MIME_FileName(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- StrBufAppendBuf(Target, mime->FileName, 0);
-}
-
-void tmplput_MIME_PartNum(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- StrBufAppendBuf(Target, mime->PartNum, 0);
-}
-
-void tmplput_MIME_MsgNum(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- StrBufAppendPrintf(Target, "%ld", mime->msgnum);
-}
-
-void tmplput_MIME_Disposition(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- StrBufAppendBuf(Target, mime->Disposition, 0);
-}
-
-void tmplput_MIME_ContentType(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- StrBufAppendBuf(Target, mime->ContentType, 0);
-}
-
-void tmplput_MIME_Charset(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- StrBufAppendBuf(Target, mime->Charset, 0);
-}
-
-void tmplput_MIME_Data(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- if (mime->Renderer != NULL)
- mime->Renderer(mime, NULL, NULL);
- StrBufAppendBuf(Target, mime->Data, 0); /// TODO: check whether we need to load it now?
-}
-
-void tmplput_MIME_Length(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
-{
- wc_mime_attachment *mime = (wc_mime_attachment*) Context;
- StrBufAppendPrintf(Target, "%ld", mime->length);
-}
-
/*
}
-/**
- * \brief Turn a vCard "n" (name) field into something displayable.
- * \param name the name field to convert
- */
-void vcard_n_prettyize(char *name)
-{
- char *original_name;
- int i, j, len;
-
- original_name = strdup(name);
- len = strlen(original_name);
- for (i=0; i<5; ++i) {
- if (len > 0) {
- if (original_name[len-1] == ' ') {
- original_name[--len] = 0;
- }
- if (original_name[len-1] == ';') {
- original_name[--len] = 0;
- }
- }
- }
- strcpy(name, "");
- j=0;
- for (i=0; i<len; ++i) {
- if (original_name[i] == ';') {
- name[j++] = ',';
- name[j++] = ' ';
- }
- else {
- name[j++] = original_name[i];
- }
- }
- name[j] = '\0';
- free(original_name);
-}
-
-
-
-
-/**
- * \brief preparse a vcard name
- * display_vcard() calls this after parsing the textual vCard into
- * our 'struct vCard' data object.
- * This gets called instead of display_parsed_vcard() if we are only looking
- * to extract the person's name instead of displaying the card.
- * \param v the vcard to retrieve the name from
- * \param storename where to put the name at
- */
-void fetchname_parsed_vcard(struct vCard *v, char *storename) {
- char *name;
-
- strcpy(storename, "");
-
- name = vcard_get_prop(v, "n", 1, 0, 0);
- if (name != NULL) {
- strcpy(storename, name);
- /* vcard_n_prettyize(storename); */
- }
-
-}
-
-
-
-/**
- * \brief html print a vcard
- * display_vcard() calls this after parsing the textual vCard into
- * our 'struct vCard' data object.
- *
- * Set 'full' to nonzero to display the full card, otherwise it will only
- * show a summary line.
- *
- * This code is a bit ugly, so perhaps an explanation is due: we do this
- * in two passes through the vCard fields. On the first pass, we process
- * fields we understand, and then render them in a pretty fashion at the
- * end. Then we make a second pass, outputting all the fields we don't
- * understand in a simple two-column name/value format.
- * \param v the vCard to display
- * \param full display all items of the vcard?
- * \param msgnum Citadel message pointer
- */
-void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum) {
- int i, j;
- char buf[SIZ];
- char *name;
- int is_qp = 0;
- int is_b64 = 0;
- char *thisname, *thisvalue;
- char firsttoken[SIZ];
- int pass;
-
- char fullname[SIZ];
- char title[SIZ];
- char org[SIZ];
- char phone[SIZ];
- char mailto[SIZ];
-
- strcpy(fullname, "");
- strcpy(phone, "");
- strcpy(mailto, "");
- strcpy(title, "");
- strcpy(org, "");
-
- if (!full) {
- StrBufAppendPrintf(Target, "<TD>");
- name = vcard_get_prop(v, "fn", 1, 0, 0);
- if (name != NULL) {
- StrEscAppend(Target, NULL, name, 0, 0);
- }
- else if (name = vcard_get_prop(v, "n", 1, 0, 0), name != NULL) {
- strcpy(fullname, name);
- vcard_n_prettyize(fullname);
- StrEscAppend(Target, NULL, fullname, 0, 0);
- }
- else {
- StrBufAppendPrintf(Target, " ");
- }
- StrBufAppendPrintf(Target, "</TD>");
- return;
- }
-
- StrBufAppendPrintf(Target, "<div align=center>"
- "<table bgcolor=#aaaaaa width=50%%>");
- for (pass=1; pass<=2; ++pass) {
-
- if (v->numprops) for (i=0; i<(v->numprops); ++i) {
- int len;
- thisname = strdup(v->prop[i].name);
- extract_token(firsttoken, thisname, 0, ';', sizeof firsttoken);
-
- for (j=0; j<num_tokens(thisname, ';'); ++j) {
- extract_token(buf, thisname, j, ';', sizeof buf);
- if (!strcasecmp(buf, "encoding=quoted-printable")) {
- is_qp = 1;
- remove_token(thisname, j, ';');
- }
- if (!strcasecmp(buf, "encoding=base64")) {
- is_b64 = 1;
- remove_token(thisname, j, ';');
- }
- }
-
- len = strlen(v->prop[i].value);
- /* if we have some untagged QP, detect it here. */
- if (!is_qp && (strstr(v->prop[i].value, "=?")!=NULL))
- utf8ify_rfc822_string(v->prop[i].value);
-
- if (is_qp) {
- // %ff can become 6 bytes in utf8
- thisvalue = malloc(len * 2 + 3);
- j = CtdlDecodeQuotedPrintable(
- thisvalue, v->prop[i].value,
- len);
- thisvalue[j] = 0;
- }
- else if (is_b64) {
- // ff will become one byte..
- thisvalue = malloc(len + 50);
- CtdlDecodeBase64(
- thisvalue, v->prop[i].value,
- strlen(v->prop[i].value) );
- }
- else {
- thisvalue = strdup(v->prop[i].value);
- }
-
- /** Various fields we may encounter ***/
-
- /** N is name, but only if there's no FN already there */
- if (!strcasecmp(firsttoken, "n")) {
- if (IsEmptyStr(fullname)) {
- strcpy(fullname, thisvalue);
- vcard_n_prettyize(fullname);
- }
- }
-
- /** FN (full name) is a true 'display name' field */
- else if (!strcasecmp(firsttoken, "fn")) {
- strcpy(fullname, thisvalue);
- }
-
- /** title */
- else if (!strcasecmp(firsttoken, "title")) {
- strcpy(title, thisvalue);
- }
-
- /** organization */
- else if (!strcasecmp(firsttoken, "org")) {
- strcpy(org, thisvalue);
- }
-
- else if (!strcasecmp(firsttoken, "email")) {
- size_t len;
- if (!IsEmptyStr(mailto)) strcat(mailto, "<br />");
- strcat(mailto,
- "<a href=\"display_enter"
- "?force_room=_MAIL_?recp=");
-
- len = strlen(mailto);
- urlesc(&mailto[len], SIZ - len, "\"");
- len = strlen(mailto);
- urlesc(&mailto[len], SIZ - len, fullname);
- len = strlen(mailto);
- urlesc(&mailto[len], SIZ - len, "\" <");
- len = strlen(mailto);
- urlesc(&mailto[len], SIZ - len, thisvalue);
- len = strlen(mailto);
- urlesc(&mailto[len], SIZ - len, ">");
-
- strcat(mailto, "\">");
- len = strlen(mailto);
- stresc(mailto+len, SIZ - len, thisvalue, 1, 1);
- strcat(mailto, "</A>");
- }
- else if (!strcasecmp(firsttoken, "tel")) {
- if (!IsEmptyStr(phone)) strcat(phone, "<br />");
- strcat(phone, thisvalue);
- for (j=0; j<num_tokens(thisname, ';'); ++j) {
- extract_token(buf, thisname, j, ';', sizeof buf);
- if (!strcasecmp(buf, "tel"))
- strcat(phone, "");
- else if (!strcasecmp(buf, "work"))
- strcat(phone, _(" (work)"));
- else if (!strcasecmp(buf, "home"))
- strcat(phone, _(" (home)"));
- else if (!strcasecmp(buf, "cell"))
- strcat(phone, _(" (cell)"));
- else {
- strcat(phone, " (");
- strcat(phone, buf);
- strcat(phone, ")");
- }
- }
- }
- else if (!strcasecmp(firsttoken, "adr")) {
- if (pass == 2) {
- StrBufAppendPrintf(Target, "<TR><TD>");
- StrBufAppendPrintf(Target, _("Address:"));
- StrBufAppendPrintf(Target, "</TD><TD>");
- for (j=0; j<num_tokens(thisvalue, ';'); ++j) {
- extract_token(buf, thisvalue, j, ';', sizeof buf);
- if (!IsEmptyStr(buf)) {
- StrEscAppend(Target, NULL, buf, 0, 0);
- if (j<3) StrBufAppendPrintf(Target, "<br />");
- else StrBufAppendPrintf(Target, " ");
- }
- }
- StrBufAppendPrintf(Target, "</TD></TR>\n");
- }
- }
- /* else if (!strcasecmp(firsttoken, "photo") && full && pass == 2) {
- // Only output on second pass
- StrBufAppendPrintf(Target, "<tr><td>");
- StrBufAppendPrintf(Target, _("Photo:"));
- StrBufAppendPrintf(Target, "</td><td>");
- StrBufAppendPrintf(Target, "<img src=\"/vcardphoto/%ld/\" alt=\"Contact photo\"/>",msgnum);
- StrBufAppendPrintf(Target, "</td></tr>\n");
- } */
- else if (!strcasecmp(firsttoken, "version")) {
- /* ignore */
- }
- else if (!strcasecmp(firsttoken, "rev")) {
- /* ignore */
- }
- else if (!strcasecmp(firsttoken, "label")) {
- /* ignore */
- }
- else {
-
- /*** Don't show extra fields. They're ugly.
- if (pass == 2) {
- StrBufAppendPrintf(Target, "<TR><TD>");
- StrEscAppend(Target, NULL, thisname, 0, 0);
- StrBufAppendPrintf(Target, "</TD><TD>");
- StrEscAppend(Target, NULL, thisvalue, 0, 0);
- StrBufAppendPrintf(Target, "</TD></TR>\n");
- }
- ***/
- }
-
- free(thisname);
- free(thisvalue);
- }
-
- if (pass == 1) {
- StrBufAppendPrintf(Target, "<TR BGCOLOR=\"#AAAAAA\">"
- "<TD COLSPAN=2 BGCOLOR=\"#FFFFFF\">"
- "<IMG ALIGN=CENTER src=\"static/viewcontacts_48x.gif\">"
- "<FONT SIZE=+1><B>");
- StrEscAppend(Target, NULL, fullname, 0, 0);
- StrBufAppendPrintf(Target, "</B></FONT>");
- if (!IsEmptyStr(title)) {
- StrBufAppendPrintf(Target, "<div align=right>");
- StrEscAppend(Target, NULL, title, 0, 0);
- StrBufAppendPrintf(Target, "</div>");
- }
- if (!IsEmptyStr(org)) {
- StrBufAppendPrintf(Target, "<div align=right>");
- StrEscAppend(Target, NULL, org, 0, 0);
- StrBufAppendPrintf(Target, "</div>");
- }
- StrBufAppendPrintf(Target, "</TD></TR>\n");
-
- if (!IsEmptyStr(phone)) {
- StrBufAppendPrintf(Target, "<tr><td>");
- StrBufAppendPrintf(Target, _("Telephone:"));
- StrBufAppendPrintf(Target, "</td><td>%s</td></tr>\n", phone);
- }
- if (!IsEmptyStr(mailto)) {
- StrBufAppendPrintf(Target, "<tr><td>");
- StrBufAppendPrintf(Target, _("E-mail:"));
- StrBufAppendPrintf(Target, "</td><td>%s</td></tr>\n", mailto);
- }
- }
-
- }
-
- StrBufAppendPrintf(Target, "</table></div>\n");
-}
-
-
-
-/**
- * \brief Display a textual vCard
- * (Converts to a vCard object and then calls the actual display function)
- * Set 'full' to nonzero to display the whole card instead of a one-liner.
- * Or, if "storename" is non-NULL, just store the person's name in that
- * buffer instead of displaying the card at all.
- * \param vcard_source the buffer containing the vcard text
- * \param alpha what???
- * \param full should we usse all lines?
- * \param storename where to store???
- * \param msgnum Citadel message pointer
- */
-void display_vcard(StrBuf *Target, const char *vcard_source, char alpha, int full, char *storename,
- long msgnum) {
- struct vCard *v;
- char *name;
- char buf[SIZ];
- char this_alpha = 0;
-
- v = vcard_load((char*)vcard_source); ///TODO
-
- if (v == NULL) return;
-
- name = vcard_get_prop(v, "n", 1, 0, 0);
- if (name != NULL) {
- utf8ify_rfc822_string(name);
- strcpy(buf, name);
- this_alpha = buf[0];
- }
-
- if (storename != NULL) {
- fetchname_parsed_vcard(v, storename);
- }
- else if ( (alpha == 0)
- || ((isalpha(alpha)) && (tolower(alpha) == tolower(this_alpha)) )
- || ((!isalpha(alpha)) && (!isalpha(this_alpha)))
- ) {
- display_parsed_vcard(Target, v, full,msgnum);
- }
-
- vcard_free(v);
-}
-
-
-
-/**
- * \brief Record compare function for sorting address book indices
- * \param ab1 adressbook one
- * \param ab2 adressbook two
- */
-int abcmp(const void *ab1, const void *ab2) {
- return(strcasecmp(
- (((const struct addrbookent *)ab1)->ab_name),
- (((const struct addrbookent *)ab2)->ab_name)
- ));
-}
-
-
-/**
- * \brief Helper function for do_addrbook_view()
- * Converts a name into a three-letter tab label
- * \param tabbuf the tabbuffer to add name to
- * \param name the name to add to the tabbuffer
- */
-void nametab(char *tabbuf, long len, char *name) {
- stresc(tabbuf, len, name, 0, 0);
- tabbuf[0] = toupper(tabbuf[0]);
- tabbuf[1] = tolower(tabbuf[1]);
- tabbuf[2] = tolower(tabbuf[2]);
- tabbuf[3] = 0;
-}
-
-
-/**
- * \brief Render the address book using info we gathered during the scan
- * \param addrbook the addressbook to render
- * \param num_ab the number of the addressbook
- */
-void do_addrbook_view(struct addrbookent *addrbook, int num_ab) {
- int i = 0;
- int displayed = 0;
- int bg = 0;
- static int NAMESPERPAGE = 60;
- int num_pages = 0;
- int tabfirst = 0;
- char tabfirst_label[64];
- int tablast = 0;
- char tablast_label[64];
- char this_tablabel[64];
- int page = 0;
- char **tablabels;
-
- if (num_ab == 0) {
- wprintf("<br /><br /><br /><div align=\"center\"><i>");
- wprintf(_("This address book is empty."));
- wprintf("</i></div>\n");
- return;
- }
-
- if (num_ab > 1) {
- qsort(addrbook, num_ab, sizeof(struct addrbookent), abcmp);
- }
-
- num_pages = (num_ab / NAMESPERPAGE) + 1;
-
- tablabels = malloc(num_pages * sizeof (char *));
- if (tablabels == NULL) {
- wprintf("<br /><br /><br /><div align=\"center\"><i>");
- wprintf(_("An internal error has occurred."));
- wprintf("</i></div>\n");
- return;
- }
-
- for (i=0; i<num_pages; ++i) {
- tabfirst = i * NAMESPERPAGE;
- tablast = tabfirst + NAMESPERPAGE - 1;
- if (tablast > (num_ab - 1)) tablast = (num_ab - 1);
- nametab(tabfirst_label, 64, addrbook[tabfirst].ab_name);
- nametab(tablast_label, 64, addrbook[tablast].ab_name);
- sprintf(this_tablabel, "%s - %s", tabfirst_label, tablast_label);
- tablabels[i] = strdup(this_tablabel);
- }
-
- tabbed_dialog(num_pages, tablabels);
- page = (-1);
-
- for (i=0; i<num_ab; ++i) {
-
- if ((i / NAMESPERPAGE) != page) { /* New tab */
- page = (i / NAMESPERPAGE);
- if (page > 0) {
- wprintf("</tr></table>\n");
- end_tab(page-1, num_pages);
- }
- begin_tab(page, num_pages);
- wprintf("<table border=0 cellspacing=0 cellpadding=3 width=100%%>\n");
- displayed = 0;
- }
-
- if ((displayed % 4) == 0) {
- if (displayed > 0) {
- wprintf("</tr>\n");
- }
- bg = 1 - bg;
- wprintf("<tr bgcolor=\"#%s\">",
- (bg ? "DDDDDD" : "FFFFFF")
- );
- }
-
- wprintf("<td>");
-
- wprintf("<a href=\"readfwd?startmsg=%ld?is_singlecard=1",
- addrbook[i].ab_msgnum);
- wprintf("?maxmsgs=1?is_summary=0?alpha=%s\">", bstr("alpha"));
- vcard_n_prettyize(addrbook[i].ab_name);
- escputs(addrbook[i].ab_name);
- wprintf("</a></td>\n");
- ++displayed;
- }
-
- /* Placeholders for empty columns at end */
- if ((num_ab % 4) != 0) {
- for (i=0; i<(4-(num_ab % 4)); ++i) {
- wprintf("<td> </td>");
- }
- }
-
- wprintf("</tr></table>\n");
- end_tab((num_pages-1), num_pages);
-
- begin_tab(num_pages, num_pages);
- /* FIXME there ought to be something here */
- end_tab(num_pages, num_pages);
-
- for (i=0; i<num_pages; ++i) {
- free(tablabels[i]);
- }
- free(tablabels);
-}
-
/*
int lo, hi;
int lowest_displayed = (-1);
int highest_displayed = 0;
- struct addrbookent *addrbook = NULL;
+ addrbookent *addrbook = NULL;
int num_ab = 0;
const StrBuf *sortby = NULL;
//SortByEnum
fetch_ab_name(Msg, buf);
++num_ab;
addrbook = realloc(addrbook,
- (sizeof(struct addrbookent) * num_ab) );
+ (sizeof(addrbookent) * num_ab) );
safestrncpy(addrbook[num_ab-1].ab_name, buf,
sizeof(addrbook[num_ab-1].ab_name));
addrbook[num_ab-1].ab_msgnum = Msg->msgnum;
WebcitAddUrlHandler(HKEY("mobilemsg"), mobile_message_view, NEED_URL);
WebcitAddUrlHandler(HKEY("msgheaders"), display_headers, NEED_URL);
- RegisterNamespace("MAIL:SUMM:DATESTR", 0, 0, tmplput_MAIL_SUMM_DATE_STR, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:DATENO", 0, 0, tmplput_MAIL_SUMM_DATE_NO, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:N", 0, 0, tmplput_MAIL_SUMM_N, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:FROM", 0, 2, tmplput_MAIL_SUMM_FROM, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:TO", 0, 2, tmplput_MAIL_SUMM_TO, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:SUBJECT", 0, 4, tmplput_MAIL_SUMM_SUBJECT, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:NTATACH", 0, 0, tmplput_MAIL_SUMM_NATTACH, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:CCCC", 0, 2, tmplput_MAIL_SUMM_CCCC, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:H_NODE", 0, 2, tmplput_MAIL_SUMM_H_NODE, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:ALLRCPT", 0, 2, tmplput_MAIL_SUMM_ALLRCPT, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:ORGROOM", 0, 2, tmplput_MAIL_SUMM_ORGROOM, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:RFCA", 0, 2, tmplput_MAIL_SUMM_RFCA, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:OTHERNODE", 2, 0, tmplput_MAIL_SUMM_OTHERNODE, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:REFIDS", 0, 0, tmplput_MAIL_SUMM_REFIDS, CTX_MAILSUM);
- RegisterNamespace("MAIL:SUMM:INREPLYTO", 0, 2, tmplput_MAIL_SUMM_INREPLYTO, CTX_MAILSUM);
- RegisterNamespace("MAIL:BODY", 0, 2, tmplput_MAIL_BODY, CTX_MAILSUM);
-
-
- RegisterConditional(HKEY("COND:MAIL:SUMM:UNREAD"), 0, Conditional_MAIL_SUMM_UNREAD, CTX_MAILSUM);
- RegisterConditional(HKEY("COND:MAIL:SUMM:H_NODE"), 0, Conditional_MAIL_SUMM_H_NODE, CTX_MAILSUM);
- RegisterConditional(HKEY("COND:MAIL:SUMM:OTHERNODE"), 0, Conditional_MAIL_SUMM_OTHERNODE, CTX_MAILSUM);
- RegisterConditional(HKEY("COND:MAIL:ANON"), 0, Conditional_ANONYMOUS_MESSAGE, CTX_MAILSUM);
-
- RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH"), 0, Conditional_MAIL_MIME_ALL, CTX_MAILSUM);
- RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH:SUBMESSAGES"), 0, Conditional_MAIL_MIME_SUBMESSAGES, CTX_MAILSUM);
- RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH:LINKS"), 0, Conditional_MAIL_MIME_ATTACHLINKS, CTX_MAILSUM);
- RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH:ATT"), 0, Conditional_MAIL_MIME_ATTACH, CTX_MAILSUM);
-
- RegisterIterator("MAIL:MIME:ATTACH", 0, NULL, iterate_get_mime_All,
- NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
- RegisterIterator("MAIL:MIME:ATTACH:SUBMESSAGES", 0, NULL, iterate_get_mime_Submessages,
- NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
- RegisterIterator("MAIL:MIME:ATTACH:LINKS", 0, NULL, iterate_get_mime_AttachLinks,
- NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
- RegisterIterator("MAIL:MIME:ATTACH:ATT", 0, NULL, iterate_get_mime_Attachments,
- NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
-
- RegisterNamespace("MAIL:MIME:NAME", 0, 2, tmplput_MIME_Name, CTX_MIME_ATACH);
- RegisterNamespace("MAIL:MIME:FILENAME", 0, 2, tmplput_MIME_FileName, CTX_MIME_ATACH);
- RegisterNamespace("MAIL:MIME:PARTNUM", 0, 2, tmplput_MIME_PartNum, CTX_MIME_ATACH);
- RegisterNamespace("MAIL:MIME:MSGNUM", 0, 2, tmplput_MIME_MsgNum, CTX_MIME_ATACH);
- RegisterNamespace("MAIL:MIME:DISPOSITION", 0, 2, tmplput_MIME_Disposition, CTX_MIME_ATACH);
- RegisterNamespace("MAIL:MIME:CONTENTTYPE", 0, 2, tmplput_MIME_ContentType, CTX_MIME_ATACH);
- RegisterNamespace("MAIL:MIME:CHARSET", 0, 2, tmplput_MIME_Charset, CTX_MIME_ATACH);
- RegisterNamespace("MAIL:MIME:LENGTH", 0, 2, tmplput_MIME_Length, CTX_MIME_ATACH);
- RegisterNamespace("MAIL:MIME:DATA", 0, 2, tmplput_MIME_Data, CTX_MIME_ATACH);
-
-
-
- RegisterMimeRenderer(HKEY("message/rfc822"), render_MAIL);
- RegisterMimeRenderer(HKEY("text/x-vcard"), render_MIME_VCard);
- RegisterMimeRenderer(HKEY("text/vcard"), render_MIME_VCard);
- RegisterMimeRenderer(HKEY("text/calendar"), render_MIME_ICS);
- RegisterMimeRenderer(HKEY("application/ics"), render_MIME_ICS);
-
- RegisterMimeRenderer(HKEY("text/x-citadel-variformat"), render_MAIL_variformat);
- RegisterMimeRenderer(HKEY("text/plain"), render_MAIL_text_plain);
- RegisterMimeRenderer(HKEY("text"), render_MAIL_text_plain);
- RegisterMimeRenderer(HKEY("text/html"), render_MAIL_html);
- RegisterMimeRenderer(HKEY(""), render_MAIL_UNKNOWN);
-
- RegisterMsgHdr(HKEY("nhdr"), examine_nhdr, 0);
- RegisterMsgHdr(HKEY("type"), examine_type, 0);
- RegisterMsgHdr(HKEY("from"), examine_from, 0);
- RegisterMsgHdr(HKEY("subj"), examine_subj, 0);
- RegisterMsgHdr(HKEY("msgn"), examine_msgn, 0);
- RegisterMsgHdr(HKEY("wefw"), examine_wefw, 0);
- RegisterMsgHdr(HKEY("cccc"), examine_cccc, 0);
- RegisterMsgHdr(HKEY("hnod"), examine_hnod, 0);
- RegisterMsgHdr(HKEY("room"), examine_room, 0);
- RegisterMsgHdr(HKEY("rfca"), examine_rfca, 0);
- RegisterMsgHdr(HKEY("node"), examine_node, 0);
- RegisterMsgHdr(HKEY("rcpt"), examine_rcpt, 0);
- RegisterMsgHdr(HKEY("time"), examine_time, 0);
- RegisterMsgHdr(HKEY("part"), examine_mime_part, 0);
- RegisterMsgHdr(HKEY("text"), examine_text, 1);
- RegisterMsgHdr(HKEY("X-Citadel-MSG4-Partnum"), examine_msg4_partnum, 0);
- RegisterMsgHdr(HKEY("Content-type"), examine_content_type, 0);
- RegisterMsgHdr(HKEY("Content-length"), examine_content_lengh, 0);
- RegisterMsgHdr(HKEY("Content-transfer-encoding"), examine_content_encoding, 0);
return ;
}
--- /dev/null
+/*----------------------------------------------------------------------------*/
+#include "webcit.h"
+#include "webserver.h"
+
+/**
+ * message index functions
+ */
+
+void DestroyMimeParts(wc_mime_attachment *Mime)
+{
+ FreeStrBuf(&Mime->Name);
+ FreeStrBuf(&Mime->FileName);
+ FreeStrBuf(&Mime->PartNum);
+ FreeStrBuf(&Mime->Disposition);
+ FreeStrBuf(&Mime->ContentType);
+ FreeStrBuf(&Mime->Charset);
+ FreeStrBuf(&Mime->Data);
+}
+
+void DestroyMime(void *vMime)
+{
+ wc_mime_attachment *Mime = (wc_mime_attachment*)vMime;
+ DestroyMimeParts(Mime);
+ free(Mime);
+}
+
+void DestroyMessageSummary(void *vMsg)
+{
+ message_summary *Msg = (message_summary*) vMsg;
+
+ FreeStrBuf(&Msg->from);
+ FreeStrBuf(&Msg->to);
+ FreeStrBuf(&Msg->subj);
+ FreeStrBuf(&Msg->reply_inreplyto);
+ FreeStrBuf(&Msg->reply_references);
+ FreeStrBuf(&Msg->cccc);
+ FreeStrBuf(&Msg->hnod);
+ FreeStrBuf(&Msg->AllRcpt);
+ FreeStrBuf(&Msg->Room);
+ FreeStrBuf(&Msg->Rfca);
+ FreeStrBuf(&Msg->OtherNode);
+
+ FreeStrBuf(&Msg->reply_to);
+
+ DeleteHash(&Msg->Attachments); /**< list of Accachments */
+ DeleteHash(&Msg->Submessages);
+ DeleteHash(&Msg->AttachLinks);
+ DeleteHash(&Msg->AllAttach);
+
+ DestroyMimeParts(&Msg->MsgBody);
+
+ free(Msg);
+}
+
+
+
+void RegisterMsgHdr(const char *HeaderName, long HdrNLen, ExamineMsgHeaderFunc evaluator, int type)
+{
+ headereval *ev;
+ ev = (headereval*) malloc(sizeof(headereval));
+ ev->evaluator = evaluator;
+ ev->Type = type;
+ Put(MsgHeaderHandler, HeaderName, HdrNLen, ev, NULL);
+}
+
+void RegisterMimeRenderer(const char *HeaderName, long HdrNLen, RenderMimeFunc MimeRenderer)
+{
+ Put(MimeRenderHandler, HeaderName, HdrNLen, MimeRenderer, reference_free_handler);
+
+}
+
+/*----------------------------------------------------------------------------*/
+
+
+void examine_nhdr(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ Msg->nhdr = 0;
+ if (!strncasecmp(ChrPtr(HdrLine), "yes", 8))
+ Msg->nhdr = 1;
+}
+int Conditional_ANONYMOUS_MESSAGE(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return Msg->nhdr != 0;
+}
+
+
+void examine_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ Msg->format_type = StrToi(HdrLine);
+
+}
+
+void examine_from(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ FreeStrBuf(&Msg->from);
+ Msg->from = NewStrBufPlain(NULL, StrLength(HdrLine));
+ StrBuf_RFC822_to_Utf8(Msg->from, HdrLine, WC->DefaultCharset, FoundCharset);
+}
+void tmplput_MAIL_SUMM_FROM(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->from, 0);
+ lprintf(1,"%s", ChrPtr(Msg->from));
+}
+
+
+
+void examine_subj(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ FreeStrBuf(&Msg->subj);
+ Msg->subj = NewStrBufPlain(NULL, StrLength(HdrLine));
+ StrBuf_RFC822_to_Utf8(Msg->subj, HdrLine, WC->DefaultCharset, FoundCharset);
+ lprintf(1,"%s", ChrPtr(Msg->subj));
+}
+void tmplput_MAIL_SUMM_SUBJECT(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{/////TODO: Fwd: and RE: filter!!
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->subj, 0);
+}
+
+
+void examine_msgn(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ FreeStrBuf(&Msg->reply_inreplyto);
+ Msg->reply_inreplyto = NewStrBufPlain(NULL, StrLength(HdrLine));
+ StrBuf_RFC822_to_Utf8(Msg->reply_inreplyto, HdrLine, WC->DefaultCharset, FoundCharset);
+}
+void tmplput_MAIL_SUMM_INREPLYTO(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->reply_inreplyto, 0);
+}
+
+int Conditional_MAIL_SUMM_UNREAD(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return Msg->is_new != 0;
+}
+
+void examine_wefw(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ FreeStrBuf(&Msg->reply_references);
+ Msg->reply_references = NewStrBufPlain(NULL, StrLength(HdrLine));
+ StrBuf_RFC822_to_Utf8(Msg->reply_references, HdrLine, WC->DefaultCharset, FoundCharset);
+}
+void tmplput_MAIL_SUMM_REFIDS(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->reply_references, 0);
+}
+
+
+void examine_cccc(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ FreeStrBuf(&Msg->cccc);
+ Msg->cccc = NewStrBufPlain(NULL, StrLength(HdrLine));
+ StrBuf_RFC822_to_Utf8(Msg->cccc, HdrLine, WC->DefaultCharset, FoundCharset);
+ if (Msg->AllRcpt == NULL)
+ Msg->AllRcpt = NewStrBufPlain(NULL, StrLength(HdrLine));
+ if (StrLength(Msg->AllRcpt) > 0) {
+ StrBufAppendBufPlain(Msg->AllRcpt, HKEY(", "), 0);
+ }
+ StrBufAppendBuf(Msg->AllRcpt, Msg->cccc, 0);
+}
+void tmplput_MAIL_SUMM_CCCC(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->cccc, 0);
+}
+
+
+
+
+void examine_room(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ if ((StrLength(HdrLine) > 0) &&
+ (strcasecmp(ChrPtr(HdrLine), WC->wc_roomname))) {
+ FreeStrBuf(&Msg->Room);
+ Msg->Room = NewStrBufDup(HdrLine);
+ }
+}
+void tmplput_MAIL_SUMM_ORGROOM(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->Room, 0);
+}
+
+
+void examine_rfca(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ FreeStrBuf(&Msg->Rfca);
+ Msg->Rfca = NewStrBufDup(HdrLine);
+}
+void tmplput_MAIL_SUMM_RFCA(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->Rfca, 0);
+}
+
+
+void examine_node(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ if ( (StrLength(HdrLine) > 0) &&
+ ((WC->room_flags & QR_NETWORK)
+ || ((strcasecmp(ChrPtr(HdrLine), serv_info.serv_nodename)
+ && (strcasecmp(ChrPtr(HdrLine), serv_info.serv_fqdn)))))) {
+ FreeStrBuf(&Msg->OtherNode);
+ Msg->OtherNode = NewStrBufDup(HdrLine);
+ }
+}
+void tmplput_MAIL_SUMM_OTHERNODE(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->OtherNode, 0);
+}
+int Conditional_MAIL_SUMM_OTHERNODE(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return StrLength(Msg->OtherNode) > 0;
+}
+
+
+void examine_rcpt(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ FreeStrBuf(&Msg->to);
+ Msg->to = NewStrBufPlain(NULL, StrLength(HdrLine));
+ StrBuf_RFC822_to_Utf8(Msg->to, HdrLine, WC->DefaultCharset, FoundCharset);
+ if (Msg->AllRcpt == NULL)
+ Msg->AllRcpt = NewStrBufPlain(NULL, StrLength(HdrLine));
+ if (StrLength(Msg->AllRcpt) > 0) {
+ StrBufAppendBufPlain(Msg->AllRcpt, HKEY(", "), 0);
+ }
+ StrBufAppendBuf(Msg->AllRcpt, Msg->to, 0);
+}
+void tmplput_MAIL_SUMM_TO(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->to, 0);
+}
+void tmplput_MAIL_SUMM_ALLRCPT(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->AllRcpt, 0);
+}
+
+
+
+void examine_time(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ Msg->date = StrTol(HdrLine);
+}
+void tmplput_MAIL_SUMM_DATE_STR(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ char datebuf[64];
+ message_summary *Msg = (message_summary*) Context;
+ webcit_fmt_date(datebuf, Msg->date, 1);
+ StrBufAppendBufPlain(Target, datebuf, -1, 0);
+}
+void tmplput_MAIL_SUMM_DATE_NO(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendPrintf(Target, "%ld", Msg->date, 0);
+}
+
+
+
+void render_MAIL(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
+{
+/*
+ if ( (!IsEmptyStr(mime_submessages)) && (!section[0]) ) {
+ for (i=0; i<num_tokens(mime_submessages, '|'); ++i) {
+ extract_token(buf, mime_submessages, i, '|', sizeof buf);
+ /** use printable_view to suppress buttons * /
+ wprintf("<blockquote>");
+ read_message(Mime->msgnum, 1, ChrPtr(Mime->Section));
+ wprintf("</blockquote>");
+ }
+ }
+*/
+}
+
+void render_MIME_VCard(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
+{
+ MimeLoadData(Mime);
+ if (StrLength(Mime->Data) > 0) {
+ StrBuf *Buf;
+ Buf = NewStrBuf();
+ /** If it's my vCard I can edit it */
+ if ( (!strcasecmp(WC->wc_roomname, USERCONFIGROOM))
+ || (!strcasecmp(&WC->wc_roomname[11], USERCONFIGROOM))
+ || (WC->wc_view == VIEW_ADDRESSBOOK)
+ ) {
+ StrBufAppendPrintf(Buf, "<a href=\"edit_vcard?msgnum=%ld&partnum=%s\">",
+ Mime->msgnum, ChrPtr(Mime->PartNum));
+ StrBufAppendPrintf(Buf, "[%s]</a>", _("edit"));
+ }
+
+ /* In all cases, display the full card */
+ display_vcard(Buf, ChrPtr(Mime->Data), 0, 1, NULL, Mime->msgnum);
+ FreeStrBuf(&Mime->Data);
+ Mime->Data = Buf;
+ }
+
+}
+void render_MIME_ICS(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
+{
+ MimeLoadData(Mime);
+ if (StrLength(Mime->Data) > 0) {
+ cal_process_attachment(Mime);
+ }
+}
+
+
+
+void examine_mime_part(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ wc_mime_attachment *mime;
+ StrBuf *Buf;
+ void *vMimeRenderer;
+
+ mime = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment));
+ memset(mime, 0, sizeof(wc_mime_attachment));
+ mime->msgnum = Msg->msgnum;
+ Buf = NewStrBuf();
+
+ mime->Name = NewStrBuf();
+ StrBufExtract_token(mime->Name, HdrLine, 0, '|');
+
+ StrBufExtract_token(Buf, HdrLine, 1, '|');
+ mime->FileName = NewStrBuf();
+ StrBuf_RFC822_to_Utf8(mime->FileName, Buf, WC->DefaultCharset, FoundCharset);
+
+ mime->PartNum = NewStrBuf();
+ StrBufExtract_token(mime->PartNum, HdrLine, 2, '|');
+
+ mime->Disposition = NewStrBuf();
+ StrBufExtract_token(mime->Disposition, HdrLine, 3, '|');
+
+ mime->ContentType = NewStrBuf();
+ StrBufExtract_token(mime->ContentType, HdrLine, 4, '|');
+
+ mime->length = StrBufExtract_int(HdrLine, 5, '|');
+
+ StrBufTrim(mime->Name);
+ StrBufTrim(mime->FileName);
+
+ if ( (StrLength(mime->FileName) == 0) && (StrLength(mime->Name) > 0) ) {
+ StrBufAppendBuf(mime->FileName, mime->Name, 0);
+ }
+
+ if (Msg->AllAttach == NULL)
+ Msg->AllAttach = NewHash(1,NULL);
+ Put(Msg->AllAttach, SKEY(mime->PartNum), mime, DestroyMime);
+
+
+ if (GetHash(MimeRenderHandler, SKEY(mime->ContentType), &vMimeRenderer) &&
+ vMimeRenderer != NULL)
+ {
+ mime->Renderer = (RenderMimeFunc) vMimeRenderer;
+ if (Msg->Submessages == NULL)
+ Msg->Submessages = NewHash(1,NULL);
+ Put(Msg->Submessages, SKEY(mime->PartNum), mime, reference_free_handler);
+ }
+ else if ((!strcasecmp(ChrPtr(mime->Disposition), "inline"))
+ && (!strncasecmp(ChrPtr(mime->ContentType), "image/", 6)) ){
+ if (Msg->AttachLinks == NULL)
+ Msg->AttachLinks = NewHash(1,NULL);
+ Put(Msg->AttachLinks, SKEY(mime->PartNum), mime, reference_free_handler);
+ }
+ else if ((StrLength(mime->ContentType) > 0) &&
+ ( (!strcasecmp(ChrPtr(mime->Disposition), "attachment"))
+ || (!strcasecmp(ChrPtr(mime->Disposition), "inline"))
+ || (!strcasecmp(ChrPtr(mime->Disposition), ""))))
+ {
+ if (Msg->AttachLinks == NULL)
+ Msg->AttachLinks = NewHash(1,NULL);
+ Put(Msg->AttachLinks, SKEY(mime->PartNum), mime, reference_free_handler);
+ if (strcasecmp(ChrPtr(mime->ContentType), "application/octet-stream") == 0) {
+ FlushStrBuf(mime->ContentType);
+ StrBufAppendBufPlain(mime->ContentType,
+ GuessMimeByFilename(SKEY(mime->FileName)),
+ -1, 0);
+ }
+ }
+
+ FreeStrBuf(&Buf);
+}
+
+void tmplput_MAIL_SUMM_NATTACH(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendPrintf(Target, "%ld", GetCount(Msg->Attachments));
+}
+
+
+
+
+
+
+
+void examine_hnod(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ FreeStrBuf(&Msg->hnod);
+ Msg->hnod = NewStrBufPlain(NULL, StrLength(HdrLine));
+ StrBuf_RFC822_to_Utf8(Msg->hnod, HdrLine, WC->DefaultCharset, FoundCharset);
+}
+void tmplput_MAIL_SUMM_H_NODE(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->hnod, 0);
+}
+int Conditional_MAIL_SUMM_H_NODE(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return StrLength(Msg->hnod) > 0;
+}
+
+
+
+void examine_text(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{////TODO: read messages here
+ Msg->MsgBody.Data = NewStrBuf();
+}
+
+void examine_msg4_partnum(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ Msg->MsgBody.PartNum = NewStrBufDup(HdrLine);
+ StrBufTrim(Msg->MsgBody.PartNum);/////TODO: striplt == trim?
+}
+
+void examine_content_encoding(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+////TODO: do we care?
+}
+
+void examine_content_lengh(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+ Msg->MsgBody.length = StrTol(HdrLine);
+ Msg->MsgBody.size_known = 1;
+}
+
+void examine_content_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{////TODO
+ int len, i;
+ Msg->MsgBody.ContentType = NewStrBufDup(HdrLine);
+ StrBufTrim(Msg->MsgBody.ContentType);/////todo==striplt?
+ len = StrLength(Msg->MsgBody.ContentType);
+ for (i=0; i<len; ++i) {
+ if (!strncasecmp(ChrPtr(Msg->MsgBody.ContentType) + i, "charset=", 8)) {/// TODO: WHUT?
+// safestrncpy(mime_charset, &mime_content_type[i+8],
+ /// sizeof mime_charset);
+ }
+ }/****
+ for (i=0; i<len; ++i) {
+ if (mime_content_type[i] == ';') {
+ mime_content_type[i] = 0;
+ len = i - 1;
+ }
+ }
+ len = strlen(mime_charset);
+ for (i=0; i<len; ++i) {
+ if (mime_charset[i] == ';') {
+ mime_charset[i] = 0;
+ len = i - 1;
+ }
+ }
+ */
+}
+
+void tmplput_MAIL_SUMM_N(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendPrintf(Target, "%ld", Msg->msgnum);
+}
+
+
+
+int Conditional_MAIL_MIME_ALL(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return GetCount(Msg->Attachments) > 0;
+}
+
+int Conditional_MAIL_MIME_SUBMESSAGES(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return GetCount(Msg->Submessages) > 0;
+}
+
+int Conditional_MAIL_MIME_ATTACHLINKS(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return GetCount(Msg->AttachLinks) > 0;
+}
+
+int Conditional_MAIL_MIME_ATTACH(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return GetCount(Msg->AllAttach) > 0;
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+
+
+void tmplput_MAIL_BODY(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ StrBufAppendBuf(Target, Msg->MsgBody.Data, 0);
+}
+
+
+void render_MAIL_variformat(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
+{
+ /* Messages in legacy Citadel variformat get handled thusly... */
+ StrBuf *Target = NewStrBufPlain(NULL, StrLength(Mime->Data));
+ FmOut(Target, "JUSTIFY", Mime->Data);
+ FreeStrBuf(&Mime->Data);
+ Mime->Data = Target;
+}
+
+void render_MAIL_text_plain(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
+{
+ StrBuf *cs = NULL;
+ const char *ptr, *pte;
+ const char *BufPtr = NULL;
+ StrBuf *Line = NewStrBuf();
+ StrBuf *Line1 = NewStrBuf();
+ StrBuf *Line2 = NewStrBuf();
+ StrBuf *Target = NewStrBufPlain(NULL, StrLength(Mime->Data));
+ int ConvertIt = 1;
+ int bn = 0;
+ int bq = 0;
+ int i, n, done = 0;
+ long len;
+#ifdef HAVE_ICONV
+ iconv_t ic = (iconv_t)(-1) ;
+#endif
+
+ /* Boring old 80-column fixed format text gets handled this way... */
+ if ((strcasecmp(ChrPtr(Mime->Charset), "us-ascii") == 0) &&
+ (strcasecmp(ChrPtr(Mime->Charset), "UTF-8") == 0))
+ ConvertIt = 0;
+
+#ifdef HAVE_ICONV
+ if (ConvertIt) {
+ if (StrLength(Mime->Charset) != 0)
+ cs = Mime->Charset;
+ else if (StrLength(FoundCharset) > 0)
+ cs = FoundCharset;
+ else if (StrLength(WC->DefaultCharset) > 0)
+ cs = WC->DefaultCharset;
+ if (cs == 0) {
+ ConvertIt = 0;
+ }
+ else {
+ ctdl_iconv_open("UTF-8", ChrPtr(cs), &ic);
+ if (ic == (iconv_t)(-1) ) {
+ lprintf(5, "%s:%d iconv_open(UTF-8, %s) failed: %s\n",
+ __FILE__, __LINE__, ChrPtr(Mime->Charset), strerror(errno));
+ }
+ }
+ }
+#endif
+
+ while ((n = StrBufSipLine(Line, Mime->Data, &BufPtr), n >= 0) && !done)
+ {
+ done = n == 0;
+ bq = 0;
+ i = 0;
+ ptr = ChrPtr(Line);
+ len = StrLength(Line);
+ pte = ptr + len;
+
+ while ((ptr < pte) &&
+ ((*ptr == '>') ||
+ isspace(*ptr)))
+ {
+ if (*ptr == '>')
+ bq++;
+ ptr ++;
+ i++;
+ }
+ if (i > 0) StrBufCutLeft(Line, i);
+
+ if (StrLength(Line) == 0)
+ continue;
+
+ for (i = bn; i < bq; i++)
+ StrBufAppendBufPlain(Target, HKEY("<blockquote>"), 0);
+ for (i = bq; i < bn; i++)
+ StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
+
+ if (ConvertIt == 1) {
+ StrBufConvert(Line, Line1, &ic);
+ }
+
+ StrBufAppendBufPlain(Target, HKEY("<tt>"), 0);
+ UrlizeText(Line1, Line, Line2);
+
+ StrEscAppend(Target, Line1, NULL, 0, 0);
+ StrBufAppendBufPlain(Target, HKEY("</tt><br />\n"), 0);
+ bn = bq;
+ }
+
+ for (i = 0; i < bn; i++)
+ StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
+
+ StrBufAppendBufPlain(Target, HKEY("</i><br />"), 0);
+#ifdef HAVE_ICONV
+ if (ic != (iconv_t)(-1) ) {
+ iconv_close(ic);
+ }
+#endif
+ FreeStrBuf(&Mime->Data);
+ Mime->Data = Target;
+ FreeStrBuf(&Line);
+ FreeStrBuf(&Line1);
+ FreeStrBuf(&Line2);
+}
+
+void render_MAIL_html(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
+{
+ StrBuf *Buf;
+ /* HTML is fun, but we've got to strip it first */
+ Buf = NewStrBufPlain(NULL, StrLength(Mime->Data));
+ output_html(ChrPtr(Mime->Charset),
+ (WC->wc_view == VIEW_WIKI ? 1 : 0),
+ StrToi(Mime->PartNum),
+ Mime->Data, Buf);
+ FreeStrBuf(&Mime->Data);
+ Mime->Data = Buf;
+}
+
+void render_MAIL_UNKNOWN(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
+{
+ /* Unknown weirdness */
+ FlushStrBuf(Mime->Data);
+ StrBufAppendBufPlain(Mime->Data, _("I don't know how to display "), -1, 0);
+ StrBufAppendBuf(Mime->Data, Mime->ContentType, 0);
+ StrBufAppendBufPlain(Mime->Data, HKEY("<br />\n"), 0);
+}
+
+
+
+
+
+
+HashList *iterate_get_mime_All(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return Msg->Attachments;
+}
+HashList *iterate_get_mime_Submessages(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return Msg->Submessages;
+}
+HashList *iterate_get_mime_AttachLinks(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return Msg->AttachLinks;
+}
+HashList *iterate_get_mime_Attachments(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ message_summary *Msg = (message_summary*) Context;
+ return Msg->AllAttach;
+}
+
+void tmplput_MIME_Name(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ StrBufAppendBuf(Target, mime->Name, 0);
+}
+
+void tmplput_MIME_FileName(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ StrBufAppendBuf(Target, mime->FileName, 0);
+}
+
+void tmplput_MIME_PartNum(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ StrBufAppendBuf(Target, mime->PartNum, 0);
+}
+
+void tmplput_MIME_MsgNum(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ StrBufAppendPrintf(Target, "%ld", mime->msgnum);
+}
+
+void tmplput_MIME_Disposition(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ StrBufAppendBuf(Target, mime->Disposition, 0);
+}
+
+void tmplput_MIME_ContentType(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ StrBufAppendBuf(Target, mime->ContentType, 0);
+}
+
+void tmplput_MIME_Charset(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ StrBufAppendBuf(Target, mime->Charset, 0);
+}
+
+void tmplput_MIME_Data(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ if (mime->Renderer != NULL)
+ mime->Renderer(mime, NULL, NULL);
+ StrBufAppendBuf(Target, mime->Data, 0); /// TODO: check whether we need to load it now?
+}
+
+void tmplput_MIME_Length(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType)
+{
+ wc_mime_attachment *mime = (wc_mime_attachment*) Context;
+ StrBufAppendPrintf(Target, "%ld", mime->length);
+}
+
+
+
+
+
+void
+InitModule_MSGRENDERERS
+(void)
+{
+ RegisterNamespace("MAIL:SUMM:DATESTR", 0, 0, tmplput_MAIL_SUMM_DATE_STR, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:DATENO", 0, 0, tmplput_MAIL_SUMM_DATE_NO, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:N", 0, 0, tmplput_MAIL_SUMM_N, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:FROM", 0, 2, tmplput_MAIL_SUMM_FROM, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:TO", 0, 2, tmplput_MAIL_SUMM_TO, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:SUBJECT", 0, 4, tmplput_MAIL_SUMM_SUBJECT, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:NTATACH", 0, 0, tmplput_MAIL_SUMM_NATTACH, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:CCCC", 0, 2, tmplput_MAIL_SUMM_CCCC, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:H_NODE", 0, 2, tmplput_MAIL_SUMM_H_NODE, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:ALLRCPT", 0, 2, tmplput_MAIL_SUMM_ALLRCPT, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:ORGROOM", 0, 2, tmplput_MAIL_SUMM_ORGROOM, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:RFCA", 0, 2, tmplput_MAIL_SUMM_RFCA, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:OTHERNODE", 2, 0, tmplput_MAIL_SUMM_OTHERNODE, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:REFIDS", 0, 0, tmplput_MAIL_SUMM_REFIDS, CTX_MAILSUM);
+ RegisterNamespace("MAIL:SUMM:INREPLYTO", 0, 2, tmplput_MAIL_SUMM_INREPLYTO, CTX_MAILSUM);
+ RegisterNamespace("MAIL:BODY", 0, 2, tmplput_MAIL_BODY, CTX_MAILSUM);
+
+
+ RegisterConditional(HKEY("COND:MAIL:SUMM:UNREAD"), 0, Conditional_MAIL_SUMM_UNREAD, CTX_MAILSUM);
+ RegisterConditional(HKEY("COND:MAIL:SUMM:H_NODE"), 0, Conditional_MAIL_SUMM_H_NODE, CTX_MAILSUM);
+ RegisterConditional(HKEY("COND:MAIL:SUMM:OTHERNODE"), 0, Conditional_MAIL_SUMM_OTHERNODE, CTX_MAILSUM);
+ RegisterConditional(HKEY("COND:MAIL:ANON"), 0, Conditional_ANONYMOUS_MESSAGE, CTX_MAILSUM);
+
+ RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH"), 0, Conditional_MAIL_MIME_ALL, CTX_MAILSUM);
+ RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH:SUBMESSAGES"), 0, Conditional_MAIL_MIME_SUBMESSAGES, CTX_MAILSUM);
+ RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH:LINKS"), 0, Conditional_MAIL_MIME_ATTACHLINKS, CTX_MAILSUM);
+ RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH:ATT"), 0, Conditional_MAIL_MIME_ATTACH, CTX_MAILSUM);
+
+ RegisterIterator("MAIL:MIME:ATTACH", 0, NULL, iterate_get_mime_All,
+ NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
+ RegisterIterator("MAIL:MIME:ATTACH:SUBMESSAGES", 0, NULL, iterate_get_mime_Submessages,
+ NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
+ RegisterIterator("MAIL:MIME:ATTACH:LINKS", 0, NULL, iterate_get_mime_AttachLinks,
+ NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
+ RegisterIterator("MAIL:MIME:ATTACH:ATT", 0, NULL, iterate_get_mime_Attachments,
+ NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
+
+ RegisterNamespace("MAIL:MIME:NAME", 0, 2, tmplput_MIME_Name, CTX_MIME_ATACH);
+ RegisterNamespace("MAIL:MIME:FILENAME", 0, 2, tmplput_MIME_FileName, CTX_MIME_ATACH);
+ RegisterNamespace("MAIL:MIME:PARTNUM", 0, 2, tmplput_MIME_PartNum, CTX_MIME_ATACH);
+ RegisterNamespace("MAIL:MIME:MSGNUM", 0, 2, tmplput_MIME_MsgNum, CTX_MIME_ATACH);
+ RegisterNamespace("MAIL:MIME:DISPOSITION", 0, 2, tmplput_MIME_Disposition, CTX_MIME_ATACH);
+ RegisterNamespace("MAIL:MIME:CONTENTTYPE", 0, 2, tmplput_MIME_ContentType, CTX_MIME_ATACH);
+ RegisterNamespace("MAIL:MIME:CHARSET", 0, 2, tmplput_MIME_Charset, CTX_MIME_ATACH);
+ RegisterNamespace("MAIL:MIME:LENGTH", 0, 2, tmplput_MIME_Length, CTX_MIME_ATACH);
+ RegisterNamespace("MAIL:MIME:DATA", 0, 2, tmplput_MIME_Data, CTX_MIME_ATACH);
+
+
+
+ RegisterMimeRenderer(HKEY("message/rfc822"), render_MAIL);
+ RegisterMimeRenderer(HKEY("text/x-vcard"), render_MIME_VCard);
+ RegisterMimeRenderer(HKEY("text/vcard"), render_MIME_VCard);
+ RegisterMimeRenderer(HKEY("text/calendar"), render_MIME_ICS);
+ RegisterMimeRenderer(HKEY("application/ics"), render_MIME_ICS);
+
+ RegisterMimeRenderer(HKEY("text/x-citadel-variformat"), render_MAIL_variformat);
+ RegisterMimeRenderer(HKEY("text/plain"), render_MAIL_text_plain);
+ RegisterMimeRenderer(HKEY("text"), render_MAIL_text_plain);
+ RegisterMimeRenderer(HKEY("text/html"), render_MAIL_html);
+ RegisterMimeRenderer(HKEY(""), render_MAIL_UNKNOWN);
+
+ RegisterMsgHdr(HKEY("nhdr"), examine_nhdr, 0);
+ RegisterMsgHdr(HKEY("type"), examine_type, 0);
+ RegisterMsgHdr(HKEY("from"), examine_from, 0);
+ RegisterMsgHdr(HKEY("subj"), examine_subj, 0);
+ RegisterMsgHdr(HKEY("msgn"), examine_msgn, 0);
+ RegisterMsgHdr(HKEY("wefw"), examine_wefw, 0);
+ RegisterMsgHdr(HKEY("cccc"), examine_cccc, 0);
+ RegisterMsgHdr(HKEY("hnod"), examine_hnod, 0);
+ RegisterMsgHdr(HKEY("room"), examine_room, 0);
+ RegisterMsgHdr(HKEY("rfca"), examine_rfca, 0);
+ RegisterMsgHdr(HKEY("node"), examine_node, 0);
+ RegisterMsgHdr(HKEY("rcpt"), examine_rcpt, 0);
+ RegisterMsgHdr(HKEY("time"), examine_time, 0);
+ RegisterMsgHdr(HKEY("part"), examine_mime_part, 0);
+ RegisterMsgHdr(HKEY("text"), examine_text, 1);
+ RegisterMsgHdr(HKEY("X-Citadel-MSG4-Partnum"), examine_msg4_partnum, 0);
+ RegisterMsgHdr(HKEY("Content-type"), examine_content_type, 0);
+ RegisterMsgHdr(HKEY("Content-length"), examine_content_lengh, 0);
+ RegisterMsgHdr(HKEY("Content-transfer-encoding"), examine_content_encoding, 0);
+}
#include "webcit.h"
+
+/**
+ * \brief Record compare function for sorting address book indices
+ * \param ab1 adressbook one
+ * \param ab2 adressbook two
+ */
+int abcmp(const void *ab1, const void *ab2) {
+ return(strcasecmp(
+ (((const addrbookent *)ab1)->ab_name),
+ (((const addrbookent *)ab2)->ab_name)
+ ));
+}
+
+
+/**
+ * \brief Helper function for do_addrbook_view()
+ * Converts a name into a three-letter tab label
+ * \param tabbuf the tabbuffer to add name to
+ * \param name the name to add to the tabbuffer
+ */
+void nametab(char *tabbuf, long len, char *name) {
+ stresc(tabbuf, len, name, 0, 0);
+ tabbuf[0] = toupper(tabbuf[0]);
+ tabbuf[1] = tolower(tabbuf[1]);
+ tabbuf[2] = tolower(tabbuf[2]);
+ tabbuf[3] = 0;
+}
+
+
+
+/**
+ * \brief Turn a vCard "n" (name) field into something displayable.
+ * \param name the name field to convert
+ */
+void vcard_n_prettyize(char *name)
+{
+ char *original_name;
+ int i, j, len;
+
+ original_name = strdup(name);
+ len = strlen(original_name);
+ for (i=0; i<5; ++i) {
+ if (len > 0) {
+ if (original_name[len-1] == ' ') {
+ original_name[--len] = 0;
+ }
+ if (original_name[len-1] == ';') {
+ original_name[--len] = 0;
+ }
+ }
+ }
+ strcpy(name, "");
+ j=0;
+ for (i=0; i<len; ++i) {
+ if (original_name[i] == ';') {
+ name[j++] = ',';
+ name[j++] = ' ';
+ }
+ else {
+ name[j++] = original_name[i];
+ }
+ }
+ name[j] = '\0';
+ free(original_name);
+}
+
+
+
+
+/**
+ * \brief preparse a vcard name
+ * display_vcard() calls this after parsing the textual vCard into
+ * our 'struct vCard' data object.
+ * This gets called instead of display_parsed_vcard() if we are only looking
+ * to extract the person's name instead of displaying the card.
+ * \param v the vcard to retrieve the name from
+ * \param storename where to put the name at
+ */
+void fetchname_parsed_vcard(struct vCard *v, char *storename) {
+ char *name;
+
+ strcpy(storename, "");
+
+ name = vcard_get_prop(v, "n", 1, 0, 0);
+ if (name != NULL) {
+ strcpy(storename, name);
+ /* vcard_n_prettyize(storename); */
+ }
+
+}
+
+
+
+/**
+ * \brief html print a vcard
+ * display_vcard() calls this after parsing the textual vCard into
+ * our 'struct vCard' data object.
+ *
+ * Set 'full' to nonzero to display the full card, otherwise it will only
+ * show a summary line.
+ *
+ * This code is a bit ugly, so perhaps an explanation is due: we do this
+ * in two passes through the vCard fields. On the first pass, we process
+ * fields we understand, and then render them in a pretty fashion at the
+ * end. Then we make a second pass, outputting all the fields we don't
+ * understand in a simple two-column name/value format.
+ * \param v the vCard to display
+ * \param full display all items of the vcard?
+ * \param msgnum Citadel message pointer
+ */
+void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum) {
+ int i, j;
+ char buf[SIZ];
+ char *name;
+ int is_qp = 0;
+ int is_b64 = 0;
+ char *thisname, *thisvalue;
+ char firsttoken[SIZ];
+ int pass;
+
+ char fullname[SIZ];
+ char title[SIZ];
+ char org[SIZ];
+ char phone[SIZ];
+ char mailto[SIZ];
+
+ strcpy(fullname, "");
+ strcpy(phone, "");
+ strcpy(mailto, "");
+ strcpy(title, "");
+ strcpy(org, "");
+
+ if (!full) {
+ StrBufAppendPrintf(Target, "<TD>");
+ name = vcard_get_prop(v, "fn", 1, 0, 0);
+ if (name != NULL) {
+ StrEscAppend(Target, NULL, name, 0, 0);
+ }
+ else if (name = vcard_get_prop(v, "n", 1, 0, 0), name != NULL) {
+ strcpy(fullname, name);
+ vcard_n_prettyize(fullname);
+ StrEscAppend(Target, NULL, fullname, 0, 0);
+ }
+ else {
+ StrBufAppendPrintf(Target, " ");
+ }
+ StrBufAppendPrintf(Target, "</TD>");
+ return;
+ }
+
+ StrBufAppendPrintf(Target, "<div align=center>"
+ "<table bgcolor=#aaaaaa width=50%%>");
+ for (pass=1; pass<=2; ++pass) {
+
+ if (v->numprops) for (i=0; i<(v->numprops); ++i) {
+ int len;
+ thisname = strdup(v->prop[i].name);
+ extract_token(firsttoken, thisname, 0, ';', sizeof firsttoken);
+
+ for (j=0; j<num_tokens(thisname, ';'); ++j) {
+ extract_token(buf, thisname, j, ';', sizeof buf);
+ if (!strcasecmp(buf, "encoding=quoted-printable")) {
+ is_qp = 1;
+ remove_token(thisname, j, ';');
+ }
+ if (!strcasecmp(buf, "encoding=base64")) {
+ is_b64 = 1;
+ remove_token(thisname, j, ';');
+ }
+ }
+
+ len = strlen(v->prop[i].value);
+ /* if we have some untagged QP, detect it here. */
+ if (!is_qp && (strstr(v->prop[i].value, "=?")!=NULL))
+ utf8ify_rfc822_string(v->prop[i].value);
+
+ if (is_qp) {
+ // %ff can become 6 bytes in utf8
+ thisvalue = malloc(len * 2 + 3);
+ j = CtdlDecodeQuotedPrintable(
+ thisvalue, v->prop[i].value,
+ len);
+ thisvalue[j] = 0;
+ }
+ else if (is_b64) {
+ // ff will become one byte..
+ thisvalue = malloc(len + 50);
+ CtdlDecodeBase64(
+ thisvalue, v->prop[i].value,
+ strlen(v->prop[i].value) );
+ }
+ else {
+ thisvalue = strdup(v->prop[i].value);
+ }
+
+ /** Various fields we may encounter ***/
+
+ /** N is name, but only if there's no FN already there */
+ if (!strcasecmp(firsttoken, "n")) {
+ if (IsEmptyStr(fullname)) {
+ strcpy(fullname, thisvalue);
+ vcard_n_prettyize(fullname);
+ }
+ }
+
+ /** FN (full name) is a true 'display name' field */
+ else if (!strcasecmp(firsttoken, "fn")) {
+ strcpy(fullname, thisvalue);
+ }
+
+ /** title */
+ else if (!strcasecmp(firsttoken, "title")) {
+ strcpy(title, thisvalue);
+ }
+
+ /** organization */
+ else if (!strcasecmp(firsttoken, "org")) {
+ strcpy(org, thisvalue);
+ }
+
+ else if (!strcasecmp(firsttoken, "email")) {
+ size_t len;
+ if (!IsEmptyStr(mailto)) strcat(mailto, "<br />");
+ strcat(mailto,
+ "<a href=\"display_enter"
+ "?force_room=_MAIL_?recp=");
+
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, "\"");
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, fullname);
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, "\" <");
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, thisvalue);
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, ">");
+
+ strcat(mailto, "\">");
+ len = strlen(mailto);
+ stresc(mailto+len, SIZ - len, thisvalue, 1, 1);
+ strcat(mailto, "</A>");
+ }
+ else if (!strcasecmp(firsttoken, "tel")) {
+ if (!IsEmptyStr(phone)) strcat(phone, "<br />");
+ strcat(phone, thisvalue);
+ for (j=0; j<num_tokens(thisname, ';'); ++j) {
+ extract_token(buf, thisname, j, ';', sizeof buf);
+ if (!strcasecmp(buf, "tel"))
+ strcat(phone, "");
+ else if (!strcasecmp(buf, "work"))
+ strcat(phone, _(" (work)"));
+ else if (!strcasecmp(buf, "home"))
+ strcat(phone, _(" (home)"));
+ else if (!strcasecmp(buf, "cell"))
+ strcat(phone, _(" (cell)"));
+ else {
+ strcat(phone, " (");
+ strcat(phone, buf);
+ strcat(phone, ")");
+ }
+ }
+ }
+ else if (!strcasecmp(firsttoken, "adr")) {
+ if (pass == 2) {
+ StrBufAppendPrintf(Target, "<TR><TD>");
+ StrBufAppendPrintf(Target, _("Address:"));
+ StrBufAppendPrintf(Target, "</TD><TD>");
+ for (j=0; j<num_tokens(thisvalue, ';'); ++j) {
+ extract_token(buf, thisvalue, j, ';', sizeof buf);
+ if (!IsEmptyStr(buf)) {
+ StrEscAppend(Target, NULL, buf, 0, 0);
+ if (j<3) StrBufAppendPrintf(Target, "<br />");
+ else StrBufAppendPrintf(Target, " ");
+ }
+ }
+ StrBufAppendPrintf(Target, "</TD></TR>\n");
+ }
+ }
+ /* else if (!strcasecmp(firsttoken, "photo") && full && pass == 2) {
+ // Only output on second pass
+ StrBufAppendPrintf(Target, "<tr><td>");
+ StrBufAppendPrintf(Target, _("Photo:"));
+ StrBufAppendPrintf(Target, "</td><td>");
+ StrBufAppendPrintf(Target, "<img src=\"/vcardphoto/%ld/\" alt=\"Contact photo\"/>",msgnum);
+ StrBufAppendPrintf(Target, "</td></tr>\n");
+ } */
+ else if (!strcasecmp(firsttoken, "version")) {
+ /* ignore */
+ }
+ else if (!strcasecmp(firsttoken, "rev")) {
+ /* ignore */
+ }
+ else if (!strcasecmp(firsttoken, "label")) {
+ /* ignore */
+ }
+ else {
+
+ /*** Don't show extra fields. They're ugly.
+ if (pass == 2) {
+ StrBufAppendPrintf(Target, "<TR><TD>");
+ StrEscAppend(Target, NULL, thisname, 0, 0);
+ StrBufAppendPrintf(Target, "</TD><TD>");
+ StrEscAppend(Target, NULL, thisvalue, 0, 0);
+ StrBufAppendPrintf(Target, "</TD></TR>\n");
+ }
+ ***/
+ }
+
+ free(thisname);
+ free(thisvalue);
+ }
+
+ if (pass == 1) {
+ StrBufAppendPrintf(Target, "<TR BGCOLOR=\"#AAAAAA\">"
+ "<TD COLSPAN=2 BGCOLOR=\"#FFFFFF\">"
+ "<IMG ALIGN=CENTER src=\"static/viewcontacts_48x.gif\">"
+ "<FONT SIZE=+1><B>");
+ StrEscAppend(Target, NULL, fullname, 0, 0);
+ StrBufAppendPrintf(Target, "</B></FONT>");
+ if (!IsEmptyStr(title)) {
+ StrBufAppendPrintf(Target, "<div align=right>");
+ StrEscAppend(Target, NULL, title, 0, 0);
+ StrBufAppendPrintf(Target, "</div>");
+ }
+ if (!IsEmptyStr(org)) {
+ StrBufAppendPrintf(Target, "<div align=right>");
+ StrEscAppend(Target, NULL, org, 0, 0);
+ StrBufAppendPrintf(Target, "</div>");
+ }
+ StrBufAppendPrintf(Target, "</TD></TR>\n");
+
+ if (!IsEmptyStr(phone)) {
+ StrBufAppendPrintf(Target, "<tr><td>");
+ StrBufAppendPrintf(Target, _("Telephone:"));
+ StrBufAppendPrintf(Target, "</td><td>%s</td></tr>\n", phone);
+ }
+ if (!IsEmptyStr(mailto)) {
+ StrBufAppendPrintf(Target, "<tr><td>");
+ StrBufAppendPrintf(Target, _("E-mail:"));
+ StrBufAppendPrintf(Target, "</td><td>%s</td></tr>\n", mailto);
+ }
+ }
+
+ }
+
+ StrBufAppendPrintf(Target, "</table></div>\n");
+}
+
+
+
+/**
+ * \brief Display a textual vCard
+ * (Converts to a vCard object and then calls the actual display function)
+ * Set 'full' to nonzero to display the whole card instead of a one-liner.
+ * Or, if "storename" is non-NULL, just store the person's name in that
+ * buffer instead of displaying the card at all.
+ * \param vcard_source the buffer containing the vcard text
+ * \param alpha what???
+ * \param full should we usse all lines?
+ * \param storename where to store???
+ * \param msgnum Citadel message pointer
+ */
+void display_vcard(StrBuf *Target, const char *vcard_source, char alpha, int full, char *storename,
+ long msgnum) {
+ struct vCard *v;
+ char *name;
+ char buf[SIZ];
+ char this_alpha = 0;
+
+ v = vcard_load((char*)vcard_source); ///TODO
+
+ if (v == NULL) return;
+
+ name = vcard_get_prop(v, "n", 1, 0, 0);
+ if (name != NULL) {
+ utf8ify_rfc822_string(name);
+ strcpy(buf, name);
+ this_alpha = buf[0];
+ }
+
+ if (storename != NULL) {
+ fetchname_parsed_vcard(v, storename);
+ }
+ else if ( (alpha == 0)
+ || ((isalpha(alpha)) && (tolower(alpha) == tolower(this_alpha)) )
+ || ((!isalpha(alpha)) && (!isalpha(this_alpha)))
+ ) {
+ display_parsed_vcard(Target, v, full,msgnum);
+ }
+
+ vcard_free(v);
+}
+
+
+
+/**
+ * \brief Render the address book using info we gathered during the scan
+ * \param addrbook the addressbook to render
+ * \param num_ab the number of the addressbook
+ */
+void do_addrbook_view(addrbookent *addrbook, int num_ab) {
+ int i = 0;
+ int displayed = 0;
+ int bg = 0;
+ static int NAMESPERPAGE = 60;
+ int num_pages = 0;
+ int tabfirst = 0;
+ char tabfirst_label[64];
+ int tablast = 0;
+ char tablast_label[64];
+ char this_tablabel[64];
+ int page = 0;
+ char **tablabels;
+
+ if (num_ab == 0) {
+ wprintf("<br /><br /><br /><div align=\"center\"><i>");
+ wprintf(_("This address book is empty."));
+ wprintf("</i></div>\n");
+ return;
+ }
+
+ if (num_ab > 1) {
+ qsort(addrbook, num_ab, sizeof(addrbookent), abcmp);
+ }
+
+ num_pages = (num_ab / NAMESPERPAGE) + 1;
+
+ tablabels = malloc(num_pages * sizeof (char *));
+ if (tablabels == NULL) {
+ wprintf("<br /><br /><br /><div align=\"center\"><i>");
+ wprintf(_("An internal error has occurred."));
+ wprintf("</i></div>\n");
+ return;
+ }
+
+ for (i=0; i<num_pages; ++i) {
+ tabfirst = i * NAMESPERPAGE;
+ tablast = tabfirst + NAMESPERPAGE - 1;
+ if (tablast > (num_ab - 1)) tablast = (num_ab - 1);
+ nametab(tabfirst_label, 64, addrbook[tabfirst].ab_name);
+ nametab(tablast_label, 64, addrbook[tablast].ab_name);
+ sprintf(this_tablabel, "%s - %s", tabfirst_label, tablast_label);
+ tablabels[i] = strdup(this_tablabel);
+ }
+
+ tabbed_dialog(num_pages, tablabels);
+ page = (-1);
+
+ for (i=0; i<num_ab; ++i) {
+
+ if ((i / NAMESPERPAGE) != page) { /* New tab */
+ page = (i / NAMESPERPAGE);
+ if (page > 0) {
+ wprintf("</tr></table>\n");
+ end_tab(page-1, num_pages);
+ }
+ begin_tab(page, num_pages);
+ wprintf("<table border=0 cellspacing=0 cellpadding=3 width=100%%>\n");
+ displayed = 0;
+ }
+
+ if ((displayed % 4) == 0) {
+ if (displayed > 0) {
+ wprintf("</tr>\n");
+ }
+ bg = 1 - bg;
+ wprintf("<tr bgcolor=\"#%s\">",
+ (bg ? "DDDDDD" : "FFFFFF")
+ );
+ }
+
+ wprintf("<td>");
+
+ wprintf("<a href=\"readfwd?startmsg=%ld?is_singlecard=1",
+ addrbook[i].ab_msgnum);
+ wprintf("?maxmsgs=1?is_summary=0?alpha=%s\">", bstr("alpha"));
+ vcard_n_prettyize(addrbook[i].ab_name);
+ escputs(addrbook[i].ab_name);
+ wprintf("</a></td>\n");
+ ++displayed;
+ }
+
+ /* Placeholders for empty columns at end */
+ if ((num_ab % 4) != 0) {
+ for (i=0; i<(4-(num_ab % 4)); ++i) {
+ wprintf("<td> </td>");
+ }
+ }
+
+ wprintf("</tr></table>\n");
+ end_tab((num_pages-1), num_pages);
+
+ begin_tab(num_pages, num_pages);
+ /* FIXME there ought to be something here */
+ end_tab(num_pages, num_pages);
+
+ for (i=0; i<num_pages; ++i) {
+ free(tablabels[i]);
+ }
+ free(tablabels);
+}
+
+
+
+
/*
* Edit the vCard component of a MIME message.
* Supply the message number
long msgnum; /**< the message number on the citadel server derived from message_summary */
RenderMimeFunc Renderer;
};
+void DestroyMime(void *vMime);
/*
wc_mime_attachment *cal_partnum_ref;
wc_mime_attachment *vcard_partnum_ref;
} message_summary;
+void DestroyMessageSummary(void *vMsg);
typedef void (*ExamineMsgHeaderFunc)(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset);
} disp_cal;
+
+/*
+ * Address book entry (keep it short and sweet, it's just a quickie lookup
+ * which we can use to get to the real meat and bones later)
+ */
+typedef struct _addrbookent {
+ char ab_name[64]; /**< name string */
+ long ab_msgnum; /**< message number of address book entry */
+} addrbookent;
+
+
+typedef struct _headereval {
+ ExamineMsgHeaderFunc evaluator;
+ int Type;
+} headereval;
+
+
+struct attach_link {
+ char partnum[32];
+ char html[1024];
+};
+
+
+enum {
+ eUp,
+ eDown,
+ eNone
+};
+
/*
* One of these is kept for each active Citadel session.
* HTTP transactions are bound to one at a time.
void serv_read(char *buf, int bytes);
void readloop(char *oper);
void read_message(long msgnum, int printable_view, char *section);
+void do_addrbook_view(addrbookent *addrbook, int num_ab);
+void display_vcard(StrBuf *Target, const char *vcard_source, char alpha, int full, char *storename, long msgnum);
void text_to_server(char *ptr);
void text_to_server_qp(char *ptr);
void confirm_delete_msg(void);