diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | headers.h | 3 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/options.c | 116 | ||||
-rw-r--r-- | src/sandbox.c | 45 | ||||
-rw-r--r-- | src/sandbox.h | 3 |
6 files changed, 129 insertions, 40 deletions
diff --git a/configure.ac b/configure.ac index b57263e..4c4cb20 100644 --- a/configure.ac +++ b/configure.ac @@ -109,6 +109,7 @@ AC_CHECK_HEADERS_ONCE(m4_flatten([ errno.h execinfo.h fcntl.h + getopt.h grp.h inttypes.h libgen.h @@ -29,6 +29,9 @@ #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif +#ifdef HAVE_GETOPT_H +# include <getopt.h> +#endif #ifdef HAVE_GRP_H # include <grp.h> #endif diff --git a/src/Makefile.am b/src/Makefile.am index c3c1f45..24ffdcf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,5 +11,6 @@ AM_CPPFLAGS = \ sandbox_LDADD = $(top_builddir)/libsbutil/libsbutil.la $(LIBDL) sandbox_SOURCES = \ environ.c \ + options.c \ sandbox.h \ sandbox.c diff --git a/src/options.c b/src/options.c new file mode 100644 index 0000000..10f937c --- /dev/null +++ b/src/options.c @@ -0,0 +1,116 @@ +/* + * Handle command line arguments + * + * Copyright 1999-2015 Gentoo Foundation + * Licensed under the GPL-2 + */ + +#include "headers.h" +#include "sbutil.h" +#include "sandbox.h" + +static void show_version(void) +{ + puts( + "Gentoo path sandbox\n" + " version: " PACKAGE_VERSION "\n" + " C lib: " LIBC_VERSION " (" LIBC_PATH ")\n" + " build: " __DATE__ " " __TIME__ "\n" + " contact: " PACKAGE_BUGREPORT " via http://bugs.gentoo.org/\n" + " rtld: " +#ifdef BROKEN_RTLD_NEXT + "next is broken ;(\n" +#else + "next is OK! :D\n" +#endif +#ifndef SB_SCHIZO +# define SB_SCHIZO "no" +#endif + " schizo: " SB_SCHIZO "\n" + "\nconfigured with these options:\n" + SANDBOX_CONFIGURE_OPTS + ); + exit(0); +} + +#define PARSE_FLAGS "+hV" +#define a_argument required_argument +static struct option const long_opts[] = { + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + {NULL, no_argument, NULL, 0x0} +}; +static const char * const opts_help[] = { + "Print this help and exit", + "Print version and exit", + NULL +}; + +static void show_usage(int status) +{ + const char a_arg[] = "<arg>"; + size_t a_arg_len = strlen(a_arg) + 2; + size_t i; + int optlen; + FILE *fp = status ? stderr : stdout; + + fprintf(fp, + "Usage: sandbox [options] [program [program args...]]\n" + "\n" + "Sandbox will start up a sandbox session and execute the specified program.\n" + "If no program is specified, an interactive shell is automatically launched.\n" + "You can use this to quickly test out sandbox behavior.\n" + "\n" + "Upon startup, initial settings are taken from these files / directories:\n" + "\t" SANDBOX_CONF_FILE "\n" + "\t" SANDBOX_CONFD_DIR "\n" + ); + + fprintf(fp, "\nOptions: -[%s]\n", PARSE_FLAGS + 1); + /* 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 > '~' || 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]); + } + + fprintf(fp, "\nContact: " PACKAGE_BUGREPORT " via http://bugs.gentoo.org/\n"); + + exit(status); +} + +void parseargs(int argc, char *argv[]) +{ + int i; + + while ((i = getopt_long(argc, argv, PARSE_FLAGS, long_opts, NULL)) != -1) { + switch (i) { + case 'V': + show_version(); + case 'h': + show_usage(0); + case '?': + show_usage(1); + } + } +} diff --git a/src/sandbox.c b/src/sandbox.c index c2a1d25..15c87b2 100644 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -204,49 +204,14 @@ int main(int argc, char **argv) char *run_str = "-c"; + /* Process the sandbox opts and leave argc/argv for the target. */ + parseargs(argc, argv); + argc -= optind - 1; + argv[optind - 1] = argv[0]; + argv += optind - 1; /* Only print info if called with no arguments .... */ if (argc < 2) print_debug = 1; - else { - /* handle a few common options */ - if (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-V")) { - puts( - "Gentoo path sandbox\n" - " version: " PACKAGE_VERSION "\n" - " C lib: " LIBC_VERSION " (" LIBC_PATH ")\n" - " build: " __DATE__ " " __TIME__ "\n" - " contact: " PACKAGE_BUGREPORT " via http://bugs.gentoo.org/\n" - " rtld: " -#ifdef BROKEN_RTLD_NEXT - "next is broken ;(\n" -#else - "next is OK! :D\n" -#endif -#ifndef SB_SCHIZO -# define SB_SCHIZO "no" -#endif - " schizo: " SB_SCHIZO "\n" - "\nconfigured with these options:\n" - SANDBOX_CONFIGURE_OPTS - ); - return 0; - } else if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) { - puts( - "Usage: sandbox [program [program args...]]\n" - "\n" - "Sandbox will start up a sandbox session and execute the specified program.\n" - "If no program is specified, an interactive shell is automatically launched.\n" - "You can use this to quickly test out sandbox behavior.\n" - "\n" - "Upon startup, initial settings are taken from these files / directories:\n" - "\t" SANDBOX_CONF_FILE "\n" - "\t" SANDBOX_CONFD_DIR "\n" - "\n" - "Contact: " PACKAGE_BUGREPORT " via http://bugs.gentoo.org/" - ); - return 0; - } - } dputs(sandbox_banner); diff --git a/src/sandbox.h b/src/sandbox.h index c0c4315..361d468 100644 --- a/src/sandbox.h +++ b/src/sandbox.h @@ -32,4 +32,7 @@ extern char **setup_environ(struct sandbox_info_t *sandbox_info); #define sb_err(fmt, args...) _sb_err(warn, fmt, ## args) #define sb_perr(fmt, args...) _sb_err(pwarn, fmt, ## args) +/* Option parsing related code */ +extern void parseargs(int argc, char *argv[]); + #endif |