X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fvcard_edit.c;h=9327ec291e6f7795169c3c8bbe42392f888db640;hb=HEAD;hp=eda369b42b253c3c23179b5e5fc5dc827d95e9db;hpb=b3a15939bdee9bc729492575a2b191562c9a38b3;p=citadel.git diff --git a/webcit/vcard_edit.c b/webcit/vcard_edit.c index eda369b42..e08a227fe 100644 --- a/webcit/vcard_edit.c +++ b/webcit/vcard_edit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996-2012 by the citadel.org team + * Copyright (c) 1996-2021 by the citadel.org team * * This program is open source software. You can redistribute it and/or * modify it under the terms of the GNU General Public License, version 3. @@ -11,7 +11,7 @@ */ #include "webcit.h" -#include "webserver.h" + #include "calendar.h" CtxType CTX_VCARD = CTX_NONE; @@ -127,6 +127,10 @@ HashList *VCTokenToDefine = NULL; HashList *vcNames = NULL; /* todo: fill with the name strings */ vcField* vcfUnknown = NULL; +/****************************************************************************** + * initialize vcard structure * + ******************************************************************************/ + void RegisterVCardToken(vcField* vf, StrBuf *name, int inTokenCount) { if (vf->Type == UnKnown) { @@ -192,6 +196,10 @@ void autoRegisterTokens(long *enumCounter, vcField* vf, StrBuf *BaseStr, int lay FreeStrBuf(&subStr); } +/****************************************************************************** + * VCard template functions * + ******************************************************************************/ + int preeval_vcard_item(WCTemplateToken *Token) { WCTemplputParams TPP; @@ -204,8 +212,7 @@ int preeval_vcard_item(WCTemplateToken *Token) TP->Tokens = Token; searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); if (searchFieldNo >= VCEnumCounter) { - LogTemplateError(NULL, "VCardItem", ERR_PARM1, TP, - "Invalid define"); + LogTemplateError(NULL, "VCardItem", ERR_PARM1, TP, "Invalid define"); return 0; } return 1; @@ -228,8 +235,7 @@ void tmpl_vcard_context_item(StrBuf *Target, WCTemplputParams *TP) addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); if (t == NULL) { - LogTemplateError(NULL, "VCard item", ERR_NAME, TP, - "Missing context"); + LogTemplateError(NULL, "VCard item", ERR_NAME, TP, "Missing context"); return; } @@ -310,23 +316,21 @@ int filter_VC_ByType(const char* key, long len, void *Context, StrBuf *Target, W long searchType; long type = 0; void *v; - int rc = 0; vcField *vf = (vcField*) Context; + int rc = 0; memcpy(&type, key, sizeof(long)); searchType = GetTemplateTokenNumber(Target, TP, IT_ADDT_PARAM(0), 0); if (vf->Type == searchType) { addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); - if (GetHash(ab->VC, LKEY(vf->cval), &v) && v != NULL) + if (GetHash(ab->VC, LKEY(vf->cval), &v) && v != NULL) { return 1; + } } return rc; } - - - HashList *getContextVcard(StrBuf *Target, WCTemplputParams *TP) { vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE); @@ -356,7 +360,6 @@ int filter_VC_ByContextType(const char* key, long len, void *Context, StrBuf *Ta } } - int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP) { addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); @@ -387,131 +390,33 @@ int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP) } - -/* - * Helper function for do_addrbook_view() - * Converts a name into a three-letter tab label +/* Returns 1 to suppress the "email" fields in the vCard editor, if we're editing a user's contact info. + * Returns 0 to present those fields, if we're editing a vCard in an address book. */ -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; -} - -wc_mime_attachment *load_vcard(message_summary *Msg) -{ - HashPos *it; - StrBuf *FoundCharset = NewStrBuf(); - StrBuf *Error; - void *vMime; - const char *Key; - long len; - wc_mime_attachment *Mime; - wc_mime_attachment *VCMime = NULL; - - Msg->MsgBody = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment)); - memset(Msg->MsgBody, 0, sizeof(wc_mime_attachment)); - Msg->MsgBody->msgnum = Msg->msgnum; - - load_message(Msg, FoundCharset, &Error); - - FreeStrBuf(&FoundCharset); - /* look up the vcard... */ - it = GetNewHashPos(Msg->AllAttach, 0); - while (GetNextHashPos(Msg->AllAttach, it, &len, &Key, &vMime) && - (vMime != NULL)) - { - Mime = (wc_mime_attachment*) vMime; - if ((strcmp(ChrPtr(Mime->ContentType), - "text/x-vcard") == 0) || - (strcmp(ChrPtr(Mime->ContentType), - "text/vcard") == 0)) - { - VCMime = Mime; - break; - } - } - DeleteHashPos(&it); - if (VCMime == NULL) - return NULL; - - if (VCMime->Data == NULL) - MimeLoadData(VCMime); - return VCMime; +int conditional_VC_SuppressEmailFields(StrBuf *Target, WCTemplputParams *TP) +{ + return(atoi(bstr("suppress_email"))); } - -/* - * Turn a vCard "n" (name) field into something displayable. - */ -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; icval), ThisFieldStr, HFreeStrBuf); } -/* - * 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. - * v the vCard to parse - * msgnum Citadel message pointer - */ + void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachment *Mime) { - StrBuf *Val = NULL; StrBuf *Swap = NULL; int i, j, k; char buf[SIZ]; @@ -530,41 +435,25 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme FlushStrBuf(thisVCToken); is_qp = 0; is_b64 = 0; - syslog(LOG_DEBUG, "i: %d oneprop: %s - value: %s", i, v->prop[i].name, v->prop[i].value); + // syslog(LOG_DEBUG, "i: %d oneprop: %s - value: %s", i, v->prop[i].name, v->prop[i].value); StrBufPlain(thisname, v->prop[i].name, -1); StrBufLowerCase(thisname); - /*len = */extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken); + extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken); ntokens = num_tokens(ChrPtr(thisname), ';'); for (j=0, k=0; j < ntokens && k < 10; ++j) { - /*int evc[10];*/ - len = extract_token(buf, ChrPtr(thisname), j, ';', sizeof buf); if (!strcasecmp(buf, "encoding=quoted-printable")) { is_qp = 1; -/* remove_token(thisname, j, ';');*/ } else if (!strcasecmp(buf, "encoding=base64")) { is_b64 = 1; -/* remove_token(thisname, j, ';');*/ } - else{ + else { if (StrLength(thisVCToken) > 0) { StrBufAppendBufPlain(thisVCToken, HKEY(";"), 0); } StrBufAppendBufPlain(thisVCToken, buf, len, 0); - /* - if (GetHash(VCToEnum, buf, len, &V)) - { - evc[k] = (int) V; - - Put(VC, IKEY(evc), Val, HFreeStrBuf); - - syslog(LOG_DEBUG, "[%ul] -> k: %d %s - %s", evc, k, buf, VCStr[evc[k]].Key); - k++; - } -*/ - } } @@ -574,7 +463,7 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme (vField != NULL)) { vcField *thisField = (vcField *)vField; StrBuf *ThisFieldStr = NULL; - syslog(LOG_DEBUG, "got this token: %s, found: %s", ChrPtr(thisVCToken), thisField->STR.Key); + // syslog(LOG_DEBUG, "got this token: %s, found: %s", ChrPtr(thisVCToken), thisField->STR.Key); switch (thisField->Type) { case StringCluster: { int j = 0; @@ -584,7 +473,6 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme while (thisField->Sub[j].STR.len > 0) { StrBufExtract_NextToken(Buf, thisArray, &Pos, ';'); ThisFieldStr = NewStrBufDup(Buf); - PutVcardItem(VC, &thisField->Sub[j], ThisFieldStr, is_qp, Swap); j++; } @@ -605,6 +493,10 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme break; case Base64BinaryAttachment: + ThisFieldStr = NewStrBufPlain(v->prop[i].value, -1); + StrBufDecodeBase64(ThisFieldStr); + PutVcardItem(VC, thisField, ThisFieldStr, is_qp, Swap); + break; case TerminateList: case UnKnown: break; @@ -630,76 +522,22 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachme StrBufAppendBufPlain(oldVal, v->prop[i].value, -1, 0); continue; } - - /* copy over the payload into a StrBuf */ - Val = NewStrBufPlain(v->prop[i].value, -1); - - /* if we have some untagged QP, detect it here. */ - if (is_qp || (strstr(v->prop[i].value, "=?")!=NULL)){ - StrBuf *b; - StrBuf_RFC822_to_Utf8(Swap, Val, NULL, NULL); /* default charset, current charset */ - b = Val; - Val = Swap; - Swap = b; - FlushStrBuf(Swap); - } - else if (is_b64) { - StrBufDecodeBase64(Val); - } -#if 0 - syslog(LOG_DEBUG, "-> firsttoken: %s thisname: %s Value: [%s][%s]", - firsttoken, - ChrPtr(thisname), - ChrPtr(Val), - v->prop[i].value); -#endif - FreeStrBuf(&Val); } FreeStrBuf(&thisname); FreeStrBuf(&Swap); FreeStrBuf(&thisVCToken); } -void tmplput_VCARD_ITEM(StrBuf *Target, WCTemplputParams *TP) -{ - addrbookent *ab = CTX(CTX_VCARD); - int evc; - void *vStr; - - evc = GetTemplateTokenNumber(Target, TP, 0, -1); - if (evc != -1) - { - if (GetHash(ab->VC, IKEY(evc), &vStr)) - { - StrBufAppendTemplate(Target, TP, - (StrBuf*) vStr, - 1); - } - } - -} - HashList *CtxGetVcardList(StrBuf *Target, WCTemplputParams *TP) { HashList *pb = CTX(CTX_VCARD_LIST); return pb; } -void display_one_vcard (StrBuf *Target, addrbookent *ab, const char *tp_name, size_t tp_name_len) -{ - WCTemplputParams *TP = NULL; - WCTemplputParams SubTP; +/****************************************************************************** + * Extract an embedded photo from a vCard for display on the client * + ******************************************************************************/ - memset(&SubTP, 0, sizeof(WCTemplputParams)); - StackContext(TP, &SubTP, ab, CTX_VCARD, 0, NULL); - - DoTemplate(tp_name, tp_name_len, Target, &SubTP); - UnStackContext(&SubTP); -} - -/* - * Extract an embedded photo from a vCard for display on the client - */ void display_vcard_photo_img(void) { long msgnum = 0L; @@ -707,18 +545,17 @@ void display_vcard_photo_img(void) struct vCard *v; char *photosrc; const char *contentType; - wcsession *WCC = WC; - msgnum = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 0, '/'); + msgnum = StrBufExtract_long(WC->Hdr->HR.ReqLine, 0, '/'); vcard = load_mimepart(msgnum,"1"); v = VCardLoad(vcard); photosrc = vcard_get_prop(v, "PHOTO", 1,0,0); - FlushStrBuf(WCC->WBuf); - StrBufAppendBufPlain(WCC->WBuf, photosrc, -1, 0); - if (StrBufDecodeBase64(WCC->WBuf) <= 0) { - FlushStrBuf(WCC->WBuf); + FlushStrBuf(WC->WBuf); + StrBufAppendBufPlain(WC->WBuf, photosrc, -1, 0); + if (StrBufDecodeBase64(WC->WBuf) <= 0) { + FlushStrBuf(WC->WBuf); hprintf("HTTP/1.1 500 %s\n","Unable to get photo"); output_headers(0, 0, 0, 0, 0, 0); @@ -728,12 +565,54 @@ void display_vcard_photo_img(void) end_burst(); return; } - contentType = GuessMimeType(ChrPtr(WCC->WBuf), StrLength(WCC->WBuf)); + contentType = GuessMimeType(ChrPtr(WC->WBuf), StrLength(WC->WBuf)); http_transmit_thing(contentType, 0); free(v); free(photosrc); } +wc_mime_attachment *load_vcard(message_summary *Msg) +{ + HashPos *it; + StrBuf *FoundCharset = NewStrBuf(); + StrBuf *Error; + void *vMime; + const char *Key; + long len; + wc_mime_attachment *Mime; + wc_mime_attachment *VCMime = NULL; + + Msg->MsgBody = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment)); + memset(Msg->MsgBody, 0, sizeof(wc_mime_attachment)); + Msg->MsgBody->msgnum = Msg->msgnum; + + load_message(Msg, FoundCharset, &Error); + + FreeStrBuf(&FoundCharset); + /* look up the vcard... */ + it = GetNewHashPos(Msg->AllAttach, 0); + while (GetNextHashPos(Msg->AllAttach, it, &len, &Key, &vMime) && + (vMime != NULL)) + { + Mime = (wc_mime_attachment*) vMime; + if ((strcmp(ChrPtr(Mime->ContentType), + "text/x-vcard") == 0) || + (strcmp(ChrPtr(Mime->ContentType), + "text/vcard") == 0)) + { + VCMime = Mime; + break; + } + } + DeleteHashPos(&it); + if (VCMime == NULL) + return NULL; + + if (VCMime->Data == NULL) + MimeLoadData(VCMime); + return VCMime; +} + /* * Edit the vCard component of a MIME message. * Supply the message number @@ -746,7 +625,6 @@ void do_edit_vcard(long msgnum, char *partnum, const char *return_to, const char *force_room) { WCTemplputParams SubTP; - wcsession *WCC = WC; message_summary *Msg = NULL; wc_mime_attachment *VCMime = NULL; struct vCard *v; @@ -782,7 +660,7 @@ void do_edit_vcard(long msgnum, char *partnum, v = VCardLoad(VCAtt->Data); } - parse_vcard(WCC->WBuf, v, ab.VC, NULL); + parse_vcard(WC->WBuf, v, ab.VC, NULL); vcard_free(v); @@ -795,7 +673,7 @@ void do_edit_vcard(long msgnum, char *partnum, StackContext(TP, &SubTP, &ab, CTX_VCARD, 0, NULL); - DoTemplate(HKEY("vcard_edit"), WCC->WBuf, &SubTP); + DoTemplate(HKEY("vcard_edit"), WC->WBuf, &SubTP); UnStackContext(&SubTP); } DeleteHash(&ab.VC); @@ -820,8 +698,6 @@ void edit_vcard(void) { do_edit_vcard(msgnum, partnum, NULL, NULL, "", NULL); } - - /* * parse edited vcard from the browser */ @@ -988,7 +864,9 @@ void submit_vcard(void) { FreeStrBuf(&Buf); } - +/****************************************************************************** + * Render Addressbooks * + ******************************************************************************/ typedef struct _vcardview_struct { long is_singlecard; @@ -1030,6 +908,8 @@ int vcard_LoadMsgFromServer(SharedMessageStatus *Stat, int is_new, int i) { + WCTemplputParams *TP = NULL; + WCTemplputParams SubTP; vcardview_struct *VS; wc_mime_attachment *VCMime = NULL; struct vCard *v; @@ -1050,14 +930,23 @@ int vcard_LoadMsgFromServer(SharedMessageStatus *Stat, abEntry->name = NewStrBuf(); abEntry->VC = NewHash(0, lFlathash); abEntry->ab_msgnum = Msg->msgnum; + parse_vcard(WC->WBuf, v, abEntry->VC, VCMime); - display_one_vcard(abEntry->name, abEntry, HKEY("vcard_list_name")); + memset(&SubTP, 0, sizeof(WCTemplputParams)); + StackContext(TP, &SubTP, abEntry, CTX_VCARD, 0, NULL); + + // No, don't display the name, it just shits all over the screen + // DoTemplate(HKEY("vcard_list_name"), WC->WBuf, &SubTP); + + UnStackContext(&SubTP); if (StrLength(abEntry->name) == 0) { StrBufPlain(abEntry->name, _("(no name)"), -1); } + syslog(LOG_DEBUG, "abEntry->name : %s", ChrPtr(abEntry->name)); + vcard_free(v); Put(VS->addrbook, SKEY(abEntry->name), abEntry, deleteAbEnt); @@ -1074,17 +963,12 @@ int vcard_LoadMsgFromServer(SharedMessageStatus *Stat, static int NAMESPERPAGE = 60; void do_addrbook_view(vcardview_struct* VS) { long i = 0; - int displayed = 0; - int bg = 0; int num_pages = 0; int tabfirst = 0; int tablast = 0; - int page = 0; - const StrBuf **tablabels; + StrBuf **tablabels; int num_ab = GetCount(VS->addrbook); HashList *headlines; - HashPos *it; - wcsession *WCC = WC; WCTemplputParams *TP = NULL; WCTemplputParams SubTP; @@ -1097,7 +981,7 @@ void do_addrbook_view(vcardview_struct* VS) { } if (num_ab > 1) { - ///SortByHashKey(VS->addrbook, 0); + SortByHashKey(VS->addrbook, 1); } num_pages = (GetCount(VS->addrbook) / NAMESPERPAGE) + 1; @@ -1124,82 +1008,25 @@ void do_addrbook_view(vcardview_struct* VS) { if (GetHashAt(VS->addrbook, tabfirst, &hklen1, &c1, &v1)) { a1 = (addrbookent*) v1; StrBufAppendBuf(headline, a1->name, 0); - + StrBuf_Utf8StrCut(headline, 3); if (GetHashAt(VS->addrbook, tablast, &hklen2, &c2, &v2)) { a2 = (addrbookent*) v2; StrBufAppendBufPlain(headline, HKEY(" - "), 0); StrBufAppendBuf(headline, a2->name, 0); + StrBuf_Utf8StrCut(headline, 9); } } tablabels[i] = headline; Put(headlines, LKEY(i), headline, HFreeStrBuf); } StrTabbedDialog(WC->WBuf, num_pages, tablabels); - page = (-1); - - StackContext(TP, &SubTP, VS->addrbook, CTX_VCARD_LIST, 0, NULL); - DoTemplate(HKEY("vcard_list"), WCC->WBuf, &SubTP); + DoTemplate(HKEY("vcard_list"), WC->WBuf, &SubTP); UnStackContext(&SubTP); -/* - it = GetNewHashPos(VS->addrbook, 0); - for (i=0; iaddrbook, it, &hklen, &key, &v); - if (v == NULL) - continue; - abEnt = (addrbookent *) v; - if ((i / NAMESPERPAGE) != page) { / * New tab * / - page = (i / NAMESPERPAGE); - if (page > 0) { - do_template("vcard_list_section_end"); - end_tab(page-1, num_pages); - } - begin_tab(page, num_pages); - do_template("vcard_list_section_start"); - displayed = 0; - } - - if ((displayed % 4) == 0) { - if (displayed > 0) { - do_template("vcard_list_row_end"); - } - do_template("vcard_list_row_start"); - bg = 1 - bg; - } - - - StackContext(TP, &SubTP, abEnt, CTX_VCARD, 0, NULL); - - DoTemplate(HKEY("vcard_list_entry"), WCC->WBuf, &SubTP); - UnStackContext(&SubTP); - - ++displayed; - } - DeleteHashPos(&it); -*/ - /* Placeholders for empty columns at end */ - if ((num_ab % 4) != 0) { - for (i=0; i<(4-(num_ab % 4)); ++i) { - do_template("vcard_list_cell_end"); - } - } - - do_template("vcard_list_section_end"); - 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); - DeleteHash(&headlines); free(tablabels); - wDumpContent(1); } @@ -1210,10 +1037,12 @@ int vcard_RenderView_or_Tail(SharedMessageStatus *Stat, void **ViewSpecific, lon vcardview_struct *VS; VS = (vcardview_struct*) *ViewSpecific; - if (VS->is_singlecard) - read_message(WC->WBuf, HKEY("view_message"), lbstr("startmsg"), NULL, &Mime); - else + if (VS->is_singlecard) { + read_message(WC->WBuf, HKEY("view_message"), lbstr("startmsg"), NULL, &Mime, NULL); + } + else { do_addrbook_view(VS); /* Render the address book */ + } return 0; } @@ -1223,11 +1052,12 @@ int vcard_Cleanup(void **ViewSpecific) VS = (vcardview_struct*) *ViewSpecific; wDumpContent(1); - if ((VS != NULL) && - (VS->addrbook != NULL)) + if ((VS != NULL) && (VS->addrbook != NULL)) { DeleteHash(&VS->addrbook); - if (VS != NULL) + } + if (VS != NULL) { free(VS); + } return 0; } @@ -1235,19 +1065,19 @@ int vcard_Cleanup(void **ViewSpecific) void render_MIME_VCard(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset) { wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH); - wcsession *WCC = WC; - if (StrLength(Mime->Data) == 0) + if (StrLength(Mime->Data) == 0) { MimeLoadData(Mime); + } if (StrLength(Mime->Data) > 0) { struct vCard *v; StrBuf *Buf; Buf = NewStrBuf(); /** If it's my vCard I can edit it */ - if ( (!strcasecmp(ChrPtr(WCC->CurRoom.name), USERCONFIGROOM)) - || ((StrLength(WCC->CurRoom.name) > 11) && - (!strcasecmp(&(ChrPtr(WCC->CurRoom.name)[11]), USERCONFIGROOM))) - || (WCC->CurRoom.view == VIEW_ADDRESSBOOK) + if ( (!strcasecmp(ChrPtr(WC->CurRoom.name), USERCONFIGROOM)) + || ((StrLength(WC->CurRoom.name) > 11) && + (!strcasecmp(&(ChrPtr(WC->CurRoom.name)[11]), USERCONFIGROOM))) + || (WC->CurRoom.view == VIEW_ADDRESSBOOK) ) { StrBufAppendPrintf(Buf, "", Mime->msgnum, ChrPtr(Mime->PartNum)); @@ -1259,16 +1089,23 @@ void render_MIME_VCard(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharse v = VCardLoad(Mime->Data); if (v != NULL) { - HashList *VC; + WCTemplputParams *TP = NULL; + WCTemplputParams SubTP; addrbookent ab; memset(&ab, 0, sizeof(addrbookent)); ab.VC = NewHash(0, lFlathash); ab.ab_msgnum = Mime->msgnum; - parse_vcard(Target, v, VC, Mime); - display_one_vcard (Target, &ab, HKEY("vcard_msg_display")); - DeleteHash(&VC); + parse_vcard(Target, v, ab.VC, Mime); + + memset(&SubTP, 0, sizeof(WCTemplputParams)); + StackContext(TP, &SubTP, &ab, CTX_VCARD, 0, NULL); + + DoTemplate(HKEY("vcard_msg_display"), Target, &SubTP); + UnStackContext(&SubTP); + DeleteHash(&ab.VC); + vcard_free(v); } else { @@ -1284,8 +1121,6 @@ void ServerStartModule_VCARD (void) { - ///VCToEnum = NewHash(0, NULL); - } void @@ -1295,7 +1130,6 @@ ServerShutdownModule_VCARD DeleteHash(&DefineToToken); DeleteHash(&vcNames); DeleteHash(&VCTokenToDefine); - /// DeleteHash(&VCToEnum); } void @@ -1324,7 +1158,8 @@ InitModule_VCARD NULL, vcard_LoadMsgFromServer, vcard_RenderView_or_Tail, - vcard_Cleanup); + vcard_Cleanup, + NULL); RegisterIterator("MAIL:VCARDS", 0, NULL, CtxGetVcardList, NULL, NULL, CTX_VCARD, CTX_VCARD_LIST, IT_NOFLAG); @@ -1349,7 +1184,9 @@ InitModule_VCARD REGISTERTokenParamDefine(TerminateList); REGISTERTokenParamDefine(Address); - RegisterConditional("VC:HAVE:TYPE", 1, conditional_VC_Havetype, CTX_VCARD); + RegisterConditional("VC:HAVE:TYPE", 1, conditional_VC_Havetype, CTX_VCARD); + RegisterConditional("COND:VC:SUPPRESS_EMAIL_FIELDS", 1, conditional_VC_SuppressEmailFields, CTX_VCARD); + RegisterFilteredIterator("VC:TYPE", 1, DefineToToken, NULL, NULL, NULL, filter_VC_ByType, CTX_VCARD_TYPE, CTX_VCARD, IT_NOFLAG); RegisterFilteredIterator("VC:TYPE:ITEMS", 0, NULL, getContextVcard, NULL, NULL, filter_VC_ByContextType, CTX_STRBUF, CTX_VCARD_TYPE, IT_NOFLAG);