typo
[oweals/gnunet.git] / src / namecache / gnunet-namecache.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012, 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  * @file gnunet-namecache.c
22  * @brief command line tool to inspect the name cache
23  * @author Christian Grothoff
24  *
25  * TODO:
26  * - test
27  */
28 #include "platform.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_dnsparser_lib.h"
31 #include "gnunet_identity_service.h"
32 #include "gnunet_gnsrecord_lib.h"
33 #include "gnunet_namecache_service.h"
34
35
36 /**
37  * Handle to the namecache.
38  */
39 static struct GNUNET_NAMECACHE_Handle *ns;
40
41 /**
42  * Queue entry for the 'query' operation.
43  */
44 static struct GNUNET_NAMECACHE_QueueEntry *qe;
45
46 /**
47  * Name (label) of the records to list.
48  */
49 static char *name;
50
51 /**
52  * Public key of the zone to look in.
53  */
54 static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey;
55
56 /**
57  * Public key of the zone to look in, in ASCII.
58  */
59 static char *pkey;
60
61 /**
62  * Global return value
63  */
64 static int ret;
65
66
67 /**
68  * Task run on shutdown.  Cleans up everything.
69  *
70  * @param cls unused
71  */
72 static void
73 do_shutdown (void *cls)
74 {
75   if (NULL != qe)
76   {
77     GNUNET_NAMECACHE_cancel (qe);
78     qe = NULL;
79   }
80   if (NULL != ns)
81   {
82     GNUNET_NAMECACHE_disconnect (ns);
83     ns = NULL;
84   }
85 }
86
87
88 /**
89  * Process a record that was stored in the namecache in a block.
90  *
91  * @param cls closure, NULL
92  * @param rd_len number of entries in @a rd array
93  * @param rd array of records with data to store
94  */
95 static void
96 display_records_from_block (void *cls,
97                             unsigned int rd_len,
98                             const struct GNUNET_GNSRECORD_Data *rd)
99 {
100   const char *typestring;
101   char *s;
102   unsigned int i;
103
104   if (0 == rd_len)
105   {
106     FPRINTF (stdout,
107              _("No records found for `%s'"),
108              name);
109     return;
110   }
111   FPRINTF (stdout,
112            "%s:\n",
113            name);
114   for (i=0;i<rd_len;i++)
115   {
116     typestring = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
117     s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
118                                           rd[i].data,
119                                           rd[i].data_size);
120     if (NULL == s)
121     {
122       FPRINTF (stdout, _("\tCorrupt or unsupported record of type %u\n"),
123                (unsigned int) rd[i].record_type);
124       continue;
125     }
126     FPRINTF (stdout,
127              "\t%s: %s\n",
128              typestring,
129              s);
130     GNUNET_free (s);
131   }
132   FPRINTF (stdout, "%s", "\n");
133 }
134
135
136 /**
137  * Display block obtained from listing (by name).
138  *
139  * @param cls NULL
140  * @param block NULL if not found
141  */
142 static void
143 handle_block (void *cls,
144               const struct GNUNET_GNSRECORD_Block *block)
145 {
146   qe = NULL;
147   if (NULL == block)
148   {
149     fprintf (stderr,
150              "No matching block found\n");
151   }
152   else if (GNUNET_OK !=
153            GNUNET_GNSRECORD_block_decrypt (block,
154                                            &pubkey,
155                                            name,
156                                            &display_records_from_block,
157                                            NULL))
158   {
159     fprintf (stderr,
160              "Failed to decrypt block!\n");
161   }
162   GNUNET_SCHEDULER_shutdown ();
163 }
164
165
166 /**
167  * Main function that will be run.
168  *
169  * @param cls closure
170  * @param args remaining command-line arguments
171  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
172  * @param cfg configuration
173  */
174 static void
175 run (void *cls, char *const *args, const char *cfgfile,
176      const struct GNUNET_CONFIGURATION_Handle *cfg)
177 {
178   struct GNUNET_HashCode dhash;
179
180   if (NULL == pkey)
181   {
182     fprintf (stderr,
183              _("You must specify which zone should be accessed\n"));
184     return;
185   }
186
187   if (GNUNET_OK !=
188       GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey,
189                                                   strlen (pkey),
190                                                   &pubkey))
191   {
192     fprintf (stderr,
193              _("Invalid public key for zone `%s'\n"),
194              pkey);
195     GNUNET_SCHEDULER_shutdown ();
196     return;
197   }
198   if (NULL == name)
199   {
200     fprintf (stderr,
201              _("You must specify a name\n"));
202     return;
203   }
204
205   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
206                                  NULL);
207   ns = GNUNET_NAMECACHE_connect (cfg);
208   GNUNET_GNSRECORD_query_from_public_key (&pubkey,
209                                           name,
210                                           &dhash);
211   qe = GNUNET_NAMECACHE_lookup_block (ns,
212                                       &dhash,
213                                       &handle_block,
214                                       NULL);
215 }
216
217
218 /**
219  * The main function for gnunet-namecache.
220  *
221  * @param argc number of arguments from the command line
222  * @param argv command line arguments
223  * @return 0 ok, 1 on error
224  */
225 int
226 main (int argc, char *const *argv)
227 {
228   struct GNUNET_GETOPT_CommandLineOption options[] = {
229     GNUNET_GETOPT_option_string ('n',
230                                  "name",
231                                  "NAME",
232                                  gettext_noop ("name of the record to add/delete/display"),
233                                  &name),
234
235     GNUNET_GETOPT_option_string ('z',
236                                  "zone",
237                                  "PKEY",
238                                  gettext_noop ("specifies the public key of the zone to look in"),
239                                  &pkey),
240
241     GNUNET_GETOPT_OPTION_END
242   };
243
244   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
245     return 2;
246
247   GNUNET_log_setup ("gnunet-namecache", "WARNING", NULL);
248   if (GNUNET_OK !=
249       GNUNET_PROGRAM_run (argc, argv, "gnunet-namecache",
250                           _("GNUnet zone manipulation tool"),
251                           options,
252                           &run, NULL))
253   {
254     GNUNET_free ((void*) argv);
255     return 1;
256   }
257   GNUNET_free ((void*) argv);
258   return ret;
259 }
260
261 /* end of gnunet-namecache.c */