GNUnet  0.10.x
getopt_helpers.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2006, 2011 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 
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 
41 static int
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 
63 GNUNET_GETOPT_option_version (const char *version)
64 {
65  struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = 'v',
66  .name = "version",
67  .description = gettext_noop (
68  "print the version number"),
69  .option_exclusive = 1,
70  .processor = &print_version,
71  .scls = (void *) version};
72  return clo;
73 }
74 
75 
79 #define BORDER 29
80 
90 static int
92  void *scls,
93  const char *option,
94  const char *value)
95 {
96  const char *about = scls;
97  size_t slen;
98  unsigned int i;
99  int j;
100  size_t ml;
101  size_t p;
102  char *scp;
103  const char *trans;
104  const struct GNUNET_GETOPT_CommandLineOption *opt;
105  const struct GNUNET_OS_ProjectData *pd;
106 
107  (void) option;
108  (void) value;
109  if (NULL != about)
110  {
111  printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
112  printf (_ (
113  "Arguments mandatory for long options are also mandatory for short options.\n"));
114  }
115  i = 0;
116  opt = ctx->allOptions;
117  while (NULL != opt[i].description)
118  {
119  if (opt[i].shortName == '\0')
120  printf (" ");
121  else
122  printf (" -%c, ", opt[i].shortName);
123  printf ("--%s", opt[i].name);
124  slen = 8 + strlen (opt[i].name);
125  if (NULL != opt[i].argumentHelp)
126  {
127  printf ("=%s", opt[i].argumentHelp);
128  slen += 1 + strlen (opt[i].argumentHelp);
129  }
130  if (slen > BORDER)
131  {
132  printf ("\n%*s", BORDER, "");
133  slen = BORDER;
134  }
135  if (slen < BORDER)
136  {
137  printf ("%*s", (int) (BORDER - slen), "");
138  slen = BORDER;
139  }
140  if (0 < strlen (opt[i].description))
141  trans = gettext (opt[i].description);
142  else
143  trans = "";
144  ml = strlen (trans);
145  p = 0;
146  OUTER:
147  while (ml - p > 78 - slen)
148  {
149  for (j = p + 78 - slen; j > (int) p; j--)
150  {
151  if (isspace ((unsigned char) trans[j]))
152  {
153  scp = GNUNET_malloc (j - p + 1);
154  GNUNET_memcpy (scp, &trans[p], j - p);
155  scp[j - p] = '\0';
156  printf ("%s\n%*s", scp, BORDER + 2, "");
157  GNUNET_free (scp);
158  p = j + 1;
159  slen = BORDER + 2;
160  goto OUTER;
161  }
162  }
163  /* could not find space to break line */
164  scp = GNUNET_malloc (78 - slen + 1);
165  GNUNET_memcpy (scp, &trans[p], 78 - slen);
166  scp[78 - slen] = '\0';
167  printf ("%s\n%*s", scp, BORDER + 2, "");
168  GNUNET_free (scp);
169  slen = BORDER + 2;
170  p = p + 78 - slen;
171  }
172  /* print rest */
173  if (p < ml)
174  printf ("%s\n", &trans[p]);
175  if (strlen (trans) == 0)
176  printf ("\n");
177  i++;
178  }
180  printf ("Report bugs to %s.\n"
181  "GNUnet home page: %s\n"
182  "General help using GNU software: http://www.gnu.org/gethelp/\n",
183  pd->bug_email,
184  pd->homepage);
185  return GNUNET_NO;
186 }
187 
188 
196 GNUNET_GETOPT_option_help (const char *about)
197 {
198  struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = 'h',
199  .name = "help",
200  .description = gettext_noop (
201  "print this help"),
202  .option_exclusive = 1,
203  .processor = format_help,
204  .scls = (void *) about};
205 
206  return clo;
207 }
208 
209 
224 static int
226  void *scls,
227  const char *option,
228  const char *value)
229 {
230  unsigned int *val = scls;
231 
232  (void) ctx;
233  (void) option;
234  (void) value;
235  (*val)++;
236  return GNUNET_OK;
237 }
238 
239 
251  const char *name,
252  const char *description,
253  unsigned int *val)
254 {
256  .name = name,
257  .description = description,
258  .processor = &increment_value,
259  .scls = (void *) val};
260 
261  return clo;
262 }
263 
264 
272 GNUNET_GETOPT_option_verbose (unsigned int *level)
273 {
274  struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = 'V',
275  .name = "verbose",
276  .description =
277  gettext_noop ("be verbose"),
278  .processor = &increment_value,
279  .scls = (void *) level};
280 
281  return clo;
282 }
283 
284 
299 static int
301  void *scls,
302  const char *option,
303  const char *value)
304 {
305  int *val = scls;
306 
307  (void) ctx;
308  (void) option;
309  (void) value;
310  *val = 1;
311  return GNUNET_OK;
312 }
313 
314 
327  const char *name,
328  const char *description,
329  int *val)
330 {
332  .name = name,
333  .description = description,
334  .processor = &set_one,
335  .scls = (void *) val};
336 
337  return clo;
338 }
339 
340 
355 static int
357  void *scls,
358  const char *option,
359  const char *value)
360 {
361  char **val = scls;
362 
363  (void) ctx;
364  (void) option;
365  GNUNET_assert (NULL != value);
366  GNUNET_free_non_null (*val);
367  *val = GNUNET_strdup (value);
368  return GNUNET_OK;
369 }
370 
371 
383  const char *name,
384  const char *argumentHelp,
385  const char *description,
386  char **str)
387 {
389  .name = name,
390  .argumentHelp = argumentHelp,
391  .description = description,
392  .require_argument = 1,
393  .processor = &set_string,
394  .scls = (void *) str};
395 
396  return clo;
397 }
398 
399 
408 {
410  {.shortName = 'L',
411  .name = "log",
412  .argumentHelp = "LOGLEVEL",
413  .description = gettext_noop ("configure logging to use LOGLEVEL"),
414  .require_argument = 1,
415  .processor = &set_string,
416  .scls = (void *) level};
417 
418  return clo;
419 }
420 
421 
433 static int
435  void *scls,
436  const char *option,
437  const char *value)
438 {
439  char **val = scls;
440 
441  (void) ctx;
442  (void) option;
443  GNUNET_assert (NULL != value);
444  GNUNET_free_non_null (*val);
445  *val = GNUNET_STRINGS_filename_expand (value);
446  return GNUNET_OK;
447 }
448 
449 
461  const char *name,
462  const char *argumentHelp,
463  const char *description,
464  char **str)
465 {
467  .name = name,
468  .argumentHelp = argumentHelp,
469  .description = description,
470  .require_argument = 1,
471  .processor = &set_filename,
472  .scls = (void *) str};
473 
474  return clo;
475 }
476 
477 
485 {
487  {.shortName = 'l',
488  .name = "logfile",
489  .argumentHelp = "FILENAME",
490  .description =
491  gettext_noop ("configure logging to write logs to FILENAME"),
492  .require_argument = 1,
493  .processor = &set_filename,
494  .scls = (void *) logfn};
495 
496  return clo;
497 }
498 
499 
507 {
509  {.shortName = 'c',
510  .name = "config",
511  .argumentHelp = "FILENAME",
512  .description = gettext_noop ("use configuration file FILENAME"),
513  .require_argument = 1,
514  .processor = &set_filename,
515  .scls = (void *) fn};
516 
517  return clo;
518 }
519 
520 
534 static int
536  void *scls,
537  const char *option,
538  const char *value)
539 {
540  unsigned long long *val = scls;
541  char dummy[2];
542 
543  (void) ctx;
544  if (1 != SSCANF (value, "%llu%1s", val, dummy))
545  {
546  FPRINTF (stderr,
547  _ ("You must pass a number to the `%s' option.\n"),
548  option);
549  return GNUNET_SYSERR;
550  }
551  return GNUNET_OK;
552 }
553 
554 
566  const char *name,
567  const char *argumentHelp,
568  const char *description,
569  unsigned long long *val)
570 {
572  .name = name,
573  .argumentHelp = argumentHelp,
574  .description = description,
575  .require_argument = 1,
576  .processor = &set_ulong,
577  .scls = (void *) val};
578 
579  return clo;
580 }
581 
582 
596 static int
598  void *scls,
599  const char *option,
600  const char *value)
601 {
602  struct GNUNET_TIME_Relative *val = scls;
603 
604  (void) ctx;
606  {
607  FPRINTF (stderr,
608  _ ("You must pass relative time to the `%s' option.\n"),
609  option);
610  return GNUNET_SYSERR;
611  }
612  return GNUNET_OK;
613 }
614 
615 
628  const char *name,
629  const char *argumentHelp,
630  const char *description,
631  struct GNUNET_TIME_Relative *val)
632 {
634  .name = name,
635  .argumentHelp = argumentHelp,
636  .description = description,
637  .require_argument = 1,
638  .processor = &set_relative_time,
639  .scls = (void *) val};
640 
641  return clo;
642 }
643 
644 
658 static int
660  void *scls,
661  const char *option,
662  const char *value)
663 {
664  struct GNUNET_TIME_Absolute *val = scls;
665 
666  (void) ctx;
668  {
669  FPRINTF (stderr,
670  _ ("You must pass absolute time to the `%s' option.\n"),
671  option);
672  return GNUNET_SYSERR;
673  }
674  return GNUNET_OK;
675 }
676 
677 
690  const char *name,
691  const char *argumentHelp,
692  const char *description,
693  struct GNUNET_TIME_Absolute *val)
694 {
696  .name = name,
697  .argumentHelp = argumentHelp,
698  .description = description,
699  .require_argument = 1,
700  .processor = &set_absolute_time,
701  .scls = (void *) val};
702 
703  return clo;
704 }
705 
706 
720 static int
722  void *scls,
723  const char *option,
724  const char *value)
725 {
726  unsigned int *val = scls;
727  char dummy[2];
728 
729  (void) ctx;
730  if ('-' == *value)
731  {
732  FPRINTF (stderr,
733  _ (
734  "Your input for the '%s' option has to be a non negative number \n"),
735  option);
736  return GNUNET_SYSERR;
737  }
738  if (1 != SSCANF (value, "%u%1s", val, dummy))
739  {
740  FPRINTF (stderr,
741  _ ("You must pass a number to the `%s' option.\n"),
742  option);
743  return GNUNET_SYSERR;
744  }
745  return GNUNET_OK;
746 }
747 
748 
760  const char *name,
761  const char *argumentHelp,
762  const char *description,
763  unsigned int *val)
764 {
766  .name = name,
767  .argumentHelp = argumentHelp,
768  .description = description,
769  .require_argument = 1,
770  .processor = &set_uint,
771  .scls = (void *) val};
772 
773  return clo;
774 }
775 
776 
790 static int
792  void *scls,
793  const char *option,
794  const char *value)
795 {
796  uint16_t *val = scls;
797  unsigned int v;
798  char dummy[2];
799 
800  (void) ctx;
801  if (1 != SSCANF (value, "%u%1s", &v, dummy))
802  {
803  FPRINTF (stderr,
804  _ ("You must pass a number to the `%s' option.\n"),
805  option);
806  return GNUNET_SYSERR;
807  }
808  if (v > UINT16_MAX)
809  {
810  FPRINTF (stderr,
811  _ ("You must pass a number below %u to the `%s' option.\n"),
812  (unsigned int) UINT16_MAX,
813  option);
814  return GNUNET_SYSERR;
815  }
816  *val = (uint16_t) v;
817  return GNUNET_OK;
818 }
819 
820 
832  const char *name,
833  const char *argumentHelp,
834  const char *description,
835  uint16_t *val)
836 {
838  .name = name,
839  .argumentHelp = argumentHelp,
840  .description = description,
841  .require_argument = 1,
842  .processor = &set_uint16,
843  .scls = (void *) val};
844 
845  return clo;
846 }
847 
848 
853 {
857  void *val;
858 
862  size_t val_size;
863 };
864 
865 
879 static int
881  void *scls,
882  const char *option,
883  const char *value)
884 {
885  struct Base32Context *bc = scls;
886 
887  (void) ctx;
889  strlen (value),
890  bc->val,
891  bc->val_size))
892  {
893  fprintf (
894  stderr,
895  _ (
896  "Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
897  option);
898  return GNUNET_SYSERR;
899  }
900  return GNUNET_OK;
901 }
902 
903 
910 static void
911 free_bc (void *cls)
912 {
913  GNUNET_free (cls);
914 }
915 
916 
930  const char *name,
931  const char *argumentHelp,
932  const char *description,
933  void *val,
934  size_t val_size)
935 {
936  struct Base32Context *bc = GNUNET_new (struct Base32Context);
938  .name = name,
939  .argumentHelp = argumentHelp,
940  .description = description,
941  .require_argument = 1,
942  .processor = &set_base32,
943  .cleaner = &free_bc,
944  .scls = (void *) bc};
945 
946  bc->val = val;
947  bc->val_size = val_size;
948  return clo;
949 }
950 
951 
960 {
961  opt.option_mandatory = 1;
962  return opt;
963 }
964 
965 
974 {
975  opt.option_exclusive = 1;
976  return opt;
977 }
978 
979 
980 /* end of getopt_helpers.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_relative_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Relative *val)
Allow user to specify a struct GNUNET_TIME_Relative (using human-readable "fancy" time)...
static int set_absolute_time(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;struct GNUNET_TIME_Absolute&#39; from the command line.
General context for command line processors.
static int increment_value(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;unsigned int&#39; from the command line.
static int print_version(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Print out program version (implements –version).
static int set_relative_time(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;struct GNUNET_TIME_Relative&#39; from the command line.
Project-specific data used to help the OS subsystem find installation paths.
const char * argumentHelp
Name of the argument for the user in help text.
void * scls
Specific closure to pass to the processor.
static struct in_addr dummy
Target "dummy" address.
static int set_one(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;int&#39; from the command line to 1 if the given option is present.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_help(const char *about)
Defining the option to print the command line help text (-h option).
#define FPRINTF
Definition: plibc.h:683
static int format_help(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Print out details on command line options (implements –help).
const char * binaryName
Name of the application.
const char * description
Help text for the option (description)
static int set_string(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;char *&#39; from the command line.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the &#39;-V&#39; verbosity option.
#define gettext(Msgid)
Definition: gettext.h:45
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_increment_uint(char shortName, const char *name, const char *description, unsigned int *val)
Increment val each time the option flag is given by one.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:353
const struct GNUNET_GETOPT_CommandLineOption * allOptions
Array with all command line options.
int GNUNET_STRINGS_fancy_time_to_absolute(const char *fancy_time, struct GNUNET_TIME_Absolute *atime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:408
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_base32_fixed_size(char shortName, const char *name, const char *argumentHelp, const char *description, void *val, size_t val_size)
Allow user to specify a binary value using Crockford Base32 encoding.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
Closure for set_base32().
const char shortName
Short name of the option.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_logfile(char **logfn)
Allow user to specify log file name (-l option)
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
const char * bug_email
E-mail address for reporting bugs.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_version(const char *version)
Define the option to print the version of the application (-v option)
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_filename(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a filename (automatically path expanded).
#define GNUNET_memcpy(dst, src, n)
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static char * value
Value of the record to add/remove.
static char * fn
Filename of the unique file.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_absolute_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Absolute *val)
Allow user to specify a struct GNUNET_TIME_Absolute (using human-readable "fancy" time)...
int option_exclusive
Is the option exclusive?
#define BORDER
At what offset does the help text start?
static char * option
Name of the option.
Definition: gnunet-config.c:38
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_loglevel(char **level)
Define the &#39;-L&#39; log level option.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_mandatory(struct GNUNET_GETOPT_CommandLineOption opt)
Make the given option mandatory.
static void free_bc(void *cls)
Helper function to clean up after GNUNET_GETOPT_option_base32_fixed_size.
static int set_uint16(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;uint16_t&#39; from the command line.
size_t val_size
Number of bytes expected for val.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static int set_base32(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;unsigned int&#39; from the command line.
static int set_filename(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;char *&#39; from the command line with filename expansion a la GNUNET_STRINGS_file...
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition: strings.c:602
const char * name
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_ulong(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned long long *val)
Allow user to specify an unsigned long long
void * val
Value to initialize (already allocated)
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_cfgfile(char **fn)
Allow user to specify configuration file name (-c option)
const char * homepage
Project homepage.
const char * binaryOptions
Name of application with option summary.
static int set_uint(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;unsigned int&#39; from the command line.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_exclusive(struct GNUNET_GETOPT_CommandLineOption opt)
Make the given option mutually exclusive with other options.
#define SSCANF
Definition: plibc.h:691
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get(void)
Time for absolute times used by GNUnet, in microseconds.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned int *val)
Allow user to specify an unsigned integer.
#define GNUNET_malloc(size)
Wrapper around malloc.
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:1021
static int set_ulong(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, void *scls, const char *option, const char *value)
Set an option of type &#39;unsigned long long&#39; from the command line.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint16(char shortName, const char *name, const char *argumentHelp, const char *description, uint16_t *val)
Allow user to specify an uint16_t.
#define gettext_noop(String)
Definition: gettext.h:69
int option_mandatory
Is the presence of this option mandatory?