From 5243cb017a7847f53caaa7c89b8e7f3abf1e5e40 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 24 Jan 2024 21:52:41 -0500 Subject: unify usage() output across all the tools The scanelf --help output is the best & most flexible, so move that to common code so the rest of the tools can benefit from it. Signed-off-by: Mike Frysinger --- dumpelf.c | 20 +++++++------------- paxinc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ paxinc.h | 11 +++++++++++ pspax.c | 21 +++++++-------------- scanelf.c | 45 +++++++-------------------------------------- scanmacho.c | 24 ++++++++---------------- 6 files changed, 90 insertions(+), 81 deletions(-) diff --git a/dumpelf.c b/dumpelf.c index c8f27e4..5b18326 100644 --- a/dumpelf.c +++ b/dumpelf.c @@ -507,7 +507,6 @@ static void dump_dyn(const elfobj *elf, const void *dyn_void, size_t dyn_cnt) /* usage / invocation handling functions */ #define PARSE_FLAGS "vhV" -#define a_argument required_argument static struct option const long_opts[] = { {"verbose", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, @@ -524,18 +523,13 @@ static const char * const opts_help[] = { /* display usage and exit */ static void usage(int status) { - size_t i; - printf("* Dump internal ELF structure\n\n" - "Usage: %s [file2 fileN ...]\n\n", argv0); - printf("Options:\n"); - for (i = 0; long_opts[i].name; ++i) - if (long_opts[i].has_arg == no_argument) - printf(" -%c, --%-13s* %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); - else - printf(" -%c, --%-6s * %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); - exit(status); + pax_usage( + "Dump internal ELF structure", + " [file2 fileN ...]", + PARSE_FLAGS, + long_opts, + opts_help, + status); } /* parse command line arguments and perform needed actions */ diff --git a/paxinc.c b/paxinc.c index 589d7ae..ff4ab85 100644 --- a/paxinc.c +++ b/paxinc.c @@ -198,3 +198,53 @@ const char *root_rel_path(const char *path) return path; } + +void pax_usage( + const char *header, + const char *args, + const char *parse_flags, + const struct option long_opts[], + const char * const opts_help[], + int status) +{ + const char a_arg[] = ""; + size_t a_arg_len = strlen(a_arg) + 2; + size_t i; + int optlen; + + printf("* %s\n\n" + "Usage: %s [options] %s\n\n", header, argv0, args); + printf("Options: -[%s]\n", parse_flags); + + /* Prescan the --long opt length to auto-align. */ + optlen = 0; + for (i = 0; long_opts[i].name; ++i) { + int l = strlen(long_opts[i].name); + if (long_opts[i].has_arg == a_argument) + l += a_arg_len; + optlen = max(l, optlen); + } + /* Use some reasonable min width. */ + optlen = max(20, optlen); + + for (i = 0; long_opts[i].name; ++i) { + /* First output the short flag if it has one. */ + if (long_opts[i].val > '~') + printf(" "); + else + printf(" -%c, ", long_opts[i].val); + + /* Then the long flag. */ + if (long_opts[i].has_arg == no_argument) + printf("--%-*s", optlen, long_opts[i].name); + else + printf("--%s %s %*s", long_opts[i].name, a_arg, + (int)(optlen - strlen(long_opts[i].name) - a_arg_len), ""); + + /* Finally the help text. */ + printf("* %s\n", opts_help[i]); + } + + printf("\nFor more information, see the %s(1) manpage.\n", argv0); + exit(status); +} diff --git a/paxinc.h b/paxinc.h index d25cf57..c8fcf71 100644 --- a/paxinc.h +++ b/paxinc.h @@ -124,6 +124,17 @@ void color_init(bool disable); /* constant pointer to a constant buffer ... each program needs to set this */ extern const char argv0[]; +/* Display usage and exit. */ +extern void pax_usage( + const char *header, + const char *args, + const char *parse_flags, + const struct option long_opts[], + const char * const opts_help[], + int status); + +#define a_argument required_argument + /* we need the space before the last comma or we trigger a bug in gcc-2 :( */ #define warn(fmt, args...) \ fprintf(stderr, "%s%s%s: " fmt "\n", RED, argv0, NORM , ## args) diff --git a/pspax.c b/pspax.c index 1cfd72f..4cd09b6 100644 --- a/pspax.c +++ b/pspax.c @@ -448,7 +448,6 @@ static void pspax(const char *find_name) /* usage / invocation handling functions */ #define PARSE_FLAGS "aeip:u:g:nwWvCBhV" -#define a_argument required_argument static struct option const long_opts[] = { {"all", no_argument, NULL, 'a'}, {"header", no_argument, NULL, 'e'}, @@ -488,19 +487,13 @@ static const char * const opts_help[] = { /* display usage and exit */ static void usage(int status) { - int i; - printf("* List ELF/PaX information about running processes\n\n" - "Usage: %s [options]\n\n", argv0); - fputs("Options:\n", stdout); - for (i = 0; long_opts[i].name; ++i) - printf(" -%c, --%-12s* %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); -#ifdef MANLYPAGE - for (i = 0; long_opts[i].name; ++i) - printf(".TP\n\\fB\\-%c, \\-\\-%s\\fR\n%s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); -#endif - exit(status); + pax_usage( + "List ELF/PaX information about running processes", + "", + PARSE_FLAGS, + long_opts, + opts_help, + status); } /* parse command line arguments and perform needed actions */ diff --git a/scanelf.c b/scanelf.c index 1a6043e..140208b 100644 --- a/scanelf.c +++ b/scanelf.c @@ -1828,7 +1828,6 @@ static void scanelf_envpath(void) /* usage / invocation handling functions */ /* Free Flags: c d j u w G H J K P Q U W */ #define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:DIYO:ZCBhV" -#define a_argument required_argument static struct option const long_opts[] = { {"path", no_argument, NULL, 'p'}, {"ldpath", no_argument, NULL, 'l'}, @@ -1924,43 +1923,13 @@ static const char * const opts_help[] = { /* display usage and exit */ static void usage(int status) { - const char a_arg[] = ""; - size_t a_arg_len = strlen(a_arg) + 2; - size_t i; - int optlen; - printf("* Scan ELF binaries for stuff\n\n" - "Usage: %s [options] [dir2 dirN file2 fileN ...]\n\n", argv0); - printf("Options: -[%s]\n", PARSE_FLAGS); - - /* prescan the --long opt length to auto-align */ - optlen = 0; - for (i = 0; long_opts[i].name; ++i) { - int l = strlen(long_opts[i].name); - if (long_opts[i].has_arg == a_argument) - l += a_arg_len; - optlen = max(l, optlen); - } - - for (i = 0; long_opts[i].name; ++i) { - /* first output the short flag if it has one */ - if (long_opts[i].val > '~') - printf(" "); - else - printf(" -%c, ", long_opts[i].val); - - /* then the long flag */ - if (long_opts[i].has_arg == no_argument) - printf("--%-*s", optlen, long_opts[i].name); - else - printf("--%s %s %*s", long_opts[i].name, a_arg, - (int)(optlen - strlen(long_opts[i].name) - a_arg_len), ""); - - /* finally the help text */ - printf("* %s\n", opts_help[i]); - } - - puts("\nFor more information, see the scanelf(1) manpage"); - exit(status); + pax_usage( + "Scan ELF binaries for stuff", + " [dir2 dirN file2 fileN ...]", + PARSE_FLAGS, + long_opts, + opts_help, + status); } /* parse command line arguments and perform needed actions */ diff --git a/scanmacho.c b/scanmacho.c index f0351ff..d33a440 100644 --- a/scanmacho.c +++ b/scanmacho.c @@ -573,7 +573,6 @@ static void scanmacho_envpath(void) /* usage / invocation handling functions */ /* Free Flags: c d e j k l s t u w x z G H I J K L P Q T W X Y */ #define PARSE_FLAGS "pRmyArnibSUN:gE:M:DO:ZaqvF:f:o:CBhV" -#define a_argument required_argument static struct option const long_opts[] = { {"path", no_argument, NULL, 'p'}, {"recursive", no_argument, NULL, 'R'}, @@ -621,7 +620,7 @@ static const char * const opts_help[] = { "Find a specified library", "Use strncmp to match libraries. (use with -N)", "Print only Mach-O files matching mach_header\n" - " MH_OBJECT,MH_EXECUTE ... (ELF: etype)", + " MH_OBJECT,MH_EXECUTE ... (ELF: etype)", "Print only Mach-O files matching numeric bits", "Print Endianness", "Print only Mach-O files matching octal permissions", @@ -642,20 +641,13 @@ static const char * const opts_help[] = { /* display usage and exit */ static void usage(int status) { - unsigned long i; - printf("* Scan Mach-O binaries for stuff\n\n" - "Usage: %s [options] [dir2 dirN file2 fileN ...]\n\n", argv0); - printf("Options: -[%s]\n", PARSE_FLAGS); - for (i = 0; long_opts[i].name; ++i) - if (long_opts[i].has_arg == no_argument) - printf(" -%c, --%-14s* %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); - else - printf(" -%c, --%-7s * %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); - - puts("\nFor more information, see the scanmacho(1) manpage"); - exit(status); + pax_usage( + "Scan Mach-O binaries for stuff", + " [dir2 dirN file2 fileN ...]", + PARSE_FLAGS, + long_opts, + opts_help, + status); } /* parse command line arguments and perform needed actions */ -- cgit v1.2.3-65-gdbad