Skip to content

Commit

Permalink
lxc_init: add custom argument parser
Browse files Browse the repository at this point in the history
lxc_init.c should not depend on tools/arguments.{c,h}, thus it needs its own custom argument parser

Signed-off-by: RicardoSanchezA <ricardo.sanchez@utexas.edu>
  • Loading branch information
RicardoSanchezA committed Dec 6, 2017
1 parent a729880 commit 5ee606b
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 25 deletions.
5 changes: 2 additions & 3 deletions src/lxc/Makefile.am
Expand Up @@ -276,7 +276,7 @@ lxc_device_SOURCES = tools/lxc_device.c tools/arguments.c
lxc_execute_SOURCES = tools/lxc_execute.c tools/arguments.c
lxc_freeze_SOURCES = tools/lxc_freeze.c tools/arguments.c
lxc_info_SOURCES = tools/lxc_info.c tools/arguments.c
init_lxc_SOURCES = lxc_init.c tools/arguments.c
init_lxc_SOURCES = lxc_init.c
lxc_monitor_SOURCES = tools/lxc_monitor.c tools/arguments.c
lxc_ls_SOURCES = tools/lxc_ls.c tools/arguments.c
lxc_copy_SOURCES = tools/lxc_copy.c tools/arguments.c
Expand Down Expand Up @@ -304,8 +304,7 @@ endif
if HAVE_STATIC_LIBCAP
sbin_PROGRAMS += init.lxc.static

init_lxc_static_SOURCES = lxc_init.c error.c log.c initutils.c caps.c \
tools/arguments.c
init_lxc_static_SOURCES = lxc_init.c error.c log.c initutils.c caps.c

if !HAVE_GETLINE
if HAVE_FGETLN
Expand Down
198 changes: 176 additions & 22 deletions src/lxc/lxc_init.c
Expand Up @@ -33,13 +33,18 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctype.h>

#include <lxc/lxccontainer.h>

#include "tools/arguments.h"
#include "error.h"
#include "initutils.h"
#include "log.h"
#include "version.h"

/* option keys for long only options */
#define OPT_USAGE 0x1000
#define OPT_VERSION OPT_USAGE - 1

lxc_log_define(lxc_init, lxc);

Expand All @@ -51,27 +56,40 @@ static void interrupt_handler(int sig)
was_interrupted = sig;
}

static const struct option my_longopts[] = {
LXC_COMMON_OPTIONS
static struct option long_options[] = {
{ "name", required_argument, 0, 'n' },
{ "help", no_argument, 0, 'h' },
{ "usage", no_argument, 0, OPT_USAGE },
{ "version", no_argument, 0, OPT_VERSION },
{ "quiet", no_argument, 0, 'q' },
{ "logfile", required_argument, 0, 'o' },
{ "logpriority", required_argument, 0, 'l' },
{ "lxcpath", required_argument, 0, 'P' },
{ 0, 0, 0, 0 }
};
static char short_options[] = "n:hqo:l:P:";

struct arguments {
const struct option *options;
const char *shortopts;

const char *name;
char *log_file;
char *log_priority;
int quiet;
const char *lxcpath;

/* remaining arguments */
char *const *argv;
int argc;
};

static int my_parser(struct lxc_arguments *args, int c, char *arg)
{
return 0;
}
static int arguments_parse(struct arguments *my_args, int argc,
char *const argv[]);

static struct lxc_arguments my_args = {
.progname = "lxc-init",
.help = "\
--name=NAME -- COMMAND\n\
\n\
lxc-init start a COMMAND as PID 2 inside a container\n\
\n\
Options :\n\
-n, --name=NAME NAME of the container\n\
",
.options = my_longopts,
.parser = my_parser,
static struct arguments my_args = {
.options = long_options,
.shortopts = short_options
};

int main(int argc, char *argv[])
Expand All @@ -83,15 +101,15 @@ int main(int argc, char *argv[])
sigset_t mask, omask;
int have_status = 0, shutdown = 0;

if (lxc_arguments_parse(&my_args, argc, argv))
if (arguments_parse(&my_args, argc, argv))
exit(EXIT_FAILURE);

log.prefix = "lxc-init";
log.name = my_args.name;
log.file = my_args.log_file;
log.level = my_args.log_priority;
log.prefix = my_args.progname;
log.quiet = my_args.quiet;
log.lxcpath = my_args.lxcpath[0];
log.lxcpath = my_args.lxcpath;

ret = lxc_log_init(&log);
if (ret < 0)
Expand Down Expand Up @@ -293,3 +311,139 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
exit(ret);
}



static void print_usage(const struct option longopts[])

{
int i;
const struct option *opt;

fprintf(stderr, "Usage: lxc-init ");

for (opt = longopts, i = 1; opt->name; opt++, i++) {
int j;
char *uppername;

uppername = strdup(opt->name);
if (!uppername)
exit(-ENOMEM);

for (j = 0; uppername[j]; j++)
uppername[j] = toupper(uppername[j]);

fprintf(stderr, "[");

if (isprint(opt->val))
fprintf(stderr, "-%c|", opt->val);

fprintf(stderr, "--%s", opt->name);

if (opt->has_arg == required_argument)
fprintf(stderr, "=%s", uppername);

if (opt->has_arg == optional_argument)
fprintf(stderr, "[=%s]", uppername);

fprintf(stderr, "] ");

if (!(i % 4))
fprintf(stderr, "\n\t");

free(uppername);
}

fprintf(stderr, "\n");
exit(0);
}

static void print_version()
{
printf("%s%s\n", LXC_VERSION, LXC_DEVEL ? "-devel" : "");
exit(0);
}

static void print_help(int code)
{
fprintf(stderr, "\
Usage: lxc-init --name=NAME -- COMMAND\n\
\n\
lxc-init start a COMMAND as PID 2 inside a container\n\
\n\
Options :\n\
-n, --name=NAME NAME of the container\n\
-o, --logfile=FILE Output log to FILE instead of stderr\n\
-l, --logpriority=LEVEL Set log priority to LEVEL\n\
-q, --quiet Don't produce any output\n\
-P, --lxcpath=PATH Use specified container path\n\
-?, --help Give this help list\n\
--usage Give a short usage message\n\
--version Print the version number\n\
\n\
Mandatory or optional arguments to long options are also mandatory or optional\n\
for any corresponding short options.\n\
\n\
See the lxc-init man page for further information.\n\n");

exit(code);
}

static int arguments_parse(struct arguments *args, int argc,
char *const argv[])
{
while (true) {
int c;
int index = 0;

c = getopt_long(argc, argv, args->shortopts, args->options, &index);
if (c == -1)
break;
switch (c) {
case 'n':
args->name = optarg;
break;
case 'o':
args->log_file = optarg;
break;
case 'l':
args->log_priority = optarg;
break;
case 'q':
args->quiet = 1;
break;
case 'P':
remove_trailing_slashes(optarg);
args->lxcpath = optarg;
break;
case OPT_USAGE:
print_usage(args->options);
case OPT_VERSION:
print_version();
case '?':
print_help(1);
case 'h':
print_help(0);
}
}

/*
* Reclaim the remaining command arguments
*/
args->argv = &argv[optind];
args->argc = argc - optind;

/* If no lxcpath was given, use default */
if (!args->lxcpath) {
args->lxcpath = lxc_global_config_value("lxc.lxcpath");
}

/* Check the command options */
if (!args->name) {
if(!args->quiet)
fprintf(stderr, "lxc-init: missing container name, use --name option\n");
return -1;
}

return 0;
}

0 comments on commit 5ee606b

Please sign in to comment.