diff options
Diffstat (limited to 'src/util/getopt_helpers.c')
-rw-r--r-- | src/util/getopt_helpers.c | 1104 |
1 files changed, 0 insertions, 1104 deletions
diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c deleted file mode 100644 index 592875531..000000000 --- a/src/util/getopt_helpers.c +++ /dev/null | |||
@@ -1,1104 +0,0 @@ | |||
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 (*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 (*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 | long long minus; | ||
627 | struct GNUNET_TIME_Relative rt; | ||
628 | |||
629 | (void) scls; | ||
630 | (void) ctx; | ||
631 | while (isspace (value[0])) | ||
632 | value++; | ||
633 | minus = 1; | ||
634 | if (value[0] == '-') | ||
635 | { | ||
636 | minus = -1; | ||
637 | value++; | ||
638 | } | ||
639 | else if (value[0] == '+') | ||
640 | { | ||
641 | value++; | ||
642 | } | ||
643 | if (GNUNET_OK != | ||
644 | GNUNET_STRINGS_fancy_time_to_relative (value, | ||
645 | &rt)) | ||
646 | { | ||
647 | fprintf (stderr, | ||
648 | _ ( | ||
649 | "You must pass a relative time (optionally with sign) to the `%s' option.\n"), | ||
650 | option); | ||
651 | return GNUNET_SYSERR; | ||
652 | } | ||
653 | if (rt.rel_value_us > LLONG_MAX) | ||
654 | { | ||
655 | fprintf (stderr, | ||
656 | _ ("Value given for time travel `%s' option is too big.\n"), | ||
657 | option); | ||
658 | return GNUNET_SYSERR; | ||
659 | } | ||
660 | delta = (long long) rt.rel_value_us; | ||
661 | delta *= minus; | ||
662 | GNUNET_TIME_set_offset (delta); | ||
663 | return GNUNET_OK; | ||
664 | } | ||
665 | |||
666 | |||
667 | /** | ||
668 | * Allow user to specify a `long long` with an offset to add to the current | ||
669 | * system time to construct the time seen by the application. Used for | ||
670 | * debugging / testing. | ||
671 | * | ||
672 | * @param shortName short name of the option | ||
673 | * @param name long name of the option | ||
674 | * @param[out] val set to the time specified at the command line | ||
675 | */ | ||
676 | struct GNUNET_GETOPT_CommandLineOption | ||
677 | GNUNET_GETOPT_option_timetravel (char shortName, | ||
678 | const char *name) | ||
679 | { | ||
680 | struct GNUNET_GETOPT_CommandLineOption clo = { | ||
681 | .shortName = shortName, | ||
682 | .name = name, | ||
683 | .argumentHelp = _ ("[+/-]MICROSECONDS"), | ||
684 | .description = _ ( | ||
685 | "modify system time by given offset (for debugging/testing only)"), | ||
686 | .require_argument = 1, | ||
687 | .processor = | ||
688 | &set_timetravel_time | ||
689 | }; | ||
690 | |||
691 | return clo; | ||
692 | } | ||
693 | |||
694 | |||
695 | /** | ||
696 | * Set an option of type 'struct GNUNET_TIME_Relative' from the command line. | ||
697 | * A pointer to this function should be passed as part of the | ||
698 | * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options | ||
699 | * of this type. It should be followed by a pointer to a value of | ||
700 | * type 'struct GNUNET_TIME_Relative'. | ||
701 | * | ||
702 | * @param ctx command line processing context | ||
703 | * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative') | ||
704 | * @param option name of the option | ||
705 | * @param value actual value of the option as a string. | ||
706 | * @return #GNUNET_OK if parsing the value worked | ||
707 | */ | ||
708 | static int | ||
709 | set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
710 | void *scls, | ||
711 | const char *option, | ||
712 | const char *value) | ||
713 | { | ||
714 | struct GNUNET_TIME_Relative *val = scls; | ||
715 | |||
716 | (void) ctx; | ||
717 | if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (value, val)) | ||
718 | { | ||
719 | fprintf (stderr, | ||
720 | _ ("You must pass relative time to the `%s' option.\n"), | ||
721 | option); | ||
722 | return GNUNET_SYSERR; | ||
723 | } | ||
724 | return GNUNET_OK; | ||
725 | } | ||
726 | |||
727 | |||
728 | /** | ||
729 | * Allow user to specify a `struct GNUNET_TIME_Relative` | ||
730 | * (using human-readable "fancy" time). | ||
731 | * | ||
732 | * @param shortName short name of the option | ||
733 | * @param name long name of the option | ||
734 | * @param argumentHelp help text for the option argument | ||
735 | * @param description long help text for the option | ||
736 | * @param[out] val set to the time specified at the command line | ||
737 | */ | ||
738 | struct GNUNET_GETOPT_CommandLineOption | ||
739 | GNUNET_GETOPT_option_relative_time (char shortName, | ||
740 | const char *name, | ||
741 | const char *argumentHelp, | ||
742 | const char *description, | ||
743 | struct GNUNET_TIME_Relative *val) | ||
744 | { | ||
745 | struct GNUNET_GETOPT_CommandLineOption clo = { | ||
746 | .shortName = shortName, | ||
747 | .name = name, | ||
748 | .argumentHelp = argumentHelp, | ||
749 | .description = description, | ||
750 | .require_argument = 1, | ||
751 | .processor = | ||
752 | &set_relative_time, | ||
753 | .scls = (void *) val | ||
754 | }; | ||
755 | |||
756 | return clo; | ||
757 | } | ||
758 | |||
759 | |||
760 | /** | ||
761 | * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line. | ||
762 | * A pointer to this function should be passed as part of the | ||
763 | * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options | ||
764 | * of this type. It should be followed by a pointer to a value of | ||
765 | * type 'struct GNUNET_TIME_Absolute'. | ||
766 | * | ||
767 | * @param ctx command line processing context | ||
768 | * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`) | ||
769 | * @param option name of the option | ||
770 | * @param value actual value of the option as a string. | ||
771 | * @return #GNUNET_OK if parsing the value worked | ||
772 | */ | ||
773 | static int | ||
774 | set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
775 | void *scls, | ||
776 | const char *option, | ||
777 | const char *value) | ||
778 | { | ||
779 | struct GNUNET_TIME_Absolute *val = scls; | ||
780 | |||
781 | (void) ctx; | ||
782 | if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (value, val)) | ||
783 | { | ||
784 | fprintf (stderr, | ||
785 | _ ("You must pass absolute time to the `%s' option.\n"), | ||
786 | option); | ||
787 | return GNUNET_SYSERR; | ||
788 | } | ||
789 | return GNUNET_OK; | ||
790 | } | ||
791 | |||
792 | |||
793 | /** | ||
794 | * Allow user to specify a `struct GNUNET_TIME_Absolute` | ||
795 | * (using human-readable "fancy" time). | ||
796 | * | ||
797 | * @param shortName short name of the option | ||
798 | * @param name long name of the option | ||
799 | * @param argumentHelp help text for the option argument | ||
800 | * @param description long help text for the option | ||
801 | * @param[out] val set to the time specified at the command line | ||
802 | */ | ||
803 | struct GNUNET_GETOPT_CommandLineOption | ||
804 | GNUNET_GETOPT_option_absolute_time (char shortName, | ||
805 | const char *name, | ||
806 | const char *argumentHelp, | ||
807 | const char *description, | ||
808 | struct GNUNET_TIME_Absolute *val) | ||
809 | { | ||
810 | struct GNUNET_GETOPT_CommandLineOption clo = { | ||
811 | .shortName = shortName, | ||
812 | .name = name, | ||
813 | .argumentHelp = argumentHelp, | ||
814 | .description = description, | ||
815 | .require_argument = 1, | ||
816 | .processor = | ||
817 | &set_absolute_time, | ||
818 | .scls = (void *) val | ||
819 | }; | ||
820 | |||
821 | return clo; | ||
822 | } | ||
823 | |||
824 | |||
825 | /** | ||
826 | * Set an option of type 'unsigned int' from the command line. | ||
827 | * A pointer to this function should be passed as part of the | ||
828 | * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options | ||
829 | * of this type. It should be followed by a pointer to a value of | ||
830 | * type 'unsigned int'. | ||
831 | * | ||
832 | * @param ctx command line processing context | ||
833 | * @param scls additional closure (will point to the 'unsigned int') | ||
834 | * @param option name of the option | ||
835 | * @param value actual value of the option as a string. | ||
836 | * @return #GNUNET_OK if parsing the value worked | ||
837 | */ | ||
838 | static int | ||
839 | set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
840 | void *scls, | ||
841 | const char *option, | ||
842 | const char *value) | ||
843 | { | ||
844 | unsigned int *val = scls; | ||
845 | char dummy[2]; | ||
846 | |||
847 | (void) ctx; | ||
848 | if ('-' == *value) | ||
849 | { | ||
850 | fprintf (stderr, | ||
851 | _ ( | ||
852 | "Your input for the '%s' option has to be a non negative number\n"), | ||
853 | option); | ||
854 | return GNUNET_SYSERR; | ||
855 | } | ||
856 | if (1 != sscanf (value, "%u%1s", val, dummy)) | ||
857 | { | ||
858 | fprintf (stderr, | ||
859 | _ ("You must pass a number to the `%s' option.\n"), | ||
860 | option); | ||
861 | return GNUNET_SYSERR; | ||
862 | } | ||
863 | return GNUNET_OK; | ||
864 | } | ||
865 | |||
866 | |||
867 | /** | ||
868 | * Allow user to specify an unsigned integer. | ||
869 | * | ||
870 | * @param shortName short name of the option | ||
871 | * @param name long name of the option | ||
872 | * @param argumentHelp help text for the option argument | ||
873 | * @param description long help text for the option | ||
874 | * @param[out] val set to the value specified at the command line | ||
875 | */ | ||
876 | struct GNUNET_GETOPT_CommandLineOption | ||
877 | GNUNET_GETOPT_option_uint (char shortName, | ||
878 | const char *name, | ||
879 | const char *argumentHelp, | ||
880 | const char *description, | ||
881 | unsigned int *val) | ||
882 | { | ||
883 | struct GNUNET_GETOPT_CommandLineOption clo = { | ||
884 | .shortName = shortName, | ||
885 | .name = name, | ||
886 | .argumentHelp = argumentHelp, | ||
887 | .description = description, | ||
888 | .require_argument = 1, | ||
889 | .processor = &set_uint, | ||
890 | .scls = (void *) val | ||
891 | }; | ||
892 | |||
893 | return clo; | ||
894 | } | ||
895 | |||
896 | |||
897 | /** | ||
898 | * Set an option of type 'uint16_t' from the command line. | ||
899 | * A pointer to this function should be passed as part of the | ||
900 | * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options | ||
901 | * of this type. It should be followed by a pointer to a value of | ||
902 | * type 'uint16_t'. | ||
903 | * | ||
904 | * @param ctx command line processing context | ||
905 | * @param scls additional closure (will point to the 'unsigned int') | ||
906 | * @param option name of the option | ||
907 | * @param value actual value of the option as a string. | ||
908 | * @return #GNUNET_OK if parsing the value worked | ||
909 | */ | ||
910 | static int | ||
911 | set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
912 | void *scls, | ||
913 | const char *option, | ||
914 | const char *value) | ||
915 | { | ||
916 | uint16_t *val = scls; | ||
917 | unsigned int v; | ||
918 | char dummy[2]; | ||
919 | |||
920 | (void) ctx; | ||
921 | if (1 != sscanf (value, "%u%1s", &v, dummy)) | ||
922 | { | ||
923 | fprintf (stderr, | ||
924 | _ ("You must pass a number to the `%s' option.\n"), | ||
925 | option); | ||
926 | return GNUNET_SYSERR; | ||
927 | } | ||
928 | if (v > UINT16_MAX) | ||
929 | { | ||
930 | fprintf (stderr, | ||
931 | _ ("You must pass a number below %u to the `%s' option.\n"), | ||
932 | (unsigned int) UINT16_MAX, | ||
933 | option); | ||
934 | return GNUNET_SYSERR; | ||
935 | } | ||
936 | *val = (uint16_t) v; | ||
937 | return GNUNET_OK; | ||
938 | } | ||
939 | |||
940 | |||
941 | /** | ||
942 | * Allow user to specify an uint16_t. | ||
943 | * | ||
944 | * @param shortName short name of the option | ||
945 | * @param name long name of the option | ||
946 | * @param argumentHelp help text for the option argument | ||
947 | * @param description long help text for the option | ||
948 | * @param[out] val set to the value specified at the command line | ||
949 | */ | ||
950 | struct GNUNET_GETOPT_CommandLineOption | ||
951 | GNUNET_GETOPT_option_uint16 (char shortName, | ||
952 | const char *name, | ||
953 | const char *argumentHelp, | ||
954 | const char *description, | ||
955 | uint16_t *val) | ||
956 | { | ||
957 | struct GNUNET_GETOPT_CommandLineOption clo = { | ||
958 | .shortName = shortName, | ||
959 | .name = name, | ||
960 | .argumentHelp = argumentHelp, | ||
961 | .description = description, | ||
962 | .require_argument = 1, | ||
963 | .processor = &set_uint16, | ||
964 | .scls = (void *) val | ||
965 | }; | ||
966 | |||
967 | return clo; | ||
968 | } | ||
969 | |||
970 | |||
971 | /** | ||
972 | * Closure for #set_base32(). | ||
973 | */ | ||
974 | struct Base32Context | ||
975 | { | ||
976 | /** | ||
977 | * Value to initialize (already allocated) | ||
978 | */ | ||
979 | void *val; | ||
980 | |||
981 | /** | ||
982 | * Number of bytes expected for @e val. | ||
983 | */ | ||
984 | size_t val_size; | ||
985 | }; | ||
986 | |||
987 | |||
988 | /** | ||
989 | * Set an option of type 'unsigned int' from the command line. | ||
990 | * A pointer to this function should be passed as part of the | ||
991 | * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options | ||
992 | * of this type. It should be followed by a pointer to a value of | ||
993 | * type 'unsigned int'. | ||
994 | * | ||
995 | * @param ctx command line processing context | ||
996 | * @param scls additional closure (will point to the 'unsigned int') | ||
997 | * @param option name of the option | ||
998 | * @param value actual value of the option as a string. | ||
999 | * @return #GNUNET_OK if parsing the value worked | ||
1000 | */ | ||
1001 | static int | ||
1002 | set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
1003 | void *scls, | ||
1004 | const char *option, | ||
1005 | const char *value) | ||
1006 | { | ||
1007 | struct Base32Context *bc = scls; | ||
1008 | |||
1009 | (void) ctx; | ||
1010 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (value, | ||
1011 | strlen (value), | ||
1012 | bc->val, | ||
1013 | bc->val_size)) | ||
1014 | { | ||
1015 | fprintf ( | ||
1016 | stderr, | ||
1017 | _ ( | ||
1018 | "Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"), | ||
1019 | option); | ||
1020 | return GNUNET_SYSERR; | ||
1021 | } | ||
1022 | return GNUNET_OK; | ||
1023 | } | ||
1024 | |||
1025 | |||
1026 | /** | ||
1027 | * Helper function to clean up after | ||
1028 | * #GNUNET_GETOPT_option_base32_fixed_size. | ||
1029 | * | ||
1030 | * @param cls value to GNUNET_free() | ||
1031 | */ | ||
1032 | static void | ||
1033 | free_bc (void *cls) | ||
1034 | { | ||
1035 | GNUNET_free (cls); | ||
1036 | } | ||
1037 | |||
1038 | |||
1039 | /** | ||
1040 | * Allow user to specify a binary value using Crockford | ||
1041 | * Base32 encoding. | ||
1042 | * | ||
1043 | * @param shortName short name of the option | ||
1044 | * @param name long name of the option | ||
1045 | * @param argumentHelp help text for the option argument | ||
1046 | * @param description long help text for the option | ||
1047 | * @param[out] val binary value decoded from Crockford Base32-encoded argument | ||
1048 | * @param val_size size of @a val in bytes | ||
1049 | */ | ||
1050 | struct GNUNET_GETOPT_CommandLineOption | ||
1051 | GNUNET_GETOPT_option_base32_fixed_size (char shortName, | ||
1052 | const char *name, | ||
1053 | const char *argumentHelp, | ||
1054 | const char *description, | ||
1055 | void *val, | ||
1056 | size_t val_size) | ||
1057 | { | ||
1058 | struct Base32Context *bc = GNUNET_new (struct Base32Context); | ||
1059 | struct GNUNET_GETOPT_CommandLineOption clo = { | ||
1060 | .shortName = shortName, | ||
1061 | .name = name, | ||
1062 | .argumentHelp = argumentHelp, | ||
1063 | .description = description, | ||
1064 | .require_argument = 1, | ||
1065 | .processor = &set_base32, | ||
1066 | .cleaner = &free_bc, | ||
1067 | .scls = (void *) bc | ||
1068 | }; | ||
1069 | |||
1070 | bc->val = val; | ||
1071 | bc->val_size = val_size; | ||
1072 | return clo; | ||
1073 | } | ||
1074 | |||
1075 | |||
1076 | /** | ||
1077 | * Make the given option mandatory. | ||
1078 | * | ||
1079 | * @param opt option to modify | ||
1080 | * @return @a opt with the mandatory flag set. | ||
1081 | */ | ||
1082 | struct GNUNET_GETOPT_CommandLineOption | ||
1083 | GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt) | ||
1084 | { | ||
1085 | opt.option_mandatory = 1; | ||
1086 | return opt; | ||
1087 | } | ||
1088 | |||
1089 | |||
1090 | /** | ||
1091 | * Make the given option mutually exclusive with other options. | ||
1092 | * | ||
1093 | * @param opt option to modify | ||
1094 | * @return @a opt with the exclusive flag set. | ||
1095 | */ | ||
1096 | struct GNUNET_GETOPT_CommandLineOption | ||
1097 | GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt) | ||
1098 | { | ||
1099 | opt.option_exclusive = 1; | ||
1100 | return opt; | ||
1101 | } | ||
1102 | |||
1103 | |||
1104 | /* end of getopt_helpers.c */ | ||