use NULL value in load_path_suffix to NOT load any files
[oweals/gnunet.git] / src / util / getopt_helpers.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2006, 2011, 2020 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 /**
22  * @file src/util/getopt_helpers.c
23  * @brief implements command line that sets option
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28
29 #define LOG(kind, ...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
30
31
32 /**
33  * Print out program version (implements --version).
34  *
35  * @param ctx command line processing context
36  * @param scls additional closure (points to version string)
37  * @param option name of the option
38  * @param value not used (NULL)
39  * @return #GNUNET_NO (do not continue, not an error)
40  */
41 static int
42 print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
43                void *scls,
44                const char *option,
45                const char *value)
46 {
47   const char *version = scls;
48
49   (void) option;
50   (void) value;
51   printf ("%s v%s\n", ctx->binaryName, version);
52   return GNUNET_NO;
53 }
54
55
56 /**
57  * Define the option to print the version of
58  * the application (-v option)
59  *
60  * @param version string with the version number
61  */
62 struct GNUNET_GETOPT_CommandLineOption
63 GNUNET_GETOPT_option_version (const char *version)
64 {
65   struct GNUNET_GETOPT_CommandLineOption clo = {
66     .shortName = 'v',
67     .name = "version",
68     .description = gettext_noop (
69       "print the version number"),
70     .option_exclusive = 1,
71     .processor = &print_version,
72     .scls = (void *) version
73   };
74
75   return clo;
76 }
77
78
79 /**
80  * At what offset does the help text start?
81  */
82 #define BORDER 29
83
84 /**
85  * Print out details on command line options (implements --help).
86  *
87  * @param ctx command line processing context
88  * @param scls additional closure (points to about text)
89  * @param option name of the option
90  * @param value not used (NULL)
91  * @return #GNUNET_NO (do not continue, not an error)
92  */
93 static int
94 format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
95              void *scls,
96              const char *option,
97              const char *value)
98 {
99   const char *about = scls;
100   size_t slen;
101   unsigned int i;
102   int j;
103   size_t ml;
104   size_t p;
105   char *scp;
106   const char *trans;
107   const struct GNUNET_GETOPT_CommandLineOption *opt;
108   const struct GNUNET_OS_ProjectData *pd;
109
110   (void) option;
111   (void) value;
112   if (NULL != about)
113   {
114     printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
115     printf (_ (
116               "Arguments mandatory for long options are also mandatory for short options.\n"));
117   }
118   i = 0;
119   opt = ctx->allOptions;
120   while (NULL != opt[i].description)
121   {
122     if (opt[i].shortName == '\0')
123       printf ("      ");
124     else
125       printf ("  -%c, ", opt[i].shortName);
126     printf ("--%s", opt[i].name);
127     slen = 8 + strlen (opt[i].name);
128     if (NULL != opt[i].argumentHelp)
129     {
130       printf ("=%s", opt[i].argumentHelp);
131       slen += 1 + strlen (opt[i].argumentHelp);
132     }
133     if (slen > BORDER)
134     {
135       printf ("\n%*s", BORDER, "");
136       slen = BORDER;
137     }
138     if (slen < BORDER)
139     {
140       printf ("%*s", (int) (BORDER - slen), "");
141       slen = BORDER;
142     }
143     if (0 < strlen (opt[i].description))
144       trans = gettext (opt[i].description);
145     else
146       trans = "";
147     ml = strlen (trans);
148     p = 0;
149 OUTER:
150     while (ml - p > 78 - slen)
151     {
152       for (j = p + 78 - slen; j > (int) p; j--)
153       {
154         if (isspace ((unsigned char) trans[j]))
155         {
156           scp = GNUNET_malloc (j - p + 1);
157           GNUNET_memcpy (scp, &trans[p], j - p);
158           scp[j - p] = '\0';
159           printf ("%s\n%*s", scp, BORDER + 2, "");
160           GNUNET_free (scp);
161           p = j + 1;
162           slen = BORDER + 2;
163           goto OUTER;
164         }
165       }
166       /* could not find space to break line */
167       scp = GNUNET_malloc (78 - slen + 1);
168       GNUNET_memcpy (scp, &trans[p], 78 - slen);
169       scp[78 - slen] = '\0';
170       printf ("%s\n%*s", scp, BORDER + 2, "");
171       GNUNET_free (scp);
172       slen = BORDER + 2;
173       p = p + 78 - slen;
174     }
175     /* print rest */
176     if (p < ml)
177       printf ("%s\n", &trans[p]);
178     if (strlen (trans) == 0)
179       printf ("\n");
180     i++;
181   }
182   pd = GNUNET_OS_project_data_get ();
183   printf ("Report bugs to %s.\n"
184           "Home page: %s\n",
185           pd->bug_email,
186           pd->homepage);
187
188   if (0 != pd->is_gnu)
189     printf ("General help using GNU software: http://www.gnu.org/gethelp/\n");
190
191   return GNUNET_NO;
192 }
193
194
195 /**
196  * Defining the option to print the command line
197  * help text (-h option).
198  *
199  * @param about string with brief description of the application
200  */
201 struct GNUNET_GETOPT_CommandLineOption
202 GNUNET_GETOPT_option_help (const char *about)
203 {
204   struct GNUNET_GETOPT_CommandLineOption clo = {
205     .shortName = 'h',
206     .name = "help",
207     .description = gettext_noop (
208       "print this help"),
209     .option_exclusive = 1,
210     .processor = format_help,
211     .scls = (void *) about
212   };
213
214   return clo;
215 }
216
217
218 /**
219  * Set an option of type 'unsigned int' from the command line. Each
220  * time the option flag is given, the value is incremented by one.
221  * A pointer to this function should be passed as part of the
222  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
223  * of this type.  It should be followed by a pointer to a value of
224  * type 'int'.
225  *
226  * @param ctx command line processing context
227  * @param scls additional closure (will point to the 'unsigned int')
228  * @param option name of the option
229  * @param value not used (NULL)
230  * @return #GNUNET_OK
231  */
232 static int
233 increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
234                  void *scls,
235                  const char *option,
236                  const char *value)
237 {
238   unsigned int *val = scls;
239
240   (void) ctx;
241   (void) option;
242   (void) value;
243   (*val)++;
244   return GNUNET_OK;
245 }
246
247
248 /**
249  * Increment @a val each time the option flag is given by one.
250  *
251  * @param shortName short name of the option
252  * @param name long name of the option
253  * @param argumentHelp help text for the option argument
254  * @param description long help text for the option
255  * @param[out] val increment by 1 each time the option is present
256  */
257 struct GNUNET_GETOPT_CommandLineOption
258 GNUNET_GETOPT_option_increment_uint (char shortName,
259                                      const char *name,
260                                      const char *description,
261                                      unsigned int *val)
262 {
263   struct GNUNET_GETOPT_CommandLineOption clo = {
264     .shortName = shortName,
265     .name = name,
266     .description = description,
267     .processor = &increment_value,
268     .scls = (void *) val
269   };
270
271   return clo;
272 }
273
274
275 /**
276  * Define the '-V' verbosity option.  Using the option more
277  * than once increments @a level each time.
278  *
279  * @param[out] level set to the verbosity level
280  */
281 struct GNUNET_GETOPT_CommandLineOption
282 GNUNET_GETOPT_option_verbose (unsigned int *level)
283 {
284   struct GNUNET_GETOPT_CommandLineOption clo = {
285     .shortName = 'V',
286     .name = "verbose",
287     .description =
288       gettext_noop ("be verbose"),
289     .processor = &increment_value,
290     .scls = (void *) level
291   };
292
293   return clo;
294 }
295
296
297 /**
298  * Set an option of type 'int' from the command line to 1 if the
299  * given option is present.
300  * A pointer to this function should be passed as part of the
301  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
302  * of this type.  It should be followed by a pointer to a value of
303  * type 'int'.
304  *
305  * @param ctx command line processing context
306  * @param scls additional closure (will point to the 'int')
307  * @param option name of the option
308  * @param value not used (NULL)
309  * @return #GNUNET_OK
310  */
311 static int
312 set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
313          void *scls,
314          const char *option,
315          const char *value)
316 {
317   int *val = scls;
318
319   (void) ctx;
320   (void) option;
321   (void) value;
322   *val = 1;
323   return GNUNET_OK;
324 }
325
326
327 /**
328  * Allow user to specify a flag (which internally means setting
329  * an integer to 1/#GNUNET_YES/#GNUNET_OK.
330  *
331  * @param shortName short name of the option
332  * @param name long name of the option
333  * @param argumentHelp help text for the option argument
334  * @param description long help text for the option
335  * @param[out] val set to 1 if the option is present
336  */
337 struct GNUNET_GETOPT_CommandLineOption
338 GNUNET_GETOPT_option_flag (char shortName,
339                            const char *name,
340                            const char *description,
341                            int *val)
342 {
343   struct GNUNET_GETOPT_CommandLineOption clo = {
344     .shortName = shortName,
345     .name = name,
346     .description = description,
347     .processor = &set_one,
348     .scls = (void *) val
349   };
350
351   return clo;
352 }
353
354
355 /**
356  * Set an option of type 'char *' from the command line.
357  * A pointer to this function should be passed as part of the
358  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
359  * of this type.  It should be followed by a pointer to a value of
360  * type 'char *', which will be allocated with the requested string.
361  *
362  * @param ctx command line processing context
363  * @param scls additional closure (will point to the 'char *',
364  *             which will be allocated)
365  * @param option name of the option
366  * @param value actual value of the option (a string)
367  * @return #GNUNET_OK
368  */
369 static int
370 set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
371             void *scls,
372             const char *option,
373             const char *value)
374 {
375   char **val = scls;
376
377   (void) ctx;
378   (void) option;
379   GNUNET_assert (NULL != value);
380   GNUNET_free_non_null (*val);
381   *val = GNUNET_strdup (value);
382   return GNUNET_OK;
383 }
384
385
386 /**
387  * Allow user to specify a string.
388  *
389  * @param shortName short name of the option
390  * @param name long name of the option
391  * @param argumentHelp help text for the option argument
392  * @param description long help text for the option
393  * @param[out] str set to the string
394  */
395 struct GNUNET_GETOPT_CommandLineOption
396 GNUNET_GETOPT_option_string (char shortName,
397                              const char *name,
398                              const char *argumentHelp,
399                              const char *description,
400                              char **str)
401 {
402   struct GNUNET_GETOPT_CommandLineOption clo = {
403     .shortName = shortName,
404     .name = name,
405     .argumentHelp = argumentHelp,
406     .description = description,
407     .require_argument = 1,
408     .processor = &set_string,
409     .scls = (void *) str
410   };
411
412   return clo;
413 }
414
415
416 /**
417  * Define the '-L' log level option.  Note that we do not check
418  * that the log level is valid here.
419  *
420  * @param[out] level set to the log level
421  */
422 struct GNUNET_GETOPT_CommandLineOption
423 GNUNET_GETOPT_option_loglevel (char **level)
424 {
425   struct GNUNET_GETOPT_CommandLineOption clo = {
426     .shortName = 'L',
427     .name = "log",
428     .argumentHelp = "LOGLEVEL",
429     .description = gettext_noop ("configure logging to use LOGLEVEL"),
430     .require_argument = 1,
431     .processor = &set_string,
432     .scls = (void *) level
433   };
434
435   return clo;
436 }
437
438
439 /**
440  * Set an option of type 'char *' from the command line with
441  * filename expansion a la #GNUNET_STRINGS_filename_expand().
442  *
443  * @param ctx command line processing context
444  * @param scls additional closure (will point to the `char *`,
445  *             which will be allocated)
446  * @param option name of the option
447  * @param value actual value of the option (a string)
448  * @return #GNUNET_OK
449  */
450 static int
451 set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
452               void *scls,
453               const char *option,
454               const char *value)
455 {
456   char **val = scls;
457
458   (void) ctx;
459   (void) option;
460   GNUNET_assert (NULL != value);
461   GNUNET_free_non_null (*val);
462   *val = GNUNET_STRINGS_filename_expand (value);
463   return GNUNET_OK;
464 }
465
466
467 /**
468  * Allow user to specify a filename (automatically path expanded).
469  *
470  * @param shortName short name of the option
471  * @param name long name of the option
472  * @param argumentHelp help text for the option argument
473  * @param description long help text for the option
474  * @param[out] str set to the string
475  */
476 struct GNUNET_GETOPT_CommandLineOption
477 GNUNET_GETOPT_option_filename (char shortName,
478                                const char *name,
479                                const char *argumentHelp,
480                                const char *description,
481                                char **str)
482 {
483   struct GNUNET_GETOPT_CommandLineOption clo = {
484     .shortName = shortName,
485     .name = name,
486     .argumentHelp = argumentHelp,
487     .description = description,
488     .require_argument = 1,
489     .processor = &set_filename,
490     .scls = (void *) str
491   };
492
493   return clo;
494 }
495
496
497 /**
498  * Allow user to specify log file name (-l option)
499  *
500  * @param[out] logfn set to the name of the logfile
501  */
502 struct GNUNET_GETOPT_CommandLineOption
503 GNUNET_GETOPT_option_logfile (char **logfn)
504 {
505   struct GNUNET_GETOPT_CommandLineOption clo = {
506     .shortName = 'l',
507     .name = "logfile",
508     .argumentHelp = "FILENAME",
509     .description =
510       gettext_noop ("configure logging to write logs to FILENAME"),
511     .require_argument = 1,
512     .processor = &set_filename,
513     .scls = (void *) logfn
514   };
515
516   return clo;
517 }
518
519
520 /**
521  * Allow user to specify configuration file name (-c option)
522  *
523  * @param[out] fn set to the name of the configuration file
524  */
525 struct GNUNET_GETOPT_CommandLineOption
526 GNUNET_GETOPT_option_cfgfile (char **fn)
527 {
528   struct GNUNET_GETOPT_CommandLineOption clo = {
529     .shortName = 'c',
530     .name = "config",
531     .argumentHelp = "FILENAME",
532     .description = gettext_noop ("use configuration file FILENAME"),
533     .require_argument = 1,
534     .processor = &set_filename,
535     .scls = (void *) fn
536   };
537
538   return clo;
539 }
540
541
542 /**
543  * Set an option of type 'unsigned long long' from the command line.
544  * A pointer to this function should be passed as part of the
545  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
546  * of this type.  It should be followed by a pointer to a value of
547  * type 'unsigned long long'.
548  *
549  * @param ctx command line processing context
550  * @param scls additional closure (will point to the 'unsigned long long')
551  * @param option name of the option
552  * @param value actual value of the option as a string.
553  * @return #GNUNET_OK if parsing the value worked
554  */
555 static int
556 set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
557            void *scls,
558            const char *option,
559            const char *value)
560 {
561   unsigned long long *val = scls;
562   char dummy[2];
563
564   (void) ctx;
565   if (1 != sscanf (value, "%llu%1s", val, dummy))
566   {
567     fprintf (stderr,
568              _ ("You must pass a number to the `%s' option.\n"),
569              option);
570     return GNUNET_SYSERR;
571   }
572   return GNUNET_OK;
573 }
574
575
576 /**
577  * Allow user to specify an `unsigned long long`
578  *
579  * @param shortName short name of the option
580  * @param name long name of the option
581  * @param argumentHelp help text for the option argument
582  * @param description long help text for the option
583  * @param[out] val set to the value specified at the command line
584  */
585 struct GNUNET_GETOPT_CommandLineOption
586 GNUNET_GETOPT_option_ulong (char shortName,
587                             const char *name,
588                             const char *argumentHelp,
589                             const char *description,
590                             unsigned long long *val)
591 {
592   struct GNUNET_GETOPT_CommandLineOption clo = {
593     .shortName = shortName,
594     .name = name,
595     .argumentHelp = argumentHelp,
596     .description = description,
597     .require_argument = 1,
598     .processor = &set_ulong,
599     .scls = (void *) val
600   };
601
602   return clo;
603 }
604
605
606 /**
607  * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
608  * A pointer to this function should be passed as part of the
609  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
610  * of this type.  It should be followed by a pointer to a value of
611  * type 'struct GNUNET_TIME_Relative'.
612  *
613  * @param ctx command line processing context
614  * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
615  * @param option name of the option
616  * @param value actual value of the option as a string.
617  * @return #GNUNET_OK if parsing the value worked
618  */
619 static int
620 set_timetravel_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
621                      void *scls,
622                      const char *option,
623                      const char *value)
624 {
625   long long delta;
626
627   (void) scls;
628   (void) ctx;
629   if (1 != sscanf (value,
630                    "%lld",
631                    &delta))
632   {
633     fprintf (stderr,
634              _ ("You must pass a number to the `%s' option.\n"),
635              option);
636     return GNUNET_SYSERR;
637   }
638   GNUNET_TIME_set_offset (delta);
639   return GNUNET_OK;
640 }
641
642
643 /**
644  * Allow user to specify a `long long` with an offset to add to the current
645  * system time to construct the time seen by the application. Used for
646  * debugging / testing.
647  *
648  * @param shortName short name of the option
649  * @param name long name of the option
650  * @param[out] val set to the time specified at the command line
651  */
652 struct GNUNET_GETOPT_CommandLineOption
653 GNUNET_GETOPT_option_timetravel (char shortName,
654                                  const char *name)
655 {
656   struct GNUNET_GETOPT_CommandLineOption clo = {
657     .shortName = shortName,
658     .name = name,
659     .argumentHelp = _ ("[+/-]MICROSECONDS"),
660     .description = _ (
661       "modify system time by given offset (for debugging/testing only)"),
662     .require_argument = 1,
663     .processor =
664       &set_timetravel_time
665   };
666
667   return clo;
668 }
669
670
671 /**
672  * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
673  * A pointer to this function should be passed as part of the
674  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
675  * of this type.  It should be followed by a pointer to a value of
676  * type 'struct GNUNET_TIME_Relative'.
677  *
678  * @param ctx command line processing context
679  * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
680  * @param option name of the option
681  * @param value actual value of the option as a string.
682  * @return #GNUNET_OK if parsing the value worked
683  */
684 static int
685 set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
686                    void *scls,
687                    const char *option,
688                    const char *value)
689 {
690   struct GNUNET_TIME_Relative *val = scls;
691
692   (void) ctx;
693   if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (value, val))
694   {
695     fprintf (stderr,
696              _ ("You must pass relative time to the `%s' option.\n"),
697              option);
698     return GNUNET_SYSERR;
699   }
700   return GNUNET_OK;
701 }
702
703
704 /**
705  * Allow user to specify a `struct GNUNET_TIME_Relative`
706  * (using human-readable "fancy" time).
707  *
708  * @param shortName short name of the option
709  * @param name long name of the option
710  * @param argumentHelp help text for the option argument
711  * @param description long help text for the option
712  * @param[out] val set to the time specified at the command line
713  */
714 struct GNUNET_GETOPT_CommandLineOption
715 GNUNET_GETOPT_option_relative_time (char shortName,
716                                     const char *name,
717                                     const char *argumentHelp,
718                                     const char *description,
719                                     struct GNUNET_TIME_Relative *val)
720 {
721   struct GNUNET_GETOPT_CommandLineOption clo = {
722     .shortName = shortName,
723     .name = name,
724     .argumentHelp = argumentHelp,
725     .description = description,
726     .require_argument = 1,
727     .processor =
728       &set_relative_time,
729     .scls = (void *) val
730   };
731
732   return clo;
733 }
734
735
736 /**
737  * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
738  * A pointer to this function should be passed as part of the
739  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
740  * of this type.  It should be followed by a pointer to a value of
741  * type 'struct GNUNET_TIME_Absolute'.
742  *
743  * @param ctx command line processing context
744  * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
745  * @param option name of the option
746  * @param value actual value of the option as a string.
747  * @return #GNUNET_OK if parsing the value worked
748  */
749 static int
750 set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
751                    void *scls,
752                    const char *option,
753                    const char *value)
754 {
755   struct GNUNET_TIME_Absolute *val = scls;
756
757   (void) ctx;
758   if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (value, val))
759   {
760     fprintf (stderr,
761              _ ("You must pass absolute time to the `%s' option.\n"),
762              option);
763     return GNUNET_SYSERR;
764   }
765   return GNUNET_OK;
766 }
767
768
769 /**
770  * Allow user to specify a `struct GNUNET_TIME_Absolute`
771  * (using human-readable "fancy" time).
772  *
773  * @param shortName short name of the option
774  * @param name long name of the option
775  * @param argumentHelp help text for the option argument
776  * @param description long help text for the option
777  * @param[out] val set to the time specified at the command line
778  */
779 struct GNUNET_GETOPT_CommandLineOption
780 GNUNET_GETOPT_option_absolute_time (char shortName,
781                                     const char *name,
782                                     const char *argumentHelp,
783                                     const char *description,
784                                     struct GNUNET_TIME_Absolute *val)
785 {
786   struct GNUNET_GETOPT_CommandLineOption clo = {
787     .shortName = shortName,
788     .name = name,
789     .argumentHelp = argumentHelp,
790     .description = description,
791     .require_argument = 1,
792     .processor =
793       &set_absolute_time,
794     .scls = (void *) val
795   };
796
797   return clo;
798 }
799
800
801 /**
802  * Set an option of type 'unsigned int' from the command line.
803  * A pointer to this function should be passed as part of the
804  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
805  * of this type.  It should be followed by a pointer to a value of
806  * type 'unsigned int'.
807  *
808  * @param ctx command line processing context
809  * @param scls additional closure (will point to the 'unsigned int')
810  * @param option name of the option
811  * @param value actual value of the option as a string.
812  * @return #GNUNET_OK if parsing the value worked
813  */
814 static int
815 set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
816           void *scls,
817           const char *option,
818           const char *value)
819 {
820   unsigned int *val = scls;
821   char dummy[2];
822
823   (void) ctx;
824   if ('-' == *value)
825   {
826     fprintf (stderr,
827              _ (
828                "Your input for the '%s' option has to be a non negative number\n"),
829              option);
830     return GNUNET_SYSERR;
831   }
832   if (1 != sscanf (value, "%u%1s", val, dummy))
833   {
834     fprintf (stderr,
835              _ ("You must pass a number to the `%s' option.\n"),
836              option);
837     return GNUNET_SYSERR;
838   }
839   return GNUNET_OK;
840 }
841
842
843 /**
844  * Allow user to specify an unsigned integer.
845  *
846  * @param shortName short name of the option
847  * @param name long name of the option
848  * @param argumentHelp help text for the option argument
849  * @param description long help text for the option
850  * @param[out] val set to the value specified at the command line
851  */
852 struct GNUNET_GETOPT_CommandLineOption
853 GNUNET_GETOPT_option_uint (char shortName,
854                            const char *name,
855                            const char *argumentHelp,
856                            const char *description,
857                            unsigned int *val)
858 {
859   struct GNUNET_GETOPT_CommandLineOption clo = {
860     .shortName = shortName,
861     .name = name,
862     .argumentHelp = argumentHelp,
863     .description = description,
864     .require_argument = 1,
865     .processor = &set_uint,
866     .scls = (void *) val
867   };
868
869   return clo;
870 }
871
872
873 /**
874  * Set an option of type 'uint16_t' from the command line.
875  * A pointer to this function should be passed as part of the
876  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
877  * of this type.  It should be followed by a pointer to a value of
878  * type 'uint16_t'.
879  *
880  * @param ctx command line processing context
881  * @param scls additional closure (will point to the 'unsigned int')
882  * @param option name of the option
883  * @param value actual value of the option as a string.
884  * @return #GNUNET_OK if parsing the value worked
885  */
886 static int
887 set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
888             void *scls,
889             const char *option,
890             const char *value)
891 {
892   uint16_t *val = scls;
893   unsigned int v;
894   char dummy[2];
895
896   (void) ctx;
897   if (1 != sscanf (value, "%u%1s", &v, dummy))
898   {
899     fprintf (stderr,
900              _ ("You must pass a number to the `%s' option.\n"),
901              option);
902     return GNUNET_SYSERR;
903   }
904   if (v > UINT16_MAX)
905   {
906     fprintf (stderr,
907              _ ("You must pass a number below %u to the `%s' option.\n"),
908              (unsigned int) UINT16_MAX,
909              option);
910     return GNUNET_SYSERR;
911   }
912   *val = (uint16_t) v;
913   return GNUNET_OK;
914 }
915
916
917 /**
918  * Allow user to specify an uint16_t.
919  *
920  * @param shortName short name of the option
921  * @param name long name of the option
922  * @param argumentHelp help text for the option argument
923  * @param description long help text for the option
924  * @param[out] val set to the value specified at the command line
925  */
926 struct GNUNET_GETOPT_CommandLineOption
927 GNUNET_GETOPT_option_uint16 (char shortName,
928                              const char *name,
929                              const char *argumentHelp,
930                              const char *description,
931                              uint16_t *val)
932 {
933   struct GNUNET_GETOPT_CommandLineOption clo = {
934     .shortName = shortName,
935     .name = name,
936     .argumentHelp = argumentHelp,
937     .description = description,
938     .require_argument = 1,
939     .processor = &set_uint16,
940     .scls = (void *) val
941   };
942
943   return clo;
944 }
945
946
947 /**
948  * Closure for #set_base32().
949  */
950 struct Base32Context
951 {
952   /**
953    * Value to initialize (already allocated)
954    */
955   void *val;
956
957   /**
958    * Number of bytes expected for @e val.
959    */
960   size_t val_size;
961 };
962
963
964 /**
965  * Set an option of type 'unsigned int' from the command line.
966  * A pointer to this function should be passed as part of the
967  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
968  * of this type.  It should be followed by a pointer to a value of
969  * type 'unsigned int'.
970  *
971  * @param ctx command line processing context
972  * @param scls additional closure (will point to the 'unsigned int')
973  * @param option name of the option
974  * @param value actual value of the option as a string.
975  * @return #GNUNET_OK if parsing the value worked
976  */
977 static int
978 set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
979             void *scls,
980             const char *option,
981             const char *value)
982 {
983   struct Base32Context *bc = scls;
984
985   (void) ctx;
986   if (GNUNET_OK != GNUNET_STRINGS_string_to_data (value,
987                                                   strlen (value),
988                                                   bc->val,
989                                                   bc->val_size))
990   {
991     fprintf (
992       stderr,
993       _ (
994         "Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
995       option);
996     return GNUNET_SYSERR;
997   }
998   return GNUNET_OK;
999 }
1000
1001
1002 /**
1003  * Helper function to clean up after
1004  * #GNUNET_GETOPT_option_base32_fixed_size.
1005  *
1006  * @param cls value to GNUNET_free()
1007  */
1008 static void
1009 free_bc (void *cls)
1010 {
1011   GNUNET_free (cls);
1012 }
1013
1014
1015 /**
1016  * Allow user to specify a binary value using Crockford
1017  * Base32 encoding.
1018  *
1019  * @param shortName short name of the option
1020  * @param name long name of the option
1021  * @param argumentHelp help text for the option argument
1022  * @param description long help text for the option
1023  * @param[out] val binary value decoded from Crockford Base32-encoded argument
1024  * @param val_size size of @a val in bytes
1025  */
1026 struct GNUNET_GETOPT_CommandLineOption
1027 GNUNET_GETOPT_option_base32_fixed_size (char shortName,
1028                                         const char *name,
1029                                         const char *argumentHelp,
1030                                         const char *description,
1031                                         void *val,
1032                                         size_t val_size)
1033 {
1034   struct Base32Context *bc = GNUNET_new (struct Base32Context);
1035   struct GNUNET_GETOPT_CommandLineOption clo = {
1036     .shortName = shortName,
1037     .name = name,
1038     .argumentHelp = argumentHelp,
1039     .description = description,
1040     .require_argument = 1,
1041     .processor = &set_base32,
1042     .cleaner = &free_bc,
1043     .scls = (void *) bc
1044   };
1045
1046   bc->val = val;
1047   bc->val_size = val_size;
1048   return clo;
1049 }
1050
1051
1052 /**
1053  * Make the given option mandatory.
1054  *
1055  * @param opt option to modify
1056  * @return @a opt with the mandatory flag set.
1057  */
1058 struct GNUNET_GETOPT_CommandLineOption
1059 GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
1060 {
1061   opt.option_mandatory = 1;
1062   return opt;
1063 }
1064
1065
1066 /**
1067  * Make the given option mutually exclusive with other options.
1068  *
1069  * @param opt option to modify
1070  * @return @a opt with the exclusive flag set.
1071  */
1072 struct GNUNET_GETOPT_CommandLineOption
1073 GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt)
1074 {
1075   opt.option_exclusive = 1;
1076   return opt;
1077 }
1078
1079
1080 /* end of getopt_helpers.c */