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