main() { int opt; x_opterr = 1; while ((opt=x_getopt(3, arglist, 5, options)) != EOF) if (opt > 0 && opt < 5) { printf("option %d: %s\n", opt, options[opt-1].description); } else printf("BAD BAD BAD\n"); puts("EOF"); printf ("optind = %d, argc = 3\n", x_optind); }
/* * df, in the flesh */ int main(int argc, char **argv) { int opt; pgm = basename(argv[0]); exclusions = malloc(1); inclusions = malloc(1); x_opterr = 1; while ((opt = x_getopt(argc, argv, NROPTIONS, options)) != EOF) switch (opt) { case 'b': display = BYTES; break; case 'P': display = POSIX; break; case 'k': display = KILOBYTES; break; case 'm': display = MEGABYTES; break; case 'H': case 'h': display = HUMAN; break; case 'i': show_inodes = 1; break; case 'l': local_fs_only = 1; break; case 'a': show_zero_length = 1; break; case 't': addToList(x_optarg, &inclusions, &nrinclusions); break; case 'v': break; case 'x': addToList(x_optarg, &exclusions, &nrexclusions); break; case 'T': show_fs_type = 1; break; default: usage(opt == '?'); /* exits */ } argc -= x_optind; argv += x_optind; if (argc > 0) { if (nrinclusions || nrexclusions) fprintf(stderr, "%s: warning: `x' and `t' options conflict with" " filesystem arguments\n", pgm); } filesys = argv; nrfilesys = argc; doit(); exit(0); } /* df */
/** * Parse the command-line parameters, setting the various globals that are * affected by them. * * Parameters: * argc - argument count, as passed to main() * argv - argument vector, as passed to main() */ static void parse_params(int argc, char **argv) { int opt; int argsLeft; opterr = 0; /* NOTE: x_getopt() is the old public domain getopt(). The source lives in "getopt.c". The function's name has been changed to avoid conflicts with the native getopt() on the host operating system. So far, I've seen two kinds of conflicts: 1. GNU getopt() (e.g., on Linux systems) behaves differently from the old getopt(), unless POSIXLY_CORRECT is defined in the environment. Specifically, it insists on processing options even after the first non-option argument has been seen on the command line. Initially, I got around this problem by forcing the use of the included public domain getopt() function. 2. The types used in the included public domain getopt() conflict with the types of the native getopt() on some operating systems (e.g., Solaris 8). Using x_getopt() ensures that daemonize uses its own version, which always behaves consistently. */ while ( (opt = x_getopt(argc, argv, "ac:u:p:vo:e:E:l:")) != -1) { switch (opt) { case 'a': append = 1; break; case 'c': cwd = x_optarg; break; case 'p': pid_file = x_optarg; break; case 'v': be_verbose = TRUE; break; case 'u': user = x_optarg; break; case 'o': out_file = x_optarg; break; case 'e': err_file = x_optarg; break; case 'l': lock_file = x_optarg; break; case 'E': add_to_env('E', x_optarg); break; default: fprintf(stderr, "Bad option: -%c\n", x_optopt); usage(argv[0]); } } argsLeft = argc - x_optind; if (argsLeft < 1) usage(argv[0]); cmd = &argv[x_optind]; return; }
/* * id, in mortal flesh */ main(int argc, char **argv) { struct passwd *pwd; struct group *grp; enum {ID,WHOAMI} mode = ID; enum opt opt; int display_opt = 0; /* what we wish to see */ int std = 0; /* show in standard format */ int real_id = 0; /* show real, not euid */ int names = 0; /* show names, not numbers */ uid_t uid; /* uid we want */ gid_t gid; /* gid we want */ #define NR_SGIDS 200 gid_t sgids[NR_SGIDS]; /* supplemental groups */ int nr_sgids; int x; char key; pgm = basename(argv[0]); if (strcasecmp(pgm, "whoami") == 0) { mode = WHOAMI; display_opt = SHOW_UID; names = 1; } else if (strcasecmp(pgm, "groups") == 0) { mode = WHOAMI; display_opt = SHOW_SUPP; names = 1; } else { x_opterr = 1; while ((opt = x_getopt(argc, argv, NROPTIONS, options)) != EOF) { switch (opt) { case REAL_ID: real_id = 1; break; case NAMES: names = 1; break; case GROUPS: display_opt |= SHOW_GROUP; break; case SUPP_GROUPS: display_opt |= SHOW_SUPP; break; case USER_ID: display_opt |= SHOW_UID; break; case STD: std = 1; break; default: case HELP: usage((opt == HELP) ? 0 : 1); } } } if (argc > x_optind) { if ( (pwd = getpwnam(argv[x_optind])) != 0) { uid = pwd->pw_uid; gid = pwd->pw_gid; } else { fprintf(stderr, "%s: no user %s\n", pgm, argv[x_optind]); exit(1); } } else { uid = real_id ? geteuid() : getuid(); gid = real_id ? getegid() : getgid(); } if (display_opt == 0) { display_opt = SHOW_ALL; std = 1; } key = 0; if (display_opt & SHOW_UID) { if (std || (display_opt & ~SHOW_UID)) fputs("uid=", stdout); if (std) { printf("%d", uid); if ( (pwd = getpwuid(uid)) != 0) printf("(%s)", pwd->pw_name); } else if (!names) printf("%d", uid); else if ( (pwd = getpwuid(uid)) != 0) fputs(pwd->pw_name, stdout); key = ' '; } if (display_opt & SHOW_GROUP) { if (key) putchar(key); if (std || (display_opt & ~SHOW_GROUP)) fputs("gid=", stdout); if (std) { printf("%d", gid); if ( (grp = getgrgid(gid)) != 0) printf("(%s)", grp->gr_name); } else if (!names) printf("%d", gid); else if ( (grp = getgrgid(gid)) != 0) fputs(grp->gr_name, stdout); key = ' '; } if (display_opt & SHOW_SUPP) { nr_sgids = mygetgroups(uid, sgids, sizeof sgids); if (nr_sgids > 0) { if (key) putchar(key); if (std||(display_opt & ~SHOW_SUPP)) { printf("groups"); key = '='; } else key = 0; for (x=0; x < nr_sgids; x++,key=(std ? ',' : ' ') ) { if (key) putchar(key); grp = getgrgid(sgids[x]); if (std) { printf("%d", sgids[x]); if (grp) printf("(%s)", grp->gr_name); } else if (names && grp) fputs(grp->gr_name, stdout); else printf("%d", sgids[x]); } key = ' '; } } if (key) putchar('\n'); exit(0); }
int x_getopt(int argc, char **argv, int optcount, struct x_option *opts) { static char* shortoptarg=0; /* currently parsing a short options arg? */ static int donewithargs; /* found -- or arg starting w/o - */ static int x_argc = 0; /* arglist currently being processed */ static char **x_argv = 0; int x; char *longopts; if (x_argv != argv) { x_optind = 1; x_argv = argv; x_argc = argc; shortoptarg = 0; donewithargs = 0; } #if DEBUG printf("\nshortoptarg: %s\n", shortoptarg ? shortoptarg : "{null}"); printf("x_optind: %d\n", x_optind); printf("x_argc: %d\n", x_argc); printf("donewithargs: %d\n", donewithargs); #endif if (shortoptarg) { char flag = *(shortoptarg++); if (*shortoptarg == 0) shortoptarg = 0; for (x=0; x<optcount; x++) if (opts[x].flag && (opts[x].flag == flag)) { if (opts[x].has_argument) { if (shortoptarg) { x_optarg = shortoptarg; shortoptarg = 0; } else if (x_optind < x_argc) x_optarg = x_argv[x_optind++]; else { if (x_opterr) fprintf(stderr, "%s: option `-%c' requires an argument\n", x_argv[0], flag); return 0; } } return opts[x].optval; } if (x_opterr) fprintf(stderr, "%s: unknown option -- %c\n", x_argv[0], flag); return 0; } /* if shortoptarg */ if (x_optind >= x_argc || donewithargs) return EOF; /* we only get here if we're just starting a new argument */ if (x_argv[x_optind][0] != '-') { donewithargs = 1; return EOF; } if (x_argv[x_optind][1] != '-') { shortoptarg = &x_argv[x_optind++][1]; return x_getopt(argc, argv, optcount, opts); } /* not a new short opts */ longopts = &x_argv[x_optind++][2]; /* solitary -- means that there are no more options */ if (*longopts == 0) { donewithargs=1; return EOF; } for (x=0; x<optcount; x++) if (opts[x].name && strcmp(opts[x].name, longopts) == 0) { if (opts[x].has_argument) { if (x_optind < x_argc) x_optarg = x_argv[x_optind++]; else { if (x_opterr) fprintf(stderr, "%s: option `--%s' requires an argument\n", x_argv[0], longopts); return 0; } } return opts[x].optval; } /* it certainly can't be an argument at this point */ if (x_opterr) fprintf(stderr, "%s: unknown option `--%s'\n", x_argv[0], longopts); return 0; } /* x_getopt */