X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fvcard_edit.c;h=9c8bd3b0c4c76b899883eb610e0df2308d633a7e;hb=4b4dc864ede7c5d8d956febe4a0afb422b78e7c4;hp=320d4322facd54edad2da145d14cf2d5e7e8a89f;hpb=6a25ee7e6476856c8f167a09f3afe71361c3e579;p=citadel.git diff --git a/webcit/vcard_edit.c b/webcit/vcard_edit.c index 320d4322f..9c8bd3b0c 100644 --- a/webcit/vcard_edit.c +++ b/webcit/vcard_edit.c @@ -1,9 +1,64 @@ /* - * $Id$ + * Copyright (c) 1996-2011 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 as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "webcit.h" - +#include "webserver.h" +#include "calendar.h" + + + +ConstStr VCStr [] = { + {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("tel_tel")}, + {HKEY("tel_work")}, + {HKEY("tel_home")}, + {HKEY("tel_cell")}, + {HKEY("adr")}, + {HKEY("photo")}, + {HKEY("version")}, + {HKEY("rev")}, + {HKEY("label")} +}; + +typedef enum _eVC{ + VC_n, + VC_fn, + VC_title, + VC_org, + VC_email, + VC_tel, + VC_tel_tel, + VC_tel_work, + VC_tel_home, + VC_tel_cell, + VC_adr, + VC_photo, + VC_version, + VC_rev, + VC_label +} eVC; + +HashList *VCToEnum = NULL; /* * Record compare function for sorting address book indices @@ -29,47 +84,6 @@ void nametab(char *tabbuf, long len, char *name) { } -/* - * display the adressbook overview - */ -void display_addressbook(long msgnum, char alpha) { - //char buf[SIZ]; - /* char mime_partnum[SIZ]; */ - ///char mime_disposition[SIZ]; - //int mime_length; - char vcard_partnum[SIZ]; - StrBuf *vcard_source = NULL; - message_summary summ;////TODO: this will leak - - memset(&summ, 0, sizeof(summ)); - // safestrncpy(summ.subj, _("(no subject)"), sizeof summ.subj); - // Load Message headers - if (!IsEmptyStr(vcard_partnum)) { - vcard_source = load_mimepart(msgnum, vcard_partnum); - if (vcard_source != NULL) { - - /* Display the summary line */ - display_vcard(WC->WBuf, vcard_source, alpha, 0, NULL, msgnum); - - /* If it's my vCard I can edit it */ - if ( (!strcasecmp(ChrPtr(WC->wc_roomname), USERCONFIGROOM)) - || (!strcasecmp(&(ChrPtr(WC->wc_roomname)[11]), USERCONFIGROOM)) - || (WC->wc_view == VIEW_ADDRESSBOOK) - ) { - wprintf("", - msgnum, vcard_partnum); - wprintf("[%s]", _("edit")); - } - - FreeStrBuf(&vcard_source); - } - } - -} - - - /* * If it's an old "Firstname Lastname" style record, try to convert it. */ @@ -148,7 +162,7 @@ void fetch_ab_name(message_summary *Msg, char **namebuf) { return; /* Grab the name off the card */ - display_vcard(WC->WBuf, VCMime->Data, 0, 0, namebuf, Msg->msgnum); + display_vcard(WC->WBuf, VCMime, 0, 0, namebuf, Msg->msgnum); if (*namebuf != NULL) { lastfirst_firstlast(*namebuf); @@ -238,7 +252,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, @@ -246,14 +260,19 @@ 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, len); } else { - *storename = strdup(name); + size_t len; + + len = strlen (name); + + *storename = malloc(len + 3); /* \0 + eventualy missing ', '*/ + memcpy(*storename, name, len + 1); } /* vcard_n_prettyize(storename); */ } @@ -279,7 +298,8 @@ void fetchname_parsed_vcard(struct vCard *v, char **storename) { * full display all items of the vcard? * msgnum Citadel message pointer */ -void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum) { +void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_attachment *Mime) +{ int i, j; char buf[SIZ]; char *name; @@ -302,7 +322,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum 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); @@ -315,12 +335,12 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum 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) { @@ -343,7 +363,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum 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); + utf8ify_rfc822_string(&v->prop[i].value); if (is_qp) { // %ff can become 6 bytes in utf8 @@ -391,7 +411,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum 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) { @@ -483,23 +503,23 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum } 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, "
"); @@ -518,6 +538,160 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum StrBufAppendPrintf(Target, "
\n"); } +/* + * 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; + char buf[SIZ]; + int is_qp = 0; + int is_b64 = 0; + StrBuf *thisname = NULL; + char firsttoken[SIZ]; + void *V; + + Swap = NewStrBuf (); + thisname = NewStrBuf(); + for (i=0; i<(v->numprops); ++i) { + is_qp = 0; + is_b64 = 0; + StrBufPlain(thisname, v->prop[i].name, -1); + StrBufLowerCase(thisname); + + /*len = */extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken); + + for (j=0; jprop[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); + + } + syslog(1, "%s [%s][%s]", + firsttoken, + ChrPtr(Val), + v->prop[i].value); + if (GetHash(VCToEnum, firsttoken, strlen(firsttoken), &V)) + { + eVC evc = (eVC) V; + Put(VC, IKEY(evc), Val, HFreeStrBuf); + syslog(1, "[%ul]\n", evc); + Val = NULL; + } + else + syslog(1, "[]\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, ")"); + } + } + } + + } +*/ + + FreeStrBuf(&Val); + free(thisname); + thisname = NULL; + } + +} + +void tmplput_VCARD_ITEM(StrBuf *Target, WCTemplputParams *TP) +{ + HashList *VC = CTX; + eVC 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("test_vcard"), Target, &SubTP); + DeleteHash(&VC); +} + /* @@ -534,7 +708,7 @@ void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, long msgnum * msgnum Citadel message pointer */ void display_vcard(StrBuf *Target, - StrBuf *vcard_source, + wc_mime_attachment *Mime, char alpha, int full, char **storename, @@ -546,7 +720,7 @@ void display_vcard(StrBuf *Target, StrBuf *Buf2; char this_alpha = 0; - v = VCardLoad(vcard_source); + v = VCardLoad(Mime->Data); if (v == NULL) return; @@ -563,12 +737,16 @@ void display_vcard(StrBuf *Target, 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); + else if ((alpha == 0) || + ((isalpha(alpha)) && (tolower(alpha) == tolower(this_alpha))) || + ((!isalpha(alpha)) && (!isalpha(this_alpha))) + ) + { +#ifdef XXX_XXX + new_vcard (Target, v, full, Mime); +#else + display_parsed_vcard(Target, v, full, Mime); +#endif } vcard_free(v); @@ -597,9 +775,9 @@ void do_addrbook_view(addrbookent *addrbook, int num_ab) { char **tablabels; if (num_ab == 0) { - wprintf("


"); - wprintf(_("This address book is empty.")); - wprintf("
\n"); + wc_printf("


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


"); - wprintf(_("An internal error has occurred.")); - wprintf("
\n"); + wc_printf("


"); + wc_printf(_("An internal error has occurred.")); + wc_printf("
\n"); return; } @@ -635,43 +813,43 @@ void do_addrbook_view(addrbookent *addrbook, int num_ab) { if ((i / NAMESPERPAGE) != page) { /* New tab */ page = (i / NAMESPERPAGE); if (page > 0) { - wprintf("\n"); + wc_printf("\n"); end_tab(page-1, num_pages); } begin_tab(page, num_pages); - wprintf("\n"); + wc_printf("
\n"); displayed = 0; } if ((displayed % 4) == 0) { if (displayed > 0) { - wprintf("\n"); + wc_printf("\n"); } bg = 1 - bg; - wprintf("", - (bg ? "DDDDDD" : "FFFFFF") + wc_printf("", + (bg ? "dddddd" : "ffffff") ); } - wprintf("\n"); + wc_printf("\n"); ++displayed; } /* Placeholders for empty columns at end */ if ((num_ab % 4) != 0) { for (i=0; i<(4-(num_ab % 4)); ++i) { - wprintf(""); + wc_printf(""); } } - wprintf("
"); + wc_printf(""); - wprintf("", bstr("alpha")); + wc_printf("?maxmsgs=1?is_summary=0?alpha=%s\">", bstr("alpha")); vcard_n_prettyize(addrbook[i].ab_name); escputs(addrbook[i].ab_name); - wprintf("  
\n"); + wc_printf("\n"); end_tab((num_pages-1), num_pages); begin_tab(num_pages, num_pages); @@ -696,7 +874,7 @@ void do_addrbook_view(addrbookent *addrbook, int num_ab) { void do_edit_vcard(long msgnum, char *partnum, message_summary *VCMsg, wc_mime_attachment *VCAtt, - char *return_to, + const char *return_to, const char *force_room) { message_summary *Msg = NULL; wc_mime_attachment *VCMime = NULL; @@ -866,170 +1044,170 @@ void do_edit_vcard(long msgnum, char *partnum, /* Display the form */ output_headers(1, 1, 1, 0, 0, 0); - svput("BOXTITLE", WCS_STRING, _("Edit contact information")); - do_template("beginboxx", NULL); + do_template("box_begin_1"); + StrBufAppendBufPlain(WC->WBuf, _("Edit contact information"), -1, 0); + do_template("box_begin_2"); - wprintf("
\n"); - wprintf("\n", WC->nonce); + wc_printf("\n"); + wc_printf("\n", WC->nonce); if (force_room != NULL) { - wprintf("\n"); + wc_printf("\">\n"); } - wprintf("
" - "
\n"); + wc_printf("
\n"); - wprintf("" + wc_printf("
" "" "" "" "" "\n", - _("Prefix"), _("First"), _("Middle"), _("Last"), _("Suffix") + _("Prefix"), _("First Name"), _("Middle Name"), _("Last Name"), _("Suffix") ); - wprintf("", prefix); - wprintf("", firstname); - wprintf("", middlename); - wprintf("", lastname); - wprintf("
%s%s%s%s%s
\n", suffix); - wprintf(""); - wprintf("
"); + wc_printf(""); + wc_printf("
"); - wprintf(_("Display name:")); - wprintf("
" + wc_printf(_("Display name:")); + wc_printf("
" "

\n", fullname ); - wprintf(_("Title:")); - wprintf("
" + wc_printf(_("Title:")); + wc_printf("
" "

\n", title ); - wprintf(_("Organization:")); - wprintf("
" + wc_printf(_("Organization:")); + wc_printf("
" "

\n", org ); - wprintf("
"); + wc_printf(""); - wprintf(""); - wprintf("
"); - wprintf(_("PO box:")); - wprintf("" + wc_printf(""); + wc_printf("\n", pobox); - wprintf("\n", extadr); - wprintf("\n", street); - wprintf("\n", city); - wprintf("\n", state); - wprintf("\n", zipcode); - wprintf("\n", country); - wprintf("
"); + wc_printf(_("PO box:")); + wc_printf("" "
"); - wprintf(_("Address:")); - wprintf("" + wc_printf("
"); + wc_printf(_("Address:")); + wc_printf("" "
" + wc_printf("
" "
"); - wprintf(_("City:")); - wprintf("" + wc_printf("
"); + wc_printf(_("City:")); + wc_printf("" "
"); - wprintf(_("State:")); - wprintf("" + wc_printf("
"); + wc_printf(_("State:")); + wc_printf("" "
"); - wprintf(_("ZIP code:")); - wprintf("" + wc_printf("
"); + wc_printf(_("ZIP code:")); + wc_printf("" "
"); - wprintf(_("Country:")); - wprintf("" + wc_printf("
"); + wc_printf(_("Country:")); + wc_printf("" "
\n"); + wc_printf("
\n"); - wprintf("
\n"); + wc_printf("
\n"); - wprintf("" + wc_printf("
"); - wprintf(_("Home telephone:")); - wprintf("
" "\n", hometel); - wprintf("" + wc_printf("" "\n", worktel); - wprintf("" + wc_printf("" "\n", mobiletel); - wprintf("" + wc_printf("" "
"); + wc_printf(_("Home telephone:")); + wc_printf(""); - wprintf(_("Work telephone:")); - wprintf(""); + wc_printf(_("Work telephone:")); + wc_printf("
"); - wprintf(_("Mobile telephone:")); - wprintf("
"); + wc_printf(_("Mobile telephone:")); + wc_printf(""); - wprintf(_("Fax number:")); - wprintf(""); + wc_printf(_("Fax number:")); + wc_printf("
\n", faxtel); - wprintf(""); - wprintf("
"); + wc_printf(""); + wc_printf("
"); - wprintf("" + wc_printf("
" "
"); - wprintf(_("Primary Internet e-mail address")); - wprintf("
" + wc_printf(_("Primary Internet e-mail address")); + wc_printf("
" "
" + wc_printf("\">
" "
"); - wprintf(_("Internet e-mail aliases")); - wprintf("
" + wc_printf(_("Internet e-mail aliases")); + wc_printf("
" "
\n"); + wc_printf("
\n"); - wprintf("
\n"); + wc_printf("
\n"); - wprintf("\n"); + wc_printf("\">\n"); - wprintf("\n"); + wc_printf("\n"); - wprintf("
\n" + wc_printf("
\n" "" " " "" @@ -1038,8 +1216,8 @@ void do_edit_vcard(long msgnum, char *partnum, _("Cancel") ); - wprintf("
\n"); - do_template("endbox", NULL); + wc_printf("\n"); + do_template("box_end"); wDumpContent(1); if (Msg != NULL) { DestroyMessageSummary(Msg); @@ -1065,67 +1243,60 @@ 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")) { - readloop(readnew); + readloop(readnew, eUseDefault); return; } 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); - /// todo: call the master dispatcher again... + 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); + readloop(readnew, eUseDefault); } return; } } - 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||||||1\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; } @@ -1167,29 +1338,33 @@ 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); + StrBuf_ServGetln(Buf); + 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); + readloop(readnew, eUseDefault); } + FreeStrBuf(&Buf); } @@ -1220,7 +1395,8 @@ void display_vcard_photo_img(void) 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"); - wprintf(_("Could Not decode vcard photo\n")); + begin_burst(); + wc_printf(_("Could Not decode vcard photo\n")); end_burst(); return; } @@ -1230,14 +1406,159 @@ void display_vcard_photo_img(void) free(photosrc); } +typedef struct _vcardview_struct { + long is_singlecard; + addrbookent *addrbook; + long num_ab; + +} 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) { + 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) +{ + vcardview_struct *VS; + char *ab_name; + + VS = (vcardview_struct*) *ViewSpecific; + + ab_name = NULL; + fetch_ab_name(Msg, &ab_name); + if (ab_name == NULL) + return 0; + ++VS->num_ab; + VS->addrbook = realloc(VS->addrbook, + (sizeof(addrbookent) * VS->num_ab) ); + safestrncpy(VS->addrbook[VS->num_ab-1].ab_name, ab_name, + sizeof(VS->addrbook[VS->num_ab-1].ab_name)); + VS->addrbook[VS->num_ab-1].ab_msgnum = Msg->msgnum; + free(ab_name); + return 0; +} + + +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); + else + do_addrbook_view(VS->addrbook, VS->num_ab); /* 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)) + free(VS->addrbook); + if (VS != NULL) + free(VS); + return 0; +} + +void +ServerStartModule_VCARD +(void) +{ + VCToEnum = NewHash(0, NULL); + +} + +void +ServerShutdownModule_VCARD +(void) +{ + DeleteHash(&VCToEnum); +} void InitModule_VCARD (void) { - WebcitAddUrlHandler(HKEY("edit_vcard"), edit_vcard, 0); - WebcitAddUrlHandler(HKEY("submit_vcard"), submit_vcard, 0); - WebcitAddUrlHandler(HKEY("vcardphoto"), display_vcard_photo_img, NEED_URL); + RegisterReadLoopHandlerset( + VIEW_ADDRESSBOOK, + vcard_GetParamsGetServerCall, + NULL, + NULL, + NULL, + vcard_LoadMsgFromServer, + vcard_RenderView_or_Tail, + vcard_Cleanup); + 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("tel_tel"), (void*)VC_tel_tel, reference_free_handler); + Put(VCToEnum, HKEY("tel_work"), (void*)VC_tel_work, reference_free_handler); + Put(VCToEnum, HKEY("tel_home"), (void*)VC_tel_home, reference_free_handler); + Put(VCToEnum, HKEY("tel_cell"), (void*)VC_tel_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_tel_tel); + REGISTERTokenParamDefine(VC_tel_work); + REGISTERTokenParamDefine(VC_tel_home); + REGISTERTokenParamDefine(VC_tel_cell); + REGISTERTokenParamDefine(VC_adr); + REGISTERTokenParamDefine(VC_photo); + REGISTERTokenParamDefine(VC_version); + REGISTERTokenParamDefine(VC_rev); + REGISTERTokenParamDefine(VC_label); + }