fix /tmp removal
[oweals/gnunet.git] / src / gns / gnunet-gns.c
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
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., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
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 #include <gnunet_util_lib.h>
27 #include <gnunet_dnsparser_lib.h>
28 #include <gnunet_gnsrecord_lib.h>
29 #include <gnunet_namestore_service.h>
30 #include <gnunet_gns_service.h>
31
32 /**
33  * Configuration we are using.
34  */
35 static const struct GNUNET_CONFIGURATION_Handle *cfg;
36
37 /**
38  * Handle to GNS service.
39  */
40 static struct GNUNET_GNS_Handle *gns;
41
42 /**
43  * GNS name to lookup. (-u option)
44  */
45 static char *lookup_name;
46
47 /**
48  * record type to look up (-t option)
49  */
50 static char *lookup_type;
51
52 /**
53  * raw output
54  */
55 static int raw;
56
57 /**
58  * Desired record type.
59  */
60 static uint32_t rtype;
61
62 /**
63  * Handle to lookup request
64  */
65 static struct GNUNET_GNS_LookupWithTldRequest *lr;
66
67 /**
68  * Global return value.
69  * 0 on success (default),
70  * 1 on internal failures, 2 on launch failure,
71  * 3 if the name is not a GNS-supported TLD,
72  */
73 static int global_ret;
74
75
76 /**
77  * Task run on shutdown.  Cleans up everything.
78  *
79  * @param cls unused
80  */
81 static void
82 do_shutdown (void *cls)
83 {
84   (void) cls;
85   if (NULL != lr)
86   {
87     GNUNET_GNS_lookup_with_tld_cancel (lr);
88     lr = NULL;
89   }
90   if (NULL != gns)
91   {
92     GNUNET_GNS_disconnect (gns);
93     gns = NULL;
94   }
95 }
96
97
98 /**
99  * Function called with the result of a GNS lookup.
100  *
101  * @param cls the 'const char *' name that was resolved
102  * @param was_gns #GNUNET_NO if TLD did not indicate use of GNS
103  * @param rd_count number of records returned
104  * @param rd array of @a rd_count records with the results
105  */
106 static void
107 process_lookup_result (void *cls,
108                        int was_gns,
109                        uint32_t rd_count,
110                        const struct GNUNET_GNSRECORD_Data *rd)
111 {
112   const char *name = cls;
113   const char *typename;
114   char* string_val;
115
116   lr = NULL;
117   if (GNUNET_NO == was_gns)
118   {
119     global_ret = 3;
120     GNUNET_SCHEDULER_shutdown ();
121     return;
122   }
123   if (! raw)
124   {
125     if (0 == rd_count)
126       printf ("No results.\n");
127     else
128       printf ("%s:\n",
129               name);
130   }
131   for (uint32_t i=0; i<rd_count; i++)
132   {
133     if ( (rd[i].record_type != rtype) &&
134          (GNUNET_GNSRECORD_TYPE_ANY != rtype) )
135       continue;
136     typename = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
137     string_val = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
138                                                    rd[i].data,
139                                                    rd[i].data_size);
140     if (NULL == string_val)
141     {
142       fprintf (stderr,
143                "Record %u of type %d malformed, skipping\n",
144                (unsigned int) i,
145                (int) rd[i].record_type);
146       continue;
147     }
148     if (raw)
149       printf ("%s\n",
150               string_val);
151     else
152       printf ("Got `%s' record: %s\n",
153               typename,
154               string_val);
155     GNUNET_free (string_val);
156   }
157   GNUNET_SCHEDULER_shutdown ();
158 }
159
160
161 /**
162  * Main function that will be run.
163  *
164  * @param cls closure
165  * @param args remaining command-line arguments
166  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
167  * @param c configuration
168  */
169 static void
170 run (void *cls,
171      char *const *args,
172      const char *cfgfile,
173      const struct GNUNET_CONFIGURATION_Handle *c)
174 {
175   (void) cls;
176   (void) args;
177   (void) cfgfile;
178
179   cfg = c;
180   gns = GNUNET_GNS_connect (cfg);
181   if (NULL == gns)
182   {
183     fprintf (stderr,
184              _("Failed to connect to GNS\n"));
185     global_ret = 2;
186     return;
187   }
188
189   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
190                                  NULL);
191
192   if (NULL != lookup_type)
193     rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type);
194   else
195     rtype = GNUNET_DNSPARSER_TYPE_A;
196   if (UINT32_MAX == rtype)
197   {
198     fprintf (stderr,
199              _("Invalid typename specified, assuming `ANY'\n"));
200     rtype = GNUNET_GNSRECORD_TYPE_ANY;
201   }
202   lr = GNUNET_GNS_lookup_with_tld (gns,
203                                    lookup_name,
204                                    rtype,
205                                    GNUNET_GNS_LO_DEFAULT,
206                                    &process_lookup_result,
207                                    lookup_name);
208   if (NULL == lr)
209   {
210     global_ret = 2;
211     GNUNET_SCHEDULER_shutdown ();
212     return;
213   }
214 }
215
216
217 /**
218  * The main function for gnunet-gns.
219  *
220  * @param argc number of arguments from the command line
221  * @param argv command line arguments
222  * @return 0 ok, 1 on error
223  */
224 int
225 main (int argc,
226       char *const *argv)
227 {
228   struct GNUNET_GETOPT_CommandLineOption options[] = {
229     GNUNET_GETOPT_option_mandatory
230     (GNUNET_GETOPT_option_string ('u',
231                                   "lookup",
232                                   "NAME",
233                                   gettext_noop ("Lookup a record for the given name"),
234                                   &lookup_name)),
235     GNUNET_GETOPT_option_string ('t',
236                                  "type",
237                                  "TYPE",
238                                  gettext_noop ("Specify the type of the record to lookup"),
239                                  &lookup_type),
240     GNUNET_GETOPT_option_flag ('r',
241                                "raw",
242                                gettext_noop ("No unneeded output"),
243                                &raw),
244     GNUNET_GETOPT_OPTION_END
245   };
246   int ret;
247
248   if (GNUNET_OK !=
249       GNUNET_STRINGS_get_utf8_args (argc, argv,
250                                     &argc, &argv))
251     return 2;
252
253   GNUNET_log_setup ("gnunet-gns",
254                     "WARNING",
255                     NULL);
256   ret = GNUNET_PROGRAM_run (argc, argv,
257                             "gnunet-gns",
258                             _("GNUnet GNS resolver tool"),
259                             options,
260                             &run, NULL);
261   GNUNET_free ((void*) argv);
262   if (GNUNET_OK != ret)
263     return 1;
264   return global_ret;
265 }
266
267 /* end of gnunet-gns.c */