commit:     3f593b47e284cd9defa15e19a37357c3e31b1b7f
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Mon Sep 21 00:14:44 2015 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Mon Sep 21 00:14:44 2015 +0000
URL:        https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=3f593b47

sandbox: add proper option parsing

This lays the groundwork for adding more runtime options.

Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>

 configure.ac    |   1 +
 headers.h       |   3 ++
 src/Makefile.am |   1 +
 src/options.c   | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/sandbox.c   |  45 +++-------------------
 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

diff --git a/headers.h b/headers.h
index 1dc140e..458958b 100644
--- a/headers.h
+++ b/headers.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

Reply via email to