From e913d1cdffaceed9d4ebe1ab85cacd9afe93c20b Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Wed, 20 Sep 2006 21:16:30 +0000 Subject: [PATCH] Added lib/silcvcard/ --- lib/Makefile.ad | 15 +- lib/configure.ad | 9 + lib/silcutil/DIRECTORY | 1 - lib/silcutil/Makefile.ad | 2 - lib/silcvcard/DIRECTORY | 21 ++ lib/silcvcard/Makefile.ad | 34 +++ lib/silcvcard/silcvcard.c | 463 ++++++++++++++++++++++++++++++++++++++ lib/silcvcard/silcvcard.h | 181 +++++++++++++++ 8 files changed, 720 insertions(+), 6 deletions(-) create mode 100644 lib/silcvcard/DIRECTORY create mode 100644 lib/silcvcard/Makefile.ad create mode 100644 lib/silcvcard/silcvcard.c create mode 100644 lib/silcvcard/silcvcard.h diff --git a/lib/Makefile.ad b/lib/Makefile.ad index 944bdc54..4622541c 100644 --- a/lib/Makefile.ad +++ b/lib/Makefile.ad @@ -39,7 +39,16 @@ SILCLIB_DIRS = \ #ifdef SILC_DIST_ASN1 silcasn1 \ #endif SILC_DIST_ASN1 - silcske + silcske \ +#ifdef SILC_DIST_HTTP + silchttp \ +#endif SILC_DIST_HTTP +#ifdef SILC_DIST_IDCACHE + silcidcache \ +#endif SILC_DIST_IDCACHE +#ifdef SILC_DIST_IDCACHE + silcvcard \ +#endif SILC_DIST_IDCACHE SILCLIB = libsilc.a @@ -55,7 +64,7 @@ SILCSERVERLIB_DIRS = silcserver SILCSERVERLIB = libsilcserver.a #endif SILC_DIST_SERVERLIB -SUBDIRS = $(SILCLIB_DIRS) $(SILCSERVERLIB_DIRS) ###$(SILCCLIENTLIB_DIRS) +SUBDIRS = $(SILCLIB_DIRS) $(SILCSERVERLIB_DIRS) $(SILCCLIENTLIB_DIRS) CLEANFILES = libsilc.a libsilcclient.a libsilcserver.a DISTCLEANFILES = libsilc.a libsilcclient.a libsilcserver.a @@ -65,7 +74,7 @@ remove: -rm -f libsilcclient.a -rm -f libsilcserver.a -all: remove $(SILCLIB) $(SILCSERVERLIB) ###$(SILCCLIENTLIB) +all: remove $(SILCLIB) $(SILCSERVERLIB) $(SILCCLIENTLIB) #ifdef SILC_DIST_TOOLKIT install-exec-hook: diff --git a/lib/configure.ad b/lib/configure.ad index 7db18ac0..c065b9b7 100644 --- a/lib/configure.ad +++ b/lib/configure.ad @@ -56,6 +56,9 @@ SILC_LIB_INCLUDES="$SILC_LIB_INCLUDES -I$SILC_TOP_SRCDIR/lib/silchttp" #ifdef SILC_DIST_IDCACHE SILC_LIB_INCLUDES="$SILC_LIB_INCLUDES -I$SILC_TOP_SRCDIR/lib/silcidcache" #endif SILC_DIST_IDCACHE +#ifdef SILC_DIST_VCARD +SILC_LIB_INCLUDES="$SILC_LIB_INCLUDES -I$SILC_TOP_SRCDIR/lib/silcvcard" +#endif SILC_DIST_VCARD ## ## Library versioning. @@ -225,6 +228,12 @@ lib/silcidcache/Makefile ) #endif SILC_DIST_IDCACHE +#ifdef SILC_DIST_VCARD +AC_CONFIG_FILES( +lib/silcvcard/Makefile +) +#endif SILC_DIST_VCARD + fi # compile_libs #endif SILC_DIST_LIB diff --git a/lib/silcutil/DIRECTORY b/lib/silcutil/DIRECTORY index abe7f837..79b2020f 100644 --- a/lib/silcutil/DIRECTORY +++ b/lib/silcutil/DIRECTORY @@ -23,7 +23,6 @@ @LINK=silcutil.html:SILC Util Interface @LINK=silclist.html:SILC List Interface @LINK=silcdlist.html:SILC Dynamic List Interface -@LINK=silcvcard.html:SILC VCard Interface @LINK=silcapputil.html:SILC Application Utilities --> diff --git a/lib/silcutil/Makefile.ad b/lib/silcutil/Makefile.ad index 3037fe24..fc3db585 100644 --- a/lib/silcutil/Makefile.ad +++ b/lib/silcutil/Makefile.ad @@ -56,7 +56,6 @@ libsilcutil_la_SOURCES = \ silcstrutil.c \ silcutil.c \ silchashtable.c \ - silcvcard.c \ silcapputil.c \ silcutf8.c \ silcstringprep.c \ @@ -89,7 +88,6 @@ include_HEADERS = \ silcfileutil.h \ silcutil.h \ silcstrutil.h \ - silcvcard.h \ silcapputil.h \ silcutf8.h \ silcstringprep.h \ diff --git a/lib/silcvcard/DIRECTORY b/lib/silcvcard/DIRECTORY new file mode 100644 index 00000000..da9710c0 --- /dev/null +++ b/lib/silcvcard/DIRECTORY @@ -0,0 +1,21 @@ + + +SILC VCard Library +
+Directory: lib/silcvcard/ +
+Library: libvcard.a, libvcard.lib +

+Introduction + +

+SILC VCard Library provides interface for creating and processing VCards, +defined in the RFC 2426. The VCard 3.0 standard is implemented by the +library. + +

+@LINKS@ diff --git a/lib/silcvcard/Makefile.ad b/lib/silcvcard/Makefile.ad new file mode 100644 index 00000000..8e34c695 --- /dev/null +++ b/lib/silcvcard/Makefile.ad @@ -0,0 +1,34 @@ +# +# Makefile.ad +# +# Author: Pekka Riikonen +# +# Copyright (C) 2006 Pekka Riikonen +# +# This program is free 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; version 2 of the License. +# +# 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. +# + +AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign + +noinst_LTLIBRARIES = libsilcvcard.la + +libsilcvcard_la_SOURCES = \ + silcvcard.c + +#ifdef SILC_DIST_TOOLKIT +include_HEADERS = \ + silcvcard.h + +#SILC_EXTRA_DIST = tests +#endif SILC_DIST_TOOLKIT + +EXTRA_DIST = *.h $(SILC_EXTRA_DIST) + +include $(top_srcdir)/Makefile.defines.in diff --git a/lib/silcvcard/silcvcard.c b/lib/silcvcard/silcvcard.c new file mode 100644 index 00000000..dad057e1 --- /dev/null +++ b/lib/silcvcard/silcvcard.c @@ -0,0 +1,463 @@ +/* + + silcvcard.c + + Author: Pekka Riikonen + + Copyright (C) 2002 - 2005 Pekka Riikonen + + This program is free 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; version 2 of the License. + + 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. + +*/ +/* $Id$ */ +/* Implementation of the VCard (RFC 2426) */ + +#include "silc.h" + +#define VCARD_HEADER "BEGIN:VCARD\n" +#define VCARD_VERSION "VERSION:3.0\n" +#define VCARD_FOOTER "END:VCARD\n" + +/* Encode VCard */ + +unsigned char *silc_vcard_encode(SilcVCard vcard, SilcUInt32 *vcard_len) +{ + SilcBufferStruct buffer; + int i; + + if (!vcard->full_name || !vcard->family_name || !vcard->first_name) + return NULL; + + memset(&buffer, 0, sizeof(buffer)); + silc_buffer_strformat( + &buffer, + VCARD_HEADER, + VCARD_VERSION, + "FN:", vcard->full_name, "\n", + "N:", vcard->family_name, ";", vcard->first_name, ";", + vcard->middle_names, ";", vcard->prefix, ";", vcard->suffix, "\n", + SILC_STRFMT_END); + + if (vcard->nickname) + silc_buffer_strformat(&buffer, + "NICKNAME:", vcard->nickname, "\n", + SILC_STRFMT_END); + if (vcard->bday) + silc_buffer_strformat(&buffer, + "BDAY:", vcard->bday, "\n", + SILC_STRFMT_END); + if (vcard->title) + silc_buffer_strformat(&buffer, + "TITLE:", vcard->title, "\n", + SILC_STRFMT_END); + if (vcard->role) + silc_buffer_strformat(&buffer, + "ROLE:", vcard->role, "\n", + SILC_STRFMT_END); + if (vcard->org_name) + silc_buffer_strformat(&buffer, + "ORG:", vcard->org_name, ";", vcard->org_unit, "\n", + SILC_STRFMT_END); + if (vcard->categories) + silc_buffer_strformat(&buffer, + "CATEGORIES:", vcard->categories, "\n", + SILC_STRFMT_END); + if (vcard->catclass) + silc_buffer_strformat(&buffer, + "CLASS:", vcard->catclass, "\n", + SILC_STRFMT_END); + if (vcard->url) + silc_buffer_strformat(&buffer, + "URL:", vcard->url, "\n", + SILC_STRFMT_END); + if (vcard->label) + silc_buffer_strformat(&buffer, + "LABEL;", vcard->url, "\n", + SILC_STRFMT_END); + for (i = 0; i < vcard->num_addrs; i++) { + silc_buffer_strformat(&buffer, + "ADR;TYPE=", + vcard->addrs[i].type, ":", + vcard->addrs[i].pbox, ";", + vcard->addrs[i].ext_addr, ";", + vcard->addrs[i].street_addr, ";", + vcard->addrs[i].city, ";", + vcard->addrs[i].state, ";", + vcard->addrs[i].code, ";", + vcard->addrs[i].country, "\n", + SILC_STRFMT_END); + } + for (i = 0; i < vcard->num_tels; i++) { + silc_buffer_strformat(&buffer, + "TEL;TYPE=", + vcard->tels[i].type, ":", + vcard->tels[i].telnum, "\n", + SILC_STRFMT_END); + } + for (i = 0; i < vcard->num_emails; i++) { + silc_buffer_strformat(&buffer, + "EMAIL;TYPE=", + vcard->emails[i].type, ":", + vcard->emails[i].address, "\n", + SILC_STRFMT_END); + } + if (vcard->note) + silc_buffer_strformat(&buffer, + "NOTE:", vcard->note, "\n", + SILC_STRFMT_END); + if (vcard->rev) + silc_buffer_strformat(&buffer, + "REV:", vcard->rev, "\n", + SILC_STRFMT_END); + + silc_buffer_strformat(&buffer, VCARD_FOOTER, SILC_STRFMT_END); + + if (vcard_len) + *vcard_len = silc_buffer_truelen(&buffer); + + return buffer.head; +} + +/* Take one token */ +#define VCARD_TOKEN(x) \ + if (!(x)) { \ + (x) = silc_memdup(val + off, i - off); \ + off = i + 1; \ + continue; \ + } + +/* Take on TYPE= token and prepare for next token, accept the + type also without TYPE= as it is possible */ +#define VCARD_TYPETOKEN(x) \ + if (!(x)) { \ + int tmpi = 0; \ + if (!strncasecmp(val + off, "TYPE=", 5)) \ + tmpi = 5; \ + (x) = silc_memdup(val + off + tmpi, i - off - tmpi - 1); \ + tmpi = off + tmpi + strlen((x)) + 1; \ + off = i; \ + i = tmpi; \ + } + +/* Take last token */ +#define VCARD_LASTTOKEN(x) \ + if (!(x)) { \ + if (off < len) \ + (x) = silc_memdup(val + off, len - off); \ + } \ + +/* Get one (single) field */ +#define VCARD_FIELD(val, c, x) \ +do { \ + if (!strncasecmp(val, (c), strlen((c)))) { \ + int tmpl = strlen((c)); \ + if ((x)) \ + break; \ + if (len - tmpl > 0) \ + (x) = silc_memdup(val + tmpl, len - tmpl); \ + goto next; \ + } \ +} while(0) + +/* Decode VCard */ + +SilcBool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, + SilcVCard vcard) +{ + unsigned char *val; + SilcBool has_begin = FALSE, has_end = FALSE; + int len, i, off = 0; + + val = (unsigned char *)data; + while (val) { + len = 0; + for (i = (val - data); i < data_len; i++) { + if (data[i] == '\0' || data[i] == '\n') { + len = i - (val - data); + break; + } + } + if (!len || len > data_len - (val - data)) + break; + + /* Check for mandatory header and footer */ + if (!strncasecmp(val, VCARD_HEADER, strlen(VCARD_HEADER))) { + has_begin = TRUE; + goto next; + } + if (!strncasecmp(val, VCARD_FOOTER, strlen(VCARD_FOOTER))) { + has_end = TRUE; + goto next; + } + + /* Get single fields */ + VCARD_FIELD(val, "FN:", vcard->full_name); + VCARD_FIELD(val, "NICKNAME:", vcard->nickname); + VCARD_FIELD(val, "BDAY:", vcard->bday); + VCARD_FIELD(val, "TITLE:", vcard->title); + VCARD_FIELD(val, "ROLE:", vcard->role); + VCARD_FIELD(val, "CATEGORIES:", vcard->categories); + VCARD_FIELD(val, "CLASS:", vcard->catclass); + VCARD_FIELD(val, "URL:", vcard->url); + VCARD_FIELD(val, "LABEL;", vcard->label); + VCARD_FIELD(val, "NOTE:", vcard->note); + VCARD_FIELD(val, "REV:", vcard->rev); + + /* Get multi-column fields */ + + if (!strncasecmp(val, "N:", 2)) { + if (vcard->family_name) + break; + if (len - 2) { + off = 2; + for (i = off; i < len; i++) + if (val[i] == ';') { + VCARD_TOKEN(vcard->family_name); + VCARD_TOKEN(vcard->first_name); + VCARD_TOKEN(vcard->middle_names); + VCARD_TOKEN(vcard->prefix); + } + if (!vcard->family_name && !vcard->first_name) { + VCARD_LASTTOKEN(vcard->family_name); + off += (len - off); + } + if (!vcard->first_name) { + VCARD_LASTTOKEN(vcard->first_name); + } else { + VCARD_LASTTOKEN(vcard->suffix); + } + } + goto next; + } + + if (!strncasecmp(val, "ORG:", 4)) { + if (vcard->org_name) + continue; + if (len - 4) { + off = 4; + for (i = off; i < len; i++) { + if (val[i] == ';') { + VCARD_TOKEN(vcard->org_name); + break; + } + } + /* It's possible to have ORG without last ';', so check for it */ + if (!vcard->org_name) { + VCARD_LASTTOKEN(vcard->org_name); + } else { + VCARD_LASTTOKEN(vcard->org_unit); + } + } + goto next; + } + + if (!strncasecmp(val, "ADR;", 4)) { + vcard->addrs = silc_realloc(vcard->addrs, sizeof(*vcard->addrs) * + (vcard->num_addrs + 1)); + memset(&vcard->addrs[vcard->num_addrs], 0, sizeof(*vcard->addrs)); + if (len - 4) { + off = 4; + for (i = off; i < len; i++) + if (val[i] == ';') { + VCARD_TYPETOKEN(vcard->addrs[vcard->num_addrs].type); + VCARD_TOKEN(vcard->addrs[vcard->num_addrs].pbox); + VCARD_TOKEN(vcard->addrs[vcard->num_addrs].ext_addr); + VCARD_TOKEN(vcard->addrs[vcard->num_addrs].street_addr); + VCARD_TOKEN(vcard->addrs[vcard->num_addrs].city); + VCARD_TOKEN(vcard->addrs[vcard->num_addrs].state); + VCARD_TOKEN(vcard->addrs[vcard->num_addrs].code); + } + VCARD_LASTTOKEN(vcard->addrs[vcard->num_addrs].country); + } + vcard->num_addrs++; + goto next; + } + + if (!strncasecmp(val, "TEL;", 4)) { + vcard->tels = silc_realloc(vcard->tels, sizeof(*vcard->tels) * + (vcard->num_tels + 1)); + memset(&vcard->tels[vcard->num_tels], 0, sizeof(*vcard->tels)); + if (len - 4) { + off = 4; + for (i = off; i < len; i++) + if (val[i] == ':') { + i++; + VCARD_TYPETOKEN(vcard->tels[vcard->num_tels].type); + break; + } + VCARD_LASTTOKEN(vcard->tels[vcard->num_tels].telnum); + } + vcard->num_tels++; + goto next; + } + + if (!strncasecmp(val, "EMAIL;", 6)) { + vcard->emails = silc_realloc(vcard->emails, sizeof(*vcard->emails) * + (vcard->num_emails + 1)); + memset(&vcard->emails[vcard->num_emails], 0, sizeof(*vcard->emails)); + if (len - 6) { + off = 6; + for (i = off; i < len; i++) + if (val[i] == ':') { + i++; + VCARD_TYPETOKEN(vcard->emails[vcard->num_emails].type); + break; + } + VCARD_LASTTOKEN(vcard->emails[vcard->num_emails].address); + } + vcard->num_emails++; + goto next; + } + + next: + val = strchr(val, '\n'); + if (!val) + break; + val++; + if (!val || !(*val)) + break; + } + + if (!has_begin || !has_end || !vcard->full_name) { + silc_vcard_free(vcard); + return FALSE; + } + + return TRUE; +} + +/* Allocate vcard context */ + +SilcVCard silc_vcard_alloc(void) +{ + SilcVCard vcard = silc_calloc(1, sizeof(*vcard)); + if (!vcard) + return NULL; + vcard->dynamic = TRUE; + return vcard; +} + +/* Free the vcard structure */ + +void silc_vcard_free(SilcVCard vcard) +{ + int i; + + silc_free(vcard->full_name); + silc_free(vcard->family_name); + silc_free(vcard->first_name); + silc_free(vcard->middle_names); + silc_free(vcard->prefix); + silc_free(vcard->suffix); + silc_free(vcard->nickname); + silc_free(vcard->bday); + silc_free(vcard->title); + silc_free(vcard->role); + silc_free(vcard->org_name); + silc_free(vcard->org_unit); + silc_free(vcard->categories); + silc_free(vcard->catclass); + silc_free(vcard->url); + silc_free(vcard->label); + for (i = 0; i < vcard->num_addrs; i++) { + silc_free(vcard->addrs[i].type); + silc_free(vcard->addrs[i].pbox); + silc_free(vcard->addrs[i].ext_addr); + silc_free(vcard->addrs[i].street_addr); + silc_free(vcard->addrs[i].city); + silc_free(vcard->addrs[i].state); + silc_free(vcard->addrs[i].code); + silc_free(vcard->addrs[i].country); + } + silc_free(vcard->addrs); + for (i = 0; i < vcard->num_tels; i++) { + silc_free(vcard->tels[i].type); + silc_free(vcard->tels[i].telnum); + } + silc_free(vcard->tels); + for (i = 0; i < vcard->num_emails; i++) { + silc_free(vcard->emails[i].type); + silc_free(vcard->emails[i].address); + } + silc_free(vcard->emails); + silc_free(vcard->note); + silc_free(vcard->rev); + if (!vcard->dynamic) + memset(vcard, 0, sizeof(*vcard)); + + if (vcard->dynamic) { + memset(vcard, 0, sizeof(*vcard)); + silc_free(vcard); + } +} + +/* Print card to file stream */ + +void silc_vcard_fprintf(SilcVCard vcard, FILE *stream) +{ + int i; + fprintf(stream, "%s", VCARD_HEADER); + fprintf(stream, "%s", VCARD_VERSION); + if (vcard->full_name) + fprintf(stream, "FN:%s\n", vcard->full_name); + if (vcard->family_name) + fprintf(stream, "N:%s;%s;%s;%s;%s\n", + vcard->family_name, + vcard->first_name ? vcard->first_name : "", + vcard->middle_names ? vcard->middle_names : "", + vcard->prefix ? vcard->prefix : "", + vcard->suffix ? vcard->suffix : ""); + if (vcard->nickname) + fprintf(stream, "NICKNAME:%s\n", vcard->nickname); + if (vcard->bday) + fprintf(stream, "BDAY:%s\n", vcard->bday); + if (vcard->title) + fprintf(stream, "TITLE:%s\n", vcard->title); + if (vcard->role) + fprintf(stream, "ROLE:%s\n", vcard->role); + if (vcard->org_name) + fprintf(stream, "ORG:%s;%s\n", vcard->org_name, + vcard->org_unit ? vcard->org_unit : ""); + if (vcard->categories) + fprintf(stream, "CATEGORIES:%s\n", vcard->categories); + if (vcard->catclass) + fprintf(stream, "CLASS:%s\n", vcard->catclass); + if (vcard->url) + fprintf(stream, "URL:%s\n", vcard->url); + if (vcard->label) + fprintf(stream, "LABEL;%s\n", vcard->label); + for (i = 0; i < vcard->num_addrs; i++) { + fprintf(stream, "ADR;TYPE=%s:%s;%s;%s;%s;%s;%s;%s\n", + vcard->addrs[i].type, + vcard->addrs[i].pbox ? vcard->addrs[i].pbox : "", + vcard->addrs[i].ext_addr ? vcard->addrs[i].ext_addr : "", + vcard->addrs[i].street_addr ? vcard->addrs[i].street_addr : "", + vcard->addrs[i].city ? vcard->addrs[i].city : "", + vcard->addrs[i].state ? vcard->addrs[i].state : "", + vcard->addrs[i].code ? vcard->addrs[i].code : "", + vcard->addrs[i].country ? vcard->addrs[i].country : ""); + } + for (i = 0; i < vcard->num_tels; i++) { + fprintf(stream, "TEL;TYPE=%s:%s\n", + vcard->tels[i].type, + vcard->tels[i].telnum ? vcard->tels[i].telnum : ""); + } + for (i = 0; i < vcard->num_emails; i++) { + fprintf(stream, "EMAIL;TYPE=%s:%s\n", + vcard->emails[i].type, + vcard->emails[i].address ? vcard->emails[i].address : ""); + } + if (vcard->note) + fprintf(stream, "NOTE:%s\n", vcard->note); + if (vcard->rev) + fprintf(stream, "REV:%s\n", vcard->rev); + fprintf(stream, "%s", VCARD_FOOTER); + fflush(stream); +} diff --git a/lib/silcvcard/silcvcard.h b/lib/silcvcard/silcvcard.h new file mode 100644 index 00000000..c71ebbab --- /dev/null +++ b/lib/silcvcard/silcvcard.h @@ -0,0 +1,181 @@ +/* + + silcvcard.h + + Author: Pekka Riikonen + + Copyright (C) 2002 Pekka Riikonen + + This program is free 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; version 2 of the License. + + 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. + +*/ + +/****h* silcvcard/SILC VCard + * + * DESCRIPTION + * + * Implementation of the VCard 3.0 standard (RFC 2426) that can be used + * with Requested Attributes (in WHOIS command) to deliver personal + * information. All fields are not supported since some of the + * information are not needed in context of SILC. If such VCard is + * received this implementation ignores the unsupported fields. + * + ***/ + +#ifndef SILCVCARD_H +#define SILCVCARD_H + +/****s* silcvcard/SilcVCard/SilcVCard + * + * NAME + * + * typedef struct { ... } SilcVCardStruct, *SilcVCard; + * + * DESCRIPTION + * + * This structure is the VCard. This holds the contents of the + * card. When a card is parsed it is parsed into this structure. + * When creating a new card application fills this structure and + * the library encodes the card from it. Free the allocated + * structure with silc_vcard_free function. + * + * SOURCE + */ +typedef struct { + char *full_name; /* full name, X.520 common name */ + char *family_name; /* last name, string */ + char *first_name; /* first name, string */ + char *middle_names; /* other names, string (comma sep.) */ + char *prefix; /* honorifix prefix (Mr., Mrs.), string */ + char *suffix; /* honorifix suffix (MD), string (comma sep.) */ + char *nickname; /* string (comma sep. if more than one) */ + char *bday; /* birth day, UTC date string */ + char *title; /* job title X.520, string */ + char *role; /* job role X.520, string */ + char *org_name; /* organization name, string */ + char *org_unit; /* organization unit, string */ + char *categories; /* application category, string */ + char *catclass; /* class (public, private, confidental), string */ + char *url; /* home page, URI string */ + char *label; /* formatted address label, string (same + format as for 'addr' but comma sep.) */ + + struct addr { + char *type; /* address type, string + (intl, dom, home, work, pref, postal, parcel) */ + char *pbox; /* post office box, string */ + char *ext_addr; /* extended address, string */ + char *street_addr; /* street address, string */ + char *city; /* city, string */ + char *state; /* state/province, string */ + char *code; /* postal code, string */ + char *country; /* country name, string */ + } *addrs; + SilcUInt8 num_addrs; /* number of addresses */ + + struct tel { + char *type; /* telephone number type, string + (msg, voice, home, work, pref, bbs, modem, car, + cell, video, pager, isdn, fax) */ + char *telnum; /* single telephone number, string */ + } *tels; + SilcUInt8 num_tels; + + struct email { + char *type; /* email type, string (internet, pref, x400) */ + char *address; /* single email address, string */ + } *emails; + SilcUInt8 num_emails; + + char *note; /* a note, string */ + char *rev; /* revision of card, UTC date string */ + + SilcBool dynamic; /* TRUE when dynamically allocated */ +} SilcVCardStruct, *SilcVCard; +/***/ + +/****f* silcvcard/SilcVCard/silc_vcard_encode + * + * SYNOPSIS + * + * char *silc_vcard_encode(SilcVCard vcard, SilcUInt32 *vcard_len); + * + * DESCRIPTION + * + * Encodes VCard from the SilcVCard structure indicated by `vcard' + * which the caller must fill before calling this function. This + * function encodes the card and returns allocated buffer and + * its length into `vcard_len'. The caller must free the returned + * buffer. Returns NULL on error. + * + ***/ +unsigned char *silc_vcard_encode(SilcVCard vcard, SilcUInt32 *vcard_len); + +/****f* silcvcard/SilcVCard/silc_vcard_decode + * + * SYNOPSIS + * + * SilcBool silc_vcard_decode(const unsigned char *data, + * SilcUInt32 data_len, SilcVCard vcard); + * + * DESCRIPTION + * + * Decodes VCard from the buffer `vcard' of length of `vcard_len' bytes + * and returns the parsed card into `vcard' structure. The caller must + * pre-allocate the structure. Returns TRUE if the `vcard' is valid + * vcard and was successfully parsed or FALSE on error. The structure + * is freed with silc_vcard_free function when it is not needed anymore. + * + ***/ +SilcBool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, + SilcVCard vcard); + +/****f* silcvcard/SilcVCard/silc_vcard_alloc + * + * SYNOPSIS + * + * SilcVCard silc_vcard_alloc(void); + * + * DESCRIPTION + * + * Allocate a SilcVCard context which must be freed with the + * silc_vcard_free function. + * + ***/ +SilcVCard silc_vcard_alloc(void); + +/****f* silcvcard/SilcVCard/silc_vcard_free + * + * SYNOPSIS + * + * void silc_vcard_free(SilcVCard vcard); + * + * DESCRIPTION + * + * Free VCard structure and all data in it. + * + ***/ +void silc_vcard_free(SilcVCard vcard); + +/****f* silcvcard/SilcVCard/silc_vcard_fprintf + * + * SYNOPSIS + * + * void silc_vcard_fprintf(SilcVCard vcard, FILE *stream); + * + * DESCRIPTION + * + * Prints the contents of the `vcard' into file stream `stream' in + * the correct VCard format. + * + ***/ +void silc_vcard_fprintf(SilcVCard vcard, FILE *stream); + +#endif /* SILCVCARD_H */ -- 2.24.0