vcard.c

00001 /*
00002  * $Id: vcard.c 5200 2007-06-04 20:54:16Z ajc $
00003  * Copyright (C) 1999-2006 by Art Cancro
00004  * This code is freely redistributable under the terms of the GNU General
00005  * Public License.  All other rights reserved.
00006  */
00012 #include "webcit.h"
00013 #include "webserver.h"
00014 #include "vcard.h"
00015 
00020 struct vCard *vcard_new() {
00021         struct vCard *v;
00022 
00023         v = (struct vCard *) malloc(sizeof(struct vCard));
00024         if (v == NULL) return v;
00025 
00026         v->magic = CTDL_VCARD_MAGIC;
00027         v->numprops = 0;
00028         v->prop = NULL;
00029 
00030         return v;
00031 }
00032 
00038 void remove_charset_attribute(char *strbuf)
00039 {
00040         int i, t;
00041         char compare[256];
00042 
00043         t = num_tokens(strbuf, ';');
00044         for (i=0; i<t; ++i) {
00045                 extract_token(compare, strbuf, i, ';', sizeof compare);
00046                 striplt(compare);
00047                 if (!strncasecmp(compare, "charset=", 8)) {
00048                         remove_token(strbuf, i, ';');
00049                 }
00050         }
00051         if (strlen(strbuf) > 0) {
00052                 if (strbuf[strlen(strbuf)-1] == ';') {
00053                         strbuf[strlen(strbuf)-1] = 0;
00054                 }
00055         }
00056 }
00057 
00058 
00059 /*
00060  * \brief       Add a property to a vCard
00061  *
00062  * \param       v               vCard structure to which we are adding
00063  * \param       propname        name of new property
00064  * \param       propvalue       value of new property
00065  */
00066 void vcard_add_prop(struct vCard *v, char *propname, char *propvalue) {
00067         ++v->numprops;
00068         v->prop = realloc(v->prop,
00069                 (v->numprops * sizeof(struct vCardProp)) );
00070         v->prop[v->numprops-1].name = strdup(propname);
00071         v->prop[v->numprops-1].value = strdup(propvalue);
00072 }
00073 
00074 
00075 
00081 struct vCard *vcard_load(char *vtext) {
00082         struct vCard *v;
00083         int valid = 0;
00084         char *mycopy, *ptr;
00085         char *namebuf, *valuebuf;
00086         int i;
00087         int colonpos, nlpos;
00088 
00089         if (vtext == NULL) return vcard_new();
00090         mycopy = strdup(vtext);
00091         if (mycopy == NULL) return NULL;
00092 
00098         for (i=0; i<strlen(mycopy); ++i) {
00099                 if (!strncmp(&mycopy[i], "\r\n", 2)) {
00100                         strcpy(&mycopy[i], &mycopy[i+1]);
00101                 }
00102                 if ( (mycopy[i]=='\n') && (isspace(mycopy[i+1])) ) {
00103                         strcpy(&mycopy[i], &mycopy[i+1]);
00104                 }
00105         }
00106 
00107         v = vcard_new();
00108         if (v == NULL) return v;
00109 
00110         ptr = mycopy;
00111         while (strlen(ptr)>0) {
00112                 colonpos = (-1);
00113                 nlpos = (-1);
00114                 colonpos = pattern2(ptr, ":");
00115                 nlpos = pattern2(ptr, "\n");
00116 
00117                 if ((nlpos > colonpos) && (colonpos > 0)) {
00118                         namebuf = malloc(colonpos + 1);
00119                         valuebuf = malloc(nlpos - colonpos + 1);
00120                         strncpy(namebuf, ptr, colonpos);
00121                         namebuf[colonpos] = 0;
00122                         strncpy(valuebuf, &ptr[colonpos+1], nlpos-colonpos-1);
00123                         valuebuf[nlpos-colonpos-1] = 0;
00124 
00125                         if (!strcasecmp(namebuf, "end")) {
00126                                 valid = 0;
00127                         }
00128                         if (    (!strcasecmp(namebuf, "begin"))
00129                                 && (!strcasecmp(valuebuf, "vcard"))
00130                         ) {
00131                                 valid = 1;
00132                         }
00133 
00134                         if ( (valid) && (strcasecmp(namebuf, "begin")) ) {
00135                                 remove_charset_attribute(namebuf);
00136                                 ++v->numprops;
00137                                 v->prop = realloc(v->prop,
00138                                         (v->numprops * sizeof(struct vCardProp))
00139                                 );
00140                                 v->prop[v->numprops-1].name = namebuf;
00141                                 v->prop[v->numprops-1].value = valuebuf;
00142                         } 
00143                         else {
00144                                 free(namebuf);
00145                                 free(valuebuf);
00146                         }
00147 
00148                 }
00149 
00150                 while ( (*ptr != '\n') && (strlen(ptr)>0) ) {
00151                         ++ptr;
00152                 }
00153                 if (*ptr == '\n') ++ptr;
00154         }
00155 
00156         free(mycopy);
00157         return v;
00158 }
00159 
00160 
00175 char *vcard_get_prop(struct vCard *v, char *propname,
00176                         int is_partial, int instance, int get_propname) {
00177         int i;
00178         int found_instance = 0;
00179 
00180         if (v->numprops) for (i=0; i<(v->numprops); ++i) {
00181                 if ( (!strcasecmp(v->prop[i].name, propname))
00182                    || (propname[0] == 0)
00183                    || (  (!strncasecmp(v->prop[i].name,
00184                                         propname, strlen(propname)))
00185                          && (v->prop[i].name[strlen(propname)] == ';')
00186                          && (is_partial) ) ) {
00187                         if (instance == found_instance++) {
00188                                 if (get_propname) {
00189                                         return(v->prop[i].name);
00190                                 }
00191                                 else {
00192                                         return(v->prop[i].value);
00193                                 }
00194                         }
00195                 }
00196         }
00197 
00198         return NULL;
00199 }
00200 
00201 
00202 
00203 
00209 void vcard_free(struct vCard *v) {
00210         int i;
00211         
00212         if (v->magic != CTDL_VCARD_MAGIC) return;       /* Self-check */
00213         
00214         if (v->numprops) for (i=0; i<(v->numprops); ++i) {
00215                 free(v->prop[i].name);
00216                 free(v->prop[i].value);
00217         }
00218 
00219         if (v->prop != NULL) free(v->prop);
00220         
00221         memset(v, 0, sizeof(struct vCard));
00222         free(v);
00223 }
00224 
00225 
00226 
00227 
00235 void vcard_set_prop(struct vCard *v, char *name, char *value, int append) {
00236         int i;
00237 
00238         if (v->magic != CTDL_VCARD_MAGIC) return;       
00241         if (!append) if (v->numprops) for (i=0; i<(v->numprops); ++i) {
00242                 if (!strcasecmp(v->prop[i].name, name)) {
00243                         free(v->prop[i].name);
00244                         free(v->prop[i].value);
00245                         v->prop[i].name = strdup(name);
00246                         v->prop[i].value = strdup(value);
00247                         return;
00248                 }
00249         }
00250 
00252         ++v->numprops;
00253         v->prop = realloc(v->prop,
00254                 (v->numprops * sizeof(struct vCardProp)) );
00255         v->prop[v->numprops-1].name = strdup(name);
00256         v->prop[v->numprops-1].value = strdup(value);
00257 }
00258 
00259 
00260 
00261 
00267 char *vcard_serialize(struct vCard *v)
00268 {
00269         char *ser;
00270         int i, j;
00271         size_t len;
00272         int is_utf8 = 0;
00273 
00274         if (v->magic != CTDL_VCARD_MAGIC) return NULL;  
00277         len = 64;       
00278         if (v->numprops) for (i=0; i<(v->numprops); ++i) {
00279                 len = len +
00280                         strlen(v->prop[i].name) +
00281                         strlen(v->prop[i].value) + 16;
00282         }
00283 
00284         ser = malloc(len);
00285         if (ser == NULL) return NULL;
00286 
00287         safestrncpy(ser, "begin:vcard\r\n", len);
00288         if (v->numprops) for (i=0; i<(v->numprops); ++i) {
00289                 if ( (strcasecmp(v->prop[i].name, "end")) && (v->prop[i].value != NULL) ) {
00290                         is_utf8 = 0;
00291                         for (j=0; j<strlen(v->prop[i].value); ++j) {
00292                                 if ( (v->prop[i].value[j] < 32) || (v->prop[i].value[j] > 126) ) {
00293                                         is_utf8 = 1;
00294                                 }
00295                         }
00296                         strcat(ser, v->prop[i].name);
00297                         if (is_utf8) {
00298                                 strcat(ser, ";charset=UTF-8");
00299                         }
00300                         strcat(ser, ":");
00301                         strcat(ser, v->prop[i].value);
00302                         strcat(ser, "\r\n");
00303                 }
00304         }
00305         strcat(ser, "end:vcard\r\n");
00306 
00307         return ser;
00308 }
00309 
00310 
00311 
00312 /*
00313  * \brief       Convert FN (Friendly Name) into N (Name)
00314  *
00315  * \param       vname           Supplied friendly-name
00316  * \param       n               Target buffer to store Name
00317  * \param       vname_size      Size of buffer
00318  */
00319 void vcard_fn_to_n(char *vname, char *n, size_t vname_size) {
00320         char lastname[256];
00321         char firstname[256];
00322         char middlename[256];
00323         char honorific_prefixes[256];
00324         char honorific_suffixes[256];
00325         char buf[256];
00326 
00327         safestrncpy(buf, n, sizeof buf);
00328 
00329         /* Try to intelligently convert the screen name to a
00330          * fully expanded vCard name based on the number of
00331          * words in the name
00332          */
00333         safestrncpy(lastname, "", sizeof lastname);
00334         safestrncpy(firstname, "", sizeof firstname);
00335         safestrncpy(middlename, "", sizeof middlename);
00336         safestrncpy(honorific_prefixes, "", sizeof honorific_prefixes);
00337         safestrncpy(honorific_suffixes, "", sizeof honorific_suffixes);
00338 
00339         /* Honorific suffixes */
00340         if (num_tokens(buf, ',') > 1) {
00341                 extract_token(honorific_suffixes, buf, (num_tokens(buf, ' ') - 1), ',',
00342                         sizeof honorific_suffixes);
00343                 remove_token(buf, (num_tokens(buf, ',') - 1), ',');
00344         }
00345 
00346         /* Find a last name */
00347         extract_token(lastname, buf, (num_tokens(buf, ' ') - 1), ' ', sizeof lastname);
00348         remove_token(buf, (num_tokens(buf, ' ') - 1), ' ');
00349 
00350         /* Find honorific prefixes */
00351         if (num_tokens(buf, ' ') > 2) {
00352                 extract_token(honorific_prefixes, buf, 0, ' ', sizeof honorific_prefixes);
00353                 remove_token(buf, 0, ' ');
00354         }
00355 
00356         /* Find a middle name */
00357         if (num_tokens(buf, ' ') > 1) {
00358                 extract_token(middlename, buf, (num_tokens(buf, ' ') - 1), ' ', sizeof middlename);
00359                 remove_token(buf, (num_tokens(buf, ' ') - 1), ' ');
00360         }
00361 
00362         /* Anything left is probably the first name */
00363         safestrncpy(firstname, buf, sizeof firstname);
00364         striplt(firstname);
00365 
00366         /* Compose the structured name */
00367         snprintf(vname, vname_size, "%s;%s;%s;%s;%s", lastname, firstname, middlename,
00368                 honorific_prefixes, honorific_suffixes);
00369 }
00370 
00371 
00372 
00373 
00374 
00375 

Generated on Wed Jun 20 23:13:11 2007 for webcit by  doxygen 1.5.2