From 9ddf79d4df125512917c5bcc6df4048b3b66c9e9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jorge=20Rodr=C3=ADguez?= Date: Thu, 27 Sep 2007 01:51:39 +0200 Subject: [PATCH] More Doxygen. API cleanup. --- Doxyfile | 4 +- include/v2l_config.h | 20 +- include/v2l_conn.h | 74 ++++- include/v2l_vcard.h | 6 +- patch/patch-v2l-jabberd-2.1.14.diff | 641 ++++++++++++++++++++++++------------ src/v2l_config.c | 7 + src/v2l_conn.c | 202 ++++++++++-- src/v2l_main.c | 50 ++- src/v2l_vcard.c | 306 +++++++++-------- 9 files changed, 910 insertions(+), 400 deletions(-) diff --git a/Doxyfile b/Doxyfile index 8eb763f..8238c24 100644 --- a/Doxyfile +++ b/Doxyfile @@ -45,7 +45,7 @@ SUBGROUPING = YES #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = YES @@ -144,7 +144,7 @@ COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = -PDF_HYPERLINKS = NO +PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO diff --git a/include/v2l_config.h b/include/v2l_config.h index e532871..42cd540 100644 --- a/include/v2l_config.h +++ b/include/v2l_config.h @@ -14,14 +14,17 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*! \file v2l_config.h */ +/*! \file v2l_config.h + \brief Config handling functions. +*/ #ifndef __V2L_CONFIG_H #define __V2L_CONFIG_H +/*! Forward declaration */ typedef struct v2l_LdapConn* v2l_LdapConnPtr; -/*! \brief The username associated with the master connection */ +/*! The username associated with the master connection */ #define V2L_ADMIN "jabberadmin" /*! \brief Type of the jabberd global config. @@ -52,17 +55,18 @@ typedef struct v2l_Config char *confpath; /*!< path to the translation template */ } v2l_Config; -/*! \brief Read global config and initialize module config. - Precondition: jabberd config exists. - Postcondition: all fields of self are valid. +/*! \brief Reads global config and initialize module config. + \pre jabberd config exists and it's valid. + \post all fields of self are set. \param self Module config. - \param cfgroot Global config. + \param cfgroot Global config. T_CONF type. \return 1 if no error, otherwise returns 0. */ extern int v2l_config_init (v2l_Config *self, T_CONF cfgroot); -/*! \brief Shutdown module. Close all connections and destroy mempools. - Precondition: self and self->master_conn exists. +/*! \brief Shutdown function, closes all connections and frees mempools. + \pre self != NULL and self->master_conn is open. + \post self->master_conn closed, all pools freeds. \param self Module config. */ extern void v2l_config_shutdown (v2l_Config *self); diff --git a/include/v2l_conn.h b/include/v2l_conn.h index 915dbf2..8b7f3d1 100644 --- a/include/v2l_conn.h +++ b/include/v2l_conn.h @@ -14,7 +14,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*! \file v2l_conn.h */ +/*! \file v2l_conn.h + \brief Handling the LDAP directory. Low-level tier. +*/ #ifndef __V2L_CONN_H #define __V2L_CONN_H @@ -36,9 +38,7 @@ typedef struct v2l_LdapConn struct v2l_LdapConn *next; } v2l_LdapConn; -/*! \brief Request (SLL) for LDAP directory. - Store LDAP request to be executed after having retrieved vCard data. -*/ +/*! \brief Request (SLL) for LDAP directory */ typedef struct v2l_LdapRequest { LDAPMod *attr; @@ -46,7 +46,7 @@ typedef struct v2l_LdapRequest } v2l_LdapRequest; /*! \brief LDAP environment. - Control struct for perform operations on LDAP directory and retrieve + Control struct for perform operations on the LDAP directory and retrieve results. */ typedef struct v2l_LdapEvt @@ -57,35 +57,63 @@ typedef struct v2l_LdapEvt LDAPMessage *result; /*!< LDAP result (see OpenLDAP API docs) */ } v2l_LdapEvt; -/*! \brief Get a (ephemeral) connection by name. Creates one if doesn't exist. - Precondition: self is valid, user is not null +/*! \brief Match function type + Generic attribute matching routine. + \param attr The attribute. + \param[out] shrdata Generic deferenced pointer. Shared data with a 'value + function' + \sa v2l_AttrValueFunction + \sa v2l_ldap_for_all_attrs + \return true if matching, otherwise false. +*/ +typedef int (*v2l_AttrMatchFunction) (const char *attr, void **shrdata); + +/*! \brief Values read function type + Generic values handling routine. + \param attr The attribute. + \param vals Values of attribute. + \param pointer Generic multipurpose pointer. + \param shrdata Shared data with 'match function' + \sa v2l_MatchValueFunction + \sa v2l_ldap_for_all_attrs +*/ +typedef void (*v2l_AttrValueFunction) (const char *attr, const char **vals, + void *pointer, void *shrdata); + +/*! \brief Gets a (ephemeral) connection by name. Creates one if doesn't exist. + \pre self is valid, user is not null and exists. + \post ephermeral connection for user is open. \param self Module config. \param user the username \return the connection if no error, otherwise NULL. */ extern v2l_LdapConn *v2l_get_conn (v2l_Config *self, const char *user); -/*! \brief Get a connection master connection. Creates one if doesn't exist. - Precondition: self is valid +/*! \brief Gets a connection master connection. Creates one if doesn't exist. + \pre self is valid + \post master connection is open. \param self Module config. \return the connection if no error, otherwise NULL. */ extern v2l_LdapConn *v2l_get_master_conn (v2l_Config *self); -/*! \brief Free and close all connections (ephemeral or not) */ +/*! \brief Frees and closes all connections (ephemeral or not) + If connections doesn't exist does nothing. + \post self->master_conn closed. Connections list empty. +*/ extern void v2l_free_allconn (); -/*! \brief Retrieve an user from the LDAP directory +/*! \brief Retrieves an user entry from the LDAP directory + \note Allocated memory must be freed by the caller. \param self Module config \param curr_conn user connection. - \param evt_res in out parameter, LDAP descriptor and control code. - \return 1 if no error, otherwise 0 + \return evt_res LDAP descriptor, control code and result. NULL if error. */ -extern int v2l_ldap_get_entry (v2l_Config *self, v2l_LdapConn *curr_conn, - v2l_LdapEvt *evt_res); +extern v2l_LdapEvt *v2l_ldap_get_entry (v2l_Config *self, + v2l_LdapConn *curr_conn); -/*! \brief Perform a list of changes on the LDAP directory. - Precondition: req != NULL +/*! \brief Executes a list of changes on the LDAP directory. + \pre req is not NULL \param self Module config \param curr_conn The user connection. \param req list of changes. @@ -94,7 +122,7 @@ extern int v2l_ldap_get_entry (v2l_Config *self, v2l_LdapConn *curr_conn, extern int v2l_request_record (v2l_Config *self, v2l_LdapConn *curr_conn, v2l_LdapRequest *req); -/*! \brief Add a new request to the list +/*! \brief Adds a new request to the list \param req The list of requests. \param attr attribute name. \param str attribute value. @@ -102,4 +130,14 @@ extern int v2l_request_record (v2l_Config *self, v2l_LdapConn *curr_conn, */ extern v2l_LdapRequest *v2l_add_attr_str (v2l_LdapRequest *req, const char *attr, const char *str); + +/*! \brief Applies a function to all LDAP object attributes. + \pre evt_res should be a valid entry (ie. result of a search in directory) + \param value_func Walker function. + \param match_func Match function. If returns true we'll call to value_func + \param pointer Generic multipurpose pointer. It will be passed to value_func + \param evt_res LDAP descriptor, control code and result. +*/ +extern void v2l_ldap_for_all_attrs (v2l_AttrValueFunction value_func, + v2l_AttrMatchFunction match_func, void *pointer, v2l_LdapEvt *evt_res); #endif diff --git a/include/v2l_vcard.h b/include/v2l_vcard.h index d288d69..92d7b5f 100644 --- a/include/v2l_vcard.h +++ b/include/v2l_vcard.h @@ -14,7 +14,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*! \file v2l_vcard.h */ +/*! \file v2l_vcard.h + \brief XML vCard's to/from LDAP objects translation functions. +*/ #ifndef __V2L_VCARD_H #define __V2L_VCARD_H @@ -24,7 +26,7 @@ /*! \brief Gets user vCard in xml format \param self Module config \param curr_conn user connection. - \return father node of vCard, NULL if error. + \return vCard main node, NULL if error. */ extern xmlnode v2l_vcard_get (v2l_Config *self, v2l_LdapConn *curr_conn); diff --git a/patch/patch-v2l-jabberd-2.1.14.diff b/patch/patch-v2l-jabberd-2.1.14.diff index 6af3d0a..151e20d 100644 --- a/patch/patch-v2l-jabberd-2.1.14.diff +++ b/patch/patch-v2l-jabberd-2.1.14.diff @@ -48,7 +48,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/Makefile.am jabberd-2.1.14/sm/Makefile.am mod_iq_version_la_LIBADD = $(top_builddir)/subst/libsubst.la diff -Naurb jabberd-2.1.14.orig/sm/mod_iq_vcard.c jabberd-2.1.14/sm/mod_iq_vcard.c --- jabberd-2.1.14.orig/sm/mod_iq_vcard.c 2007-08-29 16:56:58.000000000 +0200 -+++ jabberd-2.1.14/sm/mod_iq_vcard.c 2007-09-08 21:32:54.000000000 +0200 ++++ jabberd-2.1.14/sm/mod_iq_vcard.c 2007-09-25 17:45:15.000000000 +0200 @@ -27,6 +27,23 @@ * $Revision: 1.25 $ */ @@ -302,8 +302,8 @@ diff -Naurb jabberd-2.1.14.orig/sm/mod_iq_vcard.c jabberd-2.1.14/sm/mod_iq_vcard DLLEXPORT int module_init(mod_instance_t mi, char *arg) { diff -Naurb jabberd-2.1.14.orig/sm/v2l_config.c jabberd-2.1.14/sm/v2l_config.c --- jabberd-2.1.14.orig/sm/v2l_config.c 1970-01-01 01:00:00.000000000 +0100 -+++ jabberd-2.1.14/sm/v2l_config.c 2007-09-25 15:52:37.000000000 +0200 -@@ -0,0 +1,169 @@ ++++ jabberd-2.1.14/sm/v2l_config.c 2007-09-26 23:51:26.000000000 +0200 +@@ -0,0 +1,176 @@ +/* + * 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 @@ -320,6 +320,10 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_config.c jabberd-2.1.14/sm/v2l_config.c + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + ++/*! \file v2l_config.c ++ \brief Config handling functions. Implementation ++*/ ++ +#include +#include + @@ -336,6 +340,9 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_config.c jabberd-2.1.14/sm/v2l_config.c +#include +#include + ++/*! \brief Gets value for tag from config ++ Generic (preprocessor) function for handling Jabberd14/2 config differences ++*/ +static char *_v2l_config_get_tag (T_CONF conn_base, const char *tag); + +int @@ -475,8 +482,8 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_config.c jabberd-2.1.14/sm/v2l_config.c +} diff -Naurb jabberd-2.1.14.orig/sm/v2l_config.h jabberd-2.1.14/sm/v2l_config.h --- jabberd-2.1.14.orig/sm/v2l_config.h 1970-01-01 01:00:00.000000000 +0100 -+++ jabberd-2.1.14/sm/v2l_config.h 2007-09-25 17:24:17.000000000 +0200 -@@ -0,0 +1,69 @@ ++++ jabberd-2.1.14/sm/v2l_config.h 2007-09-27 01:05:30.000000000 +0200 +@@ -0,0 +1,73 @@ +/* + * 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 @@ -493,14 +500,17 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_config.h jabberd-2.1.14/sm/v2l_config.h + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + -+/*! \file v2l_config.h */ ++/*! \file v2l_config.h ++ \brief Config handling functions. ++*/ + +#ifndef __V2L_CONFIG_H +#define __V2L_CONFIG_H + ++/*! Forward declaration */ +typedef struct v2l_LdapConn* v2l_LdapConnPtr; + -+/*! \brief The username associated with the master connection */ ++/*! The username associated with the master connection */ +#define V2L_ADMIN "jabberadmin" + +/*! \brief Type of the jabberd global config. @@ -531,25 +541,26 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_config.h jabberd-2.1.14/sm/v2l_config.h + char *confpath; /*!< path to the translation template */ +} v2l_Config; + -+/*! \brief Read global config and initialize module config. -+ Precondition: jabberd config exists. -+ Postcondition: all fields of self are valid. ++/*! \brief Reads global config and initialize module config. ++ \pre jabberd config exists and it's valid. ++ \post all fields of self are set. + \param self Module config. -+ \param cfgroot Global config. ++ \param cfgroot Global config. T_CONF type. + \return 1 if no error, otherwise returns 0. +*/ +extern int v2l_config_init (v2l_Config *self, T_CONF cfgroot); + -+/*! \brief Shutdown module. Close all connections and destroy mempools. -+ Precondition: self and self->master_conn exists. ++/*! \brief Shutdown function, closes all connections and frees mempools. ++ \pre self != NULL and self->master_conn is open. ++ \post self->master_conn closed, all pools freeds. + \param self Module config. +*/ +extern void v2l_config_shutdown (v2l_Config *self); +#endif diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c --- jabberd-2.1.14.orig/sm/v2l_conn.c 1970-01-01 01:00:00.000000000 +0100 -+++ jabberd-2.1.14/sm/v2l_conn.c 2007-09-25 17:01:54.000000000 +0200 -@@ -0,0 +1,723 @@ ++++ jabberd-2.1.14/sm/v2l_conn.c 2007-09-27 01:47:13.000000000 +0200 +@@ -0,0 +1,875 @@ +/* + * 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 @@ -566,10 +577,11 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + ++/*! \file v2l_conn.c ++ \brief Handling the LDAP directory. Implementation ++*/ ++ +#include -+#include -+#include -+#include + +#ifndef _V2L_JABBER2 +#include @@ -583,39 +595,137 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c +#endif + +#include -+#include + -+#define V2L_CONN_LIFETIME 30 /* seconds */ -+#define V2L_POLL_INTERVAL 1 /* seconds */ ++/*! \brief Lifetime of an ephemeral connection, in seconds ++ The recall connections thread period. ++*/ ++#define V2L_CONN_LIFETIME 30 ++ ++/*! How often thread checks for LDAP results, in seconds */ ++#define V2L_POLL_INTERVAL 1 + +#define LOG_ERROR_MEM log_error(ZONE, "Unable to allocate memory") + -+/* Global hashtable of all currently active LDAP connections */ ++/*! Global hashtable of all currently active LDAP connections */ +static xht V2L_CONN_LIST = NULL; + ++/*! \brief Creates new LDAP connection ++ \param host LDAP hostname. ++ \param port LDAP port. ++ \param binddn Bind DN. ++ \param user User name. ++ \param passwd User password. ++ \param expire Boolean, ephemeral connection? ++ \return LDAP connectior or NULL if error. ++*/ +static v2l_LdapConn *_v2l_create_conn (char *host, int port, const char *binddn, + const char *user, const char *passwd, int expire); + -+/* NOTE: Allocated memory must be freed by the caller */ ++/*! \brief Gets user password ++ Retrieves user password from LDAP directory using master connection. ++ \note Allocated memory must be freed by the caller. ++ \param self Module config. ++ \param user User name. ++ \pre self is valid, user is not NULL ++ \return user password string or NULL if doesn't exist or error. ++*/ +static char *_v2l_ldap_get_passwd (v2l_Config *self, const char *user); ++ ++/*! \brief Closes and frees a connection. ++ Utility function, common code for two hash walker functions. ++ \param h Jabberd hash. Hash table "username"->connection. ++ \param user User name. ++ \param val deference pointer to connection. ++ \sa _v2l_free_walker ++ \sa _v2l_free_expired_walker ++*/ +static void _v2l_free_conn (xht h, const char *user, void *val); ++ ++/*! \brief Gets the number or attributes in a LDAP request. ++ \param[in,out] req The SLL of LDAP requests. ++ \return number of attributes, 0 if req is NULL. ++*/ +static int _v2l_count_attrs (v2l_LdapRequest *req); ++ ++/*! \brief Modifies an entry in the LDAP directory ++ Utility function. ++ \param dn Entry bind DN ++ \param attrs List of attributes changed. ++ \param[in,out] evt_res Control and info parameter. ++ \return LDAP error code. ++*/ +static int _v2l_ldap_modify (char *dn, LDAPMod **attrs, v2l_LdapEvt *evt_res); ++ ++/*! \brief Searchs and retrieves an entry from the LDAP directory ++ Utility function. ++ \param dn Entry bind DN. ++ \param suffix LDAP suffix ++ \param[out] attrs Entry attributes. ++ \param subtree boolean. Search in a one level or in entire subtree? ++ \param[in,out] evt_res Control and info parameter. ++ \return LDAP error code. ++*/ +static int _v2l_ldap_search (char *dn, char *suffix, char **attrs, int subtree, + v2l_LdapEvt *evt_res); ++ ++/*! \brief Waits for LDAP results ++ Operations on the directory are asynchronous. This is a sync wait function. ++ \param \param[in,out] evt_res Control and info parameter. ++*/ +static void _v2l_ldap_sync (v2l_LdapEvt *evt_res); ++ ++/*! \brief Adds LDAP attr to request. ++ Utility function, hides OpenLDAP API to upper level. ++ \param[in,out] req The SLL of LDAP requests. ++ \param attr The attr, LDAPMod pointer. ++ \return The list of requests + the last added. The list of request if error. ++*/ +static v2l_LdapRequest *_v2l_add_attr (v2l_LdapRequest *req, LDAPMod *attr); ++ ++/*! \brief Adds a conn to the global list. ++ If list is empty, initializes it and starts the thread who recalls expired ++ connections. ++ \param ldap_conn New connection. ++*/ +static void _v2l_add_conn (v2l_LdapConn *ldap_conn); -+static void _v2l_free_callback (xht h, const char *key, void *val, ++ ++/*! \brief Frees connection unconditionally. ++ Utility function. Hash walker function. ++ See jabberd API for details. ++*/ ++static void _v2l_free_walker (xht h, const char *key, void *val, + void *arg); + -+/* Free connections when its time has expired (periodic thread) */ ++/*! \brief Frees connections when its slice time expired (periodic thread) ++ \dot ++ digraph G { ++ rankdir = LR ++ node [shape = ellipse, fontname = Helvetica fontsize = 12] ++ {node[style = filled, fontsize = 16, bgcolor = grey] sleep} ++ {node[shape = circle, label = delete] free} ++ {node[label = "expired?" ] is_expired} ++ {node[label = "conn left?" ] any_conn} ++ sleep -> sleep ++ sleep -> any_conn [label = " "] ++ any_conn -> sleep [label = no] ++ any_conn -> is_expired [label = yes] ++ is_expired -> free [label = yes] ++ is_expired -> any_conn [label = no] ++ free -> any_conn ++ } ++ \enddot ++ \param arg Unused. ++*/ +static void *_v2l_purge_conn_callback (void *arg); -+/* Free connections in a hashtable, walker function */ -+static void _v2l_free_expired (xht h, const char *key, void *val, ++ ++/*! \brief Frees expired connections. ++ Utility function. Hash walker function. ++ See jabberd API for details. ++*/ ++static void _v2l_free_expired_walker (xht h, const char *key, void *val, + void *arg); + -+/* A thread for wait for LDAP results */ ++/*! A thread for active wait for LDAP results */ +static int _v2l_ldap_wait_callback(void *arg); + +#ifdef _V2L_JABBER2 @@ -680,23 +790,34 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c +void +v2l_free_allconn () +{ -+ xhash_walk (V2L_CONN_LIST, _v2l_free_callback, NULL); ++ xhash_walk (V2L_CONN_LIST, _v2l_free_walker, NULL); + xhash_free (V2L_CONN_LIST); +} + -+int -+v2l_ldap_get_entry (v2l_Config *self, v2l_LdapConn *curr_conn, -+ v2l_LdapEvt *evt_res) ++v2l_LdapEvt * ++v2l_ldap_get_entry (v2l_Config *self, v2l_LdapConn *curr_conn) +{ ++ v2l_LdapEvt *evt_res; + int rc; + ++ evt_res = (v2l_LdapEvt *) malloc (sizeof (v2l_LdapEvt)); ++ ++ if (evt_res == NULL) ++ { ++ LOG_ERROR_MEM; ++ return NULL; ++ } ++ ++ evt_res->ld = curr_conn->ld; ++ + rc = _v2l_ldap_search (curr_conn->entry, self->suffix, NULL, 1, evt_res); + + if (rc != LDAP_SUCCESS) + { + log_error (ZONE, "LDAP error attempting to retrieve user info: %s", + ldap_err2string (rc)); -+ return 0; ++ free (evt_res); ++ return NULL; + } + + _v2l_ldap_sync(evt_res); @@ -704,10 +825,11 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c + if (ldap_count_entries (evt_res->ld, evt_res->result) != 1) + { + log_warn (ZONE, "Multiple users with the same dn?"); -+ return 0; ++ free (evt_res); ++ return NULL; + } + -+ return 1; ++ return evt_res; +} + +int @@ -847,7 +969,6 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c + return _v2l_add_attr (req, mod); +} + -+/************************/ +/* public api ends here */ + +static v2l_LdapConn * @@ -1078,7 +1199,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c +#endif +} + -+/* count the number of LDAPMod in the structure */ ++/*! Count the number of LDAPMod in the structure */ +static int +_v2l_count_attrs (v2l_LdapRequest *req) +{ @@ -1182,7 +1303,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c +#endif + +static void -+_v2l_free_callback (xht h, const char *key, void *val, void *arg) ++_v2l_free_walker (xht h, const char *key, void *val, void *arg) +{ + _v2l_free_conn (h, key, val); +} @@ -1200,7 +1321,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c +} + +static void -+_v2l_free_expired (xht h, const char *key, void *val, void *arg) ++_v2l_free_expired_walker (xht h, const char *key, void *val, void *arg) +{ + v2l_LdapConn *temp_conn = (v2l_LdapConn *) val; + @@ -1221,7 +1342,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c + /* V2L_CONN_LIST has been freed? */ + if (V2L_CONN_LIST != NULL) + { -+ xhash_walk (V2L_CONN_LIST, _v2l_free_expired, NULL); ++ xhash_walk (V2L_CONN_LIST, _v2l_free_expired_walker, NULL); + } +#ifndef _V2L_JABBER2 + pth_sleep (V2L_CONN_LIFETIME); @@ -1273,10 +1394,52 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.c jabberd-2.1.14/sm/v2l_conn.c + + xhash_put (V2L_CONN_LIST, ldap_conn->user, (void *) ldap_conn); +} ++ ++void ++v2l_ldap_for_all_attrs(v2l_AttrValueFunction value_func, ++ v2l_AttrMatchFunction match_func, void *pointer, v2l_LdapEvt *evt_res) ++{ ++ LDAPMessage *current_result; ++ BerElement *ber; ++ char *current_attr, **vals; ++ void *shrdata; ++ ++ current_result = ldap_first_entry (evt_res->ld, evt_res->result); ++ current_attr = ldap_first_attribute (evt_res->ld, current_result, &ber); ++ ++ /* step through each attribute in objectclass */ ++ for (; ++ current_attr != NULL; ++ current_attr = ldap_next_attribute (evt_res->ld, current_result, ber)) ++ { ++ ++ if (match_func (current_attr, &shrdata)) ++ { ++ vals = ldap_get_values (evt_res->ld, current_result, current_attr); ++ value_func (current_attr, (const char **) vals, pointer, shrdata); ++ ++ if (vals != NULL) ++ { ++ ldap_value_free (vals); ++ } ++ } ++ ++ ldap_memfree (current_attr); ++ } /* attributes loop */ ++ ++ if (ber != NULL) ++ { ++ ber_free (ber, 0); ++ } ++ ++ /* don't forget to free the next attribute */ ++ ldap_memfree (current_attr); ++ ldap_msgfree (evt_res->result); ++} diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.h jabberd-2.1.14/sm/v2l_conn.h --- jabberd-2.1.14.orig/sm/v2l_conn.h 1970-01-01 01:00:00.000000000 +0100 -+++ jabberd-2.1.14/sm/v2l_conn.h 2007-09-25 17:23:52.000000000 +0200 -@@ -0,0 +1,105 @@ ++++ jabberd-2.1.14/sm/v2l_conn.h 2007-09-27 01:03:26.000000000 +0200 +@@ -0,0 +1,143 @@ +/* + * 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 @@ -1293,7 +1456,9 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.h jabberd-2.1.14/sm/v2l_conn.h + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + -+/*! \file v2l_conn.h */ ++/*! \file v2l_conn.h ++ \brief Handling the LDAP directory. Low-level tier. ++*/ + +#ifndef __V2L_CONN_H +#define __V2L_CONN_H @@ -1315,9 +1480,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.h jabberd-2.1.14/sm/v2l_conn.h + struct v2l_LdapConn *next; +} v2l_LdapConn; + -+/*! \brief Request (SLL) for LDAP directory. -+ Store LDAP request to be executed after having retrieved vCard data. -+*/ ++/*! \brief Request (SLL) for LDAP directory */ +typedef struct v2l_LdapRequest +{ + LDAPMod *attr; @@ -1325,7 +1488,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.h jabberd-2.1.14/sm/v2l_conn.h +} v2l_LdapRequest; + +/*! \brief LDAP environment. -+ Control struct for perform operations on LDAP directory and retrieve ++ Control struct for perform operations on the LDAP directory and retrieve + results. +*/ +typedef struct v2l_LdapEvt @@ -1336,35 +1499,63 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.h jabberd-2.1.14/sm/v2l_conn.h + LDAPMessage *result; /*!< LDAP result (see OpenLDAP API docs) */ +} v2l_LdapEvt; + -+/*! \brief Get a (ephemeral) connection by name. Creates one if doesn't exist. -+ Precondition: self is valid, user is not null ++/*! \brief Match function type ++ Generic attribute matching routine. ++ \param attr The attribute. ++ \param[out] shrdata Generic deferenced pointer. Shared data with a 'value ++ function' ++ \sa v2l_AttrValueFunction ++ \sa v2l_ldap_for_all_attrs ++ \return true if matching, otherwise false. ++*/ ++typedef int (*v2l_AttrMatchFunction) (const char *attr, void **shrdata); ++ ++/*! \brief Values read function type ++ Generic values handling routine. ++ \param attr The attribute. ++ \param vals Values of attribute. ++ \param pointer Generic multipurpose pointer. ++ \param shrdata Shared data with 'match function' ++ \sa v2l_MatchValueFunction ++ \sa v2l_ldap_for_all_attrs ++*/ ++typedef void (*v2l_AttrValueFunction) (const char *attr, const char **vals, ++ void *pointer, void *shrdata); ++ ++/*! \brief Gets a (ephemeral) connection by name. Creates one if doesn't exist. ++ \pre self is valid, user is not null and exists. ++ \post ephermeral connection for user is open. + \param self Module config. + \param user the username + \return the connection if no error, otherwise NULL. +*/ +extern v2l_LdapConn *v2l_get_conn (v2l_Config *self, const char *user); + -+/*! \brief Get a connection master connection. Creates one if doesn't exist. -+ Precondition: self is valid ++/*! \brief Gets a connection master connection. Creates one if doesn't exist. ++ \pre self is valid ++ \post master connection is open. + \param self Module config. + \return the connection if no error, otherwise NULL. +*/ +extern v2l_LdapConn *v2l_get_master_conn (v2l_Config *self); + -+/*! \brief Free and close all connections (ephemeral or not) */ ++/*! \brief Frees and closes all connections (ephemeral or not) ++ If connections doesn't exist does nothing. ++ \post self->master_conn closed. Connections list empty. ++*/ +extern void v2l_free_allconn (); + -+/*! \brief Retrieve an user from the LDAP directory ++/*! \brief Retrieves an user entry from the LDAP directory ++ \note Allocated memory must be freed by the caller. + \param self Module config + \param curr_conn user connection. -+ \param evt_res in out parameter, LDAP descriptor and control code. -+ \return 1 if no error, otherwise 0 ++ \return evt_res LDAP descriptor, control code and result. NULL if error. +*/ -+extern int v2l_ldap_get_entry (v2l_Config *self, v2l_LdapConn *curr_conn, -+ v2l_LdapEvt *evt_res); ++extern v2l_LdapEvt *v2l_ldap_get_entry (v2l_Config *self, ++ v2l_LdapConn *curr_conn); + -+/*! \brief Perform a list of changes on the LDAP directory. -+ Precondition: req != NULL ++/*! \brief Executes a list of changes on the LDAP directory. ++ \pre req is not NULL + \param self Module config + \param curr_conn The user connection. + \param req list of changes. @@ -1373,7 +1564,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.h jabberd-2.1.14/sm/v2l_conn.h +extern int v2l_request_record (v2l_Config *self, v2l_LdapConn *curr_conn, + v2l_LdapRequest *req); + -+/*! \brief Add a new request to the list ++/*! \brief Adds a new request to the list + \param req The list of requests. + \param attr attribute name. + \param str attribute value. @@ -1381,11 +1572,21 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_conn.h jabberd-2.1.14/sm/v2l_conn.h +*/ +extern v2l_LdapRequest *v2l_add_attr_str (v2l_LdapRequest *req, + const char *attr, const char *str); ++ ++/*! \brief Applies a function to all LDAP object attributes. ++ \pre evt_res should be a valid entry (ie. result of a search in directory) ++ \param value_func Walker function. ++ \param match_func Match function. If returns true we'll call to value_func ++ \param pointer Generic multipurpose pointer. It will be passed to value_func ++ \param evt_res LDAP descriptor, control code and result. ++*/ ++extern void v2l_ldap_for_all_attrs (v2l_AttrValueFunction value_func, ++ v2l_AttrMatchFunction match_func, void *pointer, v2l_LdapEvt *evt_res); +#endif diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c --- jabberd-2.1.14.orig/sm/v2l_vcard.c 1970-01-01 01:00:00.000000000 +0100 -+++ jabberd-2.1.14/sm/v2l_vcard.c 2007-09-25 17:23:11.000000000 +0200 -@@ -0,0 +1,554 @@ ++++ jabberd-2.1.14/sm/v2l_vcard.c 2007-09-26 23:46:59.000000000 +0200 +@@ -0,0 +1,588 @@ +/* + * 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 @@ -1402,10 +1603,13 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + -+/*! \file v2l_vcard.c */ ++/*! \file v2l_vcard.c ++ \brief XML vCard's to/from LDAP objects translation functions. ++ Implementation ++*/ + +#include -+#include ++ +#ifndef _V2L_JABBER2 +#include +#else @@ -1416,8 +1620,6 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c +#define log_error log_debug + +#endif -+#include -+#include +#include + +#define LOG_ERROR_MEM log_error(ZONE, "Unable to allocate memory") @@ -1433,34 +1635,88 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c + struct v2l_vCardItem *next; +} v2l_vCardItem; + -+static int _v2l_vcard_maps_init (v2l_Config *self); ++/*! \brief Gets the translation map. ++ If it is not initilized yet, the function reads the template from disk ++ and sets the map. ++ \param self Module config, if map is initialized can be NULL. ++ \return The map, NULL if error. ++*/ ++static v2l_vCardItem *_v2l_vcard_map (v2l_Config *self); + -+/* create the tag */ ++/*! \brief Creates the FN tag ++ Creates FN tag from GIVEN and FAMILY tags. ++ \param vcard The vCard. ++ \return 1 if no error, otherwise 0. ++*/ +static int _v2l_create_fn (xmlnode vcard); -+/* set sn1 and sn2 from sn */ ++ ++/*! \brief Sets sn1 and sn2 from sn ++ Hack. IrisPerson has two surnames: first surname and mother's maiden name. ++ This function splits sn in two. Should be called when the list of request ++ are complete and before program excutes them. ++ \param req The SLL of LDAP requests. ++*/ +static v2l_LdapRequest *_v2l_set_sn12 (v2l_LdapRequest *req); + -+/* mapping functions from LDAP to XML vCard */ -+static xmlnode _v2l_ldap2vcard_generic (v2l_vCardItem *item, char **vals, ++/*! \brief Map function from LDAP to XML vCard ++ \param item Info about the tag (name, parent group and attribute associated) ++ \param vals array of values for the attribe. ++ \param[in,out] res The vCard, output is appended here. ++ \return res + new tag or res if error. ++*/ ++static xmlnode _v2l_ldap2vcard_generic (v2l_vCardItem *item, const char **vals, + xmlnode res); + -+static xmlnode _v2l_ldap2vcard_photo (v2l_vCardItem *item, char **vals, ++/*! \brief Function for maps PHOTO tag. ++ Hack. InetOrgPerson has a jpegphoto attribute so PHOTO/MIMETYPE tag can be ++ only "image/jpeg" ++ \warning The module doesn't support storing avatars in another format (png) ++*/ ++static xmlnode _v2l_ldap2vcard_photo (v2l_vCardItem *item, const char **vals, + xmlnode res); + -+/* mapping functions from XML Vcard to LDAP */ ++/*! \brief Map function from XML Vcard to LDAP ++ \param item Info about the tag (name, parent group and attribute associated) ++ \param data Thhe vCard. ++ \param[in,out] req List of requests, the new request is appended here. ++ \return req + new request or req if error. ++*/ +static v2l_LdapRequest *_v2l_vcard2ldap_generic (v2l_vCardItem *item, + xmlnode data, v2l_LdapRequest *req); + ++/*! \brief Finds tag linked to attr ++ Parses the translation map since 'item' node. ++ \param item Where the search starts. ++ \param attr The attribute; ++ \return node with tag<->attr association or NULL if error or not found. ++*/ +static v2l_vCardItem *_v2l_vcard_find_attr (v2l_vCardItem *item, -+ char *attr); ++ const char *attr); ++ ++/*! \brief Is LDAP object attribute linked to any tag? ++ Utility function. ++ \param attr The attribute. ++ \param[out] shrdata Contents the address of any map's node. NULL if no match ++ \return true if attr is linked to any tag, otherwise false ++*/ ++static int _v2l_vcard_attr_match (const char *attr, void **shrdata); ++ ++/*! \brief Function applied to all attrs. ++ Utility function, walker function. ++ \param attr The attribute. ++ \param vals Values of attribute. ++ \param pointer Deferenced pointer to vCard. ++ \param shrdata Data shared with the match function. ++*/ ++static void _v2l_vcard_attr_value (const char *attr, const char **vals, ++ void *pointer, void *shrdata); ++ +#if 0 +static v2l_vCardItem * + _v2l_vcard_find_tag (v2l_vCardItem *item, char *tag); +#endif + -+static v2l_vCardItem *_V2L_TPL; -+ -+/******* Translation maps */ ++/*! List of all XML vCard tags supported */ +static const char *_V2L_MAP_VCARD [] = { + "FN", + "NICKNAME", @@ -1513,38 +1769,23 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c +}; + +/* public api */ -+ +xmlnode +v2l_vcard_get (v2l_Config *self, v2l_LdapConn *curr_conn) +{ -+ LDAPMessage *current_result; -+ BerElement *ber; + xmlnode vcard; -+ char *current_attr; ++ v2l_LdapEvt *evt_res; + -+ if (!_v2l_vcard_maps_init (self)) ++ if (_v2l_vcard_map (self) == NULL) + { + log_error (ZONE, "Unreadable/malformed vCard template!"); + return NULL; + } + -+ /* LDAP request is asynchronous */ -+ v2l_LdapEvt *evt_res; -+ -+ evt_res = (v2l_LdapEvt *) malloc (sizeof (v2l_LdapEvt)); ++ /* get user info from LDAP */ ++ evt_res = v2l_ldap_get_entry (self, curr_conn); + + if (evt_res == NULL) + { -+ LOG_ERROR_MEM; -+ return NULL; -+ } -+ -+ evt_res->ld = curr_conn->ld; -+ -+ /* get user info from LDAP */ -+ if (v2l_ldap_get_entry (self, curr_conn, evt_res) != 1) -+ { -+ free (evt_res); + return NULL; + } + @@ -1552,52 +1793,10 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c + vcard = xmlnode_new_tag ("vCard"); + xmlnode_put_attrib (vcard, "xmlns", "vcard-temp"); + -+ current_result = ldap_first_entry (evt_res->ld, evt_res->result); -+ -+ /* step through each attribute in objectclass */ -+ for (current_attr = -+ ldap_first_attribute (evt_res->ld, current_result, &ber); -+ current_attr != NULL; -+ current_attr = ldap_next_attribute (evt_res->ld, current_result, ber)) -+ { -+ v2l_vCardItem *match; -+ -+ match = _v2l_vcard_find_attr (_V2L_TPL, current_attr); -+ -+ if (match != NULL) -+ { -+ char **vals; -+ vals = ldap_get_values (evt_res->ld, current_result, current_attr); -+ -+ if (vals != NULL) -+ { -+ /* FIXME: ugly */ -+ if (match->group != NULL && (strcmp (match->group, "PHOTO") == 0)) -+ { -+ _v2l_ldap2vcard_photo (match, vals, vcard); -+ } -+ else -+ { -+ _v2l_ldap2vcard_generic (match, vals, vcard); -+ } -+ -+ ldap_value_free (vals); -+ } -+ } -+ -+ ldap_memfree (current_attr); -+ } -+ -+ if (ber != NULL) -+ { -+ ber_free (ber, 0); -+ } ++ v2l_ldap_for_all_attrs (_v2l_vcard_attr_value, _v2l_vcard_attr_match, vcard, ++ evt_res); + -+ /* don't forget to free the next attribute */ -+ ldap_memfree (current_attr); -+ ldap_msgfree (evt_res->result); + free (evt_res); -+ + _v2l_create_fn (vcard); + + return vcard; @@ -1616,14 +1815,14 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c + return 0; + } + -+ if (!_v2l_vcard_maps_init (self)) ++ item = _v2l_vcard_map (self); ++ ++ if (item == NULL) + { + log_error (ZONE, "Unreadable/Malformed vCard template!"); + return 0; + } + -+ item = _V2L_TPL; -+ + do + { + if (strcmp (item->vcard, "FN") == 0) /* FIXME: ugly */ @@ -1658,75 +1857,79 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c + +/* public api ends here */ + -+static int -+_v2l_vcard_maps_init (v2l_Config *self) ++static v2l_vCardItem * ++_v2l_vcard_map (v2l_Config *self) +{ ++ static v2l_vCardItem *_V2L_TPL = NULL; + xmlnode tpl, tag; + char **stag, *tmp, group[10]; + v2l_vCardItem *item; + -+ if (_V2L_TPL != NULL) -+ { -+ return 1; -+ } -+ -+ tpl = xmlnode_file (self->confpath); -+ -+ for (stag = (char **) _V2L_MAP_VCARD; *stag != NULL; stag++) ++ if (_V2L_TPL == NULL && self != NULL && self->confpath != NULL) + { -+ tmp = strchr(*stag, '/'); ++ tpl = xmlnode_file (self->confpath); + -+ if (tmp == NULL) ++ if (tpl == NULL) + { -+ group[0] = 0; -+ tmp = *stag; -+ } -+ else -+ { -+ sprintf(group, "%.*s", tmp - *stag, *stag); -+ tmp++; ++ return NULL; + } + -+ tag = xmlnode_get_tag (tpl, *stag); -+ -+ if (xmlnode_get_data(tag) != NULL) ++ for (stag = (char **) _V2L_MAP_VCARD; *stag != NULL; stag++) + { -+ int ntags = 0; -+ char find_attr[30]; ++ tmp = strchr(*stag, '/'); + -+ do ++ if (tmp == NULL) ++ { ++ group[0] = 0; ++ tmp = *stag; ++ } ++ else + { -+ v2l_vCardItem *ptr; ++ sprintf(group, "%.*s", tmp - *stag, *stag); ++ tmp++; ++ } + -+ ptr = (v2l_vCardItem *) pmalloc (self->poolref, -+ sizeof(v2l_vCardItem)); ++ tag = xmlnode_get_tag (tpl, *stag); + -+ ptr->vcard = tmp; -+ ptr->ldap = pstrdup (self->poolref, xmlnode_get_data(tag)); -+ ptr->next = NULL; -+ ptr->group = group[0] == 0 ? NULL : -+ pstrdup (self->poolref, group); ++ if (xmlnode_get_data(tag) != NULL) ++ { ++ int ntags = 0; ++ char find_attr[30]; + -+ if (_V2L_TPL == NULL) ++ do + { -+ _V2L_TPL = ptr; -+ item = ptr; -+ } -+ else -+ { -+ item->next = ptr; -+ item = item->next; -+ } ++ v2l_vCardItem *ptr; + -+ sprintf (find_attr, "%s?v2ln=%d", *stag, ++ntags); -+ tag = xmlnode_get_tag (tpl, find_attr); -+ } while (tag && xmlnode_get_data (tag) != NULL && ntags < 10); -+ } -+ } ++ ptr = (v2l_vCardItem *) pmalloc (self->poolref, ++ sizeof(v2l_vCardItem)); + -+ xmlnode_free (tpl); ++ ptr->vcard = tmp; ++ ptr->ldap = pstrdup (self->poolref, xmlnode_get_data(tag)); ++ ptr->next = NULL; ++ ptr->group = group[0] == 0 ? NULL : ++ pstrdup (self->poolref, group); + -+ return 1; ++ if (_V2L_TPL == NULL) ++ { ++ _V2L_TPL = ptr; ++ item = ptr; ++ } ++ else ++ { ++ item->next = ptr; ++ item = item->next; ++ } ++ ++ sprintf (find_attr, "%s?v2ln=%d", *stag, ++ntags); ++ tag = xmlnode_get_tag (tpl, find_attr); ++ } while (tag && xmlnode_get_data (tag) != NULL && ntags < 10); ++ }/* xmlnode_get_data(tag) != NULL */ ++ } /* for loop, all tags in template */ ++ ++ xmlnode_free (tpl); ++ } ++ ++ return _V2L_TPL; +} + +#if 0 @@ -1751,7 +1954,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c +#endif + +static v2l_vCardItem * -+_v2l_vcard_find_attr (v2l_vCardItem *item, char *attr) ++_v2l_vcard_find_attr (v2l_vCardItem *item, const char *attr) +{ + v2l_vCardItem *res = NULL; + @@ -1770,6 +1973,38 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c +} + +static int ++_v2l_vcard_attr_match (const char *attr, void **shrdata) ++{ ++ *shrdata = _v2l_vcard_find_attr (_v2l_vcard_map (NULL), attr); ++ ++ return *shrdata != NULL; ++} ++ ++static void ++_v2l_vcard_attr_value (const char *attr, const char **vals, void *pointer, ++ void *shrdata) ++{ ++ xmlnode vcard; ++ v2l_vCardItem *match; ++ ++ vcard = (xmlnode) pointer; ++ match = (v2l_vCardItem *) shrdata; ++ ++ if (vals != NULL) ++ { ++ /* FIXME: ugly */ ++ if (match->group != NULL && (strcmp (match->group, "PHOTO") == 0)) ++ { ++ _v2l_ldap2vcard_photo (match, vals, vcard); ++ } ++ else ++ { ++ _v2l_ldap2vcard_generic (match, vals, vcard); ++ } ++ } ++} ++ ++static int +_v2l_create_fn (xmlnode vcard) +{ + xmlnode n, fn; @@ -1820,7 +2055,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c +/* LDAP -> vCard */ + +static xmlnode -+_v2l_ldap2vcard_generic (v2l_vCardItem *item, char **vals, xmlnode res) ++_v2l_ldap2vcard_generic (v2l_vCardItem *item, const char **vals, xmlnode res) +{ + xmlnode node; + @@ -1845,7 +2080,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c +} + +static xmlnode -+_v2l_ldap2vcard_photo (v2l_vCardItem *item, char **vals, xmlnode res) ++_v2l_ldap2vcard_photo (v2l_vCardItem *item, const char **vals, xmlnode res) +{ + xmlnode mimetype, photo; + @@ -1935,15 +2170,15 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.c jabberd-2.1.14/sm/v2l_vcard.c + + req = ptr; + } -+ } /* sn != NULL */ -+ } /* req != NULL */ ++ } /* sn != NULL */ ++ } /* req != NULL */ + + return req; +} diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.h jabberd-2.1.14/sm/v2l_vcard.h --- jabberd-2.1.14.orig/sm/v2l_vcard.h 1970-01-01 01:00:00.000000000 +0100 -+++ jabberd-2.1.14/sm/v2l_vcard.h 2007-09-25 17:21:00.000000000 +0200 -@@ -0,0 +1,39 @@ ++++ jabberd-2.1.14/sm/v2l_vcard.h 2007-09-26 23:52:13.000000000 +0200 +@@ -0,0 +1,41 @@ +/* + * 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 @@ -1960,7 +2195,9 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.h jabberd-2.1.14/sm/v2l_vcard.h + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + -+/*! \file v2l_vcard.h */ ++/*! \file v2l_vcard.h ++ \brief XML vCard's to/from LDAP objects translation functions. ++*/ + +#ifndef __V2L_VCARD_H +#define __V2L_VCARD_H @@ -1970,7 +2207,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.h jabberd-2.1.14/sm/v2l_vcard.h +/*! \brief Gets user vCard in xml format + \param self Module config + \param curr_conn user connection. -+ \return father node of vCard, NULL if error. ++ \return vCard main node, NULL if error. +*/ +extern xmlnode v2l_vcard_get (v2l_Config *self, v2l_LdapConn *curr_conn); + @@ -1985,7 +2222,7 @@ diff -Naurb jabberd-2.1.14.orig/sm/v2l_vcard.h jabberd-2.1.14/sm/v2l_vcard.h +#endif diff -Naurb jabberd-2.1.14.orig/sm/xmlnode.c jabberd-2.1.14/sm/xmlnode.c --- jabberd-2.1.14.orig/sm/xmlnode.c 1970-01-01 01:00:00.000000000 +0100 -+++ jabberd-2.1.14/sm/xmlnode.c 2007-09-08 21:44:09.000000000 +0200 ++++ jabberd-2.1.14/sm/xmlnode.c 2007-09-25 17:45:15.000000000 +0200 @@ -0,0 +1,1029 @@ +/* -------------------------------------------------------------------------- + * diff --git a/src/v2l_config.c b/src/v2l_config.c index 342ea25..c62f835 100644 --- a/src/v2l_config.c +++ b/src/v2l_config.c @@ -14,6 +14,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/*! \file v2l_config.c + \brief Config handling functions. Implementation +*/ + #include #include @@ -30,6 +34,9 @@ typedef pool_t pool; #include #include +/*! \brief Gets value for tag from config + Generic (preprocessor) function for handling Jabberd14/2 config differences +*/ static char *_v2l_config_get_tag (T_CONF conn_base, const char *tag); int diff --git a/src/v2l_conn.c b/src/v2l_conn.c index 012391f..6f415a8 100644 --- a/src/v2l_conn.c +++ b/src/v2l_conn.c @@ -14,10 +14,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/*! \file v2l_conn.c + \brief Handling the LDAP directory. Implementation +*/ + #include -#include -#include -#include #ifndef _V2L_JABBER2 #include @@ -31,39 +32,137 @@ typedef pool_t pool; #endif #include -#include -#define V2L_CONN_LIFETIME 30 /* seconds */ -#define V2L_POLL_INTERVAL 1 /* seconds */ +/*! \brief Lifetime of an ephemeral connection, in seconds + The recall connections thread period. +*/ +#define V2L_CONN_LIFETIME 30 + +/*! How often thread checks for LDAP results, in seconds */ +#define V2L_POLL_INTERVAL 1 #define LOG_ERROR_MEM log_error(ZONE, "Unable to allocate memory") -/* Global hashtable of all currently active LDAP connections */ +/*! Global hashtable of all currently active LDAP connections */ static xht V2L_CONN_LIST = NULL; +/*! \brief Creates new LDAP connection + \param host LDAP hostname. + \param port LDAP port. + \param binddn Bind DN. + \param user User name. + \param passwd User password. + \param expire Boolean, ephemeral connection? + \return LDAP connectior or NULL if error. +*/ static v2l_LdapConn *_v2l_create_conn (char *host, int port, const char *binddn, const char *user, const char *passwd, int expire); -/* NOTE: Allocated memory must be freed by the caller */ +/*! \brief Gets user password + Retrieves user password from LDAP directory using master connection. + \note Allocated memory must be freed by the caller. + \param self Module config. + \param user User name. + \pre self is valid, user is not NULL + \return user password string or NULL if doesn't exist or error. +*/ static char *_v2l_ldap_get_passwd (v2l_Config *self, const char *user); + +/*! \brief Closes and frees a connection. + Utility function, common code for two hash walker functions. + \param h Jabberd hash. Hash table "username"->connection. + \param user User name. + \param val deference pointer to connection. + \sa _v2l_free_walker + \sa _v2l_free_expired_walker +*/ static void _v2l_free_conn (xht h, const char *user, void *val); + +/*! \brief Gets the number or attributes in a LDAP request. + \param[in,out] req The SLL of LDAP requests. + \return number of attributes, 0 if req is NULL. +*/ static int _v2l_count_attrs (v2l_LdapRequest *req); + +/*! \brief Modifies an entry in the LDAP directory + Utility function. + \param dn Entry bind DN + \param attrs List of attributes changed. + \param[in,out] evt_res Control and info parameter. + \return LDAP error code. +*/ static int _v2l_ldap_modify (char *dn, LDAPMod **attrs, v2l_LdapEvt *evt_res); + +/*! \brief Searchs and retrieves an entry from the LDAP directory + Utility function. + \param dn Entry bind DN. + \param suffix LDAP suffix + \param[out] attrs Entry attributes. + \param subtree boolean. Search in a one level or in entire subtree? + \param[in,out] evt_res Control and info parameter. + \return LDAP error code. +*/ static int _v2l_ldap_search (char *dn, char *suffix, char **attrs, int subtree, v2l_LdapEvt *evt_res); + +/*! \brief Waits for LDAP results + Operations on the directory are asynchronous. This is a sync wait function. + \param \param[in,out] evt_res Control and info parameter. +*/ static void _v2l_ldap_sync (v2l_LdapEvt *evt_res); + +/*! \brief Adds LDAP attr to request. + Utility function, hides OpenLDAP API to upper level. + \param[in,out] req The SLL of LDAP requests. + \param attr The attr, LDAPMod pointer. + \return The list of requests + the last added. The list of request if error. +*/ static v2l_LdapRequest *_v2l_add_attr (v2l_LdapRequest *req, LDAPMod *attr); + +/*! \brief Adds a conn to the global list. + If list is empty, initializes it and starts the thread who recalls expired + connections. + \param ldap_conn New connection. +*/ static void _v2l_add_conn (v2l_LdapConn *ldap_conn); -static void _v2l_free_callback (xht h, const char *key, void *val, + +/*! \brief Frees connection unconditionally. + Utility function. Hash walker function. + See jabberd API for details. +*/ +static void _v2l_free_walker (xht h, const char *key, void *val, void *arg); -/* Free connections when its time has expired (periodic thread) */ +/*! \brief Frees connections when its slice time expired (periodic thread) + \dot + digraph G { + rankdir = LR + node [shape = ellipse, fontname = Helvetica fontsize = 12] + {node[style = filled, fontsize = 16, bgcolor = grey] sleep} + {node[shape = circle, label = delete] free} + {node[label = "expired?" ] is_expired} + {node[label = "conn left?" ] any_conn} + sleep -> sleep + sleep -> any_conn [label = " "] + any_conn -> sleep [label = no] + any_conn -> is_expired [label = yes] + is_expired -> free [label = yes] + is_expired -> any_conn [label = no] + free -> any_conn + } + \enddot + \param arg Unused. +*/ static void *_v2l_purge_conn_callback (void *arg); -/* Free connections in a hashtable, walker function */ -static void _v2l_free_expired (xht h, const char *key, void *val, + +/*! \brief Frees expired connections. + Utility function. Hash walker function. + See jabberd API for details. +*/ +static void _v2l_free_expired_walker (xht h, const char *key, void *val, void *arg); -/* A thread for wait for LDAP results */ +/*! A thread for active wait for LDAP results */ static int _v2l_ldap_wait_callback(void *arg); #ifdef _V2L_JABBER2 @@ -128,23 +227,34 @@ v2l_get_master_conn (v2l_Config *self) void v2l_free_allconn () { - xhash_walk (V2L_CONN_LIST, _v2l_free_callback, NULL); + xhash_walk (V2L_CONN_LIST, _v2l_free_walker, NULL); xhash_free (V2L_CONN_LIST); } -int -v2l_ldap_get_entry (v2l_Config *self, v2l_LdapConn *curr_conn, - v2l_LdapEvt *evt_res) +v2l_LdapEvt * +v2l_ldap_get_entry (v2l_Config *self, v2l_LdapConn *curr_conn) { + v2l_LdapEvt *evt_res; int rc; + evt_res = (v2l_LdapEvt *) malloc (sizeof (v2l_LdapEvt)); + + if (evt_res == NULL) + { + LOG_ERROR_MEM; + return NULL; + } + + evt_res->ld = curr_conn->ld; + rc = _v2l_ldap_search (curr_conn->entry, self->suffix, NULL, 1, evt_res); if (rc != LDAP_SUCCESS) { log_error (ZONE, "LDAP error attempting to retrieve user info: %s", ldap_err2string (rc)); - return 0; + free (evt_res); + return NULL; } _v2l_ldap_sync(evt_res); @@ -152,10 +262,11 @@ v2l_ldap_get_entry (v2l_Config *self, v2l_LdapConn *curr_conn, if (ldap_count_entries (evt_res->ld, evt_res->result) != 1) { log_warn (ZONE, "Multiple users with the same dn?"); - return 0; + free (evt_res); + return NULL; } - return 1; + return evt_res; } int @@ -295,7 +406,6 @@ v2l_add_attr_str (v2l_LdapRequest *req, const char *attr, const char *str) return _v2l_add_attr (req, mod); } -/************************/ /* public api ends here */ static v2l_LdapConn * @@ -526,7 +636,7 @@ _v2l_ldap_sync (v2l_LdapEvt *evt_res) #endif } -/* count the number of LDAPMod in the structure */ +/*! Count the number of LDAPMod in the structure */ static int _v2l_count_attrs (v2l_LdapRequest *req) { @@ -630,7 +740,7 @@ _v2l_ldap_wait_callback_g (void *arg) #endif static void -_v2l_free_callback (xht h, const char *key, void *val, void *arg) +_v2l_free_walker (xht h, const char *key, void *val, void *arg) { _v2l_free_conn (h, key, val); } @@ -648,7 +758,7 @@ _v2l_free_conn (xht h, const char *user, void *val) } static void -_v2l_free_expired (xht h, const char *key, void *val, void *arg) +_v2l_free_expired_walker (xht h, const char *key, void *val, void *arg) { v2l_LdapConn *temp_conn = (v2l_LdapConn *) val; @@ -669,7 +779,7 @@ _v2l_purge_conn_callback (void *arg) /* V2L_CONN_LIST has been freed? */ if (V2L_CONN_LIST != NULL) { - xhash_walk (V2L_CONN_LIST, _v2l_free_expired, NULL); + xhash_walk (V2L_CONN_LIST, _v2l_free_expired_walker, NULL); } #ifndef _V2L_JABBER2 pth_sleep (V2L_CONN_LIFETIME); @@ -721,3 +831,45 @@ _v2l_add_conn (v2l_LdapConn *ldap_conn) xhash_put (V2L_CONN_LIST, ldap_conn->user, (void *) ldap_conn); } + +void +v2l_ldap_for_all_attrs(v2l_AttrValueFunction value_func, + v2l_AttrMatchFunction match_func, void *pointer, v2l_LdapEvt *evt_res) +{ + LDAPMessage *current_result; + BerElement *ber; + char *current_attr, **vals; + void *shrdata; + + current_result = ldap_first_entry (evt_res->ld, evt_res->result); + current_attr = ldap_first_attribute (evt_res->ld, current_result, &ber); + + /* step through each attribute in objectclass */ + for (; + current_attr != NULL; + current_attr = ldap_next_attribute (evt_res->ld, current_result, ber)) + { + + if (match_func (current_attr, &shrdata)) + { + vals = ldap_get_values (evt_res->ld, current_result, current_attr); + value_func (current_attr, (const char **) vals, pointer, shrdata); + + if (vals != NULL) + { + ldap_value_free (vals); + } + } + + ldap_memfree (current_attr); + } /* attributes loop */ + + if (ber != NULL) + { + ber_free (ber, 0); + } + + /* don't forget to free the next attribute */ + ldap_memfree (current_attr); + ldap_msgfree (evt_res->result); +} diff --git a/src/v2l_main.c b/src/v2l_main.c index 2732152..60f505f 100644 --- a/src/v2l_main.c +++ b/src/v2l_main.c @@ -14,8 +14,41 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/*! \file v2l_main.c + \brief Module skeleton. + \mainpage + \dot + digraph Packages { + node [shape = plaintext, fontname = Helvetica, fontsize = 12] + server [shape = egg, label = jabberd ] + vcard [ + label =< + + +
v2l_vcard
XML vCard Handling
> + ] + config [ + label =< + + +
v2l_config
Config handling package
> + ] + conn [ + label =< + + +
v2l_conn
LDAP-level package
> + ] + config -> server + vcard -> config + vcard -> conn + conn -> config + server -> vcard + } + \enddot +*/ + #include -#include #include #include #include @@ -28,9 +61,9 @@ static int _v2l_check_attr_value (xmlnode node, char *attr_name, char *attr_value); static void _v2l_shutdown (void *arg); -/* - * xdb_v2l (), module entry point. - */ +/*! \brief Module entry point. + See jabberd14 API docs for details. +*/ #ifdef __cplusplus extern "C" #endif @@ -69,15 +102,18 @@ xdb_v2l (instance i, xmlnode x) log_debug (ZONE, "xdb_v2l has been successfully initialized"); } +/*! \brief shutdown and cleanup callback + See jabberd14 API docs for details. +*/ static void _v2l_shutdown (void *arg) { v2l_config_shutdown ((v2l_Config *) arg); } -/* - * Main callback. Handle xdb packets - */ +/*! \brief Main callback. Handle xdb packets + See jabberd14 API docs for details. +*/ static result _v2l_packets_handler (instance i, dpacket p, void *args) { diff --git a/src/v2l_vcard.c b/src/v2l_vcard.c index fdc31d8..9fb6037 100644 --- a/src/v2l_vcard.c +++ b/src/v2l_vcard.c @@ -14,10 +14,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*! \file v2l_vcard.c */ +/*! \file v2l_vcard.c + \brief XML vCard's to/from LDAP objects translation functions. + Implementation +*/ #include -#include + #ifndef _V2L_JABBER2 #include #else @@ -28,8 +31,6 @@ #define log_error log_debug #endif -#include -#include #include #define LOG_ERROR_MEM log_error(ZONE, "Unable to allocate memory") @@ -45,34 +46,88 @@ typedef struct v2l_vCardItem struct v2l_vCardItem *next; } v2l_vCardItem; -static int _v2l_vcard_maps_init (v2l_Config *self); +/*! \brief Gets the translation map. + If it is not initilized yet, the function reads the template from disk + and sets the map. + \param self Module config, if map is initialized can be NULL. + \return The map, NULL if error. +*/ +static v2l_vCardItem *_v2l_vcard_map (v2l_Config *self); -/* create the tag */ +/*! \brief Creates the FN tag + Creates FN tag from GIVEN and FAMILY tags. + \param vcard The vCard. + \return 1 if no error, otherwise 0. +*/ static int _v2l_create_fn (xmlnode vcard); -/* set sn1 and sn2 from sn */ + +/*! \brief Sets sn1 and sn2 from sn + Hack. IrisPerson has two surnames: first surname and mother's maiden name. + This function splits sn in two. Should be called when the list of request + are complete and before program excutes them. + \param req The SLL of LDAP requests. +*/ static v2l_LdapRequest *_v2l_set_sn12 (v2l_LdapRequest *req); -/* mapping functions from LDAP to XML vCard */ -static xmlnode _v2l_ldap2vcard_generic (v2l_vCardItem *item, char **vals, +/*! \brief Map function from LDAP to XML vCard + \param item Info about the tag (name, parent group and attribute associated) + \param vals array of values for the attribe. + \param[in,out] res The vCard, output is appended here. + \return res + new tag or res if error. +*/ +static xmlnode _v2l_ldap2vcard_generic (v2l_vCardItem *item, const char **vals, xmlnode res); -static xmlnode _v2l_ldap2vcard_photo (v2l_vCardItem *item, char **vals, +/*! \brief Function for maps PHOTO tag. + Hack. InetOrgPerson has a jpegphoto attribute so PHOTO/MIMETYPE tag can be + only "image/jpeg" + \warning The module doesn't support storing avatars in another format (png) +*/ +static xmlnode _v2l_ldap2vcard_photo (v2l_vCardItem *item, const char **vals, xmlnode res); -/* mapping functions from XML Vcard to LDAP */ +/*! \brief Map function from XML Vcard to LDAP + \param item Info about the tag (name, parent group and attribute associated) + \param data Thhe vCard. + \param[in,out] req List of requests, the new request is appended here. + \return req + new request or req if error. +*/ static v2l_LdapRequest *_v2l_vcard2ldap_generic (v2l_vCardItem *item, xmlnode data, v2l_LdapRequest *req); +/*! \brief Finds tag linked to attr + Parses the translation map since 'item' node. + \param item Where the search starts. + \param attr The attribute; + \return node with tag<->attr association or NULL if error or not found. +*/ static v2l_vCardItem *_v2l_vcard_find_attr (v2l_vCardItem *item, - char *attr); + const char *attr); + +/*! \brief Is LDAP object attribute linked to any tag? + Utility function. + \param attr The attribute. + \param[out] shrdata Contents the address of any map's node. NULL if no match + \return true if attr is linked to any tag, otherwise false +*/ +static int _v2l_vcard_attr_match (const char *attr, void **shrdata); + +/*! \brief Function applied to all attrs. + Utility function, walker function. + \param attr The attribute. + \param vals Values of attribute. + \param pointer Deferenced pointer to vCard. + \param shrdata Data shared with the match function. +*/ +static void _v2l_vcard_attr_value (const char *attr, const char **vals, + void *pointer, void *shrdata); + #if 0 static v2l_vCardItem * _v2l_vcard_find_tag (v2l_vCardItem *item, char *tag); #endif -static v2l_vCardItem *_V2L_TPL; - -/******* Translation maps */ +/*! List of all XML vCard tags supported */ static const char *_V2L_MAP_VCARD [] = { "FN", "NICKNAME", @@ -125,38 +180,23 @@ static const char *_V2L_MAP_VCARD [] = { }; /* public api */ - xmlnode v2l_vcard_get (v2l_Config *self, v2l_LdapConn *curr_conn) { - LDAPMessage *current_result; - BerElement *ber; xmlnode vcard; - char *current_attr; + v2l_LdapEvt *evt_res; - if (!_v2l_vcard_maps_init (self)) + if (_v2l_vcard_map (self) == NULL) { log_error (ZONE, "Unreadable/malformed vCard template!"); return NULL; } - /* LDAP request is asynchronous */ - v2l_LdapEvt *evt_res; - - evt_res = (v2l_LdapEvt *) malloc (sizeof (v2l_LdapEvt)); + /* get user info from LDAP */ + evt_res = v2l_ldap_get_entry (self, curr_conn); if (evt_res == NULL) { - LOG_ERROR_MEM; - return NULL; - } - - evt_res->ld = curr_conn->ld; - - /* get user info from LDAP */ - if (v2l_ldap_get_entry (self, curr_conn, evt_res) != 1) - { - free (evt_res); return NULL; } @@ -164,52 +204,10 @@ v2l_vcard_get (v2l_Config *self, v2l_LdapConn *curr_conn) vcard = xmlnode_new_tag ("vCard"); xmlnode_put_attrib (vcard, "xmlns", "vcard-temp"); - current_result = ldap_first_entry (evt_res->ld, evt_res->result); - - /* step through each attribute in objectclass */ - for (current_attr = - ldap_first_attribute (evt_res->ld, current_result, &ber); - current_attr != NULL; - current_attr = ldap_next_attribute (evt_res->ld, current_result, ber)) - { - v2l_vCardItem *match; - - match = _v2l_vcard_find_attr (_V2L_TPL, current_attr); - - if (match != NULL) - { - char **vals; - vals = ldap_get_values (evt_res->ld, current_result, current_attr); - - if (vals != NULL) - { - /* FIXME: ugly */ - if (match->group != NULL && (strcmp (match->group, "PHOTO") == 0)) - { - _v2l_ldap2vcard_photo (match, vals, vcard); - } - else - { - _v2l_ldap2vcard_generic (match, vals, vcard); - } - - ldap_value_free (vals); - } - } - - ldap_memfree (current_attr); - } - - if (ber != NULL) - { - ber_free (ber, 0); - } + v2l_ldap_for_all_attrs (_v2l_vcard_attr_value, _v2l_vcard_attr_match, vcard, + evt_res); - /* don't forget to free the next attribute */ - ldap_memfree (current_attr); - ldap_msgfree (evt_res->result); free (evt_res); - _v2l_create_fn (vcard); return vcard; @@ -228,14 +226,14 @@ v2l_vcard_set (v2l_Config *self, v2l_LdapConn *curr_conn, xmlnode data) return 0; } - if (!_v2l_vcard_maps_init (self)) + item = _v2l_vcard_map (self); + + if (item == NULL) { log_error (ZONE, "Unreadable/Malformed vCard template!"); return 0; } - item = _V2L_TPL; - do { if (strcmp (item->vcard, "FN") == 0) /* FIXME: ugly */ @@ -270,75 +268,79 @@ is_fn: /* public api ends here */ -static int -_v2l_vcard_maps_init (v2l_Config *self) +static v2l_vCardItem * +_v2l_vcard_map (v2l_Config *self) { + static v2l_vCardItem *_V2L_TPL = NULL; xmlnode tpl, tag; char **stag, *tmp, group[10]; v2l_vCardItem *item; - if (_V2L_TPL != NULL) - { - return 1; - } - - tpl = xmlnode_file (self->confpath); - - for (stag = (char **) _V2L_MAP_VCARD; *stag != NULL; stag++) + if (_V2L_TPL == NULL && self != NULL && self->confpath != NULL) { - tmp = strchr(*stag, '/'); + tpl = xmlnode_file (self->confpath); - if (tmp == NULL) - { - group[0] = 0; - tmp = *stag; - } - else + if (tpl == NULL) { - sprintf(group, "%.*s", tmp - *stag, *stag); - tmp++; + return NULL; } - tag = xmlnode_get_tag (tpl, *stag); - - if (xmlnode_get_data(tag) != NULL) + for (stag = (char **) _V2L_MAP_VCARD; *stag != NULL; stag++) { - int ntags = 0; - char find_attr[30]; + tmp = strchr(*stag, '/'); - do + if (tmp == NULL) { - v2l_vCardItem *ptr; + group[0] = 0; + tmp = *stag; + } + else + { + sprintf(group, "%.*s", tmp - *stag, *stag); + tmp++; + } - ptr = (v2l_vCardItem *) pmalloc (self->poolref, - sizeof(v2l_vCardItem)); + tag = xmlnode_get_tag (tpl, *stag); - ptr->vcard = tmp; - ptr->ldap = pstrdup (self->poolref, xmlnode_get_data(tag)); - ptr->next = NULL; - ptr->group = group[0] == 0 ? NULL : - pstrdup (self->poolref, group); + if (xmlnode_get_data(tag) != NULL) + { + int ntags = 0; + char find_attr[30]; - if (_V2L_TPL == NULL) + do { - _V2L_TPL = ptr; - item = ptr; - } - else - { - item->next = ptr; - item = item->next; - } - - sprintf (find_attr, "%s?v2ln=%d", *stag, ++ntags); - tag = xmlnode_get_tag (tpl, find_attr); - } while (tag && xmlnode_get_data (tag) != NULL && ntags < 10); - } + v2l_vCardItem *ptr; + + ptr = (v2l_vCardItem *) pmalloc (self->poolref, + sizeof(v2l_vCardItem)); + + ptr->vcard = tmp; + ptr->ldap = pstrdup (self->poolref, xmlnode_get_data(tag)); + ptr->next = NULL; + ptr->group = group[0] == 0 ? NULL : + pstrdup (self->poolref, group); + + if (_V2L_TPL == NULL) + { + _V2L_TPL = ptr; + item = ptr; + } + else + { + item->next = ptr; + item = item->next; + } + + sprintf (find_attr, "%s?v2ln=%d", *stag, ++ntags); + tag = xmlnode_get_tag (tpl, find_attr); + } while (tag && xmlnode_get_data (tag) != NULL && ntags < 10); + }/* xmlnode_get_data(tag) != NULL */ + } /* for loop, all tags in template */ + + xmlnode_free (tpl); } - xmlnode_free (tpl); - - return 1; + return _V2L_TPL; } #if 0 @@ -363,7 +365,7 @@ _v2l_vcard_find_tag (v2l_vCardItem *item, char *tag) #endif static v2l_vCardItem * -_v2l_vcard_find_attr (v2l_vCardItem *item, char *attr) +_v2l_vcard_find_attr (v2l_vCardItem *item, const char *attr) { v2l_vCardItem *res = NULL; @@ -382,6 +384,38 @@ _v2l_vcard_find_attr (v2l_vCardItem *item, char *attr) } static int +_v2l_vcard_attr_match (const char *attr, void **shrdata) +{ + *shrdata = _v2l_vcard_find_attr (_v2l_vcard_map (NULL), attr); + + return *shrdata != NULL; +} + +static void +_v2l_vcard_attr_value (const char *attr, const char **vals, void *pointer, + void *shrdata) +{ + xmlnode vcard; + v2l_vCardItem *match; + + vcard = (xmlnode) pointer; + match = (v2l_vCardItem *) shrdata; + + if (vals != NULL) + { + /* FIXME: ugly */ + if (match->group != NULL && (strcmp (match->group, "PHOTO") == 0)) + { + _v2l_ldap2vcard_photo (match, vals, vcard); + } + else + { + _v2l_ldap2vcard_generic (match, vals, vcard); + } + } +} + +static int _v2l_create_fn (xmlnode vcard) { xmlnode n, fn; @@ -432,7 +466,7 @@ _v2l_create_fn (xmlnode vcard) /* LDAP -> vCard */ static xmlnode -_v2l_ldap2vcard_generic (v2l_vCardItem *item, char **vals, xmlnode res) +_v2l_ldap2vcard_generic (v2l_vCardItem *item, const char **vals, xmlnode res) { xmlnode node; @@ -457,7 +491,7 @@ _v2l_ldap2vcard_generic (v2l_vCardItem *item, char **vals, xmlnode res) } static xmlnode -_v2l_ldap2vcard_photo (v2l_vCardItem *item, char **vals, xmlnode res) +_v2l_ldap2vcard_photo (v2l_vCardItem *item, const char **vals, xmlnode res) { xmlnode mimetype, photo; @@ -547,8 +581,8 @@ _v2l_set_sn12 (v2l_LdapRequest *req) req = ptr; } - } /* sn != NULL */ - } /* req != NULL */ + } /* sn != NULL */ + } /* req != NULL */ return req; } -- 2.11.4.GIT