1
0

presence.c 34 KB

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