From 3f0fa5587f6e69e8957e674d3ccde6ff8873302e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sun, 28 Apr 2019 15:17:38 +0200 Subject: Add argument parser This implements argument parser based on glibc argp. --- child.c | 5 +---- main.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/child.c b/child.c index d0e09a8..a9c5c26 100644 --- a/child.c +++ b/child.c @@ -50,10 +50,7 @@ int child_main(void *_args) { const char *shell = get_shell(); execl(shell, shell, NULL); } else { - char *new_argv[args->argc + 1]; - memcpy(new_argv, args->argv + 1, args->argc * sizeof *new_argv); - new_argv[args->argc] = NULL; - execvp(new_argv[0], new_argv); + execvp(args->argv[0], args->argv); assert_perror(errno); } return 1; diff --git a/main.c b/main.c index 7957be3..0f4815c 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ /* uroot - User's root * main.c Source file with main function * - * Copyright (C) 2018 Karel Kočí + * Copyright (C) 2018-2019 Karel Kočí * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define _GNU_SOURCE +#include #include #include #include @@ -25,19 +26,67 @@ #include #include #include +#include +#include #include "child.h" #include "utils.h" #include "sigpipe.h" #include "conf.h" +const char *argp_program_version = PACKAGE_STRING; +const char *argp_program_bug_address = PACKAGE_BUGREPORT; +static const char usage_doc[] = "[CMD [ARG..]]"; +static const char doc[] = "Tool using Linux namespaces to provide root like functionality for unprivileged users."; + +struct opts { + char **child_argv; + size_t child_argc; +}; + +static struct argp_option options[] = { + {"debug", 'd', NULL, 0, "Report uroot operations.", 0}, + {NULL} +}; + +static error_t parse_opt(int key, char *arg, struct argp_state *state) { + struct opts *opts = state->input; + switch (key) { + case 'd': + // TODO logging + break; + case ARGP_KEY_ARGS: + opts->child_argc = state->argc - state->next; + opts->child_argv = malloc((opts->child_argc + 1) * sizeof *opts->child_argv); + memcpy(opts->child_argv, state->argv + state->next, opts->child_argc * + sizeof *opts->child_argv); + opts->child_argv[opts->child_argc] = NULL; + break; + case ARGP_KEY_INIT: + opts->child_argv = NULL; + opts->child_argc = 0; + break; + default: + return ARGP_ERR_UNKNOWN; + }; + return 0; +} + +static const struct argp argp_parser = { + .options = options, + .parser = parse_opt, + .args_doc = usage_doc, + .doc = doc, +}; + int main(int argc, char **argv) { - // TODO arguments parsing + struct opts opts; + argp_parse(&argp_parser, argc, argv, ARGP_IN_ORDER, 0, &opts); struct child_args chargs = (struct child_args) { .ppid = getpid(), - .argc = argc, - .argv = argv, + .argc = opts.child_argc, + .argv = opts.child_argv, .sigpipe = sigpipe_new() }; -- cgit v1.2.3