X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fvcard.c;h=d236b00c5a2774cc7d8ae008fe884cf272450610;hb=694a3ea878536e2deda1c0168e51837a31b81af7;hp=f11d253b707c933b5f32ecfbb8e5ad3dd73405a2;hpb=3039e545aa96928937b0b380c24bfa8937f47d3f;p=citadel.git diff --git a/webcit/vcard.c b/webcit/vcard.c index f11d253b7..d236b00c5 100644 --- a/webcit/vcard.c +++ b/webcit/vcard.c @@ -1,42 +1,21 @@ /* * $Id$ - * - * vCard implementation for Citadel/UX - * - * Copyright (C) 1999 by Art Cancro + * Copyright (C) 1999-2006 by Art Cancro * This code is freely redistributable under the terms of the GNU General * Public License. All other rights reserved. */ - - -#include -#include -#include -#include -#include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#include -#include -#include -#include -#include - +/** + * \defgroup VCardMain vCard data type implementation for the Citadel system. + * \ingroup VCards + */ +/*@{*/ #include "webcit.h" +#include "webserver.h" #include "vcard.h" -/* - * Constructor (empty vCard) +/** + * \brief Constructor (empty vCard) + * \return an empty vcard */ struct vCard *vcard_new() { struct vCard *v; @@ -51,9 +30,53 @@ struct vCard *vcard_new() { return v; } +/** + * \brief Remove the "charset=" attribute from a vCard property name + * + * \param strbuf The property name string to be stripped + */ +void remove_charset_attribute(char *strbuf) +{ + int i, t; + char compare[256]; + + t = num_tokens(strbuf, ';'); + for (i=0; inumprops; v->prop = realloc(v->prop, - (v->numprops * sizeof(char *) * 2) ); + (v->numprops * sizeof(struct vCardProp)) + ); v->prop[v->numprops-1].name = namebuf; v->prop[v->numprops-1].value = valuebuf; } @@ -127,13 +158,19 @@ struct vCard *vcard_load(char *vtext) { } -/* - * Fetch the value of a particular key. +/** + * \brief Fetch the value of a particular key. * If is_partial is set to 1, a partial match is ok (for example, * a key of "tel;home" will satisfy a search for "tel"). * Set "instance" to a value higher than 0 to return subsequent instances * of the same key. * Set "get_propname" to nonzero to fetch the property name instead of value. + * \param v vCard to get keyvalue from + * \param propname key to retrieve + * \param is_partial dunno??? + * \param instance if >0 return a later token of the value + * \param get_propname if nonzero get the real property name??? + * \return the requested value / token / propertyname */ char *vcard_get_prop(struct vCard *v, char *propname, int is_partial, int instance, int get_propname) { @@ -164,8 +201,10 @@ char *vcard_get_prop(struct vCard *v, char *propname, -/* - * Destructor +/** + * \brief Destructor + * kill a vCard + * \param v the vCard to purge from memory */ void vcard_free(struct vCard *v) { int i; @@ -186,15 +225,19 @@ void vcard_free(struct vCard *v) { -/* - * Set a name/value pair in the card +/** + * \brief Set a name/value pair in the card + * \param v vCard to inspect + * \param name key to set + * \param value the value to assign to key + * \param append should we append the value to an existing one? */ void vcard_set_prop(struct vCard *v, char *name, char *value, int append) { int i; - if (v->magic != CTDL_VCARD_MAGIC) return; /* Self-check */ + if (v->magic != CTDL_VCARD_MAGIC) return; /** Self-check */ - /* If this key is already present, replace it */ + /** If this key is already present, replace it */ if (!append) if (v->numprops) for (i=0; i<(v->numprops); ++i) { if (!strcasecmp(v->prop[i].name, name)) { free(v->prop[i].name); @@ -205,10 +248,10 @@ void vcard_set_prop(struct vCard *v, char *name, char *value, int append) { } } - /* Otherwise, append it */ + /** Otherwise, append it */ ++v->numprops; v->prop = realloc(v->prop, - (v->numprops * sizeof(char *) * 2) ); + (v->numprops * sizeof(struct vCardProp)) ); v->prop[v->numprops-1].name = strdup(name); v->prop[v->numprops-1].value = strdup(value); } @@ -216,37 +259,118 @@ void vcard_set_prop(struct vCard *v, char *name, char *value, int append) { -/* - * Serialize a struct vcard into a standard text/x-vcard MIME type. - * +/** + * \brief Serialize a struct vcard into a standard text/x-vcard MIME type. + * \param v vCard to serialize + * \return the serialized vCard */ char *vcard_serialize(struct vCard *v) { char *ser; - int i; + int i, j; size_t len; + int is_utf8 = 0; - if (v->magic != CTDL_VCARD_MAGIC) return NULL; /* self check */ + if (v->magic != CTDL_VCARD_MAGIC) return NULL; /** self check */ - /* Figure out how big a buffer we need to allocate */ - len = 64; /* for begin, end, and a little padding for safety */ + /** Figure out how big a buffer we need to allocate */ + len = 64; /** for begin, end, and a little padding for safety */ if (v->numprops) for (i=0; i<(v->numprops); ++i) { len = len + strlen(v->prop[i].name) + - strlen(v->prop[i].value) + 4; + strlen(v->prop[i].value) + 16; } ser = malloc(len); if (ser == NULL) return NULL; - strcpy(ser, "begin:vcard\r\n"); + safestrncpy(ser, "begin:vcard\r\n", len); if (v->numprops) for (i=0; i<(v->numprops); ++i) { - strcat(ser, v->prop[i].name); - strcat(ser, ":"); - strcat(ser, v->prop[i].value); - strcat(ser, "\r\n"); + if (strcasecmp(v->prop[i].name, "end")) { + is_utf8 = 0; + for (j=0; iprop[i].value); ++i) { + if ( (v->prop[i].value[j] < 32) || (v->prop[i].value[j] > 126) ) { + is_utf8 = 1; + } + } + strcat(ser, v->prop[i].name); + if (is_utf8) { + strcat(ser, ";charset=UTF-8"); + } + strcat(ser, ":"); + strcat(ser, v->prop[i].value); + strcat(ser, "\r\n"); + } } strcat(ser, "end:vcard\r\n"); return ser; } + + + +/* + * \brief Convert FN (Friendly Name) into N (Name) + * + * \param vname Supplied friendly-name + * \param n Target buffer to store Name + * \param vname_size Size of buffer + */ +void vcard_fn_to_n(char *vname, char *n, size_t vname_size) { + char lastname[256]; + char firstname[256]; + char middlename[256]; + char honorific_prefixes[256]; + char honorific_suffixes[256]; + char buf[256]; + + safestrncpy(buf, n, sizeof buf); + + /* Try to intelligently convert the screen name to a + * fully expanded vCard name based on the number of + * words in the name + */ + safestrncpy(lastname, "", sizeof lastname); + safestrncpy(firstname, "", sizeof firstname); + safestrncpy(middlename, "", sizeof middlename); + safestrncpy(honorific_prefixes, "", sizeof honorific_prefixes); + safestrncpy(honorific_suffixes, "", sizeof honorific_suffixes); + + /* Honorific suffixes */ + if (num_tokens(buf, ',') > 1) { + extract_token(honorific_suffixes, buf, (num_tokens(buf, ' ') - 1), ',', + sizeof honorific_suffixes); + remove_token(buf, (num_tokens(buf, ',') - 1), ','); + } + + /* Find a last name */ + extract_token(lastname, buf, (num_tokens(buf, ' ') - 1), ' ', sizeof lastname); + remove_token(buf, (num_tokens(buf, ' ') - 1), ' '); + + /* Find honorific prefixes */ + if (num_tokens(buf, ' ') > 2) { + extract_token(honorific_prefixes, buf, 0, ' ', sizeof honorific_prefixes); + remove_token(buf, 0, ' '); + } + + /* Find a middle name */ + if (num_tokens(buf, ' ') > 1) { + extract_token(middlename, buf, (num_tokens(buf, ' ') - 1), ' ', sizeof middlename); + remove_token(buf, (num_tokens(buf, ' ') - 1), ' '); + } + + /* Anything left is probably the first name */ + safestrncpy(firstname, buf, sizeof firstname); + striplt(firstname); + + /* Compose the structured name */ + snprintf(vname, vname_size, "%s;%s;%s;%s;%s", lastname, firstname, middlename, + honorific_prefixes, honorific_suffixes); +} + + + + + + +/*@}*/