src/v2l_vcard.c

Go to the documentation of this file.
00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00015  */
00016 
00022 #include <stdlib.h>
00023 
00024 #ifndef _V2L_JABBER2
00025 #include <jabberd.h>
00026 #else
00027 #include "../util/util.h"
00028 #include <xmlnode.h>
00029 
00030 #define log_warn log_debug
00031 #define log_error log_debug
00032 
00033 #endif
00034 #include <v2l_vcard.h>
00035 
00036 #define LOG_ERROR_MEM log_error (ZONE, "Unable to allocate memory")
00037 
00041 typedef struct v2l_vCardItem
00042 {
00043   char *vcard;  
00044   char *ldap;   
00045   char *group;  
00046   struct v2l_vCardItem *next;
00047 } v2l_vCardItem;
00048 
00055 static v2l_vCardItem *_v2l_vcard_map (v2l_Config *self);
00056 
00062 static int _v2l_create_fn (xmlnode vcard);
00063 
00070 static v2l_LdapRequest *_v2l_set_sn12 (v2l_LdapRequest *req);
00071 
00078 static xmlnode _v2l_ldap2vcard_generic (v2l_vCardItem *item, const char **vals,
00079   xmlnode res);
00080 
00087 static v2l_LdapRequest *_v2l_vcard2ldap_generic (v2l_vCardItem *item,
00088   xmlnode data, v2l_LdapRequest *req);
00089 
00096 static v2l_vCardItem *_v2l_vcard_find_attr (v2l_vCardItem *item,
00097   const char *attr);
00098 
00105 static int _v2l_vcard_attr_match (const char *attr, void **shrdata);
00106 
00114 static void _v2l_vcard_attr_value (const char *attr, const char **vals,
00115   void *pointer, void *shrdata);
00116 
00117 #if 0
00118 static v2l_vCardItem *
00119   _v2l_vcard_find_tag (v2l_vCardItem *item, char *tag);
00120 #endif
00121 
00123 static const char *_V2L_MAP_VCARD [] = {
00124     "FN",
00125     "NICKNAME",
00126     "URL",
00127     "TEL/NUMBER",
00128     "EMAIL/USERID",
00129     "TITLE",
00130     "ROLE",
00131     "BDAY",
00132     "DESC",
00133     "N/FAMILY",
00134     "N/GIVEN",
00135     "N/MIDDLE",
00136     "N/PREFIX",
00137     "N/SUFFIX",
00138     "ADR/STREET",
00139     "ADR/POBOX",
00140     "ADR/EXTADD",
00141     "ADR/LOCALITY",
00142     "ADR/REGION",
00143     "ADR/PCODE",
00144     "ADR/CTRY",
00145     "ORG/ORGNAME",
00146     "ORG/ORGUNIT",
00147 
00148     "TZ",
00149     "GEO/LAT",
00150     "GEO/LON",
00151     "AGENT/EXTVAL",
00152     "NOTE",
00153     "REV",
00154     "SORT-STRING",
00155 
00156     "KEY/TYPE",
00157     "KEY/CRED",
00158 
00159     "PHOTO/TYPE",
00160     "PHOTO/BINVAL",
00161     "PHOTO/EXTVAL",
00162 
00163     "LOGO/TYPE",
00164     "LOGO/BINVAL",
00165     "LOGO/EXTVAL",
00166 
00167     "SOUND/PHONETIC",
00168     "SOUND/BINVAL",
00169     "SOUND/EXTVAL",
00170 
00171     NULL
00172 };
00173 
00174 /* public api */
00175 
00176 xmlnode
00177 v2l_vcard_get (v2l_Config *self, v2l_LdapConn *curr_conn)
00178 {
00179   xmlnode vcard;
00180   v2l_LdapEvt *evt_res;
00181 
00182   if (_v2l_vcard_map (self) == NULL)
00183     {
00184       log_error (ZONE, "Unreadable/malformed vCard template!");
00185       return NULL;
00186     }
00187 
00188   /* get user info from LDAP */
00189   evt_res = v2l_ldap_get_entry (self, curr_conn);
00190 
00191   if (evt_res == NULL)
00192     {
00193       return NULL;
00194     }
00195 
00196   /* prepare the XML result */
00197   vcard = xmlnode_new_tag ("vCard");
00198   xmlnode_put_attrib (vcard, "xmlns", "vcard-temp");
00199 
00200   v2l_ldap_for_all_attrs (_v2l_vcard_attr_value, _v2l_vcard_attr_match, vcard,
00201     evt_res);
00202   free (evt_res);
00203 
00204   if (self->irishack == 1)
00205     {
00206       xmlnode photo;
00207 
00208       /* <FN/> := <GIVEN/> + <FAMILY/> */
00209 
00210       _v2l_create_fn (vcard);
00211 
00212       /* InetOrgPerson has a jpegphoto attribute so PHOTO/MIMETYPE tag can be
00213          FIXME: RedIRIS schema doesn't support avatars in another format (png)
00214       */
00215 
00216       photo = xmlnode_get_tag (vcard, "PHOTO");
00217 
00218       if (photo != NULL)
00219         {
00220           /* FIXME: mimetype is hardcoded */
00221           xmlnode mimetype = xmlnode_insert_tag (photo, "TYPE");
00222           xmlnode_insert_cdata (mimetype, "image/jpeg", sizeof ("image/jpeg"));
00223         }
00224     }
00225 
00226   return vcard;
00227 }
00228 
00229 int
00230 v2l_vcard_set (v2l_Config *self, v2l_LdapConn *curr_conn, xmlnode data)
00231 {
00232   xmlnode node;
00233   v2l_LdapRequest *ldap_req = NULL;
00234   v2l_vCardItem *item;
00235 
00236   if (data == NULL)
00237     {
00238       log_warn (ZONE, "vCard data is NULL?");
00239       return 0;
00240     }
00241 
00242   item = _v2l_vcard_map (self);
00243 
00244   if (item == NULL)
00245     {
00246       log_error (ZONE, "Unreadable/Malformed vCard template!");
00247       return 0;
00248     }
00249 
00250   do
00251     {
00252       if (self->irishack == 1 && strcmp (item->vcard, "FN") == 0)
00253         {
00254           goto is_fn;
00255         }
00256 
00257       if (item->group != NULL)
00258         {
00259           char tag[30];
00260 
00261           sprintf (tag, "%s/%s", item->group, item->vcard);
00262           node = xmlnode_get_tag (data, tag);
00263         }
00264       else
00265         {
00266           node = xmlnode_get_tag (data, item->vcard);
00267         }
00268 
00269       if (node != NULL)
00270         {
00271           ldap_req = _v2l_vcard2ldap_generic (item, node, ldap_req);
00272         }
00273 is_fn:
00274       item = item->next;
00275     } while (item != NULL);
00276 
00277   if (self->irishack == 1)
00278     {
00279       ldap_req = _v2l_set_sn12 (ldap_req);
00280     }
00281 
00282   return v2l_request_record (self, curr_conn, ldap_req);
00283 }
00284 
00285 /* public api ends here */
00286 
00287 static v2l_vCardItem *
00288 _v2l_vcard_map (v2l_Config *self)
00289 {
00290   static v2l_vCardItem *_V2L_TPL = NULL;
00291   xmlnode tpl, tag;
00292   char **stag, *tmp, group[10];
00293   v2l_vCardItem *item;
00294 
00295   if (_V2L_TPL == NULL && self != NULL && self->confpath != NULL)
00296     {
00297       tpl = xmlnode_file (self->confpath);
00298 
00299       if (tpl == NULL)
00300         {
00301           return NULL;
00302         }
00303 
00304       for (stag = (char **) _V2L_MAP_VCARD; *stag != NULL; stag++)
00305         {
00306           tmp = strchr (*stag, '/');
00307 
00308           if (tmp == NULL)
00309             {
00310               group[0] = 0;
00311               tmp = *stag;
00312             }
00313           else
00314             {
00315               sprintf (group, "%.*s", tmp - *stag, *stag);
00316               tmp++;
00317             }
00318 
00319           tag = xmlnode_get_tag (tpl, *stag);
00320 
00321           if (xmlnode_get_data (tag) != NULL)
00322             {
00323               int ntags = 0;
00324               char find_attr[30];
00325 
00326               do
00327                 {
00328                   v2l_vCardItem *ptr;
00329 
00330                   ptr = (v2l_vCardItem *) pmalloc (self->poolref,
00331                     sizeof (v2l_vCardItem));
00332 
00333                   ptr->vcard = tmp;
00334                   ptr->ldap  = pstrdup (self->poolref, xmlnode_get_data (tag));
00335                   ptr->next  = NULL;
00336                   ptr->group = group[0] == 0 ? NULL :
00337                   pstrdup (self->poolref, group);
00338 
00339                   if (_V2L_TPL == NULL)
00340                     {
00341                       _V2L_TPL = ptr;
00342                       item = ptr;
00343                     }
00344                   else
00345                     {
00346                       item->next = ptr;
00347                       item = item->next;
00348                     }
00349 
00350                   sprintf (find_attr, "%s?v2ln=%d", *stag, ++ntags);
00351                   tag = xmlnode_get_tag (tpl, find_attr);
00352                 } while (tag && xmlnode_get_data (tag) != NULL && ntags < 10);
00353             }/* xmlnode_get_data (tag) != NULL */
00354         }  /* for loop, all tags in template */
00355 
00356       xmlnode_free (tpl);
00357     }
00358 
00359   return _V2L_TPL;
00360 }
00361 
00362 #if 0
00363 static v2l_vCardItem *
00364 _v2l_vcard_find_tag (v2l_vCardItem *item, char *tag)
00365 {
00366   v2l_vCardItem *res = NULL;
00367 
00368   while (item != NULL)
00369     {
00370       if (strcmp (item->vcard, tag) == 0)
00371         {
00372           res = item;
00373           break;
00374         }
00375 
00376         item = item->next;
00377     }
00378 
00379   return res;
00380 }
00381 #endif
00382 
00383 static v2l_vCardItem *
00384 _v2l_vcard_find_attr (v2l_vCardItem *item, const char *attr)
00385 {
00386   v2l_vCardItem *res = NULL;
00387 
00388   while (item != NULL)
00389     {
00390       if (strcmp (item->ldap, attr) == 0)
00391         {
00392           res = item;
00393           break;
00394         }
00395 
00396         item = item->next;
00397     }
00398 
00399   return res;
00400 }
00401 
00402 static int
00403 _v2l_vcard_attr_match (const char *attr, void **shrdata)
00404 {
00405   *shrdata = _v2l_vcard_find_attr (_v2l_vcard_map (NULL), attr);
00406 
00407   return *shrdata != NULL;
00408 }
00409 
00410 static void
00411 _v2l_vcard_attr_value (const char *attr, const char **vals, void *pointer,
00412   void *shrdata)
00413 {
00414   xmlnode vcard;
00415   v2l_vCardItem *match;
00416 
00417   vcard = (xmlnode) pointer;
00418   match = (v2l_vCardItem *) shrdata;
00419 
00420   if (vals != NULL)
00421     {
00422         _v2l_ldap2vcard_generic (match, vals, vcard);
00423     }
00424 }
00425 
00426 static int
00427 _v2l_create_fn (xmlnode vcard)
00428 {
00429   xmlnode n, fn;
00430   char *family, *given, *fn_str;
00431   int len;
00432 
00433   fn = xmlnode_insert_tag (vcard, "FN");
00434   n  = xmlnode_get_tag (vcard, "N");
00435   family = xmlnode_get_tag_data (n, "FAMILY");
00436   given  = xmlnode_get_tag_data (n, "GIVEN");
00437 
00438   len = 0;
00439   len += (family != NULL) ? strlen (family) : 0;
00440   len += (given  != NULL) ? strlen (given)  : 0;
00441 
00442   if (len == 0)
00443     {
00444       log_debug (ZONE, "<fn><n>...</n></fn> is empty, returning");
00445       return 1;
00446     }
00447 
00448   fn_str = (char *) malloc (sizeof (char) * (len + 2));
00449 
00450   if (fn_str == NULL)
00451     {
00452       LOG_ERROR_MEM;
00453       return 0;
00454     }
00455 
00456   fn_str[0] = 0;
00457 
00458   if (family != NULL)
00459     {
00460       sprintf (fn_str, "%s ", family);
00461     }
00462 
00463   if (given != NULL)
00464     {
00465       strcat (fn_str, given);
00466     }
00467 
00468   xmlnode_insert_cdata (fn, fn_str, len + 1);
00469   free (fn_str);
00470 
00471   return 1;
00472 }
00473 
00474 /* LDAP -> vCard */
00475 
00476 static xmlnode
00477 _v2l_ldap2vcard_generic (v2l_vCardItem *item, const char **vals, xmlnode res)
00478 {
00479   xmlnode node;
00480 
00481   if (item->group != NULL)
00482     {
00483       node = xmlnode_get_tag (res, item->group);
00484 
00485       if (node == NULL)
00486         {
00487           node = xmlnode_insert_tag (res, item->group);
00488         }
00489     }
00490   else
00491     {
00492       node = res;
00493     }
00494 
00495   node = xmlnode_insert_tag (node, item->vcard);
00496   xmlnode_insert_cdata (node, vals[0], strlen (vals[0]));
00497 
00498   return res;
00499 }
00500 
00501 /*  vCard -> LDAP */
00502 
00503 static v2l_LdapRequest *
00504 _v2l_vcard2ldap_generic (v2l_vCardItem *item, xmlnode data,
00505   v2l_LdapRequest *req)
00506 {
00507   const char *str;
00508 
00509   str = xmlnode_get_data (data);
00510 
00511   return str == NULL ? req : v2l_add_attr_str (req, item->ldap, str);
00512 }
00513 
00514 static v2l_LdapRequest *
00515 _v2l_set_sn12 (v2l_LdapRequest *req)
00516 {
00517   if (req != NULL)
00518     {
00519       v2l_LdapRequest *ptr;
00520       char *sn;
00521 
00522       for (ptr = req, sn = NULL; ptr != NULL; ptr = ptr->next)
00523         {
00524           if (strcmp (ptr->attr->mod_type, "sn") == 0)
00525             {
00526               sn = ptr->attr->mod_values[0];
00527               break;
00528             }
00529         }
00530 
00531       if (sn != NULL)
00532         {
00533           char *sit, *sn1, *sn2;
00534 
00535           for (sit = sn; *sit != ' ' && *sit != 0; sit++);
00536 
00537           sn1 = (char *) malloc (sizeof (char) * (sit - sn + 1));
00538 
00539           if (sn1 == NULL)
00540             {
00541               return req;
00542             }
00543 
00544           strncpy (sn1, sn, sizeof (char) * (sit - sn));
00545           sn1[sit - sn] = 0;
00546           ptr = v2l_add_attr_str (req, "sn1", sn1);
00547           free (sn1);
00548 
00549           if (ptr == NULL)
00550             {
00551               return req;
00552             }
00553 
00554           req = ptr;
00555 
00556           if (sit - sn != strlen (sn))
00557             {
00558               sn2 = (char *) malloc (strlen (sit) + 1);
00559 
00560               if (sn2 == NULL)
00561                 {
00562                   LOG_ERROR_MEM;
00563                   return req;
00564                 }
00565 
00566               strcpy (sn2, sit);
00567               ptr = v2l_add_attr_str (req, "sn2", sn2);
00568               free (sn2);
00569 
00570               if (ptr == NULL)
00571                 {
00572                   return req;
00573                 }
00574 
00575               req = ptr;
00576             }
00577         }  /* sn != NULL */
00578     }  /* req != NULL */
00579 
00580   return req;
00581 }

Generated on Sun Oct 7 14:38:12 2007 for vCard2LDAP by  doxygen 1.5.1