X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcvcard.c;h=dad057e1f3a038671e8c2b6c67adce3d1672940f;hb=40f8443d8d3a6577336ee66d18e04d9ac4d956bb;hp=37522e78a922d9837a62f0512bc39d6c2e4da6ef;hpb=abd71ec283745b783d98f6c55a596d328e09eb1d;p=silc.git diff --git a/lib/silcutil/silcvcard.c b/lib/silcutil/silcvcard.c index 37522e78..dad057e1 100644 --- a/lib/silcutil/silcvcard.c +++ b/lib/silcutil/silcvcard.c @@ -1,10 +1,10 @@ /* - silcvcard.c + silcvcard.c Author: Pekka Riikonen - Copyright (C) 2002 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 @@ -19,7 +19,7 @@ /* $Id$ */ /* Implementation of the VCard (RFC 2426) */ -#include "silcincludes.h" +#include "silc.h" #define VCARD_HEADER "BEGIN:VCARD\n" #define VCARD_VERSION "VERSION:3.0\n" @@ -43,44 +43,44 @@ unsigned char *silc_vcard_encode(SilcVCard vcard, SilcUInt32 *vcard_len) "FN:", vcard->full_name, "\n", "N:", vcard->family_name, ";", vcard->first_name, ";", vcard->middle_names, ";", vcard->prefix, ";", vcard->suffix, "\n", - SILC_STR_END); + SILC_STRFMT_END); if (vcard->nickname) silc_buffer_strformat(&buffer, "NICKNAME:", vcard->nickname, "\n", - SILC_STR_END); + SILC_STRFMT_END); if (vcard->bday) silc_buffer_strformat(&buffer, "BDAY:", vcard->bday, "\n", - SILC_STR_END); + SILC_STRFMT_END); if (vcard->title) silc_buffer_strformat(&buffer, "TITLE:", vcard->title, "\n", - SILC_STR_END); + SILC_STRFMT_END); if (vcard->role) silc_buffer_strformat(&buffer, "ROLE:", vcard->role, "\n", - SILC_STR_END); + SILC_STRFMT_END); if (vcard->org_name) silc_buffer_strformat(&buffer, "ORG:", vcard->org_name, ";", vcard->org_unit, "\n", - SILC_STR_END); + SILC_STRFMT_END); if (vcard->categories) silc_buffer_strformat(&buffer, "CATEGORIES:", vcard->categories, "\n", - SILC_STR_END); - if (vcard->class) + SILC_STRFMT_END); + if (vcard->catclass) silc_buffer_strformat(&buffer, - "CLASS:", vcard->class, "\n", - SILC_STR_END); + "CLASS:", vcard->catclass, "\n", + SILC_STRFMT_END); if (vcard->url) silc_buffer_strformat(&buffer, "URL:", vcard->url, "\n", - SILC_STR_END); + SILC_STRFMT_END); if (vcard->label) silc_buffer_strformat(&buffer, "LABEL;", vcard->url, "\n", - SILC_STR_END); + SILC_STRFMT_END); for (i = 0; i < vcard->num_addrs; i++) { silc_buffer_strformat(&buffer, "ADR;TYPE=", @@ -92,35 +92,35 @@ unsigned char *silc_vcard_encode(SilcVCard vcard, SilcUInt32 *vcard_len) vcard->addrs[i].state, ";", vcard->addrs[i].code, ";", vcard->addrs[i].country, "\n", - SILC_STR_END); + SILC_STRFMT_END); } for (i = 0; i < vcard->num_tels; i++) { silc_buffer_strformat(&buffer, "TEL;TYPE=", vcard->tels[i].type, ":", - vcard->tels[i].tel, "\n", - SILC_STR_END); + 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_STR_END); + SILC_STRFMT_END); } if (vcard->note) silc_buffer_strformat(&buffer, "NOTE:", vcard->note, "\n", - SILC_STR_END); + SILC_STRFMT_END); if (vcard->rev) silc_buffer_strformat(&buffer, "REV:", vcard->rev, "\n", - SILC_STR_END); + SILC_STRFMT_END); - silc_buffer_strformat(&buffer, VCARD_FOOTER, SILC_STR_END); + silc_buffer_strformat(&buffer, VCARD_FOOTER, SILC_STRFMT_END); if (vcard_len) - *vcard_len = buffer.truelen; + *vcard_len = silc_buffer_truelen(&buffer); return buffer.head; } @@ -137,8 +137,8 @@ unsigned char *silc_vcard_encode(SilcVCard vcard, SilcUInt32 *vcard_len) type also without TYPE= as it is possible */ #define VCARD_TYPETOKEN(x) \ if (!(x)) { \ - int tmpi = 0; \ - if (!strcasecmp(val + off, "TYPE=")) \ + 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; \ @@ -153,15 +153,28 @@ unsigned char *silc_vcard_encode(SilcVCard vcard, SilcUInt32 *vcard_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 */ -bool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, +SilcBool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, SilcVCard vcard) { unsigned char *val; - bool has_begin = FALSE, has_end = FALSE; + SilcBool has_begin = FALSE, has_end = FALSE; int len, i, off = 0; - + val = (unsigned char *)data; while (val) { len = 0; @@ -174,14 +187,32 @@ bool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, 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; - } else if (!strncasecmp(val, "FN:", 3)) { - if (vcard->full_name) - break; - if (len - 3) - vcard->full_name = silc_memdup(val + 3, len - 3); - } else if (!strncasecmp(val, "N:", 2)) { + 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) { @@ -203,27 +234,10 @@ bool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, VCARD_LASTTOKEN(vcard->suffix); } } - } else if (!strncasecmp(val, "NICKNAME:", 9)) { - if (vcard->nickname) - continue; - if (len - 9) - vcard->nickname = silc_memdup(val + 9, len - 9); - } else if (!strncasecmp(val, "BDAY:", 5)) { - if (vcard->bday) - continue; - if (len - 5) - vcard->bday = silc_memdup(val + 5, len - 5); - } else if (!strncasecmp(val, "TITLE:", 6)) { - if (vcard->title) - continue; - if (len - 6) - vcard->title = silc_memdup(val + 6, len - 6); - } else if (!strncasecmp(val, "ROLE:", 5)) { - if (vcard->role) - continue; - if (len - 5) - vcard->role = silc_memdup(val + 5, len - 5); - } else if (!strncasecmp(val, "ORG:", 4)) { + goto next; + } + + if (!strncasecmp(val, "ORG:", 4)) { if (vcard->org_name) continue; if (len - 4) { @@ -241,27 +255,10 @@ bool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, VCARD_LASTTOKEN(vcard->org_unit); } } - } else if (!strncasecmp(val, "CATEGORIES:", 11)) { - if (vcard->categories) - continue; - if (len - 11) - vcard->categories = silc_memdup(val + 11, len - 11); - } else if (!strncasecmp(val, "CLASS:", 6)) { - if (vcard->class) - continue; - if (len - 6) - vcard->class = silc_memdup(val + 6, len - 6); - } else if (!strncasecmp(val, "URL:", 4)) { - if (vcard->url) - continue; - if (len - 4) - vcard->url = silc_memdup(val + 4, len - 4); - } else if (!strncasecmp(val, "LABEL;", 6)) { - if (vcard->label) - continue; - if (len - 6) - vcard->label = silc_memdup(val + 6, len - 6); - } else if (!strncasecmp(val, "ADR;", 4)) { + 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)); @@ -280,7 +277,10 @@ bool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, VCARD_LASTTOKEN(vcard->addrs[vcard->num_addrs].country); } vcard->num_addrs++; - } else if (!strncasecmp(val, "TEL;", 4)) { + 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)); @@ -292,10 +292,13 @@ bool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, VCARD_TYPETOKEN(vcard->tels[vcard->num_tels].type); break; } - VCARD_LASTTOKEN(vcard->tels[vcard->num_tels].tel); + VCARD_LASTTOKEN(vcard->tels[vcard->num_tels].telnum); } vcard->num_tels++; - } else if (!strncasecmp(val, "EMAIL;", 6)) { + 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)); @@ -310,30 +313,19 @@ bool silc_vcard_decode(const unsigned char *data, SilcUInt32 data_len, VCARD_LASTTOKEN(vcard->emails[vcard->num_emails].address); } vcard->num_emails++; - } else if (!strncasecmp(val, "NOTE:", 5)) { - if (vcard->note) - continue; - if (len - 5) - vcard->note = silc_memdup(val + 5, len - 5); - } else if (!strncasecmp(val, "REV:", 4)) { - if (vcard->rev) - continue; - if (len - 4) - vcard->rev = silc_memdup(val + 4, len - 4); - } else if (!strncasecmp(val, VCARD_FOOTER, strlen(VCARD_FOOTER))) { - has_end = TRUE; - break; + goto next; } + next: val = strchr(val, '\n'); - if (!val || !(*val)) + if (!val) break; val++; if (!val || !(*val)) break; } - if (!has_begin || !has_end) { + if (!has_begin || !has_end || !vcard->full_name) { silc_vcard_free(vcard); return FALSE; } @@ -371,7 +363,7 @@ void silc_vcard_free(SilcVCard vcard) silc_free(vcard->org_name); silc_free(vcard->org_unit); silc_free(vcard->categories); - silc_free(vcard->class); + silc_free(vcard->catclass); silc_free(vcard->url); silc_free(vcard->label); for (i = 0; i < vcard->num_addrs; i++) { @@ -387,7 +379,7 @@ void silc_vcard_free(SilcVCard vcard) silc_free(vcard->addrs); for (i = 0; i < vcard->num_tels; i++) { silc_free(vcard->tels[i].type); - silc_free(vcard->tels[i].tel); + silc_free(vcard->tels[i].telnum); } silc_free(vcard->tels); for (i = 0; i < vcard->num_emails; i++) { @@ -435,8 +427,8 @@ void silc_vcard_fprintf(SilcVCard vcard, FILE *stream) vcard->org_unit ? vcard->org_unit : ""); if (vcard->categories) fprintf(stream, "CATEGORIES:%s\n", vcard->categories); - if (vcard->class) - fprintf(stream, "CLASS:%s\n", vcard->class); + if (vcard->catclass) + fprintf(stream, "CLASS:%s\n", vcard->catclass); if (vcard->url) fprintf(stream, "URL:%s\n", vcard->url); if (vcard->label) @@ -455,7 +447,7 @@ void silc_vcard_fprintf(SilcVCard vcard, FILE *stream) for (i = 0; i < vcard->num_tels; i++) { fprintf(stream, "TEL;TYPE=%s:%s\n", vcard->tels[i].type, - vcard->tels[i].tel ? vcard->tels[i].tel : ""); + vcard->tels[i].telnum ? vcard->tels[i].telnum : ""); } for (i = 0; i < vcard->num_emails; i++) { fprintf(stream, "EMAIL;TYPE=%s:%s\n",