presence.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /**
  42. * IM Presence plug-in
  43. */
  44. #include <stdio.h>
  45. #include <ctype.h>
  46. #include <string.h>
  47. #include "portable.h"
  48. #include "nspr.h"
  49. #include "slapi-plugin.h"
  50. #include "slapi-private.h"
  51. #include "vattr_spi.h"
  52. #include "plhash.h"
  53. #include "ldif.h"
  54. #include "http_client.h"
  55. /* get file mode flags for unix */
  56. #ifndef _WIN32
  57. #include <sys/stat.h>
  58. #endif
  59. /*** from proto-slap.h ***/
  60. int slapd_log_error_proc( char *subsystem, char *fmt, ... );
  61. /*** from ldaplog.h ***/
  62. /* edited ldaplog.h for LDAPDebug()*/
  63. #ifndef _LDAPLOG_H
  64. #define _LDAPLOG_H
  65. #ifdef __cplusplus
  66. extern "C" {
  67. #endif
  68. #define LDAP_DEBUG_TRACE 0x00001 /* 1 */
  69. #define LDAP_DEBUG_ANY 0x04000 /* 16384 */
  70. #define LDAP_DEBUG_PLUGIN 0x10000 /* 65536 */
  71. /* debugging stuff */
  72. # ifdef _WIN32
  73. extern int *module_ldap_debug;
  74. # define LDAPDebugLevelIsSet( level ) ( *module_ldap_debug & level )
  75. # else /* _WIN32 */
  76. extern int slapd_ldap_debug;
  77. # define LDAPDebugLevelIsSet( level ) ( slapd_ldap_debug & level )
  78. # endif /* Win32 */
  79. #define LDAPDebug( level, fmt, arg1, arg2, arg3 ) \
  80. { \
  81. if ( LDAPDebugLevelIsSet( level )) { \
  82. slapd_log_error_proc( NULL, fmt, arg1, arg2, arg3 ); \
  83. } \
  84. }
  85. #ifdef __cplusplus
  86. }
  87. #endif
  88. #endif /* _LDAP_H */
  89. #define PRESENCE_PLUGIN_SUBSYSTEM "presence-plugin"
  90. #define PRESENCE_PLUGIN_VERSION 0x00050050
  91. /**
  92. * this may become unnecessary when we are able to get
  93. * the plug-in DN dynamically (pete?)
  94. */
  95. #define PRESENCE_DN "cn=Presence,cn=plugins,cn=config" /* temporary */
  96. #define PRESENCE_SUCCESS 0
  97. #define PRESENCE_FAILURE -1
  98. /**
  99. * Presence vendor specific config parameters
  100. */
  101. #define NS_IM_ID "nsIM-ID"
  102. #define NS_IM_URL_TEXT "nsIM-URLText"
  103. #define NS_IM_URL_GRAPHIC "nsIM-URLGraphic"
  104. #define NS_IM_ON_VALUE_MAP_TEXT "nsIM-OnValueMapText"
  105. #define NS_IM_OFF_VALUE_MAP_TEXT "nsIM-OffValueMapText"
  106. #define NS_IM_ON_VALUE_MAP_GRAPHIC "nsIM-OnValueMapGraphic"
  107. #define NS_IM_OFF_VALUE_MAP_GRAPHIC "nsIM-OffValueMapGraphic"
  108. #define NS_IM_DISABLED_VALUE_MAP_GRAPHIC "nsIM-disabledValueMapGraphic"
  109. #define NS_IM_REQUEST_METHOD "nsIM-RequestMethod"
  110. #define NS_IM_URL_TEXT_RETURN_TYPE "nsIM-URLTextReturnType"
  111. #define NS_IM_URL_GRAPHIC_RETURN_TYPE "nsIM-URLGraphicReturnType"
  112. #define NS_IM_STATUS_TEXT "nsIM-StatusText"
  113. #define NS_IM_STATUS_GRAPHIC "nsIM-StatusGraphic"
  114. #define PRESENCE_STRING 1
  115. #define PRESENCE_BINARY 2
  116. #define PRESENCE_TEXT_RETURN_TYPE "TEXT"
  117. #define PRESENCE_BINARY_RETURN_TYPE "BINARY"
  118. #define PRESENCE_REQUEST_METHOD_GET "GET"
  119. #define PRESENCE_REQUEST_METHOD_REDIRECT "REDIRECT"
  120. #define PRESENCE_RETURNED_ON_TEXT "ONLINE"
  121. #define PRESENCE_RETURNED_OFF_TEXT "OFFLINE"
  122. #define PRESENCE_RETURNED_ERROR_TEXT "ERROR"
  123. static Slapi_PluginDesc pdesc = { "IM Presence",
  124. VENDOR,
  125. PACKAGE_VERSION,
  126. "presence plugin" };
  127. /**
  128. * struct used to pass the argument to PL_Enumerator Callback
  129. */
  130. struct _vattrtypes
  131. {
  132. Slapi_Entry *entry;
  133. vattr_type_list_context *context;
  134. };
  135. /**
  136. * This structure holds the mapping between the virtual attributes and
  137. * the IM IDs. This information is used to find out whether this plugin
  138. * should service the attributes it was asked to. Also, it stores the
  139. * syntax of the attribute. 1 is String and 2 is binary.
  140. */
  141. struct _vattrmap {
  142. char *imID;
  143. int syntax;
  144. };
  145. typedef struct _vattrmap _Vmap;
  146. /**
  147. * struct to store the config values for each presence vendor
  148. */
  149. struct _defs {
  150. char *textURL;
  151. char *graphicURL;
  152. char *onTextMap;
  153. char *offTextMap;
  154. Slapi_Attr *onGraphicMap;
  155. Slapi_Attr *offGraphicMap;
  156. Slapi_Attr *disabledGraphicMap;
  157. char *requestMethod;
  158. char *textReturnType;
  159. char *graphicReturnType;
  160. };
  161. typedef struct _defs _ConfigEntry;
  162. static vattr_sp_handle *_VattrHandle = NULL;
  163. static void *_PluginID = NULL;
  164. static char *_PluginDN = NULL;
  165. static PLHashTable *_IdVattrMapTable = NULL;
  166. static PLHashTable *_IdConfigMapTable = NULL;
  167. static void **_HttpAPI = NULL;
  168. /**
  169. *
  170. * Presence plug-in management functions
  171. *
  172. */
  173. int presence_init(Slapi_PBlock *pb);
  174. int presence_start(Slapi_PBlock *pb);
  175. int presence_close(Slapi_PBlock *pb);
  176. /**
  177. *
  178. * Vattr operation callbacks functions
  179. *
  180. */
  181. static int presence_vattr_get(vattr_sp_handle *handle, vattr_context *c, Slapi_Entry *e, char *type, Slapi_ValueSet** results,int *type_name_disposition, char** actual_type_name, int flags, int *free_flags, void *hint);
  182. static int presence_vattr_compare(vattr_sp_handle *handle, vattr_context *c, Slapi_Entry *e, char *type, Slapi_Value *test_this, int* result, int flags, void *hint);
  183. static int presence_vattr_types(vattr_sp_handle *handle,Slapi_Entry *e,vattr_type_list_context *type_context,int flags);
  184. /**
  185. *
  186. * Local operation functions
  187. *
  188. */
  189. static int loadPluginConfig();
  190. static int parseConfigEntry(Slapi_Entry *e);
  191. static int imIDExists(Slapi_Entry *e, char *type, char **value, _Vmap **map, _ConfigEntry **entry);
  192. static int makeHttpRequest(char *id, _Vmap *map, _ConfigEntry *info, char **buf, int *size);
  193. static char * replaceIdWithValue(char *str, char *id, char *value);
  194. static int setIMStatus(char *id, _Vmap *map, _ConfigEntry *info, char *returnedBUF, int size, Slapi_ValueSet **results);
  195. static int setTypes(PLHashEntry *he, PRIntn i, void *arg);
  196. static void deleteMapTables();
  197. static PRIntn destroyHashEntry(PLHashEntry *he, PRIntn index, void *arg);
  198. static void logGraphicAttributeValue( Slapi_Attr *attr, const char *attrname );
  199. static void toLowerCase(char* str);
  200. /**
  201. * utility function
  202. */
  203. void printMapTable();
  204. PRIntn printIdVattrMapTable(PLHashEntry *he, PRIntn i, void *arg);
  205. PRIntn printIdConfigMapTable(PLHashEntry *he, PRIntn i, void *arg);
  206. /**
  207. * set the debug level
  208. */
  209. #ifdef _WIN32
  210. int *module_ldap_debug = 0;
  211. void plugin_init_debug_level(int *level_ptr)
  212. {
  213. module_ldap_debug = level_ptr;
  214. }
  215. #endif
  216. /**
  217. *
  218. * Get the presence plug-in version
  219. *
  220. */
  221. int presence_version()
  222. {
  223. return PRESENCE_PLUGIN_VERSION;
  224. }
  225. /**
  226. * Plugin identity mgmt
  227. */
  228. void setPluginID(void * pluginID)
  229. {
  230. _PluginID=pluginID;
  231. }
  232. void * getPluginID()
  233. {
  234. return _PluginID;
  235. }
  236. void setPluginDN(char *pluginDN)
  237. {
  238. _PluginDN = pluginDN;
  239. }
  240. char * getPluginDN()
  241. {
  242. return _PluginDN;
  243. }
  244. /*
  245. presence_init
  246. -------------
  247. adds our callbacks to the list
  248. */
  249. int presence_init( Slapi_PBlock *pb )
  250. {
  251. int status = PRESENCE_SUCCESS;
  252. char * plugin_identity=NULL;
  253. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> presence_init -- BEGIN\n",0,0,0);
  254. /**
  255. * Store the plugin identity for later use.
  256. * Used for internal operations
  257. */
  258. slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
  259. PR_ASSERT (plugin_identity);
  260. setPluginID(plugin_identity);
  261. if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
  262. SLAPI_PLUGIN_VERSION_01 ) != 0 ||
  263. slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
  264. (void *) presence_start ) != 0 ||
  265. slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
  266. (void *) presence_close ) != 0 ||
  267. slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
  268. (void *)&pdesc ) != 0 )
  269. {
  270. slapi_log_error( SLAPI_LOG_FATAL, PRESENCE_PLUGIN_SUBSYSTEM,
  271. "presence_init: failed to register plugin\n" );
  272. status = PRESENCE_FAILURE;
  273. }
  274. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- presence_init -- END\n",0,0,0);
  275. return status;
  276. }
  277. /*
  278. presence_start
  279. --------------
  280. This function registers the computed attribute evaluator
  281. and loads the configuration parameters in the local cache.
  282. It is called after presence_init.
  283. */
  284. int presence_start( Slapi_PBlock *pb )
  285. {
  286. char * plugindn = NULL;
  287. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> presence_start -- begin\n",0,0,0);
  288. if(slapi_apib_get_interface(HTTP_v1_0_GUID, &_HttpAPI))
  289. {
  290. /**
  291. * error cannot proceeed
  292. */
  293. return PRESENCE_FAILURE;
  294. }
  295. /**
  296. * register our vattr callbacks
  297. */
  298. if (slapi_vattrspi_register((vattr_sp_handle **)&_VattrHandle,
  299. presence_vattr_get,
  300. presence_vattr_compare,
  301. presence_vattr_types) != 0)
  302. {
  303. slapi_log_error( SLAPI_LOG_FATAL, PRESENCE_PLUGIN_SUBSYSTEM,
  304. "presence_start: cannot register as service provider\n" );
  305. return PRESENCE_FAILURE;
  306. }
  307. /**
  308. * Get the plug-in target dn from the system
  309. * and store it for future use. This should avoid
  310. * hardcoding of DN's in the code.
  311. */
  312. slapi_pblock_get(pb, SLAPI_TARGET_DN, &plugindn);
  313. if (plugindn == NULL || strlen(plugindn) == 0)
  314. {
  315. /**
  316. * This is not required as the above statement
  317. * should work and give you a valid DN for this
  318. * plugin. ??? remove it later
  319. */
  320. plugindn = PRESENCE_DN;
  321. }
  322. setPluginDN(plugindn);
  323. /**
  324. * Load the config info for our plug-in in memory
  325. * In the 6.0 release this information will be stored
  326. * statically and if any change is done to this info a server
  327. * restart is necessary :-(. Probably if time permits then
  328. * state change plug-in would be used to notify the state
  329. * change. We also register the virtual attributes we are
  330. * interested in here.
  331. */
  332. if (loadPluginConfig() != PRESENCE_SUCCESS)
  333. {
  334. slapi_log_error( SLAPI_LOG_FATAL, PRESENCE_PLUGIN_SUBSYSTEM,
  335. "presence_start: unable to load plug-in configuration\n" );
  336. return PRESENCE_FAILURE;
  337. }
  338. LDAPDebug( LDAP_DEBUG_PLUGIN, "presence: ready for service\n",0,0,0);
  339. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- presence_start -- end\n",0,0,0);
  340. return PRESENCE_SUCCESS;
  341. }
  342. /*
  343. presence_close
  344. --------------
  345. closes down the cache
  346. */
  347. int presence_close( Slapi_PBlock *pb )
  348. {
  349. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> presence_close\n",0,0,0);
  350. deleteMapTables();
  351. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- presence_close\n",0,0,0);
  352. return PRESENCE_SUCCESS;
  353. }
  354. static int presence_vattr_get(vattr_sp_handle *handle,
  355. vattr_context *c,
  356. Slapi_Entry *e,
  357. char *type,
  358. Slapi_ValueSet** results,
  359. int *type_name_disposition,
  360. char** actual_type_name,
  361. int flags,
  362. int *free_flags,
  363. void *hint)
  364. {
  365. int status = PRESENCE_SUCCESS;
  366. char *id = NULL;
  367. char *returnedBUF = NULL;
  368. int size = 0;
  369. _Vmap *map = NULL;
  370. _ConfigEntry *info = NULL;
  371. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> presence_vattr_get \n",0,0,0);
  372. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> Type=[%s] \n",type,0,0);
  373. if (imIDExists(e, type, &id, &map, &info) != PRESENCE_SUCCESS)
  374. {
  375. /**
  376. * we didn't find any valid matching nsimid in this
  377. * entry so since we cannot process a request without
  378. * a valid nsimid we just return.
  379. */
  380. status = PRESENCE_FAILURE;
  381. goto cleanup;
  382. }
  383. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> ID=[%s] \n",id,0,0);
  384. /**
  385. * Now since we got a valid id we do a quick schema check
  386. * if schema checking is on to make sure that there is no
  387. * schema violation ?
  388. */
  389. /* do_schema_check() */
  390. /**
  391. * At this stage we have a valid attribute and we have to
  392. * get its value from the IM Server. so make an Http request
  393. * depending on whether it is a request for Text or Graphic
  394. */
  395. status = makeHttpRequest(id, map, info, &returnedBUF, &size);
  396. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> size=[%d] \n",size,0,0);
  397. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> buffer=[%s]\n",(returnedBUF) ? returnedBUF : "NULL",0,0);
  398. if(status == PRESENCE_SUCCESS)
  399. {
  400. status = setIMStatus(id, map, info, returnedBUF, size, results);
  401. }
  402. else
  403. {
  404. /**
  405. * Report all HTTP failures as a single predefined value of the
  406. * attribute
  407. */
  408. Slapi_Value *value =
  409. slapi_value_new_string(PRESENCE_RETURNED_ERROR_TEXT);
  410. if (!*results) {
  411. *results = slapi_valueset_new();
  412. }
  413. slapi_valueset_add_value(*results, value);
  414. slapi_value_free(&value); /* slapi_valueset_add_value copies value */
  415. /**
  416. * It's a success only in the sense that we are returning a value
  417. */
  418. status = PRESENCE_SUCCESS;
  419. }
  420. if(status == PRESENCE_SUCCESS)
  421. {
  422. *free_flags = SLAPI_VIRTUALATTRS_RETURNED_COPIES;
  423. *actual_type_name = slapi_ch_strdup(type);
  424. *type_name_disposition = SLAPI_VIRTUALATTRS_TYPE_NAME_MATCHED_EXACTLY_OR_ALIAS;
  425. }
  426. cleanup:
  427. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> Processed ID=[%s] \n",id,0,0);
  428. if (id != NULL ) {
  429. slapi_ch_free((void **)&id);
  430. }
  431. if (returnedBUF != NULL ) {
  432. PR_Free(returnedBUF);
  433. }
  434. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- presence_vattr_get \n",0,0,0);
  435. return status;
  436. }
  437. static int presence_vattr_compare(vattr_sp_handle *handle, vattr_context *c, Slapi_Entry *e, char *type, Slapi_Value *test_this, int* result, int flags, void *hint)
  438. {
  439. int status = PRESENCE_SUCCESS;
  440. /**
  441. * not yet implemented ???
  442. */
  443. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> presence_vattr_compare \n",0,0,0);
  444. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- presence_vattr_compare \n",0,0,0);
  445. return status;
  446. }
  447. static int presence_vattr_types(vattr_sp_handle *handle,Slapi_Entry *e,vattr_type_list_context *type_context,int flags)
  448. {
  449. int status = PRESENCE_SUCCESS;
  450. struct _vattrtypes args;
  451. args.entry = e;
  452. args.context = type_context;
  453. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> presence_vattr_types\n",0,0,0);
  454. PL_HashTableEnumerateEntries(_IdVattrMapTable, setTypes, &args);
  455. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- presence_vattr_types\n",0,0,0);
  456. return status;
  457. }
  458. static int loadPluginConfig()
  459. {
  460. int status = PRESENCE_SUCCESS;
  461. int result;
  462. int i;
  463. Slapi_PBlock *search_pb;
  464. Slapi_Entry **entries = NULL;
  465. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> loadPluginConfig\n",0,0,0);
  466. search_pb = slapi_pblock_new();
  467. slapi_search_internal_set_pb(search_pb, PRESENCE_DN, LDAP_SCOPE_ONELEVEL,
  468. "objectclass=*", NULL, 0, NULL, NULL, getPluginID(), 0);
  469. slapi_search_internal_pb(search_pb);
  470. slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  471. if (status != PRESENCE_SUCCESS)
  472. {
  473. slapi_log_error(SLAPI_LOG_FATAL, PRESENCE_PLUGIN_SUBSYSTEM,
  474. "Error getting level1 presence configurations<%s>\n", getPluginDN());
  475. status = PRESENCE_FAILURE;
  476. goto cleanup;
  477. }
  478. slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  479. if (NULL == entries || entries[0] == NULL)
  480. {
  481. slapi_log_error(SLAPI_LOG_FATAL, PRESENCE_PLUGIN_SUBSYSTEM,
  482. "No entries found for <%s>\n", getPluginDN());
  483. status = PRESENCE_FAILURE;
  484. goto cleanup;
  485. }
  486. _IdVattrMapTable = PL_NewHashTable( 0,
  487. PL_HashString,
  488. PL_CompareStrings,
  489. PL_CompareValues,
  490. NULL,
  491. NULL
  492. );
  493. _IdConfigMapTable = PL_NewHashTable(0,
  494. PL_HashString,
  495. PL_CompareStrings,
  496. PL_CompareValues,
  497. NULL,
  498. NULL
  499. );
  500. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> parseConfigEntry \n",0,0,0);
  501. for (i = 0; (entries[i] != NULL); i++)
  502. {
  503. status = parseConfigEntry(entries[i]);
  504. if (status != PRESENCE_SUCCESS)
  505. {
  506. deleteMapTables();
  507. goto cleanup;
  508. }
  509. }
  510. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- parseConfigEntry \n",0,0,0);
  511. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- loadPluginConfig\n",0,0,0);
  512. cleanup:
  513. slapi_free_search_results_internal(search_pb);
  514. slapi_pblock_destroy(search_pb);
  515. return status;
  516. }
  517. static int parseConfigEntry(Slapi_Entry *e)
  518. {
  519. char *key = NULL;
  520. char *value = NULL;
  521. _ConfigEntry *entry = NULL;
  522. _Vmap *map = NULL;
  523. Slapi_Attr *attr = NULL;
  524. key = slapi_entry_attr_get_charptr(e, NS_IM_ID);
  525. if (!key) {
  526. /**
  527. * IM Id not defined in the config, unfortunately
  528. * cannot do anything without it so better not to
  529. * load the plug-in.
  530. */
  531. return PRESENCE_FAILURE;
  532. }
  533. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> key [%s] \n",key,0,0);
  534. /**
  535. * Now create the config entry which will hold all the
  536. * attributes of a presence vendor
  537. */
  538. entry = (_ConfigEntry*) slapi_ch_calloc(1, sizeof(_ConfigEntry));
  539. /**
  540. * Next 2 are the virtual attributes for which this plug-in
  541. * is responsible. Register them with the vattr system so
  542. * that the system can call us whenever their
  543. * values are requested. Also update these entries in the
  544. * map table for later access.
  545. */
  546. value = slapi_entry_attr_get_charptr(e, NS_IM_STATUS_TEXT);
  547. if (value) {
  548. slapi_vattrspi_regattr(_VattrHandle, value, "", NULL);
  549. map = (_Vmap*) slapi_ch_calloc(1, sizeof(_Vmap));
  550. map->imID = key;
  551. map->syntax = PRESENCE_STRING;
  552. toLowerCase(value);
  553. PL_HashTableAdd(_IdVattrMapTable, value, map);
  554. }
  555. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMStatusText [%s] \n",value,0,0);
  556. value = slapi_entry_attr_get_charptr(e, NS_IM_STATUS_GRAPHIC);
  557. if (value) {
  558. slapi_vattrspi_regattr(_VattrHandle, value, "", NULL);
  559. map = (_Vmap*) slapi_ch_calloc(1, sizeof(_Vmap));
  560. map->imID = key;
  561. map->syntax = PRESENCE_BINARY;
  562. toLowerCase(value);
  563. PL_HashTableAdd(_IdVattrMapTable, value, map);
  564. }
  565. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMStatusGraphic [%s] \n",value,0,0);
  566. value = slapi_entry_attr_get_charptr(e, NS_IM_URL_TEXT);
  567. if (value) {
  568. entry->textURL = value;
  569. }
  570. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMURLText [%s] \n",value,0,0);
  571. value = slapi_entry_attr_get_charptr(e, NS_IM_URL_GRAPHIC);
  572. if (value) {
  573. entry->graphicURL = value;
  574. }
  575. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMStatusGraphic [%s] \n",value,0,0);
  576. value = slapi_entry_attr_get_charptr(e, NS_IM_ON_VALUE_MAP_TEXT);
  577. if (value) {
  578. entry->onTextMap = value;
  579. }
  580. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMOnValueMapText [%s] \n",value,0,0);
  581. value = slapi_entry_attr_get_charptr(e, NS_IM_OFF_VALUE_MAP_TEXT);
  582. if (value) {
  583. entry->offTextMap = value;
  584. }
  585. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMOffValueMapText [%s] \n",value,0,0);
  586. /**
  587. * Next 3 are binary syntax types so needs special handling
  588. */
  589. slapi_entry_attr_find(e, NS_IM_ON_VALUE_MAP_GRAPHIC, &attr);
  590. if (attr) {
  591. entry->onGraphicMap = slapi_attr_dup(attr);
  592. logGraphicAttributeValue(attr,NS_IM_ON_VALUE_MAP_GRAPHIC);
  593. }
  594. slapi_entry_attr_find(e, NS_IM_OFF_VALUE_MAP_GRAPHIC, &attr);
  595. if (attr) {
  596. entry->offGraphicMap = slapi_attr_dup(attr);
  597. logGraphicAttributeValue(attr,NS_IM_OFF_VALUE_MAP_GRAPHIC);
  598. }
  599. slapi_entry_attr_find(e, NS_IM_DISABLED_VALUE_MAP_GRAPHIC, &attr);
  600. if (attr) {
  601. entry->disabledGraphicMap = slapi_attr_dup(attr);
  602. logGraphicAttributeValue(attr,NS_IM_DISABLED_VALUE_MAP_GRAPHIC);
  603. }
  604. value = slapi_entry_attr_get_charptr(e, NS_IM_REQUEST_METHOD);
  605. if (value) {
  606. entry->requestMethod = value;
  607. }
  608. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMRequestMethod [%s] \n",value,0,0);
  609. value = slapi_entry_attr_get_charptr(e, NS_IM_URL_TEXT_RETURN_TYPE);
  610. if (value) {
  611. entry->textReturnType = value;
  612. }
  613. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMURLTextReturnType [%s] \n",value,0,0);
  614. value = slapi_entry_attr_get_charptr(e, NS_IM_URL_GRAPHIC_RETURN_TYPE);
  615. if (value) {
  616. entry->graphicReturnType = value;
  617. }
  618. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> nsIMURLGraphicReturnType [%s] \n",value,0,0);
  619. /**
  620. * Finally add the entry to the map table
  621. */
  622. PL_HashTableAdd(_IdConfigMapTable, key, entry);
  623. return PRESENCE_SUCCESS;
  624. }
  625. /**
  626. * this function goes thru the valid stored ids
  627. * and return the correct one for which we have to
  628. * do further processing
  629. */
  630. static int imIDExists(Slapi_Entry *e, char *type, char **value, _Vmap **map, _ConfigEntry **entry)
  631. {
  632. int status = PRESENCE_SUCCESS;
  633. char *tValue = NULL;
  634. _ConfigEntry *tEntry = NULL;
  635. _Vmap *tMap = NULL;
  636. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> imIDExists \n",0,0,0);
  637. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> Type [%s] \n",type,0,0);
  638. /**
  639. * The public function PL_HashTableLookup modifies the
  640. * the table while reading. so using this private function
  641. * which just does a lookup and doesn't modifies the
  642. * hashtable
  643. */
  644. toLowerCase(type);
  645. tMap = PL_HashTableLookupConst(_IdVattrMapTable, type);
  646. if (!tMap)
  647. {
  648. /**
  649. * this should not happen but no harm we just return
  650. */
  651. status = PRESENCE_FAILURE;
  652. slapi_log_error(SLAPI_LOG_FATAL, PRESENCE_PLUGIN_SUBSYSTEM,
  653. "No hashtable for vattr types\n");
  654. goto bail;
  655. }
  656. /**
  657. * We found a matching id in the map table
  658. * now see if that id exists in the Slapi_Entry
  659. */
  660. tValue = slapi_entry_attr_get_charptr(e, tMap->imID);
  661. if (!tValue)
  662. {
  663. /**
  664. * we don't do anything here but just return
  665. */
  666. status = PRESENCE_FAILURE;
  667. goto bail;
  668. }
  669. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> Value [%s] \n",tValue,0,0);
  670. tEntry = PL_HashTableLookupConst(_IdConfigMapTable, tMap->imID);
  671. *value = tValue;
  672. *entry = tEntry;
  673. *map = tMap;
  674. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- imIDExists \n",0,0,0);
  675. bail:
  676. return status;
  677. }
  678. static int makeHttpRequest(char *id, _Vmap *map, _ConfigEntry *info, char **BUF, int *size)
  679. {
  680. int status = PRESENCE_SUCCESS;
  681. char *buf = NULL;
  682. char *url = NULL;
  683. char *urltosend = NULL;
  684. int bytesRead;
  685. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> makeHttpRequest:: \n",0,0,0);
  686. if (map->syntax == PRESENCE_STRING) {
  687. url = info->textURL;
  688. } else {
  689. url = info->graphicURL;
  690. }
  691. if (url == NULL) {
  692. status = PRESENCE_FAILURE;
  693. goto bail;
  694. }
  695. urltosend = replaceIdWithValue(url, map->imID, id);
  696. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> URL [%s] \n",urltosend,0,0);
  697. /**
  698. * make an actual HTTP call now
  699. */
  700. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> RequestMethod [%s] \n", info->requestMethod,0,0);
  701. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> Syntax [%d] \n", map->syntax,0,0);
  702. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> TextReturnType [%s] \n", info->textReturnType,0,0);
  703. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> GraphicReturnType [%s] \n", info->graphicReturnType,0,0);
  704. if (!strcasecmp(info->requestMethod, PRESENCE_REQUEST_METHOD_GET)) {
  705. if (map->syntax == PRESENCE_STRING) {
  706. if (!strcasecmp(info->textReturnType, PRESENCE_TEXT_RETURN_TYPE)) {
  707. status = http_get_text(_HttpAPI, urltosend, &buf, &bytesRead);
  708. } else {
  709. status = http_get_binary(_HttpAPI, urltosend, &buf, &bytesRead);
  710. }
  711. } else {
  712. if (!strcasecmp(info->graphicReturnType, PRESENCE_TEXT_RETURN_TYPE)) {
  713. status = http_get_text(_HttpAPI, urltosend, &buf, &bytesRead);
  714. } else {
  715. status = http_get_binary(_HttpAPI, urltosend, &buf, &bytesRead);
  716. }
  717. }
  718. } else if (!strcasecmp(info->requestMethod, PRESENCE_REQUEST_METHOD_REDIRECT)) {
  719. status = http_get_redirected_uri(_HttpAPI, urltosend, &buf, &bytesRead);
  720. } else {
  721. /**
  722. * error : unknown method
  723. * probably we should check at the time of loading
  724. * of the plugin itself that the config values are
  725. * properly checked and throw warning/errors in case
  726. * of any invalid entry
  727. */
  728. slapi_log_error(SLAPI_LOG_FATAL, PRESENCE_PLUGIN_SUBSYSTEM,
  729. "Unknown request type <%s>\n", info->requestMethod);
  730. status = PRESENCE_FAILURE;
  731. goto bail;
  732. }
  733. if (buf && status == PRESENCE_SUCCESS)
  734. {
  735. *BUF = buf;
  736. *size = bytesRead;
  737. }
  738. bail:
  739. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- makeHttpRequest:: <%d>\n",status,0,0);
  740. slapi_ch_free((void**)&urltosend);
  741. return status;
  742. }
  743. /**
  744. * This function replaces the occurrence of $ns[<vendor>]imid with its
  745. * actual value
  746. * e.g.
  747. * URL : http://opi.yahoo.com/online?u=$nsyimid
  748. * after replacing
  749. * newURL : http://opi.yahoo.com/online?u=srajam
  750. */
  751. static char * replaceIdWithValue(char *str, char *id, char *value)
  752. {
  753. int i=0;
  754. int k=0;
  755. char *newstr = NULL;
  756. char c;
  757. if (!str || !id || !value)
  758. {
  759. return NULL;
  760. }
  761. /* extra space for userids */
  762. newstr = (char *)slapi_ch_malloc(strlen(str) + strlen(value));
  763. while ((c=str[i]) != '\0')
  764. {
  765. if (c == '$')
  766. {
  767. int j = 0;
  768. i++; /*skip one char */
  769. /**
  770. * we found the begining of the string to be
  771. * substituted. Now skip the chars we want to replace
  772. */
  773. while (str[i] != '\0' && id[j] != '\0' &&
  774. (toupper(str[i]) == toupper(id[j])))
  775. {
  776. i++;
  777. j++;
  778. }
  779. j=0;
  780. while (value[j] != '\0')
  781. {
  782. newstr[k++] = value[j++];
  783. }
  784. }
  785. else
  786. {
  787. newstr[k++]=c;
  788. i++;
  789. }
  790. }
  791. newstr[k] = '\0';
  792. return newstr;
  793. }
  794. static int setIMStatus(char *id, _Vmap *map, _ConfigEntry *info,
  795. char *returnedBUF, int size, Slapi_ValueSet **results)
  796. {
  797. int status = PRESENCE_SUCCESS;
  798. char *ontxtmap = NULL;
  799. char *offtxtmap = NULL;
  800. Slapi_Value *value = NULL;
  801. Slapi_Value *value1 = NULL;
  802. Slapi_Value *value2 = NULL;
  803. struct berval bval;
  804. Slapi_Attr *attr = NULL;
  805. const struct berval *tmp = NULL;
  806. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> setIMStatus \n", 0,0,0);
  807. /**
  808. * we got some data back so lets try to map it to
  809. * the existing set of on/off data
  810. *
  811. * first we need to take a look at the
  812. * returned type and depending upon that parse
  813. * the data
  814. */
  815. if (map->syntax == PRESENCE_STRING) {
  816. /**
  817. * we had send a request for text
  818. * but chances are we might end up
  819. * getting an image back. So we need
  820. * to compare it to existing set of
  821. * images that we have in store ???
  822. */
  823. if (!strcasecmp(info->textReturnType, PRESENCE_TEXT_RETURN_TYPE)) {
  824. /* return value is in text format */
  825. ontxtmap = replaceIdWithValue(info->onTextMap, map->imID, id);
  826. offtxtmap = replaceIdWithValue(info->offTextMap, map->imID, id);
  827. if (!strcasecmp(ontxtmap, returnedBUF)) {
  828. /**
  829. * set the on value
  830. */
  831. value = slapi_value_new_string(PRESENCE_RETURNED_ON_TEXT);
  832. } else if (!strcasecmp(offtxtmap, returnedBUF)) {
  833. /**
  834. * set the off value
  835. */
  836. value = slapi_value_new_string(PRESENCE_RETURNED_OFF_TEXT);
  837. } else {
  838. value = slapi_value_new_string(PRESENCE_RETURNED_ERROR_TEXT);
  839. }
  840. } else if (!strcasecmp(info->textReturnType, PRESENCE_BINARY_RETURN_TYPE)) {
  841. /**
  842. * call binary compare method
  843. */
  844. bval.bv_len = size;
  845. bval.bv_val = returnedBUF;
  846. value1 = slapi_value_new_berval(&bval);
  847. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> returned size [%d] \n", bval.bv_len,0,0);
  848. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> returned value [%s] \n", bval.bv_val,0,0);
  849. attr = info->onGraphicMap;
  850. if (attr) {
  851. slapi_attr_first_value(attr, &value2);
  852. tmp = slapi_value_get_berval(value2);
  853. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> Stored size [%d] \n", tmp->bv_len,0,0);
  854. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> Stored value [%s] \n", tmp->bv_val,0,0);
  855. if (!slapi_value_compare(attr, value1, value2)) {
  856. value = slapi_value_new_string(PRESENCE_RETURNED_ON_TEXT);
  857. }
  858. }
  859. if (!value) {
  860. attr = info->offGraphicMap;
  861. if (attr) {
  862. slapi_attr_first_value(attr, &value2);
  863. if (!slapi_value_compare(attr, value1, value2)) {
  864. value = slapi_value_new_string(PRESENCE_RETURNED_OFF_TEXT);
  865. }
  866. }
  867. }
  868. if (!value) {
  869. attr = info->disabledGraphicMap;
  870. if (attr) {
  871. slapi_attr_first_value(attr, &value2);
  872. if (!slapi_value_compare(attr, value1, value2)) {
  873. value = slapi_value_new_string(PRESENCE_RETURNED_OFF_TEXT);
  874. }
  875. }
  876. }
  877. if (!value) {
  878. /* some error */
  879. value = slapi_value_new_string(PRESENCE_RETURNED_ERROR_TEXT);
  880. }
  881. } else {
  882. /**
  883. * set the error condition
  884. */
  885. value = slapi_value_new_string(PRESENCE_RETURNED_ERROR_TEXT);
  886. }
  887. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> value [%s] \n", returnedBUF,0,0);
  888. } else {
  889. /**
  890. * we had send a request for image
  891. * so whatever we get back we just
  892. * return instead of analyzing it
  893. */
  894. if (!strcasecmp(info->graphicReturnType, PRESENCE_TEXT_RETURN_TYPE)) {
  895. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> value [%s] \n", returnedBUF,0,0);
  896. if (!strcasecmp(info->requestMethod, PRESENCE_REQUEST_METHOD_REDIRECT)) {
  897. /**
  898. * a redirect case in which we should probably have a
  899. * gif in store so return that value
  900. *
  901. * for now
  902. */
  903. ontxtmap = replaceIdWithValue(info->onTextMap, map->imID, id);
  904. offtxtmap = replaceIdWithValue(info->offTextMap, map->imID, id);
  905. if (!strcasecmp(ontxtmap, returnedBUF)) {
  906. /**
  907. * set the on value
  908. */
  909. attr = info->onGraphicMap;
  910. } else if (!strcasecmp(offtxtmap, returnedBUF)) {
  911. /**
  912. * set the off value
  913. */
  914. attr = info->offGraphicMap;
  915. } else {
  916. attr = info->disabledGraphicMap;
  917. }
  918. if (attr) {
  919. slapi_attr_first_value(attr, &value);
  920. }
  921. } else {
  922. /**
  923. * for now just set the returned value
  924. * should not happen in our case
  925. * ERROR
  926. */
  927. }
  928. } else {
  929. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> value [%s] \n", returnedBUF,0,0);
  930. bval.bv_len = size;
  931. bval.bv_val = returnedBUF;
  932. value = slapi_value_new_berval(&bval);
  933. }
  934. }
  935. if (!*results) {
  936. *results = slapi_valueset_new();
  937. }
  938. slapi_valueset_add_value(*results, value);
  939. if (ontxtmap) {
  940. slapi_ch_free((void **)&ontxtmap);
  941. }
  942. if (offtxtmap) {
  943. slapi_ch_free((void **)&offtxtmap);
  944. }
  945. if (value && map->syntax == PRESENCE_STRING) {
  946. slapi_value_free(&value);
  947. }
  948. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- setIMStatus \n", 0,0,0);
  949. return status;
  950. }
  951. static int setTypes(PLHashEntry *he, PRIntn i, void *arg)
  952. {
  953. int status;
  954. int props = SLAPI_ATTR_FLAG_OPATTR;
  955. Slapi_ValueSet *results = NULL;
  956. int type_name_disposition = 0;
  957. char *actual_type_name = 0;
  958. int free_flags = 0;
  959. struct _vattrtypes *args = arg;
  960. char *type = (char *)he->key;
  961. _Vmap *map = (_Vmap *)he->value;
  962. char *id = map->imID;
  963. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> setTypes \n", 0,0,0);
  964. status = slapi_vattr_values_get_sp(NULL, args->entry, id, &results, &type_name_disposition, &actual_type_name, 0, &free_flags);
  965. if(status == PRESENCE_SUCCESS)
  966. {
  967. /* entry contains this attr */
  968. vattr_type_thang thang = {0};
  969. thang.type_name = type;
  970. thang.type_flags = props;
  971. slapi_vattrspi_add_type(args->context,&thang,0);
  972. slapi_vattr_values_free(&results, &actual_type_name, free_flags);
  973. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> ID [%s] Type[%s]\n", actual_type_name,type,0);
  974. }
  975. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- setTypes \n", 0,0,0);
  976. return HT_ENUMERATE_NEXT;
  977. }
  978. static void
  979. logGraphicAttributeValue( Slapi_Attr *attr, const char *attrname )
  980. {
  981. Slapi_Value *val = NULL;
  982. const struct berval *v = NULL;
  983. if ( LDAPDebugLevelIsSet( LDAP_DEBUG_PLUGIN )) {
  984. slapi_attr_first_value(attr, &val);
  985. v = slapi_value_get_berval(val);
  986. if (v) {
  987. char *ldifvalue;
  988. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> %s size [%d] \n",
  989. attrname,v->bv_len,0);
  990. ldifvalue = ldif_type_and_value_with_options(
  991. (char *)attrname, /* XXX: had to cast away const */
  992. v->bv_val, v->bv_len, 0 );
  993. if ( NULL != ldifvalue ) {
  994. LDAPDebug( LDAP_DEBUG_PLUGIN, "----------> %s value [\n%s]\n",
  995. attrname,ldifvalue,0);
  996. slapi_ch_free_string( &ldifvalue );
  997. }
  998. }
  999. }
  1000. }
  1001. static void deleteMapTables()
  1002. {
  1003. PL_HashTableEnumerateEntries(_IdConfigMapTable, destroyHashEntry, 0);
  1004. if (_IdConfigMapTable)
  1005. {
  1006. PL_HashTableDestroy(_IdConfigMapTable);
  1007. }
  1008. PL_HashTableEnumerateEntries(_IdVattrMapTable, destroyHashEntry, 0);
  1009. if (_IdVattrMapTable)
  1010. {
  1011. PL_HashTableDestroy(_IdVattrMapTable);
  1012. }
  1013. return;
  1014. }
  1015. static PRIntn destroyHashEntry(PLHashEntry *he, PRIntn index, void *arg)
  1016. {
  1017. void *value = NULL;
  1018. if (he == NULL)
  1019. {
  1020. return HT_ENUMERATE_NEXT;
  1021. }
  1022. value = he->value;
  1023. if (value)
  1024. {
  1025. slapi_ch_free(&value);
  1026. }
  1027. return HT_ENUMERATE_REMOVE;
  1028. }
  1029. static void toLowerCase(char* str)
  1030. {
  1031. if (str) {
  1032. char* lstr = str;
  1033. for(; (*lstr != '\0'); ++lstr) {
  1034. *lstr = tolower(*lstr);
  1035. }
  1036. }
  1037. }
  1038. /**
  1039. * utility function to print the array
  1040. */
  1041. void printMapTable()
  1042. {
  1043. PL_HashTableEnumerateEntries(_IdVattrMapTable, printIdVattrMapTable, 0);
  1044. PL_HashTableEnumerateEntries(_IdConfigMapTable, printIdConfigMapTable, 0);
  1045. }
  1046. PRIntn printIdVattrMapTable(PLHashEntry *he, PRIntn i, void *arg)
  1047. {
  1048. char *key = (char *)he->key;
  1049. _Vmap *map = (_Vmap *)he->value;
  1050. printf("<---- Key -------> %s\n", key);
  1051. printf("<---- ImId ------> %s\n", map->imID);
  1052. printf("<---- syntax ----> %d\n", map->syntax);
  1053. return HT_ENUMERATE_NEXT;
  1054. }
  1055. PRIntn printIdConfigMapTable(PLHashEntry *he, PRIntn i, void *arg)
  1056. {
  1057. char *key = (char *)he->key;
  1058. _ConfigEntry *value = (_ConfigEntry *)he->value;
  1059. printf("<- Key ---------------------> %s\n", key);
  1060. printf("<---- text_url -------------> %s\n", value->textURL);
  1061. printf("<---- graphic_url ----------> %s\n", value->graphicURL);
  1062. printf("<---- on_text_map ----------> %s\n", value->onTextMap);
  1063. printf("<---- off_text_map ---------> %s\n", value->offTextMap);
  1064. printf("<---- request_method -------> %s\n", value->requestMethod);
  1065. printf("<---- text_return_type -----> %s\n", value->textReturnType);
  1066. printf("<---- graphic_return_type --> %s\n", value->graphicReturnType);
  1067. return HT_ENUMERATE_NEXT;
  1068. }