Add the uid and gid options
[untie.git] / cmdline.c
blobe9d867747522babb385cdb04c122d5e840c6ebae
1 /*
2 File autogenerated by gengetopt version 2.19.1
3 generated with the following command:
4 gengetopt -uCOMMAND
6 The developers of gengetopt consider the fixed text that goes in all
7 gengetopt output files to be in the public domain:
8 we make no copyright claims on it.
9 */
11 /* If we use autoconf. */
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
20 #include "getopt.h"
22 #include "cmdline.h"
24 const char *gengetopt_args_info_purpose = "";
26 const char *gengetopt_args_info_usage = "Usage: untie [OPTIONS]... [COMMAND]...";
28 const char *gengetopt_args_info_description = "";
30 const char *gengetopt_args_info_help[] = {
31 " -h, --help Print help and exit",
32 " -V, --version Print version and exit",
33 " --mount New mount namespace (default=off)",
34 " --uname New uname (default=off)",
35 " --ipc New IPC context (default=off)",
36 " --mask=MASK Pass user defined flag",
37 " --chroot=DIRECTORY Chroot in the specified directory",
38 " --uid=UID Change to the specified UID",
39 " --gid=GID Add the specified GID",
43 static
44 void clear_given (struct gengetopt_args_info *args_info);
45 static
46 void clear_args (struct gengetopt_args_info *args_info);
48 static int
49 cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error);
51 static int
52 cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error);
54 struct int_list
56 int arg;
57 char *orig;
58 struct int_list * next;
61 static char *
62 gengetopt_strdup (const char *s);
64 static
65 void clear_given (struct gengetopt_args_info *args_info)
67 args_info->help_given = 0 ;
68 args_info->version_given = 0 ;
69 args_info->mount_given = 0 ;
70 args_info->uname_given = 0 ;
71 args_info->ipc_given = 0 ;
72 args_info->mask_given = 0 ;
73 args_info->chroot_given = 0 ;
74 args_info->uid_given = 0 ;
75 args_info->gid_given = 0 ;
78 static
79 void clear_args (struct gengetopt_args_info *args_info)
81 args_info->mount_flag = 0;
82 args_info->uname_flag = 0;
83 args_info->ipc_flag = 0;
84 args_info->mask_arg = NULL;
85 args_info->mask_orig = NULL;
86 args_info->chroot_arg = NULL;
87 args_info->chroot_orig = NULL;
88 args_info->uid_orig = NULL;
89 args_info->gid_arg = NULL;
90 args_info->gid_orig = NULL;
94 static
95 void init_args_info(struct gengetopt_args_info *args_info)
97 args_info->help_help = gengetopt_args_info_help[0] ;
98 args_info->version_help = gengetopt_args_info_help[1] ;
99 args_info->mount_help = gengetopt_args_info_help[2] ;
100 args_info->uname_help = gengetopt_args_info_help[3] ;
101 args_info->ipc_help = gengetopt_args_info_help[4] ;
102 args_info->mask_help = gengetopt_args_info_help[5] ;
103 args_info->mask_min = -1;
104 args_info->mask_max = -1;
105 args_info->chroot_help = gengetopt_args_info_help[6] ;
106 args_info->uid_help = gengetopt_args_info_help[7] ;
107 args_info->gid_help = gengetopt_args_info_help[8] ;
108 args_info->gid_min = -1;
109 args_info->gid_max = -1;
113 void
114 cmdline_parser_print_version (void)
116 printf ("%s %s\n", CMDLINE_PARSER_PACKAGE, CMDLINE_PARSER_VERSION);
119 void
120 cmdline_parser_print_help (void)
122 int i = 0;
123 cmdline_parser_print_version ();
125 if (strlen(gengetopt_args_info_purpose) > 0)
126 printf("\n%s\n", gengetopt_args_info_purpose);
128 printf("\n%s\n\n", gengetopt_args_info_usage);
130 if (strlen(gengetopt_args_info_description) > 0)
131 printf("%s\n", gengetopt_args_info_description);
133 while (gengetopt_args_info_help[i])
134 printf("%s\n", gengetopt_args_info_help[i++]);
137 void
138 cmdline_parser_init (struct gengetopt_args_info *args_info)
140 clear_given (args_info);
141 clear_args (args_info);
142 init_args_info (args_info);
144 args_info->inputs = NULL;
145 args_info->inputs_num = 0;
148 static void
149 cmdline_parser_release (struct gengetopt_args_info *args_info)
152 unsigned int i;
153 if (args_info->mask_arg)
155 for (i = 0; i < args_info->mask_given; ++i)
157 if (args_info->mask_orig [i])
159 free (args_info->mask_orig [i]); /* free previous argument */
160 args_info->mask_orig [i] = 0;
163 free (args_info->mask_arg); /* free previous argument */
164 args_info->mask_arg = 0;
165 free (args_info->mask_orig); /* free previous argument */
166 args_info->mask_orig = 0;
168 if (args_info->chroot_arg)
170 free (args_info->chroot_arg); /* free previous argument */
171 args_info->chroot_arg = 0;
173 if (args_info->chroot_orig)
175 free (args_info->chroot_orig); /* free previous argument */
176 args_info->chroot_orig = 0;
178 if (args_info->uid_orig)
180 free (args_info->uid_orig); /* free previous argument */
181 args_info->uid_orig = 0;
183 if (args_info->gid_arg)
185 for (i = 0; i < args_info->gid_given; ++i)
187 if (args_info->gid_orig [i])
189 free (args_info->gid_orig [i]); /* free previous argument */
190 args_info->gid_orig [i] = 0;
193 free (args_info->gid_arg); /* free previous argument */
194 args_info->gid_arg = 0;
195 free (args_info->gid_orig); /* free previous argument */
196 args_info->gid_orig = 0;
199 for (i = 0; i < args_info->inputs_num; ++i)
200 free (args_info->inputs [i]);
202 if (args_info->inputs_num)
203 free (args_info->inputs);
205 clear_given (args_info);
209 cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
211 FILE *outfile;
212 int i = 0;
214 outfile = fopen(filename, "w");
216 if (!outfile)
218 fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
219 return EXIT_FAILURE;
222 if (args_info->help_given) {
223 fprintf(outfile, "%s\n", "help");
225 if (args_info->version_given) {
226 fprintf(outfile, "%s\n", "version");
228 if (args_info->mount_given) {
229 fprintf(outfile, "%s\n", "mount");
231 if (args_info->uname_given) {
232 fprintf(outfile, "%s\n", "uname");
234 if (args_info->ipc_given) {
235 fprintf(outfile, "%s\n", "ipc");
237 if (args_info->mask_orig)
239 for (i = 0; i < args_info->mask_given; ++i)
241 if (args_info->mask_orig [i])
243 fprintf(outfile, "%s=\"%s\"\n", "mask", args_info->mask_orig [i]);
247 if (args_info->chroot_given) {
248 if (args_info->chroot_orig) {
249 fprintf(outfile, "%s=\"%s\"\n", "chroot", args_info->chroot_orig);
250 } else {
251 fprintf(outfile, "%s\n", "chroot");
254 if (args_info->uid_given) {
255 if (args_info->uid_orig) {
256 fprintf(outfile, "%s=\"%s\"\n", "uid", args_info->uid_orig);
257 } else {
258 fprintf(outfile, "%s\n", "uid");
261 if (args_info->gid_orig)
263 for (i = 0; i < args_info->gid_given; ++i)
265 if (args_info->gid_orig [i])
267 fprintf(outfile, "%s=\"%s\"\n", "gid", args_info->gid_orig [i]);
272 fclose (outfile);
274 i = EXIT_SUCCESS;
275 return i;
278 void
279 cmdline_parser_free (struct gengetopt_args_info *args_info)
281 cmdline_parser_release (args_info);
285 /* gengetopt_strdup() */
286 /* strdup.c replacement of strdup, which is not standard */
287 char *
288 gengetopt_strdup (const char *s)
290 char *result = NULL;
291 if (!s)
292 return result;
294 result = (char*)malloc(strlen(s) + 1);
295 if (result == (char*)0)
296 return (char*)0;
297 strcpy(result, s);
298 return result;
301 static char *
302 get_multiple_arg_token(const char *arg)
304 char *tok, *ret;
305 size_t len, num_of_escape;
306 int i, j;
308 if (!arg)
309 return NULL;
311 tok = strchr (arg, ',');
312 num_of_escape = 0;
314 /* make sure it is not escaped */
315 while (tok)
317 if (*(tok-1) == '\\')
319 /* find the next one */
320 tok = strchr (tok+1, ',');
321 ++num_of_escape;
323 else
324 break;
327 if (tok)
328 len = (size_t)(tok - arg + 1);
329 else
330 len = strlen (arg) + 1;
332 len -= num_of_escape;
334 ret = (char *) malloc (len);
336 i = 0;
337 j = 0;
338 while (arg[i] && (j < len-1))
340 if (arg[i] == '\\')
341 ++i;
343 ret[j++] = arg[i++];
346 ret[len-1] = '\0';
348 return ret;
351 static char *
352 get_multiple_arg_token_next(const char *arg)
354 char *tok;
356 if (!arg)
357 return NULL;
359 tok = strchr (arg, ',');
361 /* make sure it is not escaped */
362 while (tok)
364 if (*(tok-1) == '\\')
366 /* find the next one */
367 tok = strchr (tok+1, ',');
369 else
370 break;
373 if (! tok || strlen(tok) == 1)
374 return 0;
376 return tok+1;
379 static int
380 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, int min, int max, const char *option_desc);
383 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, int min, int max, const char *option_desc)
385 int error = 0;
387 if (option_given && ! (min < 0 && max < 0))
389 if (min >= 0 && max >= 0)
391 if (min == max)
393 /* specific occurrences */
394 if (option_given != min)
396 fprintf (stderr, "%s: %s option occurrences must be %d\n",
397 prog_name, option_desc, min);
398 error = 1;
401 else if (option_given < min
402 || option_given > max)
404 /* range occurrences */
405 fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n",
406 prog_name, option_desc, min, max);
407 error = 1;
410 else if (min >= 0)
412 /* at least check */
413 if (option_given < min)
415 fprintf (stderr, "%s: %s option occurrences must be at least %d\n",
416 prog_name, option_desc, min);
417 error = 1;
420 else if (max >= 0)
422 /* at most check */
423 if (option_given > max)
425 fprintf (stderr, "%s: %s option occurrences must be at most %d\n",
426 prog_name, option_desc, max);
427 error = 1;
432 return error;
435 cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info)
437 return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
441 cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
443 int result;
445 result = cmdline_parser_internal (argc, argv, args_info, override, initialize, check_required, NULL);
447 if (result == EXIT_FAILURE)
449 cmdline_parser_free (args_info);
450 exit (EXIT_FAILURE);
453 return result;
457 cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
459 int result = EXIT_SUCCESS;
461 if (cmdline_parser_required2(args_info, prog_name, NULL) > 0)
462 result = EXIT_FAILURE;
464 if (result == EXIT_FAILURE)
466 cmdline_parser_free (args_info);
467 exit (EXIT_FAILURE);
470 return result;
474 cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error)
476 int error = 0;
478 /* checks for required options */
479 if (check_multiple_option_occurrences(prog_name, args_info->mask_given, args_info->mask_min, args_info->mask_max, "'--mask'"))
480 error = 1;
482 if (check_multiple_option_occurrences(prog_name, args_info->gid_given, args_info->gid_min, args_info->gid_max, "'--gid'"))
483 error = 1;
486 /* checks for dependences among options */
488 return error;
492 cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error)
494 int c; /* Character of the parsed option. */
495 char *multi_token, *multi_next; /* for multiple options */
497 int i; /* Counter */
499 struct int_list * mask_list = NULL,* mask_new = NULL;
500 struct int_list * gid_list = NULL,* gid_new = NULL;
501 int error = 0;
502 struct gengetopt_args_info local_args_info;
504 if (initialize)
505 cmdline_parser_init (args_info);
507 cmdline_parser_init (&local_args_info);
509 optarg = 0;
510 optind = 0;
511 opterr = 1;
512 optopt = '?';
514 while (1)
516 int option_index = 0;
517 char *stop_char;
519 static struct option long_options[] = {
520 { "help", 0, NULL, 'h' },
521 { "version", 0, NULL, 'V' },
522 { "mount", 0, NULL, 0 },
523 { "uname", 0, NULL, 0 },
524 { "ipc", 0, NULL, 0 },
525 { "mask", 1, NULL, 0 },
526 { "chroot", 1, NULL, 0 },
527 { "uid", 1, NULL, 0 },
528 { "gid", 1, NULL, 0 },
529 { NULL, 0, NULL, 0 }
532 stop_char = 0;
533 c = getopt_long (argc, argv, "hV", long_options, &option_index);
535 if (c == -1) break; /* Exit from `while (1)' loop. */
537 switch (c)
539 case 'h': /* Print help and exit. */
540 cmdline_parser_print_help ();
541 cmdline_parser_free (&local_args_info);
542 exit (EXIT_SUCCESS);
544 case 'V': /* Print version and exit. */
545 cmdline_parser_print_version ();
546 cmdline_parser_free (&local_args_info);
547 exit (EXIT_SUCCESS);
550 case 0: /* Long option with no short option */
551 /* New mount namespace. */
552 if (strcmp (long_options[option_index].name, "mount") == 0)
554 if (local_args_info.mount_given)
556 fprintf (stderr, "%s: `--mount' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
557 goto failure;
559 if (args_info->mount_given && ! override)
560 continue;
561 local_args_info.mount_given = 1;
562 args_info->mount_given = 1;
563 args_info->mount_flag = !(args_info->mount_flag);
565 /* New uname. */
566 else if (strcmp (long_options[option_index].name, "uname") == 0)
568 if (local_args_info.uname_given)
570 fprintf (stderr, "%s: `--uname' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
571 goto failure;
573 if (args_info->uname_given && ! override)
574 continue;
575 local_args_info.uname_given = 1;
576 args_info->uname_given = 1;
577 args_info->uname_flag = !(args_info->uname_flag);
579 /* New IPC context. */
580 else if (strcmp (long_options[option_index].name, "ipc") == 0)
582 if (local_args_info.ipc_given)
584 fprintf (stderr, "%s: `--ipc' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
585 goto failure;
587 if (args_info->ipc_given && ! override)
588 continue;
589 local_args_info.ipc_given = 1;
590 args_info->ipc_given = 1;
591 args_info->ipc_flag = !(args_info->ipc_flag);
593 /* Pass user defined flag. */
594 else if (strcmp (long_options[option_index].name, "mask") == 0)
596 local_args_info.mask_given++;
598 multi_token = get_multiple_arg_token(optarg);
599 multi_next = get_multiple_arg_token_next (optarg);
601 while (1)
603 mask_new = (struct int_list *) malloc (sizeof (struct int_list));
604 mask_new->next = mask_list;
605 mask_list = mask_new;
606 mask_new->arg = strtol (multi_token, &stop_char, 0);
607 if (!(stop_char && *stop_char == '\0')) {
608 fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], multi_token);
609 goto failure;
611 mask_new->orig = multi_token;
613 if (multi_next)
615 multi_token = get_multiple_arg_token(multi_next);
616 multi_next = get_multiple_arg_token_next (multi_next);
617 local_args_info.mask_given++;
619 else
620 break;
622 break;
624 /* Chroot in the specified directory. */
625 else if (strcmp (long_options[option_index].name, "chroot") == 0)
627 if (local_args_info.chroot_given)
629 fprintf (stderr, "%s: `--chroot' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
630 goto failure;
632 if (args_info->chroot_given && ! override)
633 continue;
634 local_args_info.chroot_given = 1;
635 args_info->chroot_given = 1;
636 if (args_info->chroot_arg)
637 free (args_info->chroot_arg); /* free previous string */
638 args_info->chroot_arg = gengetopt_strdup (optarg);
639 if (args_info->chroot_orig)
640 free (args_info->chroot_orig); /* free previous string */
641 args_info->chroot_orig = gengetopt_strdup (optarg);
643 /* Change to the specified UID. */
644 else if (strcmp (long_options[option_index].name, "uid") == 0)
646 if (local_args_info.uid_given)
648 fprintf (stderr, "%s: `--uid' option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
649 goto failure;
651 if (args_info->uid_given && ! override)
652 continue;
653 local_args_info.uid_given = 1;
654 args_info->uid_given = 1;
655 args_info->uid_arg = strtol (optarg, &stop_char, 0);
656 if (!(stop_char && *stop_char == '\0')) {
657 fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg);
658 goto failure;
660 if (args_info->uid_orig)
661 free (args_info->uid_orig); /* free previous string */
662 args_info->uid_orig = gengetopt_strdup (optarg);
664 /* Add the specified GID. */
665 else if (strcmp (long_options[option_index].name, "gid") == 0)
667 local_args_info.gid_given++;
669 multi_token = get_multiple_arg_token(optarg);
670 multi_next = get_multiple_arg_token_next (optarg);
672 while (1)
674 gid_new = (struct int_list *) malloc (sizeof (struct int_list));
675 gid_new->next = gid_list;
676 gid_list = gid_new;
677 gid_new->arg = strtol (multi_token, &stop_char, 0);
678 if (!(stop_char && *stop_char == '\0')) {
679 fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], multi_token);
680 goto failure;
682 gid_new->orig = multi_token;
684 if (multi_next)
686 multi_token = get_multiple_arg_token(multi_next);
687 multi_next = get_multiple_arg_token_next (multi_next);
688 local_args_info.gid_given++;
690 else
691 break;
693 break;
696 break;
697 case '?': /* Invalid option. */
698 /* `getopt_long' already printed an error message. */
699 goto failure;
701 default: /* bug: option not considered. */
702 fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
703 abort ();
704 } /* switch */
705 } /* while */
708 if (local_args_info.mask_given && mask_list)
710 struct int_list *tmp;
711 args_info->mask_arg = (int *) realloc (args_info->mask_arg, (args_info->mask_given + local_args_info.mask_given) * sizeof (int));
712 args_info->mask_orig = (char **) realloc (args_info->mask_orig, (args_info->mask_given + local_args_info.mask_given) * sizeof (char *));
713 for (i = (local_args_info.mask_given - 1); i >= 0; --i)
715 tmp = mask_list;
716 args_info->mask_arg [i + args_info->mask_given] = mask_list->arg;
717 args_info->mask_orig [i + args_info->mask_given] = mask_list->orig;
718 mask_list = mask_list->next;
719 free (tmp);
723 if (local_args_info.gid_given && gid_list)
725 struct int_list *tmp;
726 args_info->gid_arg = (int *) realloc (args_info->gid_arg, (args_info->gid_given + local_args_info.gid_given) * sizeof (int));
727 args_info->gid_orig = (char **) realloc (args_info->gid_orig, (args_info->gid_given + local_args_info.gid_given) * sizeof (char *));
728 for (i = (local_args_info.gid_given - 1); i >= 0; --i)
730 tmp = gid_list;
731 args_info->gid_arg [i + args_info->gid_given] = gid_list->arg;
732 args_info->gid_orig [i + args_info->gid_given] = gid_list->orig;
733 gid_list = gid_list->next;
734 free (tmp);
739 args_info->mask_given += local_args_info.mask_given;
740 local_args_info.mask_given = 0;
741 args_info->gid_given += local_args_info.gid_given;
742 local_args_info.gid_given = 0;
744 if (check_required)
746 error += cmdline_parser_required2 (args_info, argv[0], additional_error);
749 cmdline_parser_release (&local_args_info);
751 if ( error )
752 return (EXIT_FAILURE);
754 if (optind < argc)
756 int i = 0 ;
757 int found_prog_name = 0;
758 /* whether program name, i.e., argv[0], is in the remaining args
759 (this may happen with some implementations of getopt,
760 but surely not with the one included by gengetopt) */
762 i = optind;
763 while (i < argc)
764 if (argv[i++] == argv[0]) {
765 found_prog_name = 1;
766 break;
768 i = 0;
770 args_info->inputs_num = argc - optind - found_prog_name;
771 args_info->inputs =
772 (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ;
773 while (optind < argc)
774 if (argv[optind++] != argv[0])
775 args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ;
778 return 0;
780 failure:
781 if (mask_list)
783 struct int_list *tmp;
784 while (mask_list)
786 tmp = mask_list;
787 free (mask_list->orig);
788 mask_list = mask_list->next;
789 free (tmp);
792 if (gid_list)
794 struct int_list *tmp;
795 while (gid_list)
797 tmp = gid_list;
798 free (gid_list->orig);
799 gid_list = gid_list->next;
800 free (tmp);
804 cmdline_parser_release (&local_args_info);
805 return (EXIT_FAILURE);