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