}
+/**
+ * \brief display the adressbook overview
+ * \param msgnum the citadel message number
+ * \param alpha what????
+ */
+void display_addressbook(long msgnum, char alpha) {
+ //char buf[SIZ];
+ /* char mime_partnum[SIZ]; */
+/* char mime_filename[SIZ]; */
+/* char mime_content_type[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
+// Msg =
+ 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("<a href=\"edit_vcard?"
+ "msgnum=%ld&partnum=%s\">",
+ msgnum, vcard_partnum);
+ wprintf("[%s]</a>", _("edit"));
+ }
+
+ FreeStrBuf(&vcard_source);
+ }
+ }
+
+}
+
+
+
+/**
+ * \brief If it's an old "Firstname Lastname" style record, try to convert it.
+ * \param namebuf name to analyze, reverse if nescessary
+ */
+void lastfirst_firstlast(char *namebuf) {
+ char firstname[SIZ];
+ char lastname[SIZ];
+ int i;
+
+ if (namebuf == NULL) return;
+ if (strchr(namebuf, ';') != NULL) return;
+
+ i = num_tokens(namebuf, ' ');
+ if (i < 2) return;
+
+ extract_token(lastname, namebuf, i-1, ' ', sizeof lastname);
+ remove_token(namebuf, i-1, ' ');
+ strcpy(firstname, namebuf);
+ sprintf(namebuf, "%s; %s", lastname, firstname);
+}
+
+/**
+ * \brief fetch what??? name
+ * \param msgnum the citadel message number
+ * \param namebuf where to put the name in???
+ */
+void fetch_ab_name(message_summary *Msg, char **namebuf) {
+ char buf[SIZ];
+ char mime_partnum[SIZ];
+ char mime_filename[SIZ];
+ char mime_content_type[SIZ];
+ char mime_disposition[SIZ];
+ int mime_length;
+ char vcard_partnum[SIZ];
+ StrBuf *vcard_source = NULL;
+ int i, len;
+ message_summary summ;/// TODO this will lak
+
+ if (namebuf == NULL) return;
+
+ memset(&summ, 0, sizeof(summ));
+ //////safestrncpy(summ.subj, "(no subject)", sizeof summ.subj);
+
+ serv_printf(buf, "MSG0 %ld|0", Msg->msgnum); /** unfortunately we need the mime info now */
+ serv_getln(buf, sizeof buf);
+ if (buf[0] != '1') return;
+
+ while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
+ if (!strncasecmp(buf, "part=", 5)) {
+ extract_token(mime_filename, &buf[5], 1, '|', sizeof mime_filename);
+ extract_token(mime_partnum, &buf[5], 2, '|', sizeof mime_partnum);
+ extract_token(mime_disposition, &buf[5], 3, '|', sizeof mime_disposition);
+ extract_token(mime_content_type, &buf[5], 4, '|', sizeof mime_content_type);
+ mime_length = extract_int(&buf[5], 5);
+
+ if ( (!strcasecmp(mime_content_type, "text/x-vcard"))
+ || (!strcasecmp(mime_content_type, "text/vcard")) ) {
+ strcpy(vcard_partnum, mime_partnum);
+ }
+
+ }
+ }
+
+ if (!IsEmptyStr(vcard_partnum)) {
+ vcard_source = load_mimepart(Msg->msgnum, vcard_partnum);
+ if (vcard_source != NULL) {
+
+ /* Grab the name off the card */
+ display_vcard(WC->WBuf, vcard_source, 0, 0, namebuf, Msg->msgnum);
+
+ FreeStrBuf(&vcard_source);
+ }
+ }
+ if (*namebuf != NULL) {
+ lastfirst_firstlast(*namebuf);
+ striplt(*namebuf);
+ len = strlen(*namebuf);
+ for (i=0; i<len; ++i) {
+ if ((*namebuf)[i] != ';') return;
+ }
+ free (*namebuf);
+ (*namebuf) = strdup(_("(no name)"));
+ }
+ else {
+ (*namebuf) = strdup(_("(no name)"));
+ }
+}
+
+
/**
* \brief Turn a vCard "n" (name) field into something displayable.
* \param v the vcard to retrieve the name from
* \param storename where to put the name at
*/
-void fetchname_parsed_vcard(struct vCard *v, char *storename) {
+void fetchname_parsed_vcard(struct vCard *v, char **storename) {
char *name;
+ char *prop;
+ char buf[SIZ];
+ int j, n, len;
+ int is_qp = 0;
+ int is_b64 = 0;
- strcpy(storename, "");
+ *storename = NULL;
name = vcard_get_prop(v, "n", 1, 0, 0);
if (name != NULL) {
- strcpy(storename, name);
+ len = strlen(name);
+ prop = vcard_get_prop(v, "n", 1, 0, 1);
+ n = num_tokens(prop, ';');
+
+ for (j=0; j<n; ++j) {
+ extract_token(buf, prop, j, ';', sizeof buf);
+ if (!strcasecmp(buf, "encoding=quoted-printable")) {
+ is_qp = 1;
+ }
+ if (!strcasecmp(buf, "encoding=base64")) {
+ is_b64 = 1;
+ }
+ }
+ if (is_qp) {
+ // %ff can become 6 bytes in utf8
+ *storename = malloc(len * 2 + 3);
+ j = CtdlDecodeQuotedPrintable(
+ *storename, name,
+ len);
+ (*storename)[j] = 0;
+ }
+ else if (is_b64) {
+ // ff will become one byte..
+ *storename = malloc(len + 50);
+ CtdlDecodeBase64(
+ *storename, name,
+ len);
+ }
+ else {
+ *storename = strdup(name);
+ }
/* vcard_n_prettyize(storename); */
}
* \param storename where to store???
* \param msgnum Citadel message pointer
*/
-void display_vcard(StrBuf *Target, const char *vcard_source, char alpha, int full, char *storename,
- long msgnum) {
+void display_vcard(StrBuf *Target,
+ StrBuf *vcard_source,
+ char alpha,
+ int full,
+ char **storename,
+ long msgnum)
+{
struct vCard *v;
char *name;
- char buf[SIZ];
+ StrBuf *Buf;
+ StrBuf *Buf2;
char this_alpha = 0;
- v = vcard_load((char*)vcard_source); ///TODO
+ v = VCardLoad(vcard_source);
if (v == NULL) return;
name = vcard_get_prop(v, "n", 1, 0, 0);
if (name != NULL) {
- utf8ify_rfc822_string(name);
- strcpy(buf, name);
- this_alpha = buf[0];
+ Buf = NewStrBufPlain(name, -1);
+ Buf2 = NewStrBufPlain(NULL, StrLength(Buf));
+ StrBuf_RFC822_to_Utf8(Buf2, Buf, WC->DefaultCharset, NULL);
+ this_alpha = ChrPtr(Buf)[0];
+ FreeStrBuf(&Buf);
+ FreeStrBuf(&Buf2);
}
if (storename != NULL) {
* 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, char *return_to, char *force_room) {
+void do_edit_vcard(long msgnum, char *partnum,
+ message_summary *VCMsg,
+ wc_mime_attachment *VCAtt,
+ char *return_to,
+ const char *force_room) {
+ StrBuf *Buf;
char buf[SIZ];
- char *serialized_vcard = NULL;
size_t total_len = 0;
struct vCard *v;
int i;
safestrncpy(whatuser, "", sizeof whatuser);
- if (msgnum >= 0) {
- sprintf(buf, "MSG0 %ld|1", msgnum);
- serv_puts(buf);
- serv_getln(buf, sizeof buf);
- if (buf[0] != '1') {
- convenience_page("770000", _("Error"), &buf[4]);
- return;
- }
- while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
- if (!strncasecmp(buf, "from=", 5)) {
- safestrncpy(whatuser, &buf[5], sizeof whatuser);
+ if ((msgnum >= 0) ||
+ ((VCMsg != NULL) && (VCAtt != NULL)))
+ {
+ if ((VCMsg == NULL) && (VCAtt == NULL)) {
+ sprintf(buf, "MSG0 %ld|1", msgnum);
+ serv_puts(buf);
+ serv_getln(buf, sizeof buf);
+ if (buf[0] != '1') {
+ convenience_page("770000", _("Error"), &buf[4]);
+ return;
}
- else if (!strncasecmp(buf, "node=", 5)) {
- strcat(whatuser, " @ ");
- strcat(whatuser, &buf[5]);
+ while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
+ if (!strncasecmp(buf, "from=", 5)) {
+ safestrncpy(whatuser, &buf[5], sizeof whatuser);
+ }
+ else if (!strncasecmp(buf, "node=", 5)) {
+ strcat(whatuser, " @ ");
+ strcat(whatuser, &buf[5]);
+ }
+ }
+ Buf = NewStrBuf();
+ serv_printf(buf, "DLAT %ld|%s", msgnum, partnum);
+ StrBuf_ServGetlnBuffered(Buf);
+ if (GetServerStatus(Buf, NULL) != 6) {
+ convenience_page("770000", "Error", &(ChrPtr(Buf)[4]));
+ return;
}
+
+ StrBufCutLeft(Buf, 4);
+ total_len = StrBufExtract_long(Buf, 0, '|');
+
+ StrBuf_ServGetBLOBBuffered(Buf, total_len);
+
+ v = VCardLoad(Buf);
}
-
- sprintf(buf, "DLAT %ld|%s", msgnum, partnum);
- serv_puts(buf);
- serv_getln(buf, sizeof buf);
- if (buf[0] != '6') {
- convenience_page("770000", "Error", &buf[4]);
- return;
+ else {
+ v = VCardLoad(VCAtt->Data);
}
-
- total_len = atoi(&buf[4]);
- serialized_vcard = malloc(total_len + 2);
-
- serv_read(serialized_vcard, total_len);
- serialized_vcard[total_len] = 0;
-
- v = vcard_load(serialized_vcard);
- free(serialized_vcard);
+ FreeStrBuf(&Buf);
/* Populate the variables for our form */
i = 0;
while (key = vcard_get_prop(v, "", 0, i, 1), key != NULL) {
+ char prp[256]; /* property name */
+ char prm[256]; /* parameters */
+
value = vcard_get_prop(v, "", 0, i++, 0);
-
- if (!strcasecmp(key, "n")) {
+
+
+ extract_token(prp, key, 0, ';', sizeof prp);
+ safestrncpy(prm, key, sizeof prm);
+ remove_token(prm, 0, ';');
+
+ if (!strcasecmp(prp, "n")) {
extract_token(lastname, value, 0, ';', sizeof lastname);
extract_token(firstname, value, 1, ';', sizeof firstname);
extract_token(middlename, value, 2, ';', sizeof middlename);
extract_token(suffix, value, 4, ';', sizeof suffix);
}
- else if (!strcasecmp(key, "fn")) {
+ else if (!strcasecmp(prp, "fn")) {
safestrncpy(fullname, value, sizeof fullname);
}
- else if (!strcasecmp(key, "title")) {
+ else if (!strcasecmp(prp, "title")) {
safestrncpy(title, value, sizeof title);
}
- else if (!strcasecmp(key, "org")) {
+ else if (!strcasecmp(prp, "org")) {
safestrncpy(org, value, sizeof org);
}
- else if ( (!strcasecmp(key, "adr")) || (!strncasecmp(key, "adr;", 4)) ) {
+ else if (!strcasecmp(prp, "adr")) {
extract_token(pobox, value, 0, ';', sizeof pobox);
extract_token(extadr, value, 1, ';', sizeof extadr);
extract_token(street, value, 2, ';', sizeof street);
extract_token(zipcode, value, 5, ';', sizeof zipcode);
extract_token(country, value, 6, ';', sizeof country);
}
-
- else if ( (!strcasecmp(key, "tel;home")) || (!strcasecmp(key, "tel;type=home")) ) {
- extract_token(hometel, value, 0, ';', sizeof hometel);
- }
-
- else if ( (!strcasecmp(key, "tel;work")) || (!strcasecmp(key, "tel;type=work")) ) {
- extract_token(worktel, value, 0, ';', sizeof worktel);
- }
-
- else if ( (!strcasecmp(key, "tel;fax")) || (!strcasecmp(key, "tel;type=fax")) ) {
- extract_token(faxtel, value, 0, ';', sizeof faxtel);
- }
-
- else if ( (!strcasecmp(key, "tel;cell")) || (!strcasecmp(key, "tel;type=cell")) ) {
- extract_token(mobiletel, value, 0, ';', sizeof mobiletel);
+
+ else if (!strcasecmp(prp, "tel")) {
+
+ if (bmstrcasestr(prm, "home")) {
+ extract_token(hometel, value, 0, ';', sizeof hometel);
+ }
+ else if (bmstrcasestr(prm, "work")) {
+ extract_token(worktel, value, 0, ';', sizeof worktel);
+ }
+ else if (bmstrcasestr(prm, "fax")) {
+ extract_token(faxtel, value, 0, ';', sizeof faxtel);
+ }
+ else if (bmstrcasestr(prm, "cell")) {
+ extract_token(mobiletel, value, 0, ';', sizeof mobiletel);
+ }
+ else { /* Missing or unknown type; put it in the home phone */
+ extract_token(hometel, value, 0, ';', sizeof hometel);
+ }
}
- else if ( (!strcasecmp(key, "email;internet"))
- || (!strcasecmp(key, "email;type=internet")) ) {
+ else if ( (!strcasecmp(prp, "email")) && (bmstrcasestr(prm, "internet")) ) {
if (primary_inetemail[0] == 0) {
safestrncpy(primary_inetemail, value, sizeof primary_inetemail);
}
strcat(other_inetemail, value);
}
}
-
+
+ /* Unrecognized properties are preserved here so we don't discard them
+ * just because the vCard was edited with WebCit.
+ */
else {
strcat(extrafields, key);
strcat(extrafields, ":");
msgnum = lbstr("msgnum");
partnum = bstr("partnum");
- do_edit_vcard(msgnum, partnum, "", NULL);
+ do_edit_vcard(msgnum, partnum, NULL, NULL, "", NULL);
}
* parse edited vcard from the browser
*/
void submit_vcard(void) {
+ wcsession *WCC = WC;
struct vCard *v;
char *serialized_vcard;
char buf[SIZ];
+ StrBuf *Buf;
int i;
if (!havebstr("ok_button")) {
}
if (havebstr("force_room")) {
- gotoroom(bstr("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...
+ if (!strcmp(bstr("return_to"), "select_user_to_edit")) {
+ select_user_to_edit(NULL, NULL);
+ }
+ else if (!strcmp(bstr("return_to"), "do_welcome")) {
+ do_welcome();
+ }
+ else {
+ readloop(readnew);
+ }
+ return;
+ }
}
sprintf(buf, "ENT0 1|||4||");
}
/** Make a vCard structure out of the data supplied in the form */
-
- snprintf(buf, sizeof buf, "begin:vcard\r\n%s\r\nend:vcard\r\n",
- bstr("extrafields")
+ Buf = NewStrBuf();
+ StrBufPrintf(Buf, "begin:vcard\r\n%s\r\nend:vcard\r\n",
+ bstr("extrafields")
);
- v = vcard_load(buf); /** Start with the extra fields */
+ v = VCardLoad(Buf); /** Start with the extra fields */
+ FreeStrBuf(&Buf);
if (v == NULL) {
- safestrncpy(WC->ImportantMessage,
+ safestrncpy(WCC->ImportantMessage,
_("An error has occurred."),
- sizeof WC->ImportantMessage
+ sizeof WCC->ImportantMessage
);
edit_vcard();
return;
serialized_vcard = vcard_serialize(v);
vcard_free(v);
if (serialized_vcard == NULL) {
- safestrncpy(WC->ImportantMessage,
+ safestrncpy(WCC->ImportantMessage,
_("An error has occurred."),
- sizeof WC->ImportantMessage
+ sizeof WCC->ImportantMessage
);
edit_vcard();
return;
+/*
+ * 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;
+ wcsession *WCC = WC;
+
+ msgnum = StrTol(WCC->UrlFragment2);
+
+ 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);
+
+ 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"));
+ end_burst();
+ return;
+ }
+ contentType = GuessMimeType(ChrPtr(WCC->WBuf), StrLength(WCC->WBuf));
+ http_transmit_thing(contentType, 0);
+ free(v);
+ free(photosrc);
+}
+
+
+
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);
}