aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-gns.c')
-rw-r--r--src/gns/gnunet-gns.c386
1 files changed, 0 insertions, 386 deletions
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c
deleted file mode 100644
index 5cf496808..000000000
--- a/src/gns/gnunet-gns.c
+++ /dev/null
@@ -1,386 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2013, 2017-2018 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 * @file gnunet-gns.c
22 * @brief command line tool to access distributed GNS
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#if HAVE_LIBIDN2
27#if HAVE_IDN2_H
28#include <idn2.h>
29#elif HAVE_IDN2_IDN2_H
30#include <idn2/idn2.h>
31#endif
32#elif HAVE_LIBIDN
33#if HAVE_IDNA_H
34#include <idna.h>
35#elif HAVE_IDN_IDNA_H
36#include <idn/idna.h>
37#endif
38#endif
39#include <gnunet_util_lib.h>
40#include <gnunet_dnsparser_lib.h>
41#include <gnunet_gnsrecord_lib.h>
42#include <gnunet_namestore_service.h>
43#include <gnunet_gns_service.h>
44
45
46/**
47 * Configuration we are using.
48 */
49static const struct GNUNET_CONFIGURATION_Handle *cfg;
50
51/**
52 * Handle to GNS service.
53 */
54static struct GNUNET_GNS_Handle *gns;
55
56/**
57 * GNS name to lookup. (-u option)
58 */
59static char *lookup_name;
60
61/**
62 * DNS IDNA name to lookup. (set if -d option is set)
63 */
64char *idna_name;
65
66/**
67 * DNS compatibility (name is given as DNS name, possible IDNA).
68 */
69static int dns_compat;
70
71/**
72 * record type to look up (-t option)
73 */
74static char *lookup_type;
75
76/**
77 * raw output
78 */
79static int raw;
80
81/**
82 * Desired record type.
83 */
84static uint32_t rtype;
85
86/**
87 * Timeout for lookup
88 */
89static struct GNUNET_TIME_Relative timeout;
90
91/**
92 * Timeout task
93 */
94static struct GNUNET_SCHEDULER_Task *to_task;
95
96/**
97 * Handle to lookup request
98 */
99static struct GNUNET_GNS_LookupWithTldRequest *lr;
100
101/**
102 * Global return value.
103 * 0 on success (default),
104 * 1 on internal failures
105 * 2 on launch failure,
106 * 4 if the name is not a GNS-supported TLD,
107 */
108static int global_ret;
109
110
111/**
112 * Task run on shutdown. Cleans up everything.
113 *
114 * @param cls unused
115 */
116static void
117do_shutdown (void *cls)
118{
119 (void) cls;
120 if (NULL != to_task)
121 {
122 GNUNET_SCHEDULER_cancel (to_task);
123 to_task = NULL;
124 }
125 if (NULL != lr)
126 {
127 GNUNET_GNS_lookup_with_tld_cancel (lr);
128 lr = NULL;
129 }
130 if (NULL != gns)
131 {
132 GNUNET_GNS_disconnect (gns);
133 gns = NULL;
134 }
135 if (NULL != idna_name)
136 {
137 GNUNET_free (idna_name);
138 idna_name = NULL;
139 }
140}
141
142
143/**
144 * Task to run on timeout
145 *
146 * @param cls unused
147 */
148static void
149do_timeout (void*cls)
150{
151 to_task = NULL;
152 global_ret = 3; // Timeout
153 GNUNET_SCHEDULER_shutdown ();
154}
155
156
157/**
158 * Function called with the result of a GNS lookup.
159 *
160 * @param cls the 'const char *' name that was resolved
161 * @param was_gns #GNUNET_NO if TLD did not indicate use of GNS
162 * @param rd_count number of records returned
163 * @param rd array of @a rd_count records with the results
164 */
165static void
166process_lookup_result (void *cls,
167 int was_gns,
168 uint32_t rd_count,
169 const struct GNUNET_GNSRECORD_Data *rd)
170{
171 const char *name = cls;
172 const char *typename;
173 char *string_val;
174
175 lr = NULL;
176 if (GNUNET_NO == was_gns)
177 {
178 global_ret = 4; /* not for GNS */
179 GNUNET_SCHEDULER_shutdown ();
180 return;
181 }
182 if (! raw)
183 {
184 if (0 == rd_count)
185 printf ("No results.\n");
186 else
187 printf ("%s:\n", name);
188 }
189 for (uint32_t i = 0; i < rd_count; i++)
190 {
191 if ((rd[i].record_type != rtype) && (GNUNET_GNSRECORD_TYPE_ANY != rtype))
192 continue;
193 typename = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
194 string_val = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
195 rd[i].data,
196 rd[i].data_size);
197 if (NULL == string_val)
198 {
199 fprintf (stderr,
200 "Record %u of type %d malformed, skipping\n",
201 (unsigned int) i,
202 (int) rd[i].record_type);
203 continue;
204 }
205 if (raw)
206 printf ("%s\n", string_val);
207 else
208 printf ("Got `%s' record: %s%s\n",
209 typename,
210 string_val,
211 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL)) ?
212 " (supplemental)" : "");
213 GNUNET_free (string_val);
214 }
215 GNUNET_SCHEDULER_shutdown ();
216}
217
218
219/**
220 * Main function that will be run.
221 *
222 * @param cls closure
223 * @param args remaining command-line arguments
224 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
225 * @param c configuration
226 */
227static void
228run (void *cls,
229 char *const *args,
230 const char *cfgfile,
231 const struct GNUNET_CONFIGURATION_Handle *c)
232{
233 (void) cls;
234 (void) args;
235 (void) cfgfile;
236
237 cfg = c;
238 to_task = NULL;
239 {
240 char *colon;
241
242 if (NULL != (colon = strchr (lookup_name, ':')))
243 *colon = '\0';
244 }
245
246 /**
247 * If DNS compatibility is requested, we first verify that the
248 * lookup_name is in a DNS format. If yes, we convert it to UTF-8.
249 */
250 if (GNUNET_YES == dns_compat)
251 {
252 Idna_rc rc;
253
254 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (lookup_name))
255 {
256 fprintf (stderr,
257 _ ("`%s' is not a valid DNS domain name\n"),
258 lookup_name);
259 global_ret = 3;
260 return;
261 }
262 if (IDNA_SUCCESS !=
263 (rc = idna_to_unicode_8z8z (lookup_name, &idna_name,
264 IDNA_ALLOW_UNASSIGNED)))
265 {
266 fprintf (stderr,
267 _ ("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"),
268 lookup_name,
269 idna_strerror (rc));
270 global_ret = 4;
271 return;
272 }
273 lookup_name = idna_name;
274 }
275
276 if (GNUNET_YES !=
277 GNUNET_CLIENT_test (cfg,
278 "arm"))
279 {
280 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
281 _ ("Cannot resolve using GNS: GNUnet peer not running\n"));
282 global_ret = 5;
283 return;
284 }
285 to_task = GNUNET_SCHEDULER_add_delayed (timeout,
286 &do_timeout,
287 NULL);
288 gns = GNUNET_GNS_connect (cfg);
289 if (NULL == gns)
290 {
291 fprintf (stderr,
292 _ ("Failed to connect to GNS\n"));
293 global_ret = 2;
294 return;
295 }
296 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
297 NULL);
298 if (NULL != lookup_type)
299 rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type);
300 else
301 rtype = GNUNET_DNSPARSER_TYPE_A;
302 if (UINT32_MAX == rtype)
303 {
304 fprintf (stderr,
305 _ ("Invalid typename specified, assuming `ANY'\n"));
306 rtype = GNUNET_GNSRECORD_TYPE_ANY;
307 }
308 lr = GNUNET_GNS_lookup_with_tld (gns,
309 lookup_name,
310 rtype,
311 GNUNET_GNS_LO_DEFAULT,
312 &process_lookup_result,
313 lookup_name);
314 if (NULL == lr)
315 {
316 global_ret = 2;
317 GNUNET_SCHEDULER_shutdown ();
318 return;
319 }
320}
321
322
323/**
324 * The main function for gnunet-gns.
325 *
326 * @param argc number of arguments from the command line
327 * @param argv command line arguments
328 * @return 0 ok, 1 on error
329 */
330int
331main (int argc, char *const *argv)
332{
333 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
334 struct GNUNET_GETOPT_CommandLineOption options[] =
335 { GNUNET_GETOPT_option_mandatory (
336 GNUNET_GETOPT_option_string ('u',
337 "lookup",
338 "NAME",
339 gettext_noop (
340 "Lookup a record for the given name"),
341 &lookup_name)),
342 GNUNET_GETOPT_option_string ('t',
343 "type",
344 "TYPE",
345 gettext_noop (
346 "Specify the type of the record to lookup"),
347 &lookup_type),
348 GNUNET_GETOPT_option_relative_time ('T',
349 "timeout",
350 "TIMEOUT",
351 gettext_noop (
352 "Specify a timeout for the lookup"),
353 &timeout),
354 GNUNET_GETOPT_option_flag ('r',
355 "raw",
356 gettext_noop ("No unneeded output"),
357 &raw),
358 GNUNET_GETOPT_option_flag ('d',
359 "dns",
360 gettext_noop (
361 "DNS Compatibility: Name is passed in IDNA instead of UTF-8"),
362 &dns_compat),
363 GNUNET_GETOPT_OPTION_END };
364 int ret;
365
366 if (GNUNET_OK !=
367 GNUNET_STRINGS_get_utf8_args (argc, argv,
368 &argc, &argv))
369 return 2;
370
371 GNUNET_log_setup ("gnunet-gns", "WARNING", NULL);
372 ret = GNUNET_PROGRAM_run (argc,
373 argv,
374 "gnunet-gns",
375 _ ("GNUnet GNS resolver tool"),
376 options,
377 &run,
378 NULL);
379 GNUNET_free_nz ((void *) argv);
380 if (GNUNET_OK != ret)
381 return 1;
382 return global_ret;
383}
384
385
386/* end of gnunet-gns.c */