f585cf6ccd63a0fecc88a5bd819a96dad4b6dfd1
[oweals/gnunet.git] / src / fs / gnunet-pseudonym.c
1 /*
2      This file is part of GNUnet.
3      (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009, 2010 Christian Grothoff (and other contributing authors)
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 2, 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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20 /**
21  * @file fs/gnunet-pseudonym.c
22  * @brief manage GNUnet namespaces / pseudonyms
23  * @author Christian Grothoff
24  */
25 #include "platform.h"
26 #include "gnunet_fs_service.h"
27
28 /**
29  * -a optiton.
30  */
31 static unsigned int anonymity;
32
33 /**
34  * -A option.
35  */
36 static int start_automate;
37
38 /**
39  * -e option
40  */
41 static int stop_automate;
42
43 /**
44  * -C option
45  */
46 static char *create_ns;
47
48 /**
49  * -D option
50  */
51 static char *delete_ns;
52
53 /**
54  * -k option
55  */
56 static struct GNUNET_FS_Uri *ksk_uri;
57
58 /**
59  * -l option.
60  */
61 static int print_local_only;
62
63 /**
64  * -m option.
65  */
66 static struct GNUNET_CONTAINER_MetaData *adv_metadata;
67
68 /**
69  * -p option.
70  */
71 static unsigned int priority = 365;
72
73 /**
74  * -q option given.
75  */
76 static int no_remote_printing; 
77
78 /**
79  * -r option.
80  */
81 static char *root_identifier;
82
83 /**
84  * -s option.
85  */
86 static char *rating_change;
87
88 /**
89  * Handle to fs service.
90  */
91 static struct GNUNET_FS_Handle *h;
92
93 /**
94  * Namespace we are looking at.
95  */
96 static struct GNUNET_FS_Namespace *ns;
97
98 /**
99  * Our configuration.
100  */
101 static const struct GNUNET_CONFIGURATION_Handle *cfg;
102
103 static int ret;
104
105 static void* 
106 progress_cb (void *cls,
107              const struct GNUNET_FS_ProgressInfo *info)
108 {
109   return NULL;
110 }
111
112
113 static void
114 ns_printer (void *cls,
115             const char *name,
116             const GNUNET_HashCode *id)
117 {
118   struct GNUNET_CRYPTO_HashAsciiEncoded enc;
119
120   GNUNET_CRYPTO_hash_to_enc (id, &enc);
121   fprintf (stdout, 
122            "%s (%s)\n",
123            name,
124            (const char*) &enc);
125 }
126
127
128 static int
129 pseudo_printer (void *cls,
130                 const GNUNET_HashCode *
131                 pseudonym,
132                 const struct
133                 GNUNET_CONTAINER_MetaData * md,
134                 int rating)
135 {
136   char *id;
137
138   id = GNUNET_PSEUDONYM_id_to_name (cfg,
139                                     pseudonym);
140   if (id == NULL)
141     {
142       GNUNET_break (0);
143       return GNUNET_OK;
144     }
145   fprintf (stdout, 
146            "%s (%d):\n",
147            id,
148            rating);
149   GNUNET_CONTAINER_meta_data_iterate (md,
150                                       &EXTRACTOR_meta_data_print, 
151                                       stdout);
152   fprintf (stdout, "\n");
153   GNUNET_free (id);
154   return GNUNET_OK;
155 }
156
157
158 static void
159 post_advertising (void *cls,
160                   const struct GNUNET_FS_Uri *uri,
161                   const char *emsg)
162 {
163   GNUNET_HashCode nsid;
164   char *set;
165   int delta;
166
167   if (emsg != NULL)
168     {
169       fprintf (stderr, "%s", emsg);
170       ret = 1;
171     }
172   if (ns != NULL)
173     {
174       if (GNUNET_OK !=
175           GNUNET_FS_namespace_delete (ns,
176                                       GNUNET_NO))
177         ret = 1;
178     }
179   if (0 != stop_automate)
180     {
181       GNUNET_break (0); // FIXME: not implemented
182     }
183   if (0 != start_automate)
184     {
185       GNUNET_break (0); // FIXME: not implemented
186     }
187   if (NULL != rating_change)
188     {
189       set = rating_change;
190       while ((*set != '\0') && (*set != ':'))
191         set++;
192       if (*set != ':')
193         {
194           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
195                       _("Invalid argument `%s'\n"),
196                       rating_change);
197         }
198       else
199         {
200           *set = '\0';
201           delta = strtol (&set[1], NULL, /* no error handling yet */
202                           10);
203           if (GNUNET_OK ==
204               GNUNET_PSEUDONYM_name_to_id (cfg,
205                                            rating_change,
206                                            &nsid))
207             {
208               (void) GNUNET_PSEUDONYM_rank (cfg,
209                                             &nsid,
210                                             delta);           
211             }
212           else
213             {
214               GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
215                           _("Namespace `%s' unknown.\n"),
216                           rating_change);
217             }
218         }
219       GNUNET_free (rating_change);
220       rating_change = NULL;
221     }
222   if (0 != print_local_only)
223     {
224       GNUNET_FS_namespace_list (h,
225                                 &ns_printer, 
226                                 NULL);
227     }  
228   else if (0 == no_remote_printing)
229     {
230       GNUNET_PSEUDONYM_list_all (cfg,
231                                  &pseudo_printer,
232                                  NULL);
233     }
234   GNUNET_FS_stop (h);
235 }
236
237
238 /**
239  * Main function that will be run by the scheduler.
240  *
241  * @param cls closure
242  * @param sched the scheduler to use
243  * @param args remaining command-line arguments
244  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
245  * @param c configuration
246  */
247 static void
248 run (void *cls,
249      struct GNUNET_SCHEDULER_Handle *sched,
250      char *const *args,
251      const char *cfgfile,
252      const struct GNUNET_CONFIGURATION_Handle *c)
253 {
254   struct GNUNET_TIME_Absolute expiration;
255   char *emsg;
256
257   cfg = c;
258   h = GNUNET_FS_start (sched,
259                        cfg,
260                        "gnunet-pseudonym",
261                        &progress_cb,
262                        NULL,
263                        GNUNET_FS_FLAGS_NONE);
264   if (NULL != delete_ns)
265     {
266       ns = GNUNET_FS_namespace_create (h, delete_ns);
267       if (ns == NULL)
268         {
269           ret = 1;
270         }
271       else
272         {
273           if (GNUNET_OK !=
274               GNUNET_FS_namespace_delete (ns,
275                                           GNUNET_YES))
276             ret = 1;
277           ns = NULL;
278         }
279     }
280   if (NULL != create_ns)
281     {
282       ns = GNUNET_FS_namespace_create (h, create_ns);
283       if (ns == NULL)
284         {
285           ret = 1;
286         }
287       else
288         {
289           if (NULL != root_identifier)
290             {
291               expiration = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_YEARS);
292               if (ksk_uri == NULL)
293                 {
294                   emsg = NULL;
295                   ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/namespace", &emsg);
296                   GNUNET_assert (NULL == emsg);
297                 }
298               GNUNET_FS_namespace_advertise (h,
299                                              ksk_uri,
300                                              ns,
301                                              adv_metadata,
302                                              anonymity,
303                                              priority,                                       
304                                              expiration,
305                                              root_identifier,
306                                              &post_advertising,
307                                              NULL);
308               return;
309             }
310           else
311             {
312               if (ksk_uri != NULL)
313                 fprintf (stderr, _("Option `%s' ignored\n"), "-k");   
314             }
315         }
316     }
317   else
318     {
319       if (root_identifier != NULL) 
320         fprintf (stderr, _("Option `%s' ignored\n"), "-r");
321       if (ksk_uri != NULL)
322         fprintf (stderr, _("Option `%s' ignored\n"), "-k");   
323     }    
324     
325   post_advertising (NULL, NULL, NULL);
326 }
327
328 /**
329  * gnunet-pseudonym command line options
330  */
331 static struct GNUNET_GETOPT_CommandLineOption options[] = {
332   {'a', "anonymity", "LEVEL",
333    gettext_noop ("set the desired LEVEL of sender-anonymity"),
334    1, &GNUNET_GETOPT_set_uint, &anonymity},
335   {'A', "automate", NULL,
336    gettext_noop ("start a collection"),
337    0, &GNUNET_GETOPT_set_one, &start_automate},
338   {'C', "create", "NAME",
339    gettext_noop
340    ("create or advertise namespace NAME"),
341    1, &GNUNET_GETOPT_set_string, &create_ns},
342   {'D', "delete", "NAME",
343    gettext_noop
344    ("delete namespace NAME "),
345    1, &GNUNET_GETOPT_set_string, &delete_ns},
346   {'e', "end", NULL,
347    gettext_noop ("end current collection"),
348    0, &GNUNET_GETOPT_set_one, &stop_automate},
349   {'k', "keyword", "VALUE",
350   gettext_noop
351    ("add an additional keyword for the advertisment"
352     " (this option can be specified multiple times)"),
353    1, &GNUNET_FS_getopt_set_keywords, &ksk_uri},
354   {'m', "meta", "TYPE:VALUE",
355    gettext_noop ("set the meta-data for the given TYPE to the given VALUE"),
356    1, &GNUNET_FS_getopt_set_metadata, &adv_metadata},
357   {'o', "only-local", NULL,
358    gettext_noop ("print names of local namespaces"),
359    0, &GNUNET_GETOPT_set_one, &print_local_only},
360   {'p', "priority", "PRIORITY",
361    gettext_noop ("use the given PRIORITY for the advertisments"),
362    1, &GNUNET_GETOPT_set_uint, &priority},
363   {'q', "quiet", NULL,
364    gettext_noop ("do not print names of remote namespaces"),
365    0, &GNUNET_GETOPT_set_one, &no_remote_printing},
366   {'r', "root", "ID",
367    gettext_noop
368    ("specify ID of the root of the namespace"),
369    1, &GNUNET_GETOPT_set_string, &root_identifier},
370   {'s', "set-rating", "ID:VALUE",
371    gettext_noop
372    ("change rating of namespace ID by VALUE"),
373    1, &GNUNET_GETOPT_set_string, &rating_change},
374   GNUNET_GETOPT_OPTION_END
375 };
376
377
378 /**
379  * The main function to inspect GNUnet directories.
380  *
381  * @param argc number of arguments from the command line
382  * @param argv command line arguments
383  * @return 0 ok, 1 on error
384  */
385 int
386 main (int argc, char *const *argv)
387 {
388   return (GNUNET_OK ==
389           GNUNET_PROGRAM_run (argc,
390                               argv,
391                               "gnunet-pseudonym",
392                               gettext_noop
393                               ("Manage GNUnet pseudonyms."),
394                               options, &run, NULL)) ? ret : 1;
395 }
396
397 /* end of gnunet-pseudonym.c */