GNUnet  0.11.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 
73  return clo;
74 }
75 
76 
80 #define BORDER 29
81 
91 static int
93  void *scls,
94  const char *option,
95  const char *value)
96 {
97  const char *about = scls;
98  size_t slen;
99  unsigned int i;
100  int j;
101  size_t ml;
102  size_t p;
103  char *scp;
104  const char *trans;
105  const struct GNUNET_GETOPT_CommandLineOption *opt;
106  const struct GNUNET_OS_ProjectData *pd;
107 
108  (void) option;
109  (void) value;
110  if (NULL != about)
111  {
112  printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
113  printf (_ (
114  "Arguments mandatory for long options are also mandatory for short options.\n"));
115  }
116  i = 0;
117  opt = ctx->allOptions;
118  while (NULL != opt[i].description)
119  {
120  if (opt[i].shortName == '\0')
121  printf (" ");
122  else
123  printf (" -%c, ", opt[i].shortName);
124  printf ("--%s", opt[i].name);
125  slen = 8 + strlen (opt[i].name);
126  if (NULL != opt[i].argumentHelp)
127  {
128  printf ("=%s", opt[i].argumentHelp);
129  slen += 1 + strlen (opt[i].argumentHelp);
130  }
131  if (slen > BORDER)
132  {
133  printf ("\n%*s", BORDER, "");
134  slen = BORDER;
135  }
136  if (slen < BORDER)
137  {
138  printf ("%*s", (int) (BORDER - slen), "");
139  slen = BORDER;
140  }
141  if (0 < strlen (opt[i].description))
142  trans = gettext (opt[i].description);
143  else
144  trans = "";
145  ml = strlen (trans);
146  p = 0;
147 OUTER:
148  while (ml - p > 78 - slen)
149  {
150  for (j = p + 78 - slen; j > (int) p; j--)
151  {
152  if (isspace ((unsigned char) trans[j]))
153  {
154  scp = GNUNET_malloc (j - p + 1);
155  GNUNET_memcpy (scp, &trans[p], j - p);
156  scp[j - p] = '\0';
157  printf ("%s\n%*s", scp, BORDER + 2, "");
158  GNUNET_free (scp);
159  p = j + 1;
160  slen = BORDER + 2;
161  goto OUTER;
162  }
163  }
164  /* could not find space to break line */
165  scp = GNUNET_malloc (78 - slen + 1);
166  GNUNET_memcpy (scp, &trans[p], 78 - slen);
167  scp[78 - slen] = '\0';
168  printf ("%s\n%*s", scp, BORDER + 2, "");
169  GNUNET_free (scp);
170  slen = BORDER + 2;
171  p = p + 78 - slen;
172  }
173  /* print rest */
174  if (p < ml)
175  printf ("%s\n", &trans[p]);
176  if (strlen (trans) == 0)
177  printf ("\n");
178  i++;
179  }
181  printf ("Report bugs to %s.\n"
182  "Home page: %s\n",
183  pd->bug_email,
184  pd->homepage);
185 
186  if (0 != pd->is_gnu)
187  printf ("General help using GNU software: http://www.gnu.org/gethelp/\n");
188 
189  return GNUNET_NO;
190 }
191 
192 
200 GNUNET_GETOPT_option_help (const char *about)
201 {
202  struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = 'h',
203  .name = "help",
204  .description = gettext_noop (
205  "print this help"),
206  .option_exclusive = 1,
207  .processor = format_help,
208  .scls = (void *) about };
209 
210  return clo;
211 }
212 
213 
228 static int
230  void *scls,
231  const char *option,
232  const char *value)
233 {
234  unsigned int *val = scls;
235 
236  (void) ctx;
237  (void) option;
238  (void) value;
239  (*val)++;
240  return GNUNET_OK;
241 }
242 
243 
255  const char *name,
256  const char *description,
257  unsigned int *val)
258 {
260  .name = name,
261  .description = description,
262  .processor = &increment_value,
263  .scls = (void *) val };
264 
265  return clo;
266 }
267 
268 
276 GNUNET_GETOPT_option_verbose (unsigned int *level)
277 {
278  struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = 'V',
279  .name = "verbose",
280  .description =
281  gettext_noop ("be verbose"),
282  .processor = &increment_value,
283  .scls = (void *) level };
284 
285  return clo;
286 }
287 
288 
303 static int
305  void *scls,
306  const char *option,
307  const char *value)
308 {
309  int *val = scls;
310 
311  (void) ctx;
312  (void) option;
313  (void) value;
314  *val = 1;
315  return GNUNET_OK;
316 }
317 
318 
331  const char *name,
332  const char *description,
333  int *val)
334 {
336  .name = name,
337  .description = description,
338  .processor = &set_one,
339  .scls = (void *) val };
340 
341  return clo;
342 }
343 
344 
359 static int
361  void *scls,
362  const char *option,
363  const char *value)
364 {
365  char **val = scls;
366 
367  (void) ctx;
368  (void) option;
369  GNUNET_assert (NULL != value);
370  GNUNET_free_non_null (*val);
371  *val = GNUNET_strdup (value);
372  return GNUNET_OK;
373 }
374 
375 
387  const char *name,
388  const char *argumentHelp,
389  const char *description,
390  char **str)
391 {
393  .name = name,
394  .argumentHelp = argumentHelp,
395  .description = description,
396  .require_argument = 1,
397  .processor = &set_string,
398  .scls = (void *) str };
399 
400  return clo;
401 }
402 
403 
412 {
414  { .shortName = 'L',
415  .name = "log",
416  .argumentHelp = "LOGLEVEL",
417  .description = gettext_noop ("configure logging to use LOGLEVEL"),
418  .require_argument = 1,
419  .processor = &set_string,
420  .scls = (void *) level };
421 
422  return clo;
423 }
424 
425 
437 static int
439  void *scls,
440  const char *option,
441  const char *value)
442 {
443  char **val = scls;
444 
445  (void) ctx;
446  (void) option;
447  GNUNET_assert (NULL != value);
448  GNUNET_free_non_null (*val);
449  *val = GNUNET_STRINGS_filename_expand (value);
450  return GNUNET_OK;
451 }
452 
453 
465  const char *name,
466  const char *argumentHelp,
467  const char *description,
468  char **str)
469 {
471  .name = name,
472  .argumentHelp = argumentHelp,
473  .description = description,
474  .require_argument = 1,
475  .processor = &set_filename,
476  .scls = (void *) str };
477 
478  return clo;
479 }
480 
481 
489 {
491  { .shortName = 'l',
492  .name = "logfile",
493  .argumentHelp = "FILENAME",
494  .description =
495  gettext_noop ("configure logging to write logs to FILENAME"),
496  .require_argument = 1,
497  .processor = &set_filename,
498  .scls = (void *) logfn };
499 
500  return clo;
501 }
502 
503 
511 {
513  { .shortName = 'c',
514  .name = "config",
515  .argumentHelp = "FILENAME",
516  .description = gettext_noop ("use configuration file FILENAME"),
517  .require_argument = 1,
518  .processor = &set_filename,
519  .scls = (void *) fn };
520 
521  return clo;
522 }
523 
524 
538 static int
540  void *scls,
541  const char *option,
542  const char *value)
543 {
544  unsigned long long *val = scls;
545  char dummy[2];
546 
547  (void) ctx;
548  if (1 != sscanf (value, "%llu%1s", val, dummy))
549  {
550  fprintf (stderr,
551  _ ("You must pass a number to the `%s' option.\n"),
552  option);
553  return GNUNET_SYSERR;
554  }
555  return GNUNET_OK;
556 }
557 
558 
570  const char *name,
571  const char *argumentHelp,
572  const char *description,
573  unsigned long long *val)
574 {
576  .name = name,
577  .argumentHelp = argumentHelp,
578  .description = description,
579  .require_argument = 1,
580  .processor = &set_ulong,
581  .scls = (void *) val };
582 
583  return clo;
584 }
585 
586 
600 static int
602  void *scls,
603  const char *option,
604  const char *value)
605 {
606  struct GNUNET_TIME_Relative *val = scls;
607 
608  (void) ctx;
610  {
611  fprintf (stderr,
612  _ ("You must pass relative time to the `%s' option.\n"),
613  option);
614  return GNUNET_SYSERR;
615  }
616  return GNUNET_OK;
617 }
618 
619 
632  const char *name,
633  const char *argumentHelp,
634  const char *description,
635  struct GNUNET_TIME_Relative *val)
636 {
638  .name = name,
639  .argumentHelp = argumentHelp,
640  .description = description,
641  .require_argument = 1,
642  .processor =
644  .scls = (void *) val };
645 
646  return clo;
647 }
648 
649 
663 static int
665  void *scls,
666  const char *option,
667  const char *value)
668 {
669  struct GNUNET_TIME_Absolute *val = scls;
670 
671  (void) ctx;
673  {
674  fprintf (stderr,
675  _ ("You must pass absolute time to the `%s' option.\n"),
676  option);
677  return GNUNET_SYSERR;
678  }
679  return GNUNET_OK;
680 }
681 
682 
695  const char *name,
696  const char *argumentHelp,
697  const char *description,
698  struct GNUNET_TIME_Absolute *val)
699 {
701  .name = name,
702  .argumentHelp = argumentHelp,
703  .description = description,
704  .require_argument = 1,
705  .processor =
707  .scls = (void *) val };
708 
709  return clo;
710 }
711 
712 
726 static int
728  void *scls,
729  const char *option,
730  const char *value)
731 {
732  unsigned int *val = scls;
733  char dummy[2];
734 
735  (void) ctx;
736  if ('-' == *value)
737  {
738  fprintf (stderr,
739  _ (
740  "Your input for the '%s' option has to be a non negative number \n"),
741  option);
742  return GNUNET_SYSERR;
743  }
744  if (1 != sscanf (value, "%u%1s", val, dummy))
745  {
746  fprintf (stderr,
747  _ ("You must pass a number to the `%s' option.\n"),
748  option);
749  return GNUNET_SYSERR;
750  }
751  return GNUNET_OK;
752 }
753 
754 
766  const char *name,
767  const char *argumentHelp,
768  const char *description,
769  unsigned int *val)
770 {
772  .name = name,
773  .argumentHelp = argumentHelp,
774  .description = description,
775  .require_argument = 1,
776  .processor = &set_uint,
777  .scls = (void *) val };
778 
779  return clo;
780 }
781 
782 
796 static int
798  void *scls,
799  const char *option,
800  const char *value)
801 {
802  uint16_t *val = scls;
803  unsigned int v;
804  char dummy[2];
805 
806  (void) ctx;
807  if (1 != sscanf (value, "%u%1s", &v, dummy))
808  {
809  fprintf (stderr,
810  _ ("You must pass a number to the `%s' option.\n"),
811  option);
812  return GNUNET_SYSERR;
813  }
814  if (v > UINT16_MAX)
815  {
816  fprintf (stderr,
817  _ ("You must pass a number below %u to the `%s' option.\n"),
818  (unsigned int) UINT16_MAX,
819  option);
820  return GNUNET_SYSERR;
821  }
822  *val = (uint16_t) v;
823  return GNUNET_OK;
824 }
825 
826 
838  const char *name,
839  const char *argumentHelp,
840  const char *description,
841  uint16_t *val)
842 {
844  .name = name,
845  .argumentHelp = argumentHelp,
846  .description = description,
847  .require_argument = 1,
848  .processor = &set_uint16,
849  .scls = (void *) val };
850 
851  return clo;
852 }
853 
854 
859 {
863  void *val;
864 
868  size_t val_size;
869 };
870 
871 
885 static int
887  void *scls,
888  const char *option,
889  const char *value)
890 {
891  struct Base32Context *bc = scls;
892 
893  (void) ctx;
895  strlen (value),
896  bc->val,
897  bc->val_size))
898  {
899  fprintf (
900  stderr,
901  _ (
902  "Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
903  option);
904  return GNUNET_SYSERR;
905  }
906  return GNUNET_OK;
907 }
908 
909 
916 static void
917 free_bc (void *cls)
918 {
919  GNUNET_free (cls);
920 }
921 
922 
936  const char *name,
937  const char *argumentHelp,
938  const char *description,
939  void *val,
940  size_t val_size)
941 {
942  struct Base32Context *bc = GNUNET_new (struct Base32Context);
944  .name = name,
945  .argumentHelp = argumentHelp,
946  .description = description,
947  .require_argument = 1,
948  .processor = &set_base32,
949  .cleaner = &free_bc,
950  .scls = (void *) bc };
951 
952  bc->val = val;
953  bc->val_size = val_size;
954  return clo;
955 }
956 
957 
966 {
967  opt.option_mandatory = 1;
968  return opt;
969 }
970 
971 
980 {
981  opt.option_exclusive = 1;
982  return opt;
983 }
984 
985 
986 /* 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 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).
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:351
const struct GNUNET_GETOPT_CommandLineOption * allOptions
Array with all command line options.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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:402
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:181
int is_gnu
Non-zero means this project is part of GNU.
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).
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:76
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:603
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)
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
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.
const char * name
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:952
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?