From 1d1b82274564204ebddbd8103b16e7950491fbec Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 12 Jul 2012 10:45:46 +0200 Subject: added generated gengetopt files, there is no decent gengetopt on most linux distributions --- src/GNUmakefile | 1 - src/cmdline.c | 1944 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cmdline.h | 275 ++++++++ 3 files changed, 2219 insertions(+), 1 deletion(-) create mode 100644 src/cmdline.c create mode 100644 src/cmdline.h (limited to 'src') diff --git a/src/GNUmakefile b/src/GNUmakefile index 07d778c..b7729e8 100644 --- a/src/GNUmakefile +++ b/src/GNUmakefile @@ -34,6 +34,5 @@ local_all: cmdline.h local_clean: local_distclean: - -@rm cmdline.c cmdline.h local_test: diff --git a/src/cmdline.c b/src/cmdline.c new file mode 100644 index 0000000..87fe6ee --- /dev/null +++ b/src/cmdline.c @@ -0,0 +1,1944 @@ +/* + File autogenerated by gengetopt version 2.22.5 + generated with the following command: + gengetopt --unamed-opts --include-getopt --conf-parser -i check_curl.ggo + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + + +#include "cmdline.h" + +const char *gengetopt_args_info_purpose = "Nagios plugin using libcurl and libpcre for http checks\nCopyright (c)2008 Andreas Baumann "; + +const char *gengetopt_args_info_usage = "Usage: [options] | --config-file "; + +const char *gengetopt_args_info_description = ""; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " --config-file=filename The optional configuration file", + " -v, --verbose Show details for command-line debugging (Nagios \n may truncate output)", + " -t, --timeout=INTEGER Seconds before connection times out (default: \n 10)", + " -c, --critical=INTEGER Response time to result in critical status \n (seconds)", + " -w, --warning=INTEGER Response time to result in warning", + " -H, --host=host The host name in a HTTP 1.1 request (virtual \n host)", + " -I, --ip=host/IP The host/IP to check", + " -p, --port=INTEGER Port number (default: 80)", + " -u, --url=PATH URL to GET or POST (default: /)", + " -f, --onredirect=STRING How to handle redirected pages (possible \n values=\"ok\", \"warning\", \"critical\", \n \"follow\")", + " -a, --authorization=Username:Password\n Username:password on sites with basic \n authentication", + " -s, --string=STRING String to expect in the content", + " -S, --ssl Connect via SSL. Port defaults to 443", + " -A, --useragent=STRING String to be sent in http header as \"User \n Agent\"", + " --no-verify-peer Allow connections to SSL sites without certs \n (SSL)", + " --no-verify-host Don't verify that the host and the certificate \n host match (SSL)", + " --cacert=file CA certificate to verify peer against (SSL)", + " -E, --cert=file Client certificate file and password (SSL)", + " --key=key Private key file name (SSL)", + " --protocol=protocol The protocol to use (http, ftp) (possible \n values=\"http\", \"ftp\" default=`http')", + 0 +}; + +typedef enum {ARG_NO + , ARG_STRING + , ARG_SHORT + , ARG_LONG +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + +static int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); +struct line_list +{ + char * string_arg; + struct line_list * next; +}; + +static struct line_list *cmd_line_list = 0; +static struct line_list *cmd_line_list_tmp = 0; + +static void +free_cmd_list(void) +{ + /* free the list of a previous call */ + if (cmd_line_list) + { + while (cmd_line_list) { + cmd_line_list_tmp = cmd_line_list; + cmd_line_list = cmd_line_list->next; + free (cmd_line_list_tmp->string_arg); + free (cmd_line_list_tmp); + } + } +} + + +const char *cmdline_parser_onredirect_values[] = {"ok", "warning", "critical", "follow", 0}; /*< Possible values for onredirect. */ +const char *cmdline_parser_protocol_values[] = {"http", "ftp", 0}; /*< Possible values for protocol. */ + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->config_file_given = 0 ; + args_info->verbose_given = 0 ; + args_info->timeout_given = 0 ; + args_info->critical_given = 0 ; + args_info->warning_given = 0 ; + args_info->host_given = 0 ; + args_info->ip_given = 0 ; + args_info->port_given = 0 ; + args_info->url_given = 0 ; + args_info->onredirect_given = 0 ; + args_info->authorization_given = 0 ; + args_info->string_given = 0 ; + args_info->ssl_given = 0 ; + args_info->useragent_given = 0 ; + args_info->no_verify_peer_given = 0 ; + args_info->no_verify_host_given = 0 ; + args_info->cacert_given = 0 ; + args_info->cert_given = 0 ; + args_info->key_given = 0 ; + args_info->protocol_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + FIX_UNUSED (args_info); + args_info->config_file_arg = NULL; + args_info->config_file_orig = NULL; + args_info->timeout_orig = NULL; + args_info->critical_orig = NULL; + args_info->warning_orig = NULL; + args_info->host_arg = NULL; + args_info->host_orig = NULL; + args_info->ip_arg = NULL; + args_info->ip_orig = NULL; + args_info->port_orig = NULL; + args_info->url_arg = NULL; + args_info->url_orig = NULL; + args_info->onredirect_arg = NULL; + args_info->onredirect_orig = NULL; + args_info->authorization_arg = NULL; + args_info->authorization_orig = NULL; + args_info->string_arg = NULL; + args_info->string_orig = NULL; + args_info->useragent_arg = NULL; + args_info->useragent_orig = NULL; + args_info->cacert_arg = NULL; + args_info->cacert_orig = NULL; + args_info->cert_arg = NULL; + args_info->cert_orig = NULL; + args_info->key_arg = NULL; + args_info->key_orig = NULL; + args_info->protocol_arg = gengetopt_strdup ("http"); + args_info->protocol_orig = NULL; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->config_file_help = gengetopt_args_info_help[2] ; + args_info->verbose_help = gengetopt_args_info_help[3] ; + args_info->verbose_min = 0; + args_info->verbose_max = 0; + args_info->timeout_help = gengetopt_args_info_help[4] ; + args_info->critical_help = gengetopt_args_info_help[5] ; + args_info->warning_help = gengetopt_args_info_help[6] ; + args_info->host_help = gengetopt_args_info_help[7] ; + args_info->ip_help = gengetopt_args_info_help[8] ; + args_info->port_help = gengetopt_args_info_help[9] ; + args_info->url_help = gengetopt_args_info_help[10] ; + args_info->onredirect_help = gengetopt_args_info_help[11] ; + args_info->authorization_help = gengetopt_args_info_help[12] ; + args_info->string_help = gengetopt_args_info_help[13] ; + args_info->ssl_help = gengetopt_args_info_help[14] ; + args_info->useragent_help = gengetopt_args_info_help[15] ; + args_info->no_verify_peer_help = gengetopt_args_info_help[16] ; + args_info->no_verify_host_help = gengetopt_args_info_help[17] ; + args_info->cacert_help = gengetopt_args_info_help[18] ; + args_info->cert_help = gengetopt_args_info_help[19] ; + args_info->key_help = gengetopt_args_info_help[20] ; + args_info->protocol_help = gengetopt_args_info_help[21] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", + (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), + CMDLINE_PARSER_VERSION); +} + +static void print_help_common(void) { + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + if (strlen(gengetopt_args_info_usage) > 0) + printf("\n%s\n", gengetopt_args_info_usage); + + printf("\n"); + + if (strlen(gengetopt_args_info_description) > 0) + printf("%s\n\n", gengetopt_args_info_description); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); + + args_info->inputs = 0; + args_info->inputs_num = 0; +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + +static void +free_string_field (char **s) +{ + if (*s) + { + free (*s); + *s = 0; + } +} + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + unsigned int i; + free_string_field (&(args_info->config_file_arg)); + free_string_field (&(args_info->config_file_orig)); + free_string_field (&(args_info->timeout_orig)); + free_string_field (&(args_info->critical_orig)); + free_string_field (&(args_info->warning_orig)); + free_string_field (&(args_info->host_arg)); + free_string_field (&(args_info->host_orig)); + free_string_field (&(args_info->ip_arg)); + free_string_field (&(args_info->ip_orig)); + free_string_field (&(args_info->port_orig)); + free_string_field (&(args_info->url_arg)); + free_string_field (&(args_info->url_orig)); + free_string_field (&(args_info->onredirect_arg)); + free_string_field (&(args_info->onredirect_orig)); + free_string_field (&(args_info->authorization_arg)); + free_string_field (&(args_info->authorization_orig)); + free_string_field (&(args_info->string_arg)); + free_string_field (&(args_info->string_orig)); + free_string_field (&(args_info->useragent_arg)); + free_string_field (&(args_info->useragent_orig)); + free_string_field (&(args_info->cacert_arg)); + free_string_field (&(args_info->cacert_orig)); + free_string_field (&(args_info->cert_arg)); + free_string_field (&(args_info->cert_orig)); + free_string_field (&(args_info->key_arg)); + free_string_field (&(args_info->key_orig)); + free_string_field (&(args_info->protocol_arg)); + free_string_field (&(args_info->protocol_orig)); + + + for (i = 0; i < args_info->inputs_num; ++i) + free (args_info->inputs [i]); + + if (args_info->inputs_num) + free (args_info->inputs); + + clear_given (args_info); +} + +/** + * @param val the value to check + * @param values the possible values + * @return the index of the matched value: + * -1 if no value matched, + * -2 if more than one value has matched + */ +static int +check_possible_values(const char *val, const char *values[]) +{ + int i, found, last; + size_t len; + + if (!val) /* otherwise strlen() crashes below */ + return -1; /* -1 means no argument for the option */ + + found = last = 0; + + for (i = 0, len = strlen(val); values[i]; ++i) + { + if (strncmp(val, values[i], len) == 0) + { + ++found; + last = i; + if (strlen(values[i]) == len) + return i; /* exact macth no need to check more */ + } + } + + if (found == 1) /* one match: OK */ + return last; + + return (found ? -2 : -1); /* return many values or none matched */ +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ + int found = -1; + if (arg) { + if (values) { + found = check_possible_values(arg, values); + } + if (found >= 0) + fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]); + else + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + +static void +write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[]) +{ + int i; + + for (i = 0; i < len; ++i) + write_into_file(outfile, opt, (arg ? arg[i] : 0), values); +} + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + if (args_info->config_file_given) + write_into_file(outfile, "config-file", args_info->config_file_orig, 0); + write_multiple_into_file(outfile, args_info->verbose_given, "verbose", 0, 0); + if (args_info->timeout_given) + write_into_file(outfile, "timeout", args_info->timeout_orig, 0); + if (args_info->critical_given) + write_into_file(outfile, "critical", args_info->critical_orig, 0); + if (args_info->warning_given) + write_into_file(outfile, "warning", args_info->warning_orig, 0); + if (args_info->host_given) + write_into_file(outfile, "host", args_info->host_orig, 0); + if (args_info->ip_given) + write_into_file(outfile, "ip", args_info->ip_orig, 0); + if (args_info->port_given) + write_into_file(outfile, "port", args_info->port_orig, 0); + if (args_info->url_given) + write_into_file(outfile, "url", args_info->url_orig, 0); + if (args_info->onredirect_given) + write_into_file(outfile, "onredirect", args_info->onredirect_orig, cmdline_parser_onredirect_values); + if (args_info->authorization_given) + write_into_file(outfile, "authorization", args_info->authorization_orig, 0); + if (args_info->string_given) + write_into_file(outfile, "string", args_info->string_orig, 0); + if (args_info->ssl_given) + write_into_file(outfile, "ssl", 0, 0 ); + if (args_info->useragent_given) + write_into_file(outfile, "useragent", args_info->useragent_orig, 0); + if (args_info->no_verify_peer_given) + write_into_file(outfile, "no-verify-peer", 0, 0 ); + if (args_info->no_verify_host_given) + write_into_file(outfile, "no-verify-host", 0, 0 ); + if (args_info->cacert_given) + write_into_file(outfile, "cacert", args_info->cacert_orig, 0); + if (args_info->cert_given) + write_into_file(outfile, "cert", args_info->cert_orig, 0); + if (args_info->key_given) + write_into_file(outfile, "key", args_info->key_orig, 0); + if (args_info->protocol_given) + write_into_file(outfile, "protocol", args_info->protocol_orig, cmdline_parser_protocol_values); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = 0; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +static int +check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc); + +int +check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc) +{ + int error = 0; + + if (option_given && (min > 0 || max > 0)) + { + if (min > 0 && max > 0) + { + if (min == max) + { + /* specific occurrences */ + if (option_given != (unsigned int) min) + { + fprintf (stderr, "%s: %s option occurrences must be %d\n", + prog_name, option_desc, min); + error = 1; + } + } + else if (option_given < (unsigned int) min + || option_given > (unsigned int) max) + { + /* range occurrences */ + fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n", + prog_name, option_desc, min, max); + error = 1; + } + } + else if (min > 0) + { + /* at least check */ + if (option_given < min) + { + fprintf (stderr, "%s: %s option occurrences must be at least %d\n", + prog_name, option_desc, min); + error = 1; + } + } + else if (max > 0) + { + /* at most check */ + if (option_given > max) + { + fprintf (stderr, "%s: %s option occurrences must be at most %d\n", + prog_name, option_desc, max); + error = 1; + } + } + } + + return error; +} +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + int result = EXIT_SUCCESS; + + if (cmdline_parser_required2(args_info, prog_name, 0) > 0) + result = EXIT_FAILURE; + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) +{ + int error = 0; + FIX_UNUSED (additional_error); + + /* checks for required options */ + if (check_multiple_option_occurrences(prog_name, args_info->verbose_given, args_info->verbose_min, args_info->verbose_max, "'--verbose' ('-v')")) + error = 1; + + if (! args_info->ip_given) + { + fprintf (stderr, "%s: '--ip' ('-I') option required%s\n", prog_name, (additional_error ? additional_error : "")); + error = 1; + } + + + /* checks for dependences among options */ + + return error; +} + +/* + * Extracted from the glibc source tree, version 2.3.6 + * + * Licensed under the GPL as per the whole glibc source tree. + * + * This file was modified so that getopt_long can be called + * many times without risking previous memory to be spoiled. + * + * Modified by Andre Noll and Lorenzo Bettini for use in + * GNU gengetopt generated files. + * + */ + +/* + * we must include anything we need since this file is not thought to be + * inserted in a file already using getopt.h + * + * Lorenzo + */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. +*/ +/* + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `custom_optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +/* Names for the values of the `has_arg' field of `struct option'. */ +#ifndef no_argument +#define no_argument 0 +#endif + +#ifndef required_argument +#define required_argument 1 +#endif + +#ifndef optional_argument +#define optional_argument 2 +#endif + +struct custom_getopt_data { + /* + * These have exactly the same meaning as the corresponding global variables, + * except that they are used for the reentrant versions of getopt. + */ + int custom_optind; + int custom_opterr; + int custom_optopt; + char *custom_optarg; + + /* True if the internal members have been initialized. */ + int initialized; + + /* + * The next char to be scanned in the option-element in which the last option + * character we returned was found. This allows us to pick up the scan where + * we left off. If this is zero, or a null string, it means resume the scan by + * advancing to the next ARGV-element. + */ + char *nextchar; + + /* + * Describe the part of ARGV that contains non-options that have been skipped. + * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is + * the index after the last of them. + */ + int first_nonopt; + int last_nonopt; +}; + +/* + * the variables optarg, optind, opterr and optopt are renamed with + * the custom_ prefix so that they don't interfere with getopt ones. + * + * Moreover they're static so they are visible only from within the + * file where this very file will be included. + */ + +/* + * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an + * option that takes an argument, the argument value is returned here. + */ +static char *custom_optarg; + +/* + * Index in ARGV of the next element to be scanned. This is used for + * communication to and from the caller and for communication between + * successive calls to `custom_getopt'. + * + * On entry to `custom_getopt', 1 means this is the first call; initialize. + * + * When `custom_getopt' returns -1, this is the index of the first of the non-option + * elements that the caller should itself scan. + * + * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV + * has been scanned so far. + * + * 1003.2 says this must be 1 before any call. + */ +static int custom_optind = 1; + +/* + * Callers store zero here to inhibit the error message for unrecognized + * options. + */ +static int custom_opterr = 1; + +/* + * Set to an option character which was unrecognized. This must be initialized + * on some systems to avoid linking in the system's own getopt implementation. + */ +static int custom_optopt = '?'; + +/* + * Exchange two adjacent subsequences of ARGV. One subsequence is elements + * [first_nonopt,last_nonopt) which contains all the non-options that have been + * skipped so far. The other is elements [last_nonopt,custom_optind), which contains + * all the options processed since those non-options were skipped. + * `first_nonopt' and `last_nonopt' are relocated so that they describe the new + * indices of the non-options in ARGV after they are moved. + */ +static void exchange(char **argv, struct custom_getopt_data *d) +{ + int bottom = d->first_nonopt; + int middle = d->last_nonopt; + int top = d->custom_optind; + char *tem; + + /* + * Exchange the shorter segment with the far end of the longer segment. + * That puts the shorter segment into the right place. It leaves the + * longer segment in the right place overall, but it consists of two + * parts that need to be swapped next. + */ + while (top > middle && middle > bottom) { + if (top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = + argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else { + /* Top segment is the short one. */ + int len = top - middle; + int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + /* Update records for the slots the non-options now occupy. */ + d->first_nonopt += (d->custom_optind - d->last_nonopt); + d->last_nonopt = d->custom_optind; +} + +/* Initialize the internal data when the first call is made. */ +static void custom_getopt_initialize(struct custom_getopt_data *d) +{ + /* + * Start processing options with ARGV-element 1 (since ARGV-element 0 + * is the program name); the sequence of previously skipped non-option + * ARGV-elements is empty. + */ + d->first_nonopt = d->last_nonopt = d->custom_optind; + d->nextchar = NULL; + d->initialized = 1; +} + +#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0') + +/* return: zero: continue, nonzero: return given value to user */ +static int shuffle_argv(int argc, char *const *argv,const struct option *longopts, + struct custom_getopt_data *d) +{ + /* + * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been + * moved back by the user (who may also have changed the arguments). + */ + if (d->last_nonopt > d->custom_optind) + d->last_nonopt = d->custom_optind; + if (d->first_nonopt > d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * If we have just processed some options following some + * non-options, exchange them so that the options come first. + */ + if (d->first_nonopt != d->last_nonopt && + d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->last_nonopt != d->custom_optind) + d->first_nonopt = d->custom_optind; + /* + * Skip any additional non-options and extend the range of + * non-options previously skipped. + */ + while (d->custom_optind < argc && NONOPTION_P) + d->custom_optind++; + d->last_nonopt = d->custom_optind; + /* + * The special ARGV-element `--' means premature end of options. Skip + * it like a null option, then exchange with previous non-options as if + * it were an option, then skip everything else like a non-option. + */ + if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) { + d->custom_optind++; + if (d->first_nonopt != d->last_nonopt + && d->last_nonopt != d->custom_optind) + exchange((char **) argv, d); + else if (d->first_nonopt == d->last_nonopt) + d->first_nonopt = d->custom_optind; + d->last_nonopt = argc; + d->custom_optind = argc; + } + /* + * If we have done all the ARGV-elements, stop the scan and back over + * any non-options that we skipped and permuted. + */ + if (d->custom_optind == argc) { + /* + * Set the next-arg-index to point at the non-options that we + * previously skipped, so the caller will digest them. + */ + if (d->first_nonopt != d->last_nonopt) + d->custom_optind = d->first_nonopt; + return -1; + } + /* + * If we have come to a non-option and did not permute it, either stop + * the scan or describe it to the caller and pass it by. + */ + if (NONOPTION_P) { + d->custom_optarg = argv[d->custom_optind++]; + return 1; + } + /* + * We have found another option-ARGV-element. Skip the initial + * punctuation. + */ + d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-')); + return 0; +} + +/* + * Check whether the ARGV-element is a long option. + * + * If there's a long option "fubar" and the ARGV-element is "-fu", consider + * that an abbreviation of the long option, just like "--fu", and not "-f" with + * arg "u". + * + * This distinction seems to be the most useful approach. + * + */ +static int check_long_opt(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + int print_errors, struct custom_getopt_data *d) +{ + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match or abbreviated matches */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) { + if ((unsigned int) (nameend - d->nextchar) + == (unsigned int) strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if (pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else if (pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' is ambiguous\n", + argv[0], argv[d->custom_optind]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optind++; + d->custom_optopt = 0; + return '?'; + } + if (pfound) { + option_index = indfound; + d->custom_optind++; + if (*nameend) { + if (pfound->has_arg != no_argument) + d->custom_optarg = nameend + 1; + else { + if (print_errors) { + if (argv[d->custom_optind - 1][1] == '-') { + /* --option */ + fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + } else { + /* +option or -option */ + fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[d->custom_optind - 1][0], pfound->name); + } + + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return '?'; + } + } else if (pfound->has_arg == required_argument) { + if (d->custom_optind < argc) + d->custom_optarg = argv[d->custom_optind++]; + else { + if (print_errors) { + fprintf(stderr, + "%s: option `%s' requires an argument\n", + argv[0], + argv[d->custom_optind - 1]); + } + d->nextchar += strlen(d->nextchar); + d->custom_optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + d->nextchar += strlen(d->nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + /* + * Can't find it as a long option. If this is not getopt_long_only, or + * the option starts with '--' or is not a valid short option, then + * it's an error. Otherwise interpret it as a short option. + */ + if (print_errors) { + if (argv[d->custom_optind][1] == '-') { + /* --option */ + fprintf(stderr, + "%s: unrecognized option `--%s'\n", + argv[0], d->nextchar); + } else { + /* +option or -option */ + fprintf(stderr, + "%s: unrecognized option `%c%s'\n", + argv[0], argv[d->custom_optind][0], + d->nextchar); + } + } + d->nextchar = (char *) ""; + d->custom_optind++; + d->custom_optopt = 0; + return '?'; +} + +static int check_short_opt(int argc, char *const *argv, const char *optstring, + int print_errors, struct custom_getopt_data *d) +{ + char c = *d->nextchar++; + const char *temp = strchr(optstring, c); + + /* Increment `custom_optind' when we start to process its last character. */ + if (*d->nextchar == '\0') + ++d->custom_optind; + if (!temp || c == ':') { + if (print_errors) + fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); + + d->custom_optopt = c; + return '?'; + } + if (temp[1] == ':') { + if (temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + d->custom_optind++; + } else + d->custom_optarg = NULL; + d->nextchar = NULL; + } else { + /* This is an option that requires an argument. */ + if (*d->nextchar != '\0') { + d->custom_optarg = d->nextchar; + /* + * If we end this ARGV-element by taking the + * rest as an arg, we must advance to the next + * element now. + */ + d->custom_optind++; + } else if (d->custom_optind == argc) { + if (print_errors) { + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], c); + } + d->custom_optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } else + /* + * We already incremented `custom_optind' once; + * increment it again when taking next ARGV-elt + * as argument. + */ + d->custom_optarg = argv[d->custom_optind++]; + d->nextchar = NULL; + } + } + return c; +} + +/* + * Scan elements of ARGV for option characters given in OPTSTRING. + * + * If an element of ARGV starts with '-', and is not exactly "-" or "--", + * then it is an option element. The characters of this element + * (aside from the initial '-') are option characters. If `getopt' + * is called repeatedly, it returns successively each of the option characters + * from each of the option elements. + * + * If `getopt' finds another option character, it returns that character, + * updating `custom_optind' and `nextchar' so that the next call to `getopt' can + * resume the scan with the following option character or ARGV-element. + * + * If there are no more option characters, `getopt' returns -1. + * Then `custom_optind' is the index in ARGV of the first ARGV-element + * that is not an option. (The ARGV-elements have been permuted + * so that those that are not options now come last.) + * + * OPTSTRING is a string containing the legitimate option characters. + * If an option character is seen that is not listed in OPTSTRING, + * return '?' after printing an error message. If you set `custom_opterr' to + * zero, the error message is suppressed but we still return '?'. + * + * If a char in OPTSTRING is followed by a colon, that means it wants an arg, + * so the following text in the same ARGV-element, or the text of the following + * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that + * wants an optional arg; if there is text in the current ARGV-element, + * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero. + * + * If OPTSTRING starts with `-' or `+', it requests different methods of + * handling the non-option ARGV-elements. + * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + * + * Long-named options begin with `--' instead of `-'. + * Their names may be abbreviated as long as the abbreviation is unique + * or is an exact match for some defined option. If they have an + * argument, it follows the option name in the same ARGV-element, separated + * from the option name by a `=', or else the in next ARGV-element. + * When `getopt' finds a long-named option, it returns 0 if that option's + * `flag' field is nonzero, the value of the option's `val' field + * if the `flag' field is zero. + * + * The elements of ARGV aren't really const, because we permute them. + * But we pretend they're const in the prototype to be compatible + * with other systems. + * + * LONGOPTS is a vector of `struct option' terminated by an + * element containing a name which is zero. + * + * LONGIND returns the index in LONGOPT of the long-named option found. + * It is only valid when a long-named option has been found by the most + * recent call. + * + * Return the option character from OPTS just read. Return -1 when there are + * no more options. For unrecognized options, or options missing arguments, + * `custom_optopt' is set to the option letter, and '?' is returned. + * + * The OPTS string is a list of characters which are recognized option letters, + * optionally followed by colons, specifying that that letter takes an + * argument, to be placed in `custom_optarg'. + * + * If a letter in OPTS is followed by two colons, its argument is optional. + * This behavior is specific to the GNU `getopt'. + * + * The argument `--' causes premature termination of argument scanning, + * explicitly telling `getopt' that there are no more options. If OPTS begins + * with `--', then non-option arguments are treated as arguments to the option + * '\0'. This behavior is specific to the GNU `getopt'. + */ + +static int getopt_internal_r(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + struct custom_getopt_data *d) +{ + int ret, print_errors = d->custom_opterr; + + if (optstring[0] == ':') + print_errors = 0; + if (argc < 1) + return -1; + d->custom_optarg = NULL; + + /* + * This is a big difference with GNU getopt, since optind == 0 + * means initialization while here 1 means first call. + */ + if (d->custom_optind == 0 || !d->initialized) { + if (d->custom_optind == 0) + d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */ + custom_getopt_initialize(d); + } + if (d->nextchar == NULL || *d->nextchar == '\0') { + ret = shuffle_argv(argc, argv, longopts, d); + if (ret) + return ret; + } + if (longopts && (argv[d->custom_optind][1] == '-' )) + return check_long_opt(argc, argv, optstring, longopts, + longind, print_errors, d); + return check_short_opt(argc, argv, optstring, print_errors, d); +} + +static int custom_getopt_internal(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind) +{ + int result; + /* Keep a global copy of all internal members of d */ + static struct custom_getopt_data d; + + d.custom_optind = custom_optind; + d.custom_opterr = custom_opterr; + result = getopt_internal_r(argc, argv, optstring, longopts, + longind, &d); + custom_optind = d.custom_optind; + custom_optarg = d.custom_optarg; + custom_optopt = d.custom_optopt; + return result; +} + +static int custom_getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return custom_getopt_internal(argc, argv, options, long_options, + opt_index); +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, + unsigned int *field_given, unsigned int *prev_given, + char *value, const char *possible_values[], + const char *default_value, + cmdline_parser_arg_type arg_type, + int check_ambiguity, int override, + int no_free, int multiple_option, + const char *long_opt, char short_opt, + const char *additional_error) +{ + char *stop_char = 0; + const char *val = value; + int found; + char **string_field; + FIX_UNUSED (field); + + stop_char = 0; + found = 0; + + if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) + { + if (short_opt != '-') + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + package_name, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: `--%s' option given more than once%s\n", + package_name, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0) + { + if (short_opt != '-') + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n", + package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n", + package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + if (field_given && *field_given && ! override) + return 0; + if (prev_given) + (*prev_given)++; + if (field_given) + (*field_given)++; + if (possible_values) + val = possible_values[found]; + + switch(arg_type) { + case ARG_SHORT: + if (val) *((short *)field) = (short)strtol (val, &stop_char, 0); + break; + case ARG_LONG: + if (val) *((long *)field) = (long)strtol (val, &stop_char, 0); + break; + case ARG_STRING: + if (val) { + string_field = (char **)field; + if (!no_free && *string_field) + free (*string_field); /* free previous string */ + *string_field = gengetopt_strdup (val); + } + break; + default: + break; + }; + + /* check numeric conversion */ + switch(arg_type) { + case ARG_SHORT: + case ARG_LONG: + if (val && !(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); + return 1; /* failure */ + } + break; + default: + ; + }; + + /* store the original value */ + switch(arg_type) { + case ARG_NO: + break; + default: + if (value && orig_field) { + if (no_free) { + *orig_field = value; + } else { + if (*orig_field) + free (*orig_field); /* free previous string */ + *orig_field = gengetopt_strdup (value); + } + } + }; + + return 0; /* OK */ +} + + +int +cmdline_parser_internal ( + int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + char *optarg; + int optind; + int opterr; + int optopt; + + package_name = argv[0]; + + override = params->override; + initialize = params->initialize; + check_required = params->check_required; + check_ambiguity = params->check_ambiguity; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "config-file", 1, NULL, 0 }, + { "verbose", 0, NULL, 'v' }, + { "timeout", 1, NULL, 't' }, + { "critical", 1, NULL, 'c' }, + { "warning", 1, NULL, 'w' }, + { "host", 1, NULL, 'H' }, + { "ip", 1, NULL, 'I' }, + { "port", 1, NULL, 'p' }, + { "url", 1, NULL, 'u' }, + { "onredirect", 1, NULL, 'f' }, + { "authorization", 1, NULL, 'a' }, + { "string", 1, NULL, 's' }, + { "ssl", 0, NULL, 'S' }, + { "useragent", 1, NULL, 'A' }, + { "no-verify-peer", 0, NULL, 0 }, + { "no-verify-host", 0, NULL, 0 }, + { "cacert", 1, NULL, 0 }, + { "cert", 1, NULL, 'E' }, + { "key", 1, NULL, 0 }, + { "protocol", 1, NULL, 0 }, + { 0, 0, 0, 0 } + }; + + custom_optarg = optarg; + custom_optind = optind; + custom_opterr = opterr; + custom_optopt = optopt; + + c = custom_getopt_long (argc, argv, "hVvt:c:w:H:I:p:u:f:a:s:SA:E:", long_options, &option_index); + + optarg = custom_optarg; + optind = custom_optind; + opterr = custom_opterr; + optopt = custom_optopt; + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'v': /* Show details for command-line debugging (Nagios may truncate output). */ + + local_args_info.verbose_given++; + + break; + case 't': /* Seconds before connection times out (default: 10). */ + + + if (update_arg( (void *)&(args_info->timeout_arg), + &(args_info->timeout_orig), &(args_info->timeout_given), + &(local_args_info.timeout_given), optarg, 0, 0, ARG_LONG, + check_ambiguity, override, 0, 0, + "timeout", 't', + additional_error)) + goto failure; + + break; + case 'c': /* Response time to result in critical status (seconds). */ + + + if (update_arg( (void *)&(args_info->critical_arg), + &(args_info->critical_orig), &(args_info->critical_given), + &(local_args_info.critical_given), optarg, 0, 0, ARG_LONG, + check_ambiguity, override, 0, 0, + "critical", 'c', + additional_error)) + goto failure; + + break; + case 'w': /* Response time to result in warning. */ + + + if (update_arg( (void *)&(args_info->warning_arg), + &(args_info->warning_orig), &(args_info->warning_given), + &(local_args_info.warning_given), optarg, 0, 0, ARG_LONG, + check_ambiguity, override, 0, 0, + "warning", 'w', + additional_error)) + goto failure; + + break; + case 'H': /* The host name in a HTTP 1.1 request (virtual host). */ + + + if (update_arg( (void *)&(args_info->host_arg), + &(args_info->host_orig), &(args_info->host_given), + &(local_args_info.host_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "host", 'H', + additional_error)) + goto failure; + + break; + case 'I': /* The host/IP to check. */ + + + if (update_arg( (void *)&(args_info->ip_arg), + &(args_info->ip_orig), &(args_info->ip_given), + &(local_args_info.ip_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "ip", 'I', + additional_error)) + goto failure; + + break; + case 'p': /* Port number (default: 80). */ + + + if (update_arg( (void *)&(args_info->port_arg), + &(args_info->port_orig), &(args_info->port_given), + &(local_args_info.port_given), optarg, 0, 0, ARG_SHORT, + check_ambiguity, override, 0, 0, + "port", 'p', + additional_error)) + goto failure; + + break; + case 'u': /* URL to GET or POST (default: /). */ + + + if (update_arg( (void *)&(args_info->url_arg), + &(args_info->url_orig), &(args_info->url_given), + &(local_args_info.url_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "url", 'u', + additional_error)) + goto failure; + + break; + case 'f': /* How to handle redirected pages. */ + + + if (update_arg( (void *)&(args_info->onredirect_arg), + &(args_info->onredirect_orig), &(args_info->onredirect_given), + &(local_args_info.onredirect_given), optarg, cmdline_parser_onredirect_values, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "onredirect", 'f', + additional_error)) + goto failure; + + break; + case 'a': /* Username:password on sites with basic authentication. */ + + + if (update_arg( (void *)&(args_info->authorization_arg), + &(args_info->authorization_orig), &(args_info->authorization_given), + &(local_args_info.authorization_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "authorization", 'a', + additional_error)) + goto failure; + + break; + case 's': /* String to expect in the content. */ + + + if (update_arg( (void *)&(args_info->string_arg), + &(args_info->string_orig), &(args_info->string_given), + &(local_args_info.string_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "string", 's', + additional_error)) + goto failure; + + break; + case 'S': /* Connect via SSL. Port defaults to 443. */ + + + if (update_arg( 0 , + 0 , &(args_info->ssl_given), + &(local_args_info.ssl_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "ssl", 'S', + additional_error)) + goto failure; + + break; + case 'A': /* String to be sent in http header as \"User Agent\". */ + + + if (update_arg( (void *)&(args_info->useragent_arg), + &(args_info->useragent_orig), &(args_info->useragent_given), + &(local_args_info.useragent_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "useragent", 'A', + additional_error)) + goto failure; + + break; + case 'E': /* Client certificate file and password (SSL). */ + + + if (update_arg( (void *)&(args_info->cert_arg), + &(args_info->cert_orig), &(args_info->cert_given), + &(local_args_info.cert_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "cert", 'E', + additional_error)) + goto failure; + + break; + + case 0: /* Long option with no short option */ + /* The optional configuration file. */ + if (strcmp (long_options[option_index].name, "config-file") == 0) + { + + + if (update_arg( (void *)&(args_info->config_file_arg), + &(args_info->config_file_orig), &(args_info->config_file_given), + &(local_args_info.config_file_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "config-file", '-', + additional_error)) + goto failure; + + } + /* Allow connections to SSL sites without certs (SSL). */ + else if (strcmp (long_options[option_index].name, "no-verify-peer") == 0) + { + + + if (update_arg( 0 , + 0 , &(args_info->no_verify_peer_given), + &(local_args_info.no_verify_peer_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "no-verify-peer", '-', + additional_error)) + goto failure; + + } + /* Don't verify that the host and the certificate host match (SSL). */ + else if (strcmp (long_options[option_index].name, "no-verify-host") == 0) + { + + + if (update_arg( 0 , + 0 , &(args_info->no_verify_host_given), + &(local_args_info.no_verify_host_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "no-verify-host", '-', + additional_error)) + goto failure; + + } + /* CA certificate to verify peer against (SSL). */ + else if (strcmp (long_options[option_index].name, "cacert") == 0) + { + + + if (update_arg( (void *)&(args_info->cacert_arg), + &(args_info->cacert_orig), &(args_info->cacert_given), + &(local_args_info.cacert_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "cacert", '-', + additional_error)) + goto failure; + + } + /* Private key file name (SSL). */ + else if (strcmp (long_options[option_index].name, "key") == 0) + { + + + if (update_arg( (void *)&(args_info->key_arg), + &(args_info->key_orig), &(args_info->key_given), + &(local_args_info.key_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "key", '-', + additional_error)) + goto failure; + + } + /* The protocol to use (http, ftp). */ + else if (strcmp (long_options[option_index].name, "protocol") == 0) + { + + + if (update_arg( (void *)&(args_info->protocol_arg), + &(args_info->protocol_orig), &(args_info->protocol_given), + &(local_args_info.protocol_given), optarg, cmdline_parser_protocol_values, "http", ARG_STRING, + check_ambiguity, override, 0, 0, + "protocol", '-', + additional_error)) + goto failure; + + } + + break; + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + + args_info->verbose_given += local_args_info.verbose_given; + local_args_info.verbose_given = 0; + + if (check_required) + { + error += cmdline_parser_required2 (args_info, argv[0], additional_error); + } + + cmdline_parser_release (&local_args_info); + + if ( error ) + return (EXIT_FAILURE); + + if (optind < argc) + { + int i = 0 ; + int found_prog_name = 0; + /* whether program name, i.e., argv[0], is in the remaining args + (this may happen with some implementations of getopt, + but surely not with the one included by gengetopt) */ + + + args_info->inputs_num = argc - optind - found_prog_name; + args_info->inputs = + (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; + while (optind < argc) + args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ; + } + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} + +#ifndef CONFIG_FILE_LINE_SIZE +#define CONFIG_FILE_LINE_SIZE 2048 +#endif +#define ADDITIONAL_ERROR " in configuration file " + +#define CONFIG_FILE_LINE_BUFFER_SIZE (CONFIG_FILE_LINE_SIZE+3) +/* 3 is for "--" and "=" */ + +static int +_cmdline_parser_configfile (const char *filename, int *my_argc) +{ + FILE* file; + char my_argv[CONFIG_FILE_LINE_BUFFER_SIZE+1]; + char linebuf[CONFIG_FILE_LINE_SIZE]; + int line_num = 0; + int result = 0, equal; + char *fopt, *farg; + char *str_index; + size_t len, next_token; + char delimiter; + + if ((file = fopen(filename, "r")) == 0) + { + fprintf (stderr, "%s: Error opening configuration file '%s'\n", + CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + while ((fgets(linebuf, CONFIG_FILE_LINE_SIZE, file)) != 0) + { + ++line_num; + my_argv[0] = '\0'; + len = strlen(linebuf); + if (len > (CONFIG_FILE_LINE_BUFFER_SIZE-1)) + { + fprintf (stderr, "%s:%s:%d: Line too long in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + break; + } + + /* find first non-whitespace character in the line */ + next_token = strspn (linebuf, " \t\r\n"); + str_index = linebuf + next_token; + + if ( str_index[0] == '\0' || str_index[0] == '#') + continue; /* empty line or comment line is skipped */ + + fopt = str_index; + + /* truncate fopt at the end of the first non-valid character */ + next_token = strcspn (fopt, " \t\r\n="); + + if (fopt[next_token] == '\0') /* the line is over */ + { + farg = 0; + equal = 0; + goto noarg; + } + + /* remember if equal sign is present */ + equal = (fopt[next_token] == '='); + fopt[next_token++] = '\0'; + + /* advance pointers to the next token after the end of fopt */ + next_token += strspn (fopt + next_token, " \t\r\n"); + + /* check for the presence of equal sign, and if so, skip it */ + if ( !equal ) + if ((equal = (fopt[next_token] == '='))) + { + next_token++; + next_token += strspn (fopt + next_token, " \t\r\n"); + } + str_index += next_token; + + /* find argument */ + farg = str_index; + if ( farg[0] == '\"' || farg[0] == '\'' ) + { /* quoted argument */ + str_index = strchr (++farg, str_index[0] ); /* skip opening quote */ + if (! str_index) + { + fprintf + (stderr, + "%s:%s:%d: unterminated string in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + break; + } + } + else + { /* read up the remaining part up to a delimiter */ + next_token = strcspn (farg, " \t\r\n#\'\""); + str_index += next_token; + } + + /* truncate farg at the delimiter and store it for further check */ + delimiter = *str_index, *str_index++ = '\0'; + + /* everything but comment is illegal at the end of line */ + if (delimiter != '\0' && delimiter != '#') + { + str_index += strspn(str_index, " \t\r\n"); + if (*str_index != '\0' && *str_index != '#') + { + fprintf + (stderr, + "%s:%s:%d: malformed string in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + break; + } + } + + noarg: + if (!strcmp(fopt,"include")) { + if (farg && *farg) { + result = _cmdline_parser_configfile(farg, my_argc); + } else { + fprintf(stderr, "%s:%s:%d: include requires a filename argument.\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + } + continue; + } + len = strlen(fopt); + strcat (my_argv, len > 1 ? "--" : "-"); + strcat (my_argv, fopt); + if (len > 1 && ((farg && *farg) || equal)) + strcat (my_argv, "="); + if (farg && *farg) + strcat (my_argv, farg); + ++(*my_argc); + + cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list)); + cmd_line_list_tmp->next = cmd_line_list; + cmd_line_list = cmd_line_list_tmp; + cmd_line_list->string_arg = gengetopt_strdup(my_argv); + } /* while */ + + if (file) + fclose(file); + return result; +} + +int +cmdline_parser_configfile ( + const char *filename, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required) +{ + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + return cmdline_parser_config_file (filename, args_info, ¶ms); +} + +int +cmdline_parser_config_file (const char *filename, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int i, result; + int my_argc = 1; + char **my_argv_arg; + char *additional_error; + + /* store the program name */ + cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list)); + cmd_line_list_tmp->next = cmd_line_list; + cmd_line_list = cmd_line_list_tmp; + cmd_line_list->string_arg = gengetopt_strdup (CMDLINE_PARSER_PACKAGE); + + result = _cmdline_parser_configfile(filename, &my_argc); + + if (result != EXIT_FAILURE) { + my_argv_arg = (char **) malloc((my_argc+1) * sizeof(char *)); + cmd_line_list_tmp = cmd_line_list; + + for (i = my_argc - 1; i >= 0; --i) { + my_argv_arg[i] = cmd_line_list_tmp->string_arg; + cmd_line_list_tmp = cmd_line_list_tmp->next; + } + + my_argv_arg[my_argc] = 0; + + additional_error = (char *)malloc(strlen(filename) + strlen(ADDITIONAL_ERROR) + 1); + strcpy (additional_error, ADDITIONAL_ERROR); + strcat (additional_error, filename); + result = + cmdline_parser_internal (my_argc, my_argv_arg, args_info, + params, + additional_error); + + free (additional_error); + free (my_argv_arg); + } + + free_cmd_list(); + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} diff --git a/src/cmdline.h b/src/cmdline.h new file mode 100644 index 0000000..7277d5f --- /dev/null +++ b/src/cmdline.h @@ -0,0 +1,275 @@ +/** @file cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.22.5 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef CMDLINE_H +#define CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE "check_url" +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#define CMDLINE_PARSER_PACKAGE_NAME "check_url" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION "0.0.4" +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + char * config_file_arg; /**< @brief The optional configuration file. */ + char * config_file_orig; /**< @brief The optional configuration file original value given at command line. */ + const char *config_file_help; /**< @brief The optional configuration file help description. */ + unsigned int verbose_min; /**< @brief Show details for command-line debugging (Nagios may truncate output)'s minimum occurreces */ + unsigned int verbose_max; /**< @brief Show details for command-line debugging (Nagios may truncate output)'s maximum occurreces */ + const char *verbose_help; /**< @brief Show details for command-line debugging (Nagios may truncate output) help description. */ + long timeout_arg; /**< @brief Seconds before connection times out (default: 10). */ + char * timeout_orig; /**< @brief Seconds before connection times out (default: 10) original value given at command line. */ + const char *timeout_help; /**< @brief Seconds before connection times out (default: 10) help description. */ + long critical_arg; /**< @brief Response time to result in critical status (seconds). */ + char * critical_orig; /**< @brief Response time to result in critical status (seconds) original value given at command line. */ + const char *critical_help; /**< @brief Response time to result in critical status (seconds) help description. */ + long warning_arg; /**< @brief Response time to result in warning. */ + char * warning_orig; /**< @brief Response time to result in warning original value given at command line. */ + const char *warning_help; /**< @brief Response time to result in warning help description. */ + char * host_arg; /**< @brief The host name in a HTTP 1.1 request (virtual host). */ + char * host_orig; /**< @brief The host name in a HTTP 1.1 request (virtual host) original value given at command line. */ + const char *host_help; /**< @brief The host name in a HTTP 1.1 request (virtual host) help description. */ + char * ip_arg; /**< @brief The host/IP to check. */ + char * ip_orig; /**< @brief The host/IP to check original value given at command line. */ + const char *ip_help; /**< @brief The host/IP to check help description. */ + short port_arg; /**< @brief Port number (default: 80). */ + char * port_orig; /**< @brief Port number (default: 80) original value given at command line. */ + const char *port_help; /**< @brief Port number (default: 80) help description. */ + char * url_arg; /**< @brief URL to GET or POST (default: /). */ + char * url_orig; /**< @brief URL to GET or POST (default: /) original value given at command line. */ + const char *url_help; /**< @brief URL to GET or POST (default: /) help description. */ + char * onredirect_arg; /**< @brief How to handle redirected pages. */ + char * onredirect_orig; /**< @brief How to handle redirected pages original value given at command line. */ + const char *onredirect_help; /**< @brief How to handle redirected pages help description. */ + char * authorization_arg; /**< @brief Username:password on sites with basic authentication. */ + char * authorization_orig; /**< @brief Username:password on sites with basic authentication original value given at command line. */ + const char *authorization_help; /**< @brief Username:password on sites with basic authentication help description. */ + char * string_arg; /**< @brief String to expect in the content. */ + char * string_orig; /**< @brief String to expect in the content original value given at command line. */ + const char *string_help; /**< @brief String to expect in the content help description. */ + const char *ssl_help; /**< @brief Connect via SSL. Port defaults to 443 help description. */ + char * useragent_arg; /**< @brief String to be sent in http header as \"User Agent\". */ + char * useragent_orig; /**< @brief String to be sent in http header as \"User Agent\" original value given at command line. */ + const char *useragent_help; /**< @brief String to be sent in http header as \"User Agent\" help description. */ + const char *no_verify_peer_help; /**< @brief Allow connections to SSL sites without certs (SSL) help description. */ + const char *no_verify_host_help; /**< @brief Don't verify that the host and the certificate host match (SSL) help description. */ + char * cacert_arg; /**< @brief CA certificate to verify peer against (SSL). */ + char * cacert_orig; /**< @brief CA certificate to verify peer against (SSL) original value given at command line. */ + const char *cacert_help; /**< @brief CA certificate to verify peer against (SSL) help description. */ + char * cert_arg; /**< @brief Client certificate file and password (SSL). */ + char * cert_orig; /**< @brief Client certificate file and password (SSL) original value given at command line. */ + const char *cert_help; /**< @brief Client certificate file and password (SSL) help description. */ + char * key_arg; /**< @brief Private key file name (SSL). */ + char * key_orig; /**< @brief Private key file name (SSL) original value given at command line. */ + const char *key_help; /**< @brief Private key file name (SSL) help description. */ + char * protocol_arg; /**< @brief The protocol to use (http, ftp) (default='http'). */ + char * protocol_orig; /**< @brief The protocol to use (http, ftp) original value given at command line. */ + const char *protocol_help; /**< @brief The protocol to use (http, ftp) help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + unsigned int config_file_given ; /**< @brief Whether config-file was given. */ + unsigned int verbose_given ; /**< @brief Whether verbose was given. */ + unsigned int timeout_given ; /**< @brief Whether timeout was given. */ + unsigned int critical_given ; /**< @brief Whether critical was given. */ + unsigned int warning_given ; /**< @brief Whether warning was given. */ + unsigned int host_given ; /**< @brief Whether host was given. */ + unsigned int ip_given ; /**< @brief Whether ip was given. */ + unsigned int port_given ; /**< @brief Whether port was given. */ + unsigned int url_given ; /**< @brief Whether url was given. */ + unsigned int onredirect_given ; /**< @brief Whether onredirect was given. */ + unsigned int authorization_given ; /**< @brief Whether authorization was given. */ + unsigned int string_given ; /**< @brief Whether string was given. */ + unsigned int ssl_given ; /**< @brief Whether ssl was given. */ + unsigned int useragent_given ; /**< @brief Whether useragent was given. */ + unsigned int no_verify_peer_given ; /**< @brief Whether no-verify-peer was given. */ + unsigned int no_verify_host_given ; /**< @brief Whether no-verify-host was given. */ + unsigned int cacert_given ; /**< @brief Whether cacert was given. */ + unsigned int cert_given ; /**< @brief Whether cert was given. */ + unsigned int key_given ; /**< @brief Whether key was given. */ + unsigned int protocol_given ; /**< @brief Whether protocol was given. */ + + char **inputs ; /**< @brief unamed options (options without names) */ + unsigned inputs_num ; /**< @brief unamed options number */ +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * The config file parser (deprecated version) + * @param filename the name of the config file + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_config_file() instead + */ +int cmdline_parser_configfile (const char *filename, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The config file parser + * @param filename the name of the config file + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_config_file (const char *filename, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + +extern const char *cmdline_parser_onredirect_values[]; /**< @brief Possible values for onredirect. */ +extern const char *cmdline_parser_protocol_values[]; /**< @brief Possible values for protocol. */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* CMDLINE_H */ -- cgit v1.2.3-54-g00ecf