gnsrecord.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2009-2013 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file gnsrecord/gnsrecord.c
  19. * @brief API to access GNS record data
  20. * @author Martin Schanzenbach
  21. * @author Matthias Wachs
  22. * @author Christian Grothoff
  23. */
  24. #include "platform.h"
  25. #include "gnunet_util_lib.h"
  26. #include "gnunet_constants.h"
  27. #include "gnunet_gnsrecord_lib.h"
  28. #include "gnunet_gnsrecord_plugin.h"
  29. #include "gnunet_tun_lib.h"
  30. #define LOG(kind,...) GNUNET_log_from (kind, "gnsrecord",__VA_ARGS__)
  31. /**
  32. * Handle for a plugin.
  33. */
  34. struct Plugin
  35. {
  36. /**
  37. * Name of the shared library.
  38. */
  39. char *library_name;
  40. /**
  41. * Plugin API.
  42. */
  43. struct GNUNET_GNSRECORD_PluginFunctions *api;
  44. };
  45. /**
  46. * Array of our plugins.
  47. */
  48. static struct Plugin **gns_plugins;
  49. /**
  50. * Size of the 'plugins' array.
  51. */
  52. static unsigned int num_plugins;
  53. /**
  54. * Global to mark if we've run the initialization.
  55. */
  56. static int once;
  57. /**
  58. * Add a plugin to the list managed by the block library.
  59. *
  60. * @param cls NULL
  61. * @param library_name name of the plugin
  62. * @param lib_ret the plugin API
  63. */
  64. static void
  65. add_plugin (void *cls,
  66. const char *library_name,
  67. void *lib_ret)
  68. {
  69. struct GNUNET_GNSRECORD_PluginFunctions *api = lib_ret;
  70. struct Plugin *plugin;
  71. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  72. "Loading block plugin `%s'\n",
  73. library_name);
  74. plugin = GNUNET_new (struct Plugin);
  75. plugin->api = api;
  76. plugin->library_name = GNUNET_strdup (library_name);
  77. GNUNET_array_append (gns_plugins, num_plugins, plugin);
  78. }
  79. /**
  80. * Loads all plugins (lazy initialization).
  81. */
  82. static void
  83. init ()
  84. {
  85. if (1 == once)
  86. return;
  87. once = 1;
  88. GNUNET_PLUGIN_load_all ("libgnunet_plugin_gnsrecord_", NULL,
  89. &add_plugin, NULL);
  90. }
  91. /**
  92. * Dual function to #init().
  93. */
  94. void __attribute__ ((destructor))
  95. GNSRECORD_fini ()
  96. {
  97. unsigned int i;
  98. struct Plugin *plugin;
  99. for (i = 0; i < num_plugins; i++)
  100. {
  101. plugin = gns_plugins[i];
  102. GNUNET_break (NULL ==
  103. GNUNET_PLUGIN_unload (plugin->library_name,
  104. plugin->api));
  105. GNUNET_free (plugin->library_name);
  106. GNUNET_free (plugin);
  107. }
  108. GNUNET_free_non_null (gns_plugins);
  109. gns_plugins = NULL;
  110. once = 0;
  111. num_plugins = 0;
  112. }
  113. /**
  114. * Convert the 'value' of a record to a string.
  115. *
  116. * @param type type of the record
  117. * @param data value in binary encoding
  118. * @param data_size number of bytes in @a data
  119. * @return NULL on error, otherwise human-readable representation of the value
  120. */
  121. char *
  122. GNUNET_GNSRECORD_value_to_string (uint32_t type,
  123. const void *data,
  124. size_t data_size)
  125. {
  126. unsigned int i;
  127. struct Plugin *plugin;
  128. char *ret;
  129. init ();
  130. for (i = 0; i < num_plugins; i++)
  131. {
  132. plugin = gns_plugins[i];
  133. if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
  134. type,
  135. data,
  136. data_size)))
  137. return ret;
  138. }
  139. return NULL;
  140. }
  141. /**
  142. * Convert human-readable version of a 'value' of a record to the binary
  143. * representation.
  144. *
  145. * @param type type of the record
  146. * @param s human-readable string
  147. * @param data set to value in binary encoding (will be allocated)
  148. * @param data_size set to number of bytes in @a data
  149. * @return #GNUNET_OK on success
  150. */
  151. int
  152. GNUNET_GNSRECORD_string_to_value (uint32_t type,
  153. const char *s,
  154. void **data,
  155. size_t *data_size)
  156. {
  157. unsigned int i;
  158. struct Plugin *plugin;
  159. init ();
  160. for (i = 0; i < num_plugins; i++)
  161. {
  162. plugin = gns_plugins[i];
  163. if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
  164. type,
  165. s,
  166. data,
  167. data_size))
  168. return GNUNET_OK;
  169. }
  170. return GNUNET_SYSERR;
  171. }
  172. /**
  173. * Convert a type name (i.e. "AAAA") to the corresponding number.
  174. *
  175. * @param dns_typename name to convert
  176. * @return corresponding number, UINT32_MAX on error
  177. */
  178. uint32_t
  179. GNUNET_GNSRECORD_typename_to_number (const char *dns_typename)
  180. {
  181. unsigned int i;
  182. struct Plugin *plugin;
  183. uint32_t ret;
  184. if (0 == strcasecmp (dns_typename,
  185. "ANY"))
  186. return GNUNET_GNSRECORD_TYPE_ANY;
  187. init ();
  188. for (i = 0; i < num_plugins; i++)
  189. {
  190. plugin = gns_plugins[i];
  191. if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls,
  192. dns_typename)))
  193. return ret;
  194. }
  195. return UINT32_MAX;
  196. }
  197. /**
  198. * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
  199. *
  200. * @param type number of a type to convert
  201. * @return corresponding typestring, NULL on error
  202. */
  203. const char *
  204. GNUNET_GNSRECORD_number_to_typename (uint32_t type)
  205. {
  206. unsigned int i;
  207. struct Plugin *plugin;
  208. const char * ret;
  209. if (GNUNET_GNSRECORD_TYPE_ANY == type)
  210. return "ANY";
  211. init ();
  212. for (i = 0; i < num_plugins; i++)
  213. {
  214. plugin = gns_plugins[i];
  215. if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls,
  216. type)))
  217. return ret;
  218. }
  219. return NULL;
  220. }
  221. /* end of gnsrecord.c */