From: Todd C. Miller Date: Mon, 21 Feb 2011 16:34:23 +0000 (-0500) Subject: add help text to sudo, visudo and sudoreplay for the -h option X-Git-Tag: SUDO_1_7_5~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=356dc98905719d13d062aa7abddcd0a889c083a1;p=sudo add help text to sudo, visudo and sudoreplay for the -h option --HG-- branch : 1.7 --- diff --git a/parse_args.c b/parse_args.c index d03ff270c..16eebbca3 100644 --- a/parse_args.c +++ b/parse_args.c @@ -51,8 +51,7 @@ /* * Local functions */ -static void usage_excl __P((int)) - __attribute__((__noreturn__)); +static void usage_excl __P((int)); /* * For sudo.c @@ -307,19 +306,26 @@ parse_args(argc, argv) } static int -usage_out(buf) +usage_err(buf) const char *buf; { return fputs(buf, stderr); } +static int +usage_out(buf) + const char *buf; +{ + return fputs(buf, stdout); +} + /* * Give usage message and exit. * The actual usage strings are in sudo_usage.h for configure substitution. */ void -usage(exit_val) - int exit_val; +usage(fatal) + int fatal; { struct lbuf lbuf; char *uvec[6]; @@ -345,22 +351,114 @@ usage(exit_val) * tty width. */ ulen = (int)strlen(getprogname()) + 8; - lbuf_init(&lbuf, usage_out, ulen, NULL); + lbuf_init(&lbuf, fatal ? usage_err : usage_out, ulen, NULL); for (i = 0; uvec[i] != NULL; i++) { lbuf_append(&lbuf, "usage: ", getprogname(), uvec[i], NULL); lbuf_print(&lbuf); } lbuf_destroy(&lbuf); - exit(exit_val); + if (fatal) + exit(1); } /* * Tell which options are mutually exclusive and exit. */ static void -usage_excl(exit_val) - int exit_val; +usage_excl(fatal) + int fatal; { warningx("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"); - usage(exit_val); + usage(fatal); +} + +void +help() +{ + struct lbuf lbuf; + int indent = 16; + const char *pname = getprogname(); + + lbuf_init(&lbuf, usage_out, indent, NULL); + if (strcmp(pname, "sudoedit") == 0) + lbuf_append(&lbuf, pname, " - edit files as another user\n\n", NULL); + else + lbuf_append(&lbuf, pname, " - execute a command as another user\n\n", NULL); + lbuf_print(&lbuf); + + usage(0); + + lbuf_append(&lbuf, "\nOptions:\n", NULL); +#ifdef HAVE_BSD_AUTH_H + lbuf_append(&lbuf, + " -A use helper program for password prompting\n", NULL); +#endif + lbuf_append(&lbuf, + " -a type use specified BSD authentication type\n", NULL); + lbuf_append(&lbuf, + " -b run command in the background\n", NULL); + lbuf_append(&lbuf, + " -C fd close all file descriptors >= fd\n", NULL); +#ifdef HAVE_LOGIN_CAP_H + lbuf_append(&lbuf, + " -c class run command with specified login class\n", NULL); +#endif + lbuf_append(&lbuf, + " -E preserve user environment when executing command\n", + NULL); + lbuf_append(&lbuf, + " -e edit files instead of running a command\n", NULL); + lbuf_append(&lbuf, + " -g group execute command as the specified group\n", NULL); + lbuf_append(&lbuf, + " -H set HOME variable to target user's home dir.\n", + NULL); + lbuf_append(&lbuf, + " -h display help message and exit\n", NULL); + lbuf_append(&lbuf, + " -i [command] run a login shell as target user\n", NULL); + lbuf_append(&lbuf, + " -K remove timestamp file completely\n", NULL); + lbuf_append(&lbuf, + " -k invalidate timestamp file\n", NULL); + lbuf_append(&lbuf, + " -L list supported sudoers Defaults values\n", NULL); + lbuf_append(&lbuf, + " -l[l] command list user's available commands\n", NULL); + lbuf_append(&lbuf, + " -n non-interactive mode, will not prompt user\n", NULL); + lbuf_append(&lbuf, + " -P preserve group vector instead of setting to target's\n", + NULL); + lbuf_append(&lbuf, + " -p prompt use specified password prompt\n", NULL); +#ifdef HAVE_SELINUX + lbuf_append(&lbuf, + " -r role create SELinux security context with specified role\n", + NULL); +#endif + lbuf_append(&lbuf, + " -S read password from standard input\n", NULL); + lbuf_append(&lbuf, + " -s [command] run a shell as target user\n", NULL); +#ifdef HAVE_SELINUX + lbuf_append(&lbuf, + " -t type create SELinux security context with specified role\n", + NULL); +#endif + lbuf_append(&lbuf, + " -U user when listing, list specified user's privileges\n", + NULL); + lbuf_append(&lbuf, + " -u user run command (or edit file) as specified user\n", NULL); + lbuf_append(&lbuf, + " -V display version information and exit\n", NULL); + lbuf_append(&lbuf, + " -v update user's timestamp without running a command\n", + NULL); + lbuf_append(&lbuf, + " -- stop processing command line arguments\n", NULL); + lbuf_print(&lbuf); + lbuf_destroy(&lbuf); + exit(0); } diff --git a/sudo.c b/sudo.c index 625f8793f..0dc2e78ad 100644 --- a/sudo.c +++ b/sudo.c @@ -235,7 +235,7 @@ main(argc, argv, envp) show_version(); break; case MODE_HELP: - usage(0); + help(); break; case MODE_VALIDATE: case MODE_VALIDATE|MODE_INVALIDATE: diff --git a/sudo.pod b/sudo.pod index 33bcb6a4e..555274cf2 100644 --- a/sudo.pod +++ b/sudo.pod @@ -221,7 +221,8 @@ command line. =item -h -The B<-h> (I) option causes B to print a usage message and exit. +The B<-h> (I) option causes B to print a short help message +to the standard output and exit. =item -i [command] diff --git a/sudo_usage.h.in b/sudo_usage.h.in index af15b8790..b26e3ec1d 100644 --- a/sudo_usage.h.in +++ b/sudo_usage.h.in @@ -19,7 +19,8 @@ #ifndef _SUDO_USAGE_H #define _SUDO_USAGE_H -void usage __P((int)) __attribute__((__noreturn__)); +void help __P((void)) __attribute__((__noreturn__)); +void usage __P((int)); /* * Usage strings for sudo. These are here because we diff --git a/sudoreplay.c b/sudoreplay.c index 1232cea74..9fdb5bbc5 100644 --- a/sudoreplay.c +++ b/sudoreplay.c @@ -199,7 +199,8 @@ static int list_sessions __P((int, char **, const char *, const char *, const ch static int parse_expr __P((struct search_node **, char **)); static void check_input __P((int, double *)); static void delay __P((double)); -static void usage __P((void)); +static void help __P((void)) __attribute__((__noreturn__)); +static void usage __P((int)); static void *open_io_fd __P((char *pathbuf, int len, const char *suffix)); static int parse_timing __P((const char *buf, const char *decimal, int *idx, double *seconds, size_t *nbytes)); @@ -237,7 +238,7 @@ main(argc, argv) decimal = localeconv()->decimal_point; #endif - while ((ch = getopt(argc, argv, "d:f:lm:s:V")) != -1) { + while ((ch = getopt(argc, argv, "d:f:hlm:s:V")) != -1) { switch(ch) { case 'd': session_dir = optarg; @@ -256,6 +257,9 @@ main(argc, argv) errorx(1, "invalid filter option: %s", optarg); } break; + case 'h': + help(); + /* NOTREACHED */ case 'l': listonly = 1; break; @@ -275,7 +279,7 @@ main(argc, argv) (void) printf("%s version %s\n", getprogname(), PACKAGE_VERSION); exit(0); default: - usage(); + usage(1); /* NOTREACHED */ } @@ -287,7 +291,7 @@ main(argc, argv) exit(list_sessions(argc, argv, pattern, user, tty)); if (argc != 1) - usage(); + usage(1); /* 6 digit ID in base 36, e.g. 01G712AB */ id = argv[0]; @@ -939,15 +943,33 @@ bad: } static void -usage() +usage(fatal) + int fatal; { - fprintf(stderr, - "usage: %s [-d directory] [-m max_wait] [-s speed_factor] ID\n", + fprintf(fatal ? stderr : stdout, + "usage: %s [-h] [-d directory] [-f filter] [-m max_wait] [-s speed_factor] ID\n", getprogname()); - fprintf(stderr, - "usage: %s [-d directory] -l [search expression]\n", + fprintf(fatal ? stderr : stdout, + "usage: %s [-h] [-d directory] -l [search expression]\n", getprogname()); - exit(1); + if (fatal) + exit(1); +} + +static void +help() +{ + (void) printf("%s - replay sudo session logs\n\n", getprogname()); + usage(0); + (void) puts("\nOptions:"); + (void) puts(" -d directory specify directory for session logs"); + (void) puts(" -f filter specify which I/O type to display"); + (void) puts(" -h display help message and exit"); + (void) puts(" -l [expression] list available session IDs that match expression"); + (void) puts(" -m max_wait max number of seconds to wait between events"); + (void) puts(" -s speed_factor speed up or slow down output"); + (void) puts(" -V display version information and exit"); + exit(0); } /* diff --git a/sudoreplay.pod b/sudoreplay.pod index c36f9133e..5eb6e1e55 100644 --- a/sudoreplay.pod +++ b/sudoreplay.pod @@ -21,9 +21,9 @@ sudoreplay - replay sudo session logs =head1 SYNOPSIS -B [B<-d> I] [B<-f> I] [B<-m> I] [B<-s> I] ID +B [B<-h>] [B<-d> I] [B<-f> I] [B<-m> I] [B<-s> I] ID -B [B<-d> I] -l [search expression] +B [B<-h>] [B<-d> I] -l [search expression] =head1 DESCRIPTION @@ -76,7 +76,12 @@ used to select which of these to output. The I argument is a comma-separated list, consisting of one or more of following: I, I, and I. -=item -l +=item -h + +The B<-h> (I) option causes B to print a short +help message to the standard output and exit. + +=item -l [I] Enable "list mode". In this mode, B will list available session IDs. If a I is specified, it will be diff --git a/visudo.c b/visudo.c index 6b152729e..bc77377f1 100644 --- a/visudo.c +++ b/visudo.c @@ -110,7 +110,8 @@ static int run_command __P((char *, char **)); static void print_selfref __P((char *, int, int, int)); static void print_undefined __P((char *, int, int, int)); static void setup_signals __P((void)); -static void usage __P((void)) __attribute__((__noreturn__)); +static void help __P((void)) __attribute__((__noreturn__)); +static void usage __P((int)); extern void yyerror __P((const char *)); extern void yyrestart __P((FILE *)); @@ -153,14 +154,14 @@ main(argc, argv) Argv = argv; if ((Argc = argc) < 1) - usage(); + usage(1); /* * Arg handling. */ checkonly = oldperms = quiet = strict = FALSE; sudoers_path = _PATH_SUDOERS; - while ((ch = getopt(argc, argv, "Vcf:sq")) != -1) { + while ((ch = getopt(argc, argv, "Vcf:hsq")) != -1) { switch (ch) { case 'V': (void) printf("%s version %s\n", getprogname(), PACKAGE_VERSION); @@ -172,6 +173,9 @@ main(argc, argv) sudoers_path = optarg; /* sudoers file path */ oldperms = TRUE; break; + case 'h': + help(); + break; case 's': strict++; /* strict mode */ break; @@ -179,13 +183,13 @@ main(argc, argv) quiet++; /* quiet mode */ break; default: - usage(); + usage(1); } } argc -= optind; argv += optind; if (argc) - usage(); + usage(1); sudo_setpwent(); sudo_setgrent(); @@ -1185,9 +1189,26 @@ quit(signo) } static void -usage() +usage(fatal) + int fatal; { - (void) fprintf(stderr, "usage: %s [-c] [-q] [-s] [-V] [-f sudoers]\n", - getprogname()); - exit(1); + (void) fprintf(fatal ? stderr : stdout, + "usage: %s [-chqsV] [-f sudoers]\n", getprogname()); + if (fatal) + exit(1); +} + +static void +help() +{ + (void) printf("%s - safely edit the sudoers file\n\n", getprogname()); + usage(0); + (void) puts("\nOptions:"); + (void) puts(" -c check-only mode"); + (void) puts(" -f sudoers specify sudoers file location"); + (void) puts(" -h display help message and exit"); + (void) puts(" -q less verbose (quiet) syntax error messages"); + (void) puts(" -s strict syntax checking"); + (void) puts(" -V display version information and exit"); + exit(0); } diff --git a/visudo.pod b/visudo.pod index 55e0c7c06..708d9549a 100644 --- a/visudo.pod +++ b/visudo.pod @@ -26,7 +26,7 @@ visudo - edit the sudoers file =head1 SYNOPSIS -B [B<-c>] [B<-q>] [B<-s>] [B<-V>] [B<-f> I] +B [B<-chqsV>] [B<-f> I] =head1 DESCRIPTION @@ -85,6 +85,11 @@ is the specified I file with ".tmp" appended to it. In B mode only, the argument to B<-f> may be "-", indicating that I will be read from the standard input. +=item -h + +The B<-h> (I) option causes B to print a short help message +to the standard output and exit. + =item -q Enable B mode. In this mode details about syntax errors