-dead
[oweals/gnunet.git] / src / namecache / gnunet-namecache.c
1
2 /*
3      This file is part of GNUnet.
4      (C) 2012, 2013 Christian Grothoff (and other contributing authors)
5
6      GNUnet is free software; you can redistribute it and/or modify
7      it under the terms of the GNU General Public License as published
8      by the Free Software Foundation; either version 3, or (at your
9      option) any later version.
10
11      GNUnet is distributed in the hope that it will be useful, but
12      WITHOUT ANY WARRANTY; without even the implied warranty of
13      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14      General Public License for more details.
15
16      You should have received a copy of the GNU General Public License
17      along with GNUnet; see the file COPYING.  If not, write to the
18      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19      Boston, MA 02111-1307, USA.
20 */
21 /**
22  * @file gnunet-namecache.c
23  * @brief command line tool to inspect the name cache
24  * @author Christian Grothoff
25  *
26  * TODO:
27  * - test
28  */
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_dnsparser_lib.h"
32 #include "gnunet_identity_service.h"
33 #include "gnunet_gnsrecord_lib.h"
34 #include "gnunet_namecache_service.h"
35
36
37 /**
38  * Handle to the namecache.
39  */
40 static struct GNUNET_NAMECACHE_Handle *ns;
41
42 /**
43  * Queue entry for the 'query' operation.
44  */
45 static struct GNUNET_NAMECACHE_QueueEntry *qe;
46
47 /**
48  * Name (label) of the records to list.
49  */
50 static char *name;
51
52 /**
53  * Public key of the zone to look in.
54  */
55 static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey;
56
57 /**
58  * Public key of the zone to look in, in ASCII.
59  */
60 static char *pkey;
61
62 /**
63  * Global return value
64  */
65 static int ret;
66
67
68 /**
69  * Task run on shutdown.  Cleans up everything.
70  *
71  * @param cls unused
72  * @param tc scheduler context
73  */
74 static void
75 do_shutdown (void *cls,
76              const struct GNUNET_SCHEDULER_TaskContext *tc)
77 {
78   if (NULL != qe)
79   {
80     GNUNET_NAMECACHE_cancel (qe);
81     qe = NULL;
82   }
83   if (NULL != ns)
84   {
85     GNUNET_NAMECACHE_disconnect (ns);
86     ns = NULL;
87   }
88 }
89
90
91 /**
92  * Process a record that was stored in the namecache in a block.
93  *
94  * @param cls closure, NULL
95  * @param rd_len number of entries in @a rd array
96  * @param rd array of records with data to store
97  */
98 static void
99 display_records_from_block (void *cls,
100                             unsigned int rd_len,
101                             const struct GNUNET_GNSRECORD_Data *rd)
102 {
103   const char *typestring;
104   char *s;
105   unsigned int i;
106
107   if (0 == rd_len)
108   {
109     FPRINTF (stdout,
110              _("No records found for `%s'"),
111              name);
112     return;
113   }
114   FPRINTF (stdout,
115            "%s:\n",
116            name);
117   for (i=0;i<rd_len;i++)
118   {
119     typestring = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
120     s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
121                                           rd[i].data,
122                                           rd[i].data_size);
123     if (NULL == s)
124     {
125       FPRINTF (stdout, _("\tCorrupt or unsupported record of type %u\n"),
126                (unsigned int) rd[i].record_type);
127       continue;
128     }
129     FPRINTF (stdout,
130              "\t%s: %s\n",
131              typestring,
132              s);
133     GNUNET_free (s);
134   }
135   FPRINTF (stdout, "%s", "\n");
136 }
137
138
139 /**
140  * Display block obtained from listing (by name).
141  *
142  * @param cls NULL
143  * @param block NULL if not found
144  */
145 static void
146 handle_block (void *cls,
147               const struct GNUNET_GNSRECORD_Block *block)
148 {
149   qe = NULL;
150   if (NULL == block)
151   {
152     fprintf (stderr,
153              "No matching block found\n");
154   }
155   else if (GNUNET_OK !=
156            GNUNET_GNSRECORD_block_decrypt (block,
157                                            &pubkey,
158                                            name,
159                                            &display_records_from_block,
160                                            NULL))
161   {
162     fprintf (stderr,
163              "Failed to decrypt block!\n");
164   }
165   GNUNET_SCHEDULER_shutdown ();
166 }
167
168
169 /**
170  * Main function that will be run.
171  *
172  * @param cls closure
173  * @param args remaining command-line arguments
174  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
175  * @param cfg configuration
176  */
177 static void
178 run (void *cls, char *const *args, const char *cfgfile,
179      const struct GNUNET_CONFIGURATION_Handle *cfg)
180 {
181   struct GNUNET_HashCode dhash;
182
183   if (NULL == pkey)
184   {
185     fprintf (stderr,
186              _("You must specify which zone should be accessed\n"));
187     return;
188   }
189
190   if (GNUNET_OK !=
191       GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey,
192                                                   strlen (pkey),
193                                                   &pubkey))
194   {
195     fprintf (stderr,
196              _("Invalid public key for reverse lookup `%s'\n"),
197              pkey);
198     GNUNET_SCHEDULER_shutdown ();
199     return;
200   }
201   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
202                                 &do_shutdown,
203                                 NULL);
204   GNUNET_GNSRECORD_query_from_public_key (&pubkey,
205                                           name,
206                                           &dhash);
207   qe = GNUNET_NAMECACHE_lookup_block (ns,
208                                       &dhash,
209                                       &handle_block,
210                                       NULL);
211 }
212
213
214 /**
215  * The main function for gnunet-namecache.
216  *
217  * @param argc number of arguments from the command line
218  * @param argv command line arguments
219  * @return 0 ok, 1 on error
220  */
221 int
222 main (int argc, char *const *argv)
223 {
224   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
225     {'n', "name", "NAME",
226      gettext_noop ("name of the record to add/delete/display"), 1,
227      &GNUNET_GETOPT_set_string, &name},
228     {'z', "zone", "PKEY",
229      gettext_noop ("spezifies the public key of the zone to look in"), 1,
230      &GNUNET_GETOPT_set_string, &pkey},
231     GNUNET_GETOPT_OPTION_END
232   };
233
234   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
235     return 2;
236
237   GNUNET_log_setup ("gnunet-namecache", "WARNING", NULL);
238   if (GNUNET_OK !=
239       GNUNET_PROGRAM_run (argc, argv, "gnunet-namecache",
240                           _("GNUnet zone manipulation tool"),
241                           options,
242                           &run, NULL))
243   {
244     GNUNET_free ((void*) argv);
245     return 1;
246   }
247   GNUNET_free ((void*) argv);
248   return ret;
249 }
250
251 /* end of gnunet-namecache.c */