X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fvcard_edit.c;h=8345d003fa9524cac5ad58f1d6a11cb9c5c2d1ba;hb=f9555db58209352cc9ae4537f36ced11d9dbee8b;hp=64061d7badc870500df637a2236e17689688971a;hpb=061684b1fca9be37ecc01cac2b10be94502def65;p=citadel.git diff --git a/webcit/vcard_edit.c b/webcit/vcard_edit.c index 64061d7ba..8345d003f 100644 --- a/webcit/vcard_edit.c +++ b/webcit/vcard_edit.c @@ -1,10 +1,351 @@ /* - * $Id$ + * Copyright (c) 1996-2012 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_TYPE = CTX_NONE; +long VCEnumCounter = 0; + +typedef enum _VCStrEnum { + FlatString, + StringCluster, + PhoneNumber, + EmailAddr, + Street, + Number, + AliasFor, + Base64BinaryAttachment, + TerminateList +}VCStrEnum; +typedef struct vcField vcField; +struct vcField { + ConstStr STR; + VCStrEnum Type; + vcField *Sub; + long cval; + ConstStr Name; +}; + +vcField VCStr_Ns [] = { + {{HKEY("last")}, FlatString, NULL, 0, {HKEY("Last Name")}}, + {{HKEY("first")}, FlatString, NULL, 0, {HKEY("First Name")}}, + {{HKEY("middle")}, FlatString, NULL, 0, {HKEY("Middle Name")}}, + {{HKEY("prefix")}, FlatString, NULL, 0, {HKEY("Prefix")}}, + {{HKEY("suffix")}, FlatString, NULL, 0, {HKEY("Suffix")}}, + {{HKEY("")}, TerminateList, NULL, 0, {HKEY("")}} +}; + +vcField VCStr_Addrs [] = { + {{HKEY("POBox")}, FlatString, NULL, 0, {HKEY("PO box")}}, + {{HKEY("address")}, FlatString, NULL, 0, {HKEY("Address")}}, + {{HKEY("address2")}, FlatString, NULL, 0, {HKEY("")}}, + {{HKEY("city")}, FlatString, NULL, 0, {HKEY("City")}}, + {{HKEY("state")}, FlatString, NULL, 0, {HKEY("State")}}, + {{HKEY("zip")}, FlatString, NULL, 0, {HKEY("ZIP code")}}, + {{HKEY("country")}, FlatString, NULL, 0, {HKEY("Country")}}, + {{HKEY("")}, TerminateList, NULL, 0, {HKEY("")}} +}; + +vcField VCStrE [] = { + {{HKEY("version")}, Number, NULL, 0, {HKEY("")}}, + {{HKEY("rev")}, Number, NULL, 0, {HKEY("")}}, + {{HKEY("label")}, FlatString, NULL, 0, {HKEY("")}}, + {{HKEY("uid")}, FlatString, NULL, 0, {HKEY("")}}, + {{HKEY("n")}, StringCluster, VCStr_Ns, 0, {HKEY("")}}, /* N is name, but only if there's no FN already there */ + {{HKEY("fn")}, FlatString, NULL, 0, {HKEY("")}}, /* FN (full name) is a true 'display name' field */ + {{HKEY("title")}, FlatString, NULL, 0, {HKEY("Title:")}}, + {{HKEY("org")}, FlatString, NULL, 0, {HKEY("Organization:")}},/* organization */ + {{HKEY("email")}, EmailAddr, NULL, 0, {HKEY("E-mail:")}}, + {{HKEY("tel")}, PhoneNumber, NULL, 0, {HKEY("Telephone:")}}, + {{HKEY("adr")}, StringCluster, VCStr_Addrs, 0, {HKEY("Address:")}}, + {{HKEY("photo")}, Base64BinaryAttachment, NULL, 0, {HKEY("Photo:")}}, + {{HKEY("tel;home")}, PhoneNumber, NULL, 0, {HKEY(" (home)")}}, + {{HKEY("tel;work")}, PhoneNumber, NULL, 0, {HKEY(" (work)")}}, + {{HKEY("tel;fax")}, PhoneNumber, NULL, 0, {HKEY(" (fax)")}}, + {{HKEY("tel;cell")}, PhoneNumber, NULL, 0, {HKEY(" (cell)")}}, + {{HKEY("email;internet")}, EmailAddr, NULL, 0, {HKEY("E-mail:")}}, + {{HKEY("")}, TerminateList, NULL, 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")} +}; + + +HashList *DefineToToken = NULL; +HashList *VCTokenToDefine = NULL; +HashList *vcNames = NULL; /* todo: fill with the name strings */ + + +void RegisterVCardToken(vcField* vf, StrBuf *name, int inTokenCount) +{ + 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) +{ + int i = 0; + while (vf[i].STR.len > 0) { + StrBuf *subStr = NewStrBuf(); + vf[i].cval = (*enumCounter) ++; + 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); + i++; + continue; + } + break; + case PhoneNumber: + break; + case EmailAddr: + break; + case Street: + break; + case Number: + break; + case AliasFor: + break; + case Base64BinaryAttachment: + break; + case TerminateList: + break; + } + RegisterVCardToken(&vf[i], subStr, i); + i++; + } +} + +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); + HashList *vc = (HashList*) CTX(CTX_VCARD); + if (GetHash(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); + HashList *vc = (HashList*) CTX(CTX_VCARD); + + if (t == NULL) { + LogTemplateError(NULL, "VCard item", ERR_NAME, TP, + "Missing context"); + return; + } + + if (GetHash(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_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; + int rc = 0; + vcField *vf = (vcField*) Context; + + memcpy(&type, key, sizeof(long)); + searchType = GetTemplateTokenNumber(Target, TP, IT_ADDT_PARAM(0), 0); + + if (vf->Type == searchType) { + HashList *vc = (HashList*) CTX(CTX_VCARD); + if (GetHash(vc, LKEY(vf->cval), &v) && v != NULL) + return 1; + } + return rc; +} + + + + +HashList *getContextVcard(StrBuf *Target, WCTemplputParams *TP) +{ + vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE); + HashList *vc = (HashList*) CTX(CTX_VCARD); + + if ((vf == NULL) || (vc == NULL)) { + LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, + "Need VCard and Vcard type in context"); + + return NULL; + } + return 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) +{ + HashList *vc = (HashList*) CTX(CTX_VCARD); + long HaveFieldType = GetTemplateTokenNumber(Target, TP, 2, 0); + int rc = 0; + void *vVCitem; + const char *Key; + long len; + HashPos *it = GetNewHashPos(vc, 0); + while (GetNextHashPos(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; +} + /* * Record compare function for sorting address book indices */ @@ -88,7 +429,8 @@ wc_mime_attachment *load_vcard(message_summary *Msg) if (VCMime == NULL) return NULL; - MimeLoadData(VCMime); + if (VCMime->Data == NULL) + MimeLoadData(VCMime); return VCMime; } @@ -197,7 +539,7 @@ void fetchname_parsed_vcard(struct vCard *v, char **storename) { } } if (is_qp) { - // %ff can become 6 bytes in utf8 + /* %ff can become 6 bytes in utf8 */ *storename = malloc(len * 2 + 3); j = CtdlDecodeQuotedPrintable( *storename, name, @@ -205,7 +547,7 @@ void fetchname_parsed_vcard(struct vCard *v, char **storename) { (*storename)[j] = 0; } else if (is_b64) { - // ff will become one byte.. + /* ff will become one byte.. */ *storename = malloc(len + 50); CtdlDecodeBase64( *storename, name, @@ -267,7 +609,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att strcpy(org, ""); if (!full) { - StrBufAppendPrintf(Target, ""); + StrBufAppendPrintf(Target, ""); name = vcard_get_prop(v, "fn", 1, 0, 0); if (name != NULL) { StrEscAppend(Target, NULL, name, 0, 0); @@ -280,12 +622,12 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att else { StrBufAppendPrintf(Target, " "); } - StrBufAppendPrintf(Target, ""); + StrBufAppendPrintf(Target, ""); return; } - StrBufAppendPrintf(Target, "
" - ""); + StrBufAppendPrintf(Target, "
" + "
"); for (pass=1; pass<=2; ++pass) { if (v->numprops) for (i=0; i<(v->numprops); ++i) { @@ -311,7 +653,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att utf8ify_rfc822_string(&v->prop[i].value); if (is_qp) { - // %ff can become 6 bytes in utf8 + /* %ff can become 6 bytes in utf8 */ thisvalue = malloc(len * 2 + 3); j = CtdlDecodeQuotedPrintable( thisvalue, v->prop[i].value, @@ -319,7 +661,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att thisvalue[j] = 0; } else if (is_b64) { - // ff will become one byte.. + /* ff will become one byte.. */ thisvalue = malloc(len + 50); CtdlDecodeBase64( thisvalue, v->prop[i].value, @@ -356,7 +698,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att else if (!strcasecmp(firsttoken, "email")) { size_t len; - if (!IsEmptyStr(mailto)) strcat(mailto, "
"); + if (!IsEmptyStr(mailto)) strcat(mailto, "
"); strcat(mailto, ""); } else if (!strcasecmp(firsttoken, "tel")) { - if (!IsEmptyStr(phone)) strcat(phone, "
"); + if (!IsEmptyStr(phone)) strcat(phone, "
"); strcat(phone, thisvalue); for (j=0; j
\n"); + StrBufAppendPrintf(Target, "\n"); } } /* else if (!strcasecmp(firsttoken, "photo") && full && pass == 2) { @@ -448,23 +790,23 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att } if (pass == 1) { - StrBufAppendPrintf(Target, "" - "" + "\n"); + StrBufAppendPrintf(Target, "\n"); if (!IsEmptyStr(phone)) { StrBufAppendPrintf(Target, "
"); + StrBufAppendPrintf(Target, "
"); StrBufAppendPrintf(Target, _("Address:")); - StrBufAppendPrintf(Target, ""); + StrBufAppendPrintf(Target, ""); for (j=0; j"); + if (j<3) StrBufAppendPrintf(Target, "
"); else StrBufAppendPrintf(Target, " "); } } - StrBufAppendPrintf(Target, "
" - "" - ""); + StrBufAppendPrintf(Target, "
" + "" + ""); StrEscAppend(Target, NULL, fullname, 0, 0); - StrBufAppendPrintf(Target, ""); + StrBufAppendPrintf(Target, ""); if (!IsEmptyStr(title)) { - StrBufAppendPrintf(Target, "
"); + StrBufAppendPrintf(Target, "
\""); StrEscAppend(Target, NULL, title, 0, 0); StrBufAppendPrintf(Target, "
"); } if (!IsEmptyStr(org)) { - StrBufAppendPrintf(Target, "
"); + StrBufAppendPrintf(Target, "
"); StrEscAppend(Target, NULL, org, 0, 0); StrBufAppendPrintf(Target, "
"); } - StrBufAppendPrintf(Target, "
"); @@ -484,6 +826,257 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_att } +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)){ + StrBuf *b; + StrBuf_RFC822_to_Utf8(Swap, ThisFieldStr, NULL, NULL); /* default charset, current charset */ + b = ThisFieldStr; + ThisFieldStr = Swap; + Swap = b; + FlushStrBuf(Swap); + } + Put(thisVC, LKEY(thisField->cval), 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 display + * full display all items of the vcard? + * msgnum Citadel message pointer + */ +void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, int full, wc_mime_attachment *Mime) +{ + StrBuf *Val = NULL; + StrBuf *Swap = NULL; + int i, j, k; + char buf[20]; //SIZ]; + int is_qp = 0; + int is_b64 = 0; + int ntokens, len; + StrBuf *thisname = NULL; + char firsttoken[20]; ///SIZ]; + //void *V; + HashList *thisVC; + StrBuf *thisVCToken; + void *vField = NULL; + + thisVC = NewHash(0, lFlathash); + 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); + + /*len = */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{ + 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++; + } +*/ + + } + } + + 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(thisVC, &thisField->Sub[j], ThisFieldStr, is_qp, Swap); + j++; + } + } + break; + 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(thisVC, thisField, ThisFieldStr, is_qp, Swap); + + break; + case Base64BinaryAttachment: + case TerminateList: + break; + } + + } + /* 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); + if (GetHash(VCToEnum, firsttoken, strlen(firsttoken), &V)) + { + eVC evc = (eVC) V; + Put(VC, IKEY(evc), Val, HFreeStrBuf); + syslog(LOG_DEBUG, "[%ul]\n", evc); + Val = NULL; + } + else + syslog(LOG_DEBUG, "[]\n"); +/* +TODO: check for layer II + else + { + long max = num_tokens(thisname, ';'); + firsttoken[len] = '_'; + + for (j = 0; j < max; j++) { +// firsttoken[len] + + 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, ")"); + } + } + } + + } +*/ +#endif + FreeStrBuf(&Val); + ////free(thisname); + /// thisname = NULL; + } + + + { + WCTemplputParams *TP = NULL; + WCTemplputParams SubTP; + FlushStrBuf(Target); + StackContext(TP, &SubTP, thisVC, CTX_VCARD, 0, NULL); + { + DoTemplate(HKEY("vcard_msg_display"), Target, &SubTP); + } + UnStackContext(&SubTP); + } + printf("%s\n", ChrPtr(Target)); + FreeStrBuf(&thisVCToken); + DeleteHash(&thisVC);/// todo +} + +void tmplput_VCARD_ITEM(StrBuf *Target, WCTemplputParams *TP) +{ + HashList *VC = CTX(CTX_VCARD); + int evc; + void *vStr; + + evc = GetTemplateTokenNumber(Target, TP, 0, -1); + if (evc != -1) + { + if (GetHash(VC, IKEY(evc), &vStr)) + { + StrBufAppendTemplate(Target, TP, + (StrBuf*) vStr, + 1); + } + } + +} + +void new_vcard (StrBuf *Target, struct vCard *v, int full, wc_mime_attachment *Mime) +{ + HashList *VC; + WCTemplputParams SubTP; + + memset(&SubTP, 0, sizeof(WCTemplputParams)); + + + VC = NewHash(0, Flathash); + parse_vcard(Target, v, VC, full, Mime); + + SubTP.Filter.ContextType = CTX_VCARD; + SubTP.Context = VC; + + //DoTemplate(HKEY("vcard_msg_display"), Target, &SubTP); + DeleteHash(&VC); +} + + /* * Display a textual vCard @@ -533,7 +1126,11 @@ void display_vcard(StrBuf *Target, ((!isalpha(alpha)) && (!isalpha(this_alpha))) ) { - display_parsed_vcard(Target, v, full, Mime); + if (ibstr("x") == 1) { + new_vcard (Target, v, full, Mime); + } else { + display_parsed_vcard(Target, v, full, Mime); + } } vcard_free(v); @@ -562,7 +1159,7 @@ void do_addrbook_view(addrbookent *addrbook, int num_ab) { char **tablabels; if (num_ab == 0) { - wc_printf("


"); + wc_printf("


"); wc_printf(_("This address book is empty.")); wc_printf("
\n"); return; @@ -576,7 +1173,7 @@ void do_addrbook_view(addrbookent *addrbook, int num_ab) { tablabels = malloc(num_pages * sizeof (char *)); if (tablabels == NULL) { - wc_printf("


"); + wc_printf("


"); wc_printf(_("An internal error has occurred.")); wc_printf("
\n"); return; @@ -604,7 +1201,7 @@ void do_addrbook_view(addrbookent *addrbook, int num_ab) { end_tab(page-1, num_pages); } begin_tab(page, num_pages); - wc_printf("\n"); + wc_printf("
\n"); displayed = 0; } @@ -614,7 +1211,7 @@ void do_addrbook_view(addrbookent *addrbook, int num_ab) { } bg = 1 - bg; wc_printf("", - (bg ? "DDDDDD" : "FFFFFF") + (bg ? "dddddd" : "ffffff") ); } @@ -663,6 +1260,7 @@ void do_edit_vcard(long msgnum, char *partnum, wc_mime_attachment *VCAtt, const char *return_to, const char *force_room) { + wcsession *WCC = WC; message_summary *Msg = NULL; wc_mime_attachment *VCMime = NULL; struct vCard *v; @@ -831,9 +1429,9 @@ void do_edit_vcard(long msgnum, char *partnum, /* Display the form */ output_headers(1, 1, 1, 0, 0, 0); - do_template("beginbox_1", NULL); + do_template("box_begin_1"); StrBufAppendBufPlain(WC->WBuf, _("Edit contact information"), -1, 0); - do_template("beginbox_2", NULL); + do_template("box_begin_2"); wc_printf("\n"); wc_printf("\n", WC->nonce); @@ -843,11 +1441,16 @@ void do_edit_vcard(long msgnum, char *partnum, escputs(force_room); wc_printf("\">\n"); } + else + { + wc_printf("WBuf, WCC->CurRoom.name, NULL, 0, 0); + wc_printf("\">\n"); + } - wc_printf("
" - "
\n"); + wc_printf("
\n"); - wc_printf("" + wc_printf("
" "" "" "" @@ -897,7 +1500,7 @@ void do_edit_vcard(long msgnum, char *partnum, wc_printf("
%s%s%s"); - wc_printf(""); + wc_printf("
"); wc_printf("
"); wc_printf(_("PO box:")); wc_printf("" @@ -973,14 +1576,14 @@ void do_edit_vcard(long msgnum, char *partnum, wc_printf("" "
"); wc_printf(_("Primary Internet e-mail address")); - wc_printf("
" + wc_printf("
" "
" + wc_printf("\">
" "
"); wc_printf(_("Internet e-mail aliases")); - wc_printf("
" + wc_printf("
" "
\n"); @@ -1005,7 +1608,7 @@ void do_edit_vcard(long msgnum, char *partnum, ); wc_printf("
\n"); - do_template("endbox", NULL); + do_template("box_end"); wDumpContent(1); if (Msg != NULL) { DestroyMessageSummary(Msg); @@ -1031,11 +1634,11 @@ void edit_vcard(void) { * parse edited vcard from the browser */ void submit_vcard(void) { - wcsession *WCC = WC; struct vCard *v; char *serialized_vcard; char buf[SIZ]; StrBuf *Buf; + const StrBuf *ForceRoom; int i; if (!havebstr("ok_button")) { @@ -1044,19 +1647,13 @@ void submit_vcard(void) { } if (havebstr("force_room")) { - if (gotoroom(sbstr("force_room")) != 200) { - StrBufAppendBufPlain(WCC->ImportantMsg, - _("Unable to enter the room to save your message"), - -1, 0); - StrBufAppendBufPlain(WCC->ImportantMsg, - HKEY(": "), 0); - StrBufAppendBuf(WCC->ImportantMsg, sbstr("force_room"), 0); - StrBufAppendBufPlain(WCC->ImportantMsg, - HKEY("; "), 0); - - StrBufAppendBufPlain(WCC->ImportantMsg, - _("Aborting."), - -1, 0); + 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); @@ -1074,27 +1671,23 @@ void submit_vcard(void) { } } - sprintf(buf, "ENT0 1|||4||"); - serv_puts(buf); - serv_getln(buf, sizeof buf); - if (buf[0] != '4') { + 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 */ - Buf = NewStrBuf(); StrBufPrintf(Buf, "begin:vcard\r\n%s\r\nend:vcard\r\n", bstr("extrafields") ); v = VCardLoad(Buf); /* Start with the extra fields */ - FreeStrBuf(&Buf); if (v == NULL) { - safestrncpy(WCC->ImportantMessage, - _("An error has occurred."), - sizeof WCC->ImportantMessage - ); + AppendImportantMessage(_("An error has occurred."), -1); edit_vcard(); + FreeStrBuf(&Buf); return; } @@ -1136,18 +1729,16 @@ void submit_vcard(void) { serialized_vcard = vcard_serialize(v); vcard_free(v); if (serialized_vcard == NULL) { - safestrncpy(WCC->ImportantMessage, - _("An error has occurred."), - sizeof WCC->ImportantMessage - ); + AppendImportantMessage(_("An error has occurred."), -1); edit_vcard(); + FreeStrBuf(&Buf); return; } - serv_puts("Content-type: text/x-vcard; charset=UTF-8"); - serv_puts(""); + serv_write(HKEY("Content-type: text/x-vcard; charset=UTF-8\n")); + serv_write(HKEY("\n")); serv_printf("%s\r\n", serialized_vcard); - serv_puts("000"); + serv_write(HKEY("000\n")); free(serialized_vcard); if (!strcmp(bstr("return_to"), "select_user_to_edit")) { @@ -1162,6 +1753,7 @@ void submit_vcard(void) { else { readloop(readnew, eUseDefault); } + FreeStrBuf(&Buf); } @@ -1214,7 +1806,9 @@ int vcard_GetParamsGetServerCall(SharedMessageStatus *Stat, void **ViewSpecific, long oper, char *cmd, - long len) + long len, + char *filter, + long flen) { vcardview_struct *VS; @@ -1288,14 +1882,32 @@ int vcard_Cleanup(void **ViewSpecific) return 0; } +void +ServerStartModule_VCARD +(void) +{ + ///VCToEnum = NewHash(0, NULL); + +} + +void +ServerShutdownModule_VCARD +(void) +{ + /// DeleteHash(&VCToEnum); +} + void InitModule_VCARD (void) { + RegisterCTX(CTX_VCARD); + RegisterCTX(CTX_VCARD_TYPE); RegisterReadLoopHandlerset( VIEW_ADDRESSBOOK, vcard_GetParamsGetServerCall, NULL, + NULL, NULL, vcard_LoadMsgFromServer, vcard_RenderView_or_Tail, @@ -1303,5 +1915,66 @@ InitModule_VCARD 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); +/* + Put(VCToEnum, HKEY("n"), (void*)VC_n, reference_free_handler); + Put(VCToEnum, HKEY("fn"), (void*)VC_fn, reference_free_handler); + Put(VCToEnum, HKEY("title"), (void*)VC_title, reference_free_handler); + Put(VCToEnum, HKEY("org"), (void*)VC_org, reference_free_handler); + Put(VCToEnum, HKEY("email"), (void*)VC_email, reference_free_handler); + Put(VCToEnum, HKEY("tel"), (void*)VC_tel, reference_free_handler); + Put(VCToEnum, HKEY("work"), (void*)VC_work, reference_free_handler); + Put(VCToEnum, HKEY("home"), (void*)VC_home, reference_free_handler); + Put(VCToEnum, HKEY("cell"), (void*)VC_cell, reference_free_handler); + Put(VCToEnum, HKEY("adr"), (void*)VC_adr, reference_free_handler); + Put(VCToEnum, HKEY("photo"), (void*)VC_photo, reference_free_handler); + Put(VCToEnum, HKEY("version"), (void*)VC_version, reference_free_handler); + Put(VCToEnum, HKEY("rev"), (void*)VC_rev, reference_free_handler); + Put(VCToEnum, HKEY("label"), (void*)VC_label, reference_free_handler); +*/ +/* + RegisterNamespace("VC", 1, 2, tmplput_VCARD_ITEM, NULL, CTX_VCARD); + + REGISTERTokenParamDefine(VC_n); + REGISTERTokenParamDefine(VC_fn); + REGISTERTokenParamDefine(VC_title); + REGISTERTokenParamDefine(VC_org); + REGISTERTokenParamDefine(VC_email); + REGISTERTokenParamDefine(VC_tel); + REGISTERTokenParamDefine(VC_work); + REGISTERTokenParamDefine(VC_home); + REGISTERTokenParamDefine(VC_cell); + REGISTERTokenParamDefine(VC_adr); + REGISTERTokenParamDefine(VC_photo); + REGISTERTokenParamDefine(VC_version); + REGISTERTokenParamDefine(VC_rev); + REGISTERTokenParamDefine(VC_label); +*/ + + { + StrBuf *Prefix = NewStrBufPlain(HKEY("VC:")); + DefineToToken = NewHash(1, lFlathash); + vcNames = NewHash(1, lFlathash); + VCTokenToDefine = NewHash(1, NULL); + autoRegisterTokens(&VCEnumCounter, VCStrE, Prefix, 0); + FreeStrBuf(&Prefix); + } + RegisterCTX(CTX_VCARD); + 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: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); + + RegisterConditional("VC:HAVE:TYPE", 1, conditional_VC_Havetype, 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); }