From a40fd1bb6c4769683c11b3e308279c17a0acbc5a Mon Sep 17 00:00:00 2001 From: Maxim Biro Date: Thu, 31 Dec 2015 18:48:44 -0500 Subject: [PATCH] Add ability to specify multiple command line arguments Needed in order to specify which log backend to use. Init scripts need to be updated to contain --config before the path to the config file. --- other/bootstrap_daemon/src/tox-bootstrapd.c | 130 ++++++++++++++++-- other/bootstrap_daemon/tox-bootstrapd.service | 2 +- other/bootstrap_daemon/tox-bootstrapd.sh | 2 +- 3 files changed, 122 insertions(+), 12 deletions(-) diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index 9a4ccf9f..e2bf7ade 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -23,6 +23,7 @@ // system provided #include +#include #include #include #include @@ -516,18 +517,125 @@ void print_public_key(const uint8_t *public_key) return; } +// Prints --help message + +bool print_help() +{ + // 2 space ident + // make sure all lines fit into 80 columns + write_log(LOG_LEVEL_INFO, + "Usage: tox-bootstrapd [OPTION]... --config=FILE_PATH\n" + "\n" + "Options:\n" + " --config=FILE_PATH Specify path to the config file.\n" + " This is a required option.\n" + " Set FILE_PATH to a path to an empty file in order to\n" + " use default settings.\n" + " --help Print this help message.\n" + " --log-backend=BACKEND Specify which logging backend to use.\n" + " Valid BACKEND values (case sensetive):\n" + " syslog Writes log messages to syslog.\n" + " Default option when no --log-backend is\n" + " specified.\n" + " stdout Writes log messages to stdout/stderr.\n" + " --version Print version information.\n"); +} + +// Handels command line arguments, setting cfg_file_path and log_backend. +// Terminates the application if incorrect arguments are specified. + +void handle_command_line_arguments(int argc, char *argv[], char **cfg_file_path, LOGGER_BACKEND *log_backend) +{ + if (argc < 2) { + write_log(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n"); + print_help(); + exit(1); + } + + opterr = 0; + + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"config", required_argument, 0, 'c'}, // required option + {"log-backend", required_argument, 0, 'l'}, // optional, defaults to syslog + {"version", no_argument, 0, 'v'}, + {0, 0, 0, 0 } + }; + + bool cfg_file_path_set = false; + bool log_backend_set = false; + + int opt; + + while ((opt = getopt_long(argc, argv, ":", long_options, NULL)) != -1) { + + switch (opt) { + case 'h': + print_help(); + exit(0); + + case 'c': + *cfg_file_path = optarg; + cfg_file_path_set = true; + break; + + case 'l': + if (strcmp(optarg, "syslog") == 0) { + *log_backend = LOGGER_BACKEND_SYSLOG; + log_backend_set = true; + } else if (strcmp(optarg, "stdout") == 0) { + *log_backend = LOGGER_BACKEND_STDOUT; + log_backend_set = true; + } else { + write_log(LOG_LEVEL_ERROR, "Error: Invalid BACKEND value for --log-backend option passed: %s\n\n", optarg); + print_help(); + exit(1); + } + break; + + case 'v': + write_log(LOG_LEVEL_INFO, "Version: %lu\n", DAEMON_VERSION_NUMBER); + exit(0); + + case '?': + write_log(LOG_LEVEL_ERROR, "Error: Unrecognized option %s\n\n", argv[optind-1]); + print_help(); + exit(1); + + case ':': + write_log(LOG_LEVEL_ERROR, "Error: No argument provided for option %s\n\n", argv[optind-1]); + print_help(); + exit(1); + } + } + + if (!log_backend_set) { + *log_backend = LOGGER_BACKEND_SYSLOG; + } + + if (!cfg_file_path_set) { + write_log(LOG_LEVEL_ERROR, "Error: The required --config option wasn't specified\n\n"); + print_help(); + exit(1); + } +} + int main(int argc, char *argv[]) { - open_log(LOGGER_BACKEND_SYSLOG); + char *cfg_file_path; + LOGGER_BACKEND log_backend; + + // choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal + log_backend = isatty(STDOUT_FILENO) ? LOGGER_BACKEND_STDOUT : LOGGER_BACKEND_SYSLOG; + + open_log(log_backend); + handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend); + close_log(); + + open_log(log_backend); write_log(LOG_LEVEL_INFO, "Running \"%s\" version %lu.\n", DAEMON_NAME, DAEMON_VERSION_NUMBER); - if (argc < 2) { - write_log(LOG_LEVEL_ERROR, "Please specify a path to a configuration file as the first argument. Exiting.\n"); - return 1; - } - - const char *cfg_file_path = argv[1]; char *pid_file_path, *keys_file_path; int port; int enable_ipv6; @@ -690,9 +798,11 @@ int main(int argc, char *argv[]) } // Go quiet - close(STDOUT_FILENO); - close(STDIN_FILENO); - close(STDERR_FILENO); + if (log_backend != LOGGER_BACKEND_STDOUT) { + close(STDOUT_FILENO); + close(STDIN_FILENO); + close(STDERR_FILENO); + } uint64_t last_LANdiscovery = 0; const uint16_t htons_port = htons(port); diff --git a/other/bootstrap_daemon/tox-bootstrapd.service b/other/bootstrap_daemon/tox-bootstrapd.service index db54cc41..20f698d2 100644 --- a/other/bootstrap_daemon/tox-bootstrapd.service +++ b/other/bootstrap_daemon/tox-bootstrapd.service @@ -8,7 +8,7 @@ RuntimeDirectory=tox-bootstrapd RuntimeDirectoryMode=750 PIDFile=/var/run/tox-bootstrapd/tox-bootstrapd.pid WorkingDirectory=/var/lib/tox-bootstrapd -ExecStart=/usr/local/bin/tox-bootstrapd /etc/tox-bootstrapd.conf +ExecStart=/usr/local/bin/tox-bootstrapd --config /etc/tox-bootstrapd.conf User=tox-bootstrapd Group=tox-bootstrapd #CapabilityBoundingSet=CAP_NET_BIND_SERVICE diff --git a/other/bootstrap_daemon/tox-bootstrapd.sh b/other/bootstrap_daemon/tox-bootstrapd.sh index 1431bde0..d33c38da 100644 --- a/other/bootstrap_daemon/tox-bootstrapd.sh +++ b/other/bootstrap_daemon/tox-bootstrapd.sh @@ -15,7 +15,7 @@ DESC="Tox DHT bootstrap daemon" NAME=tox-bootstrapd DAEMON=/usr/local/bin/$NAME CFGFILE=/etc/$NAME.conf -DAEMON_ARGS="$CFGFILE" +DAEMON_ARGS="--config $CFGFILE" PIDDIR=/var/run/$NAME PIDFILE=$PIDDIR/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME