aboutsummaryrefslogtreecommitdiff
path: root/src/lib/gnsrecord/gnsrecord.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/gnsrecord/gnsrecord.c')
-rw-r--r--src/lib/gnsrecord/gnsrecord.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/src/lib/gnsrecord/gnsrecord.c b/src/lib/gnsrecord/gnsrecord.c
new file mode 100644
index 000000000..c71dc1708
--- /dev/null
+++ b/src/lib/gnsrecord/gnsrecord.c
@@ -0,0 +1,267 @@
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 SPDX-License-Identifier: AGPL3.0-or-later
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
34#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
35
36
37/**
38 * Handle for a plugin.
39 */
40struct Plugin
41{
42 /**
43 * Name of the shared library.
44 */
45 char *library_name;
46
47 /**
48 * Plugin API.
49 */
50 struct GNUNET_GNSRECORD_PluginFunctions *api;
51};
52
53
54/**
55 * Array of our plugins.
56 */
57static struct Plugin **gns_plugins;
58
59/**
60 * Size of the 'plugins' array.
61 */
62static unsigned int num_plugins;
63
64/**
65 * Global to mark if we've run the initialization.
66 */
67static int once;
68
69
70/**
71 * Add a plugin to the list managed by the block library.
72 *
73 * @param cls NULL
74 * @param library_name name of the plugin
75 * @param lib_ret the plugin API
76 */
77static void
78add_plugin (void *cls,
79 const char *library_name,
80 void *lib_ret)
81{
82 struct GNUNET_GNSRECORD_PluginFunctions *api = lib_ret;
83 struct Plugin *plugin;
84
85 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
86 "Loading block plugin `%s'\n",
87 library_name);
88 plugin = GNUNET_new (struct Plugin);
89 plugin->api = api;
90 plugin->library_name = GNUNET_strdup (library_name);
91 GNUNET_array_append (gns_plugins, num_plugins, plugin);
92}
93
94
95/**
96 * Loads all plugins (lazy initialization).
97 */
98static void
99init ()
100{
101 if (1 == once)
102 return;
103 once = 1;
104
105 GNUNET_PLUGIN_load_all_in_context (GNUNET_OS_project_data_default (),
106 "libgnunet_plugin_gnsrecord_",
107 NULL,
108 &add_plugin,
109 NULL);
110}
111
112
113/**
114 * Dual function to #init().
115 */
116void __attribute__ ((destructor))
117GNSRECORD_fini ()
118{
119 struct Plugin *plugin;
120 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
121 const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
122
123 if (pd != dpd)
124 GNUNET_OS_init (dpd);
125
126 for (unsigned int i = 0; i < num_plugins; i++)
127 {
128 plugin = gns_plugins[i];
129 GNUNET_break (NULL ==
130 GNUNET_PLUGIN_unload (plugin->library_name,
131 plugin->api));
132 GNUNET_free (plugin->library_name);
133 GNUNET_free (plugin);
134 }
135 GNUNET_free (gns_plugins);
136
137 if (pd != dpd)
138 GNUNET_OS_init (pd);
139
140 gns_plugins = NULL;
141 once = 0;
142 num_plugins = 0;
143}
144
145
146/**
147 * Convert the 'value' of a record to a string.
148 *
149 * @param type type of the record
150 * @param data value in binary encoding
151 * @param data_size number of bytes in @a data
152 * @return NULL on error, otherwise human-readable representation of the value
153 */
154char *
155GNUNET_GNSRECORD_value_to_string (uint32_t type,
156 const void *data,
157 size_t data_size)
158{
159 struct Plugin *plugin;
160 char *ret;
161
162 init ();
163 for (unsigned int i = 0; i < num_plugins; i++)
164 {
165 plugin = gns_plugins[i];
166 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
167 type,
168 data,
169 data_size)))
170 return ret;
171 }
172 return NULL;
173}
174
175
176int
177GNUNET_GNSRECORD_string_to_value (uint32_t type,
178 const char *s,
179 void **data,
180 size_t *data_size)
181{
182 struct Plugin *plugin;
183
184 init ();
185 for (unsigned int i = 0; i < num_plugins; i++)
186 {
187 plugin = gns_plugins[i];
188 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
189 type,
190 s,
191 data,
192 data_size))
193 return GNUNET_OK;
194 }
195 return GNUNET_SYSERR;
196}
197
198
199uint32_t
200GNUNET_GNSRECORD_typename_to_number (const char *dns_typename)
201{
202 struct Plugin *plugin;
203 uint32_t ret;
204
205 if (0 == strcasecmp (dns_typename,
206 "ANY"))
207 return GNUNET_GNSRECORD_TYPE_ANY;
208 init ();
209 for (unsigned int i = 0; i < num_plugins; i++)
210 {
211 plugin = gns_plugins[i];
212 if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls,
213 dns_typename)))
214 return ret;
215 }
216 return UINT32_MAX;
217}
218
219
220/**
221 * Convert a type number to the corresponding type string (e.g. 1 to "A")
222 *
223 * @param type number of a type to convert
224 * @return corresponding typestring, NULL on error
225 */
226const char *
227GNUNET_GNSRECORD_number_to_typename (uint32_t type)
228{
229 struct Plugin *plugin;
230 const char *ret;
231
232 if (GNUNET_GNSRECORD_TYPE_ANY == type)
233 return "ANY";
234 init ();
235 for (unsigned int i = 0; i < num_plugins; i++)
236 {
237 plugin = gns_plugins[i];
238 if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls,
239 type)))
240 return ret;
241 }
242 return NULL;
243}
244
245
246enum GNUNET_GenericReturnValue
247GNUNET_GNSRECORD_is_critical (uint32_t type)
248{
249 struct Plugin *plugin;
250
251 if (GNUNET_GNSRECORD_TYPE_ANY == type)
252 return GNUNET_NO;
253 init ();
254 for (unsigned int i = 0; i < num_plugins; i++)
255 {
256 plugin = gns_plugins[i];
257 if (NULL == plugin->api->is_critical)
258 continue;
259 if (GNUNET_NO == plugin->api->is_critical (plugin->api->cls, type))
260 continue;
261 return GNUNET_YES;
262 }
263 return GNUNET_NO;
264}
265
266
267/* end of gnsrecord.c */