X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fvcard_edit.c;fp=webcit%2Fvcard_edit.c;h=0000000000000000000000000000000000000000;hb=76a0f8571de023fe6bd20390174a2302e0a0b982;hp=d1a16d383a62ab3c83da8c935d60f9d2e4f6bad8;hpb=50511759c152f4ca2e22fb39a9bf31fc9f9d916d;p=citadel.git diff --git a/webcit/vcard_edit.c b/webcit/vcard_edit.c deleted file mode 100644 index d1a16d383..000000000 --- a/webcit/vcard_edit.c +++ /dev/null @@ -1,1196 +0,0 @@ -/* - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "webcit.h" -#include "webserver.h" -#include "calendar.h" - -CtxType CTX_VCARD = CTX_NONE; -CtxType CTX_VCARD_LIST = CTX_NONE; -CtxType CTX_VCARD_TYPE = CTX_NONE; -long VCEnumCounter = 0; - -typedef enum _VCStrEnum { - FlatString, - StringCluster, - PhoneNumber, - EmailAddr, - Address, - Street, - Number, - AliasFor, - Base64BinaryAttachment, - UnKnown, - TerminateList -}VCStrEnum; -typedef struct vcField vcField; -struct vcField { - ConstStr STR; - VCStrEnum Type; - vcField *Sub; - long cval; - long parentCVal; - ConstStr Name; -}; - -vcField VCStr_Ns [] = { - {{HKEY("last")}, FlatString, NULL, 0, 0, {HKEY("Last Name")}}, - {{HKEY("first")}, FlatString, NULL, 0, 0, {HKEY("First Name")}}, - {{HKEY("middle")}, FlatString, NULL, 0, 0, {HKEY("Middle Name")}}, - {{HKEY("prefix")}, FlatString, NULL, 0, 0, {HKEY("Prefix")}}, - {{HKEY("suffix")}, FlatString, NULL, 0, 0, {HKEY("Suffix")}}, - {{HKEY("")}, TerminateList, NULL, 0, 0, {HKEY("")}} -}; - -vcField VCStr_Addrs [] = { - {{HKEY("POBox")}, Address, NULL, 0, 0, {HKEY("PO box")}}, - {{HKEY("extadr")}, Address, NULL, 0, 0, {HKEY("Address")}}, - {{HKEY("street")}, Address, NULL, 0, 0, {HKEY("")}}, - {{HKEY("city")}, Address, NULL, 0, 0, {HKEY("City")}}, - {{HKEY("state")}, Address, NULL, 0, 0, {HKEY("State")}}, - {{HKEY("zip")}, Address, NULL, 0, 0, {HKEY("ZIP code")}}, - {{HKEY("country")}, Address, NULL, 0, 0, {HKEY("Country")}}, - {{HKEY("")}, TerminateList, NULL, 0, 0, {HKEY("")}} -}; - -vcField VCStrE [] = { - {{HKEY("version")}, Number, NULL, 0, 0, {HKEY("")}}, - {{HKEY("rev")}, Number, NULL, 0, 0, {HKEY("")}}, - {{HKEY("label")}, FlatString, NULL, 0, 0, {HKEY("")}}, - {{HKEY("uid")}, FlatString, NULL, 0, 0, {HKEY("")}}, - {{HKEY("n")}, StringCluster, VCStr_Ns, 0, 0, {HKEY("")}}, /* N is name, but only if there's no FN already there */ - {{HKEY("fn")}, FlatString, NULL, 0, 0, {HKEY("")}}, /* FN (full name) is a true 'display name' field */ - {{HKEY("title")}, FlatString, NULL, 0, 0, {HKEY("Title:")}}, - {{HKEY("org")}, FlatString, NULL, 0, 0, {HKEY("Organization:")}},/* organization */ - {{HKEY("email")}, EmailAddr, NULL, 0, 0, {HKEY("E-mail:")}}, - {{HKEY("tel")}, PhoneNumber, NULL, 0, 0, {HKEY("Telephone:")}}, - {{HKEY("adr")}, StringCluster, VCStr_Addrs, 0, 0, {HKEY("Address:")}}, - {{HKEY("photo")}, Base64BinaryAttachment, NULL, 0, 0, {HKEY("Photo:")}}, - {{HKEY("tel;home")}, PhoneNumber, NULL, 0, 0, {HKEY(" (home)")}}, - {{HKEY("tel;work")}, PhoneNumber, NULL, 0, 0, {HKEY(" (work)")}}, - {{HKEY("tel;fax")}, PhoneNumber, NULL, 0, 0, {HKEY(" (fax)")}}, - {{HKEY("tel;cell")}, PhoneNumber, NULL, 0, 0, {HKEY(" (cell)")}}, - {{HKEY("email;internet")}, EmailAddr, NULL, 0, 0, {HKEY("E-mail:")}}, - {{HKEY("UNKNOWN")}, UnKnown, NULL, 0, 0, {HKEY("")}}, - {{HKEY("")}, TerminateList, NULL, 0, 0, {HKEY("")}} -}; - -ConstStr VCStr [] = { - {HKEY("")}, - {HKEY("n")}, /* N is name, but only if there's no FN already there */ - {HKEY("fn")}, /* FN (full name) is a true 'display name' field */ - {HKEY("title")}, /* title */ - {HKEY("org")}, /* organization */ - {HKEY("email")}, - {HKEY("tel")}, - {HKEY("work")}, - {HKEY("home")}, - {HKEY("cell")}, - {HKEY("adr")}, - {HKEY("photo")}, - {HKEY("version")}, - {HKEY("rev")}, - {HKEY("label")}, - {HKEY("uid")} -}; - -/* - * 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 { - StrBuf *name; - HashList *VC; - long ab_msgnum; /* message number of address book entry */ - StrBuf *msgNoStr; -} addrbookent; - -void deleteAbEnt(void *v) { - addrbookent *vc = (addrbookent*)v; - DeleteHash(&vc->VC); - FreeStrBuf(&vc->name); - FreeStrBuf(&vc->msgNoStr); - free(vc); -} - -HashList *DefineToToken = NULL; -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) { - vcfUnknown = vf; - } - RegisterTokenParamDefine(SKEY(name), vf->cval); - Put(DefineToToken, LKEY(vf->cval), vf, reference_free_handler); - Put(vcNames, LKEY(vf->cval), NewStrBufPlain(CKEY(vf->Name)), HFreeStrBuf); - - syslog(LOG_DEBUG, "Token: %s -> %ld, %d", - ChrPtr(name), - vf->cval, - inTokenCount); - -} - -void autoRegisterTokens(long *enumCounter, vcField* vf, StrBuf *BaseStr, int layer, long parentCVal) -{ - int i = 0; - StrBuf *subStr = NewStrBuf(); - while (vf[i].STR.len > 0) { - FlushStrBuf(subStr); - vf[i].cval = (*enumCounter) ++; - vf[i].parentCVal = parentCVal; - StrBufAppendBuf(subStr, BaseStr, 0); - if (StrLength(subStr) > 0) { - StrBufAppendBufPlain(subStr, HKEY("."), 0); - } - StrBufAppendBufPlain(subStr, CKEY(vf[i].STR), 0); - if (layer == 0) { - Put(VCTokenToDefine, CKEY(vf[i].STR), &vf[i], reference_free_handler); - } - switch (vf[i].Type) { - case FlatString: - break; - case StringCluster: - { - autoRegisterTokens(enumCounter, vf[i].Sub, subStr, 1, vf[i].cval); - } - break; - case PhoneNumber: - break; - case EmailAddr: - break; - case Street: - break; - case Number: - break; - case AliasFor: - break; - case Base64BinaryAttachment: - break; - case TerminateList: - break; - case Address: - break; - case UnKnown: - break; - } - RegisterVCardToken(&vf[i], subStr, i); - i++; - } - FreeStrBuf(&subStr); -} - -/****************************************************************************** - * VCard template functions * - ******************************************************************************/ - -int preeval_vcard_item(WCTemplateToken *Token) -{ - WCTemplputParams TPP; - WCTemplputParams *TP; - int searchFieldNo; - StrBuf *Target = NULL; - - memset(&TPP, 0, sizeof(WCTemplputParams)); - TP = &TPP; - TP->Tokens = Token; - searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); - if (searchFieldNo >= VCEnumCounter) { - LogTemplateError(NULL, "VCardItem", ERR_PARM1, TP, "Invalid define"); - return 0; - } - return 1; -} - -void tmpl_vcard_item(StrBuf *Target, WCTemplputParams *TP) -{ - void *vItem; - long searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); - addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); - if (GetHash(ab->VC, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) { - StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1); - } -} - -void tmpl_vcard_context_item(StrBuf *Target, WCTemplputParams *TP) -{ - void *vItem; - vcField *t = (vcField*) CTX(CTX_VCARD_TYPE); - addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); - - if (t == NULL) { - LogTemplateError(NULL, "VCard item", ERR_NAME, TP, "Missing context"); - return; - } - - if (GetHash(ab->VC, LKEY(t->cval), &vItem) && (vItem != NULL)) { - StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 0); - } - else { - LogTemplateError(NULL, "VCard item", ERR_NAME, TP, - "Doesn't have that key - did you miss to filter in advance?"); - } -} -int preeval_vcard_name_str(WCTemplateToken *Token) -{ - WCTemplputParams TPP; - WCTemplputParams *TP; - int searchFieldNo; - StrBuf *Target = NULL; - - memset(&TPP, 0, sizeof(WCTemplputParams)); - TP = &TPP; - TP->Tokens = Token; - searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); - if (searchFieldNo >= VCEnumCounter) { - LogTemplateError(NULL, "VCardName", ERR_PARM1, TP, - "Invalid define"); - return 0; - } - return 1; -} - -void tmpl_vcard_name_str(StrBuf *Target, WCTemplputParams *TP) -{ - void *vItem; - long searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0); - /* todo: get descriptive string for this vcard type */ - if (GetHash(vcNames, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) { - StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1); - } - else { - LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, - "No i18n string for this."); - return; - } -} - -void tmpl_vcard_msgno(StrBuf *Target, WCTemplputParams *TP) -{ - addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); - if (ab->msgNoStr == NULL) { - ab->msgNoStr = NewStrBufPlain(NULL, 64); - } - StrBufPrintf(ab->msgNoStr, "%ld", ab->ab_msgnum); - StrBufAppendTemplate(Target, TP, ab->msgNoStr, 0); -} -void tmpl_vcard_context_name_str(StrBuf *Target, WCTemplputParams *TP) -{ - void *vItem; - vcField *t = (vcField*) CTX(CTX_VCARD_TYPE); - - if (t == NULL) { - LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, - "Missing context"); - return; - } - - if (GetHash(vcNames, LKEY(t->cval), &vItem) && (vItem != NULL)) { - StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1); - } - else { - LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, - "No i18n string for this."); - return; - } -} - -int filter_VC_ByType(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP) -{ - long searchType; - long type = 0; - void *v; - 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) { - return 1; - } - } - return rc; -} - -HashList *getContextVcard(StrBuf *Target, WCTemplputParams *TP) -{ - vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE); - addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); - - if ((vf == NULL) || (ab == NULL)) { - LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, - "Need VCard and Vcard type in context"); - - return NULL; - } - return ab->VC; -} - -int filter_VC_ByContextType(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP) -{ - long searchType; - vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE); - - memcpy(&searchType, key, sizeof(long)); - - if (vf->cval == searchType) { - return 1; - } - else { - return 0; - } -} - -int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP) -{ - addrbookent *ab = (addrbookent*) CTX(CTX_VCARD); - long HaveFieldType = GetTemplateTokenNumber(Target, TP, 2, 0); - int rc = 0; - void *vVCitem; - const char *Key; - long len; - HashPos *it = GetNewHashPos(ab->VC, 0); - while (GetNextHashPos(ab->VC, it, &len, &Key, &vVCitem) && - (vVCitem != NULL)) - { - void *vvcField; - long type = 0; - memcpy(&type, Key, sizeof(long)); - if (GetHash(DefineToToken, LKEY(type), &vvcField) && - (vvcField != NULL)) - { - vcField *t = (vcField*) vvcField; - if (t && t->Type == HaveFieldType) { - rc = 1; - break; - } - } - } - DeleteHashPos(&it); - return rc; -} - - -/* 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. - */ -int conditional_VC_SuppressEmailFields(StrBuf *Target, WCTemplputParams *TP) -{ - return(atoi(bstr("suppress_email"))); -} - - -/****************************************************************************** - * parse one VCard * - ******************************************************************************/ - -void PutVcardItem(HashList *thisVC, vcField *thisField, StrBuf *ThisFieldStr, int is_qp, StrBuf *Swap) -{ - /* if we have some untagged QP, detect it here. */ - if (is_qp || (strstr(ChrPtr(ThisFieldStr), "=?")!=NULL)){ - FlushStrBuf(Swap); - StrBuf_RFC822_to_Utf8(Swap, ThisFieldStr, NULL, NULL); /* default charset, current charset */ - SwapBuffers(Swap, ThisFieldStr); - FlushStrBuf(Swap); - } - Put(thisVC, LKEY(thisField->cval), ThisFieldStr, HFreeStrBuf); -} - -void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, wc_mime_attachment *Mime) -{ - StrBuf *Swap = NULL; - int i, j, k; - char buf[SIZ]; - int is_qp = 0; - int is_b64 = 0; - int ntokens, len; - StrBuf *thisname = NULL; - char firsttoken[SIZ]; - StrBuf *thisVCToken; - void *vField = NULL; - - Swap = NewStrBuf (); - thisname = NewStrBuf(); - thisVCToken = NewStrBufPlain(NULL, 63); - for (i=0; i<(v->numprops); ++i) { - 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); - StrBufPlain(thisname, v->prop[i].name, -1); - StrBufLowerCase(thisname); - - extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken); - ntokens = num_tokens(ChrPtr(thisname), ';'); - for (j=0, k=0; j < ntokens && k < 10; ++j) { - len = extract_token(buf, ChrPtr(thisname), j, ';', sizeof buf); - if (!strcasecmp(buf, "encoding=quoted-printable")) { - is_qp = 1; - } - else if (!strcasecmp(buf, "encoding=base64")) { - is_b64 = 1; - } - else { - if (StrLength(thisVCToken) > 0) { - StrBufAppendBufPlain(thisVCToken, HKEY(";"), 0); - } - StrBufAppendBufPlain(thisVCToken, buf, len, 0); - } - } - - vField = NULL; - if ((StrLength(thisVCToken) > 0) && - GetHash(VCTokenToDefine, SKEY(thisVCToken), &vField) && - (vField != NULL)) { - vcField *thisField = (vcField *)vField; - StrBuf *ThisFieldStr = NULL; - // syslog(LOG_DEBUG, "got this token: %s, found: %s", ChrPtr(thisVCToken), thisField->STR.Key); - switch (thisField->Type) { - case StringCluster: { - int j = 0; - const char *Pos = NULL; - StrBuf *thisArray = NewStrBufPlain(v->prop[i].value, -1); - StrBuf *Buf = NewStrBufPlain(NULL, StrLength(thisArray)); - 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++; - } - FreeStrBuf(&thisArray); - FreeStrBuf(&Buf); - } - break; - case Address: - case FlatString: - case PhoneNumber: - case EmailAddr: - case Street: - case Number: - case AliasFor: - /* copy over the payload into a StrBuf */ - ThisFieldStr = NewStrBufPlain(v->prop[i].value, -1); - PutVcardItem(VC, thisField, ThisFieldStr, is_qp, Swap); - - 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; - } - - } - else if (StrLength(thisVCToken) > 0) { - /* Add it to the UNKNOWN field... */ - void *pv = NULL; - StrBuf *oldVal; - GetHash(VC, IKEY(vcfUnknown->cval), &pv); - oldVal = (StrBuf*) pv; - if (oldVal == NULL) { - oldVal = NewStrBuf(); - Put(VC, IKEY(vcfUnknown->cval), oldVal, HFreeStrBuf); - } - else { - StrBufAppendBufPlain(oldVal, HKEY("\n"), 0); - } - - StrBufAppendBuf(oldVal, thisVCToken, 0); - StrBufAppendBufPlain(oldVal, HKEY(":"), 0); - StrBufAppendBufPlain(oldVal, v->prop[i].value, -1, 0); - continue; - } - } - FreeStrBuf(&thisname); - FreeStrBuf(&Swap); - FreeStrBuf(&thisVCToken); -} - -HashList *CtxGetVcardList(StrBuf *Target, WCTemplputParams *TP) -{ - HashList *pb = CTX(CTX_VCARD_LIST); - return pb; -} - -/****************************************************************************** - * Extract an embedded photo from a vCard for display on the client * - ******************************************************************************/ - -void display_vcard_photo_img(void) -{ - long msgnum = 0L; - StrBuf *vcard; - struct vCard *v; - char *photosrc; - const char *contentType; - - 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(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); - hprintf("Content-Type: text/plain\r\n"); - begin_burst(); - wc_printf(_("Could Not decode vcard photo\n")); - end_burst(); - return; - } - 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 - * and MIME part number to fetch. Or, specify -1 for the message number - * to start with a blank card. - */ -void do_edit_vcard(long msgnum, char *partnum, - message_summary *VCMsg, - wc_mime_attachment *VCAtt, - const char *return_to, - const char *force_room) { - WCTemplputParams SubTP; - message_summary *Msg = NULL; - wc_mime_attachment *VCMime = NULL; - struct vCard *v; - char whatuser[256]; - addrbookent ab; - - memset(&ab, 0, sizeof(addrbookent)); - ab.VC = NewHash(0, lFlathash); - /* Display the form */ - output_headers(1, 1, 1, 0, 0, 0); - - safestrncpy(whatuser, "", sizeof whatuser); - - if ((msgnum >= 0) || - ((VCMsg != NULL) && (VCAtt != NULL))) - { - if ((VCMsg == NULL) && (VCAtt == NULL)) { - - Msg = (message_summary *) malloc(sizeof(message_summary)); - memset(Msg, 0, sizeof(message_summary)); - Msg->msgnum = msgnum; - VCMime = load_vcard(Msg); - if (VCMime == NULL) { - convenience_page("770000", _("Error"), "");/*TODO: important message*/ - DestroyMessageSummary(Msg); - return; - DeleteHash(&ab.VC); - } - - v = VCardLoad(VCMime->Data); - } - else { - v = VCardLoad(VCAtt->Data); - } - - parse_vcard(WC->WBuf, v, ab.VC, NULL); - - - vcard_free(v); - } - - memset(&SubTP, 0, sizeof(WCTemplputParams)); - { - WCTemplputParams *TP = NULL; - WCTemplputParams SubTP; - - StackContext(TP, &SubTP, &ab, CTX_VCARD, 0, NULL); - - DoTemplate(HKEY("vcard_edit"), WC->WBuf, &SubTP); - UnStackContext(&SubTP); - } - DeleteHash(&ab.VC); - - - wDumpContent(1); - if (Msg != NULL) { - DestroyMessageSummary(Msg); - } -} - - -/* - * commit the edits to the citadel server - */ -void edit_vcard(void) { - long msgnum; - char *partnum; - - msgnum = lbstr("msgnum"); - partnum = bstr("partnum"); - do_edit_vcard(msgnum, partnum, NULL, NULL, "", NULL); -} - -/* - * parse edited vcard from the browser - */ -void submit_vcard(void) { - struct vCard *v; - char *serialized_vcard; - StrBuf *Buf; - const StrBuf *ForceRoom; - HashList* postVcard; - HashPos *it, *itSub; - const char *Key; - long len; - void *pv; - StrBuf *SubStr; - const StrBuf *s; - const char *Pos = NULL; - - if (!havebstr("ok_button")) { - readloop(readnew, eUseDefault); - return; - } - - if (havebstr("force_room")) { - ForceRoom = sbstr("force_room"); - if (gotoroom(ForceRoom) != 200) { - AppendImportantMessage(_("Unable to enter the room to save your message"), -1); - AppendImportantMessage(HKEY(": ")); - AppendImportantMessage(SKEY(ForceRoom)); - AppendImportantMessage(HKEY("; ")); - AppendImportantMessage(_("Aborting."), -1); - - if (!strcmp(bstr("return_to"), "select_user_to_edit")) { - select_user_to_edit(NULL); - } - else if (!strcmp(bstr("return_to"), "do_welcome")) { - do_welcome(); - } - else if (!IsEmptyStr(bstr("return_to"))) { - http_redirect(bstr("return_to")); - } - else { - readloop(readnew, eUseDefault); - } - return; - } - } - - postVcard = getSubStruct(HKEY("VC")); - if (postVcard == NULL) { - AppendImportantMessage(_("An error has occurred."), -1); - edit_vcard(); - return;/*/// more details*/ - } - - Buf = NewStrBuf(); - serv_write(HKEY("ENT0 1|||4\n")); - if (!StrBuf_ServGetln(Buf) && (GetServerStatus(Buf, NULL) != 4)) - { - edit_vcard(); - return; - } - - /* Make a vCard structure out of the data supplied in the form */ - StrBufPrintf(Buf, "begin:vcard\r\n%s\r\nend:vcard\r\n", - bstr("extrafields") - ); - v = VCardLoad(Buf); /* Start with the extra fields */ - if (v == NULL) { - AppendImportantMessage(_("An error has occurred."), -1); - edit_vcard(); - FreeStrBuf(&Buf); - return; - } - - SubStr = NewStrBuf(); - it = GetNewHashPos(DefineToToken, 0); - while (GetNextHashPos(DefineToToken, it, &len, &Key, &pv) && - (pv != NULL)) - { - char buf[32]; - long blen; - vcField *t = (vcField*) pv; - - if (t->Sub != NULL){ - vcField *Sub; - FlushStrBuf(SubStr); - itSub = GetNewHashPos(DefineToToken, 0); - while (GetNextHashPos(DefineToToken, itSub, &len, &Key, &pv) && - (pv != NULL)) - { - Sub = (vcField*) pv; - if (Sub->parentCVal == t->cval) { - if (StrLength(SubStr) > 0) - StrBufAppendBufPlain(SubStr, HKEY(";"), 0); - - - - blen = snprintf(buf, sizeof(buf), "%ld", Sub->cval); - s = SSubBstr(postVcard, buf, blen); - - if ((s != NULL) && (StrLength(s) > 0)) { - /// todo: utf8 qp - StrBufAppendBuf(SubStr, s, 0); - } - } - } - if (StrLength(SubStr) > 0) { - vcard_add_prop(v, t->STR.Key, ChrPtr(SubStr)); - } - DeleteHashPos(&itSub); - } - else if (t->parentCVal == 0) { - blen = snprintf(buf, sizeof(buf), "%ld", t->cval); - s = SSubBstr(postVcard, buf, blen); - - if ((s != NULL) && (StrLength(s) > 0)) { - vcard_add_prop(v, t->STR.Key, ChrPtr(s)); - } - } - } - DeleteHashPos(&it); - - s = sbstr("other_inetemail"); - if (StrLength(s) > 0) { - FlushStrBuf(SubStr); - while (StrBufSipLine(SubStr, s, &Pos), ((Pos!=StrBufNOTNULL) && (Pos!=NULL)) ) { - if (StrLength(SubStr) > 0) { - vcard_add_prop(v, "email;internet", ChrPtr(SubStr)); - } - } - } - - FreeStrBuf(&SubStr); - - - serialized_vcard = vcard_serialize(v); - vcard_free(v); - if (serialized_vcard == NULL) { - AppendImportantMessage(_("An error has occurred."), -1); - edit_vcard(); - FreeStrBuf(&Buf); - return; - } - - printf("%s", serialized_vcard); - serv_write(HKEY("Content-type: text/x-vcard; charset=UTF-8\n")); - serv_write(HKEY("\n")); - serv_printf("%s\r\n", serialized_vcard); - serv_write(HKEY("000\n")); - free(serialized_vcard); - - if (!strcmp(bstr("return_to"), "select_user_to_edit")) { - select_user_to_edit(NULL); - } - else if (!strcmp(bstr("return_to"), "do_welcome")) { - do_welcome(); - } - else if (!IsEmptyStr(bstr("return_to"))) { - http_redirect(bstr("return_to")); - } - else { - readloop(readnew, eUseDefault); - } - FreeStrBuf(&Buf); -} - -/****************************************************************************** - * Render Addressbooks * - ******************************************************************************/ - -typedef struct _vcardview_struct { - long is_singlecard; - HashList *addrbook; - -} vcardview_struct; - -int vcard_GetParamsGetServerCall(SharedMessageStatus *Stat, - void **ViewSpecific, - long oper, - char *cmd, - long len, - char *filter, - long flen) -{ - vcardview_struct *VS; - - VS = (vcardview_struct*) malloc (sizeof(vcardview_struct)); - memset(VS, 0, sizeof(vcardview_struct)); - *ViewSpecific = (void*)VS; - - VS->is_singlecard = ibstr("is_singlecard"); - if (VS->is_singlecard != 1) { - VS->addrbook = NewHash(0, NULL); - if (oper == do_search) { - snprintf(cmd, len, "MSGS SEARCH|%s", bstr("query")); - } - else { - strcpy(cmd, "MSGS ALL"); - } - Stat->maxmsgs = 9999999; - } - return 200; -} - -int vcard_LoadMsgFromServer(SharedMessageStatus *Stat, - void **ViewSpecific, - message_summary* Msg, - int is_new, - int i) -{ - WCTemplputParams *TP = NULL; - WCTemplputParams SubTP; - vcardview_struct *VS; - wc_mime_attachment *VCMime = NULL; - struct vCard *v; - addrbookent* abEntry; - - VS = (vcardview_struct*) *ViewSpecific; - - VCMime = load_vcard(Msg); - if (VCMime == NULL) - return 0; - - v = VCardLoad(VCMime->Data); - - if (v == NULL) return 0; - - abEntry = (addrbookent*) malloc(sizeof(addrbookent)); - memset(abEntry, 0, sizeof(addrbookent)); - abEntry->name = NewStrBuf(); - abEntry->VC = NewHash(0, lFlathash); - abEntry->ab_msgnum = Msg->msgnum; - - parse_vcard(WC->WBuf, v, abEntry->VC, VCMime); - - 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); - return 0; -} - - -/* - * Render the address book using info we gathered during the scan - * - * addrbook the addressbook to render - * num_ab the number of the addressbook - */ -static int NAMESPERPAGE = 60; -void do_addrbook_view(vcardview_struct* VS) { - long i = 0; - int num_pages = 0; - int tabfirst = 0; - int tablast = 0; - StrBuf **tablabels; - int num_ab = GetCount(VS->addrbook); - HashList *headlines; - - WCTemplputParams *TP = NULL; - WCTemplputParams SubTP; - - memset(&SubTP, 0, sizeof(WCTemplputParams)); - - if (num_ab == 0) { - do_template("vcard_list_empty"); - return; - } - - if (num_ab > 1) { - SortByHashKey(VS->addrbook, 1); - } - - num_pages = (GetCount(VS->addrbook) / NAMESPERPAGE) + 1; - - tablabels = malloc(num_pages * sizeof (StrBuf *)); - if (tablabels == NULL) { - return; - } - - headlines = NewHash(0, lFlathash); - for (i=0; i (num_ab - 1)) tablast = (num_ab - 1); - - headline = NewStrBufPlain(NULL, StrLength(v1) + StrLength(v2) + 10); - 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); - StackContext(TP, &SubTP, VS->addrbook, CTX_VCARD_LIST, 0, NULL); - - DoTemplate(HKEY("vcard_list"), WC->WBuf, &SubTP); - UnStackContext(&SubTP); - DeleteHash(&headlines); - free(tablabels); - StrBufAppendBufPlain(WC->WBuf, HKEY(""), 0);/* closes: id=global */ -} - - - -int vcard_RenderView_or_Tail(SharedMessageStatus *Stat, void **ViewSpecific, long oper) -{ - const StrBuf *Mime; - vcardview_struct *VS; - - VS = (vcardview_struct*) *ViewSpecific; - 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; -} - -int vcard_Cleanup(void **ViewSpecific) -{ - vcardview_struct *VS; - - VS = (vcardview_struct*) *ViewSpecific; - wDumpContent(1); - if ((VS != NULL) && (VS->addrbook != NULL)) { - DeleteHash(&VS->addrbook); - } - if (VS != NULL) { - free(VS); - } - - return 0; -} - -void render_MIME_VCard(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset) -{ - wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH); - 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(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)); - StrBufAppendPrintf(Buf, "[%s]", _("edit")); - } - - /* In all cases, display the full card */ - - v = VCardLoad(Mime->Data); - - if (v != NULL) { - 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, 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 { - StrBufPlain(Buf, _("failed to load vcard"), -1); - } - FreeStrBuf(&Mime->Data); - Mime->Data = Buf; - } - -} - -void -ServerStartModule_VCARD -(void) -{ -} - -void -ServerShutdownModule_VCARD -(void) -{ - DeleteHash(&DefineToToken); - DeleteHash(&vcNames); - DeleteHash(&VCTokenToDefine); -} - -void -InitModule_VCARD -(void) -{ - StrBuf *Prefix = NewStrBufPlain(HKEY("VC:")); - DefineToToken = NewHash(1, lFlathash); - vcNames = NewHash(1, lFlathash); - VCTokenToDefine = NewHash(1, NULL); - autoRegisterTokens(&VCEnumCounter, VCStrE, Prefix, 0, 0); - FreeStrBuf(&Prefix); - - REGISTERTokenParamDefine(NAMESPERPAGE); - - - RegisterCTX(CTX_VCARD); - RegisterCTX(CTX_VCARD_LIST); - RegisterCTX(CTX_VCARD_TYPE); - - RegisterReadLoopHandlerset( - VIEW_ADDRESSBOOK, - vcard_GetParamsGetServerCall, - NULL, - NULL, - NULL, - vcard_LoadMsgFromServer, - vcard_RenderView_or_Tail, - vcard_Cleanup, - NULL); - - RegisterIterator("MAIL:VCARDS", 0, NULL, CtxGetVcardList, NULL, NULL, CTX_VCARD, CTX_VCARD_LIST, IT_NOFLAG); - - - WebcitAddUrlHandler(HKEY("edit_vcard"), "", 0, edit_vcard, 0); - WebcitAddUrlHandler(HKEY("submit_vcard"), "", 0, submit_vcard, 0); - WebcitAddUrlHandler(HKEY("vcardphoto"), "", 0, display_vcard_photo_img, NEED_URL); - - RegisterNamespace("VC:ITEM", 2, 2, tmpl_vcard_item, preeval_vcard_item, CTX_VCARD); - RegisterNamespace("VC:CTXITEM", 1, 1, tmpl_vcard_context_item, NULL, CTX_VCARD_TYPE); - RegisterNamespace("VC:NAME", 1, 1, tmpl_vcard_name_str, preeval_vcard_name_str, CTX_VCARD); - RegisterNamespace("VC:MSGNO", 0, 1, tmpl_vcard_msgno, NULL, CTX_VCARD); - RegisterNamespace("VC:CTXNAME", 1, 1, tmpl_vcard_context_name_str, NULL, CTX_VCARD_TYPE); - REGISTERTokenParamDefine(FlatString); - REGISTERTokenParamDefine(StringCluster); - REGISTERTokenParamDefine(PhoneNumber); - REGISTERTokenParamDefine(EmailAddr); - REGISTERTokenParamDefine(Street); - REGISTERTokenParamDefine(Number); - REGISTERTokenParamDefine(AliasFor); - REGISTERTokenParamDefine(Base64BinaryAttachment); - REGISTERTokenParamDefine(TerminateList); - REGISTERTokenParamDefine(Address); - - 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); - - RegisterMimeRenderer(HKEY("text/x-vcard"), render_MIME_VCard, 1, 201); - RegisterMimeRenderer(HKEY("text/vcard"), render_MIME_VCard, 1, 200); -}