From 1b3e57701744ac33878fa129c087c1798fee4936 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 4 May 2010 11:13:56 +0200 Subject: Use newer gengetopt which also frees memory Taken from http://sourceforge.net/tracker/index.php?func=detail&aid=1811521&group_id=68956&atid=522957 --- ggsn/cmdline.c | 1286 ++++++++++++++++++++++------------- ggsn/cmdline.h | 79 ++- ggsn/ggsn.c | 3 +- sgsnemu/cmdline.c | 1941 +++++++++++++++++++++++++++++++++-------------------- sgsnemu/cmdline.h | 109 ++- sgsnemu/sgsnemu.c | 2 +- 6 files changed, 2191 insertions(+), 1229 deletions(-) diff --git a/ggsn/cmdline.c b/ggsn/cmdline.c index d8eafe5..d83376f 100644 --- a/ggsn/cmdline.c +++ b/ggsn/cmdline.c @@ -1,5 +1,5 @@ /* - File autogenerated by gengetopt version 2.8 + File autogenerated by gengetopt version 2.17 generated with the following command: gengetopt --conf-parser @@ -8,81 +8,84 @@ we make no copyright claims on it. */ - -#include -#include -#include /* If we use autoconf. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -/* Check for configure's getopt check result. */ -#ifndef HAVE_GETOPT_LONG -#include "getopt.h" -#else -#include -#endif -#ifndef HAVE_STRDUP -#define strdup gengetopt_strdup -#endif /* HAVE_STRDUP */ +#include +#include +#include + +#include "getopt.h" #include "cmdline.h" +const char *gengetopt_args_info_purpose = ""; -void -cmdline_parser_print_version (void) +const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [OPTIONS]..."; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -f, --fg Run in foreground (default=off)", + " -d, --debug Run in debug mode (default=off)", + " -c, --conf=STRING Read configuration file (default=`/etc/ggsn.conf')", + " --pidfile=STRING Filename of process id file \n (default=`/var/run/ggsn.pid')", + " --statedir=STRING Directory of nonvolatile data \n (default=`/var/lib/ggsn/')", + " -l, --listen=STRING Local interface", + " -n, --net=STRING Network (default=`192.168.0.0/24')", + " --ipup=STRING Script to run after link-up", + " --ipdown=STRING Script to run after link-down", + " --dynip=STRING Dynamic IP address pool", + " --statip=STRING Static IP address pool", + " --pcodns1=STRING PCO DNS Server 1 (default=`0.0.0.0')", + " --pcodns2=STRING PCO DNS Server 2 (default=`0.0.0.0')", + " --timelimit=INT Exit after timelimit seconds (default=`0')", + " -a, --apn=STRING Access point name (default=`internet')", + " -q, --qos=INT Requested quality of service (default=`0x0b921f')", + 0 +}; + +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 * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error); + +struct line_list { - printf ("%s %s\n", PACKAGE, VERSION); -} + char * string_arg; + struct line_list * next; +}; -void -cmdline_parser_print_help (void) +static struct line_list *cmd_line_list = 0; +static struct line_list *cmd_line_list_tmp = 0; + +static void +free_cmd_list(void) { - cmdline_parser_print_version (); - printf("\n" - "Usage: %s [OPTIONS]...\n", PACKAGE); - printf(" -h --help Print help and exit\n"); - printf(" -V --version Print version and exit\n"); - printf(" -f --fg Run in foreground (default=off)\n"); - printf(" -d --debug Run in debug mode (default=off)\n"); - printf(" -cSTRING --conf=STRING Read configuration file (default='/etc/ggsn.conf')\n"); - printf(" --pidfile=STRING Filename of process id file (default='/var/run/ggsn.pid')\n"); - printf(" --statedir=STRING Directory of nonvolatile data (default='/var/lib/ggsn/')\n"); - printf(" -lSTRING --listen=STRING Local interface\n"); - printf(" -nSTRING --net=STRING Network (default='192.168.0.0/24')\n"); - printf(" --ipup=STRING Script to run after link-up\n"); - printf(" --ipdown=STRING Script to run after link-down\n"); - printf(" --dynip=STRING Dynamic IP address pool\n"); - printf(" --statip=STRING Static IP address pool\n"); - printf(" --pcodns1=STRING PCO DNS Server 1 (default='0.0.0.0')\n"); - printf(" --pcodns2=STRING PCO DNS Server 2 (default='0.0.0.0')\n"); - printf(" --timelimit=INT Exit after timelimit seconds (default='0')\n"); - printf(" -aSTRING --apn=STRING Access point name (default='internet')\n"); - printf(" -qINT --qos=INT Requested quality of service (default='0x0b921f')\n"); + /* 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); + } + } } -#ifndef HAVE_STRDUP -/* gengetopt_strdup(): automatically generated from strdup.c. */ -/* strdup.c replacement of strdup, which is not standard */ static char * -gengetopt_strdup (const char *s) -{ - char *result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} -#endif /* HAVE_STRDUP */ +gengetopt_strdup (const char *s); -int -cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) +static +void clear_given (struct gengetopt_args_info *args_info) { - int c; /* Character of the parsed option. */ - int missing_required_options = 0; - args_info->help_given = 0 ; args_info->version_given = 0 ; args_info->fg_given = 0 ; @@ -101,29 +104,431 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i args_info->timelimit_given = 0 ; args_info->apn_given = 0 ; args_info->qos_given = 0 ; -#define clear_args() { \ - args_info->fg_flag = 0;\ - args_info->debug_flag = 0;\ - args_info->conf_arg = strdup("/etc/ggsn.conf") ;\ - args_info->pidfile_arg = strdup("/var/run/ggsn.pid") ;\ - args_info->statedir_arg = strdup("/var/lib/ggsn/") ;\ - args_info->listen_arg = NULL; \ - args_info->net_arg = strdup("192.168.0.0/24") ;\ - args_info->ipup_arg = NULL; \ - args_info->ipdown_arg = NULL; \ - args_info->dynip_arg = NULL; \ - args_info->statip_arg = NULL; \ - args_info->pcodns1_arg = strdup("0.0.0.0") ;\ - args_info->pcodns2_arg = strdup("0.0.0.0") ;\ - args_info->timelimit_arg = 0 ;\ - args_info->apn_arg = strdup("internet") ;\ - args_info->qos_arg = 0x0b921f ;\ } - clear_args(); +static +void clear_args (struct gengetopt_args_info *args_info) +{ + args_info->fg_flag = 0; + args_info->debug_flag = 0; + args_info->conf_arg = gengetopt_strdup ("/etc/ggsn.conf"); + args_info->conf_orig = NULL; + args_info->pidfile_arg = gengetopt_strdup ("/var/run/ggsn.pid"); + args_info->pidfile_orig = NULL; + args_info->statedir_arg = gengetopt_strdup ("/var/lib/ggsn/"); + args_info->statedir_orig = NULL; + args_info->listen_arg = NULL; + args_info->listen_orig = NULL; + args_info->net_arg = gengetopt_strdup ("192.168.0.0/24"); + args_info->net_orig = NULL; + args_info->ipup_arg = NULL; + args_info->ipup_orig = NULL; + args_info->ipdown_arg = NULL; + args_info->ipdown_orig = NULL; + args_info->dynip_arg = NULL; + args_info->dynip_orig = NULL; + args_info->statip_arg = NULL; + args_info->statip_orig = NULL; + args_info->pcodns1_arg = gengetopt_strdup ("0.0.0.0"); + args_info->pcodns1_orig = NULL; + args_info->pcodns2_arg = gengetopt_strdup ("0.0.0.0"); + args_info->pcodns2_orig = NULL; + args_info->timelimit_arg = 0; + args_info->timelimit_orig = NULL; + args_info->apn_arg = gengetopt_strdup ("internet"); + args_info->apn_orig = NULL; + args_info->qos_arg = 0x0b921f; + args_info->qos_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->fg_help = gengetopt_args_info_help[2] ; + args_info->debug_help = gengetopt_args_info_help[3] ; + args_info->conf_help = gengetopt_args_info_help[4] ; + args_info->pidfile_help = gengetopt_args_info_help[5] ; + args_info->statedir_help = gengetopt_args_info_help[6] ; + args_info->listen_help = gengetopt_args_info_help[7] ; + args_info->net_help = gengetopt_args_info_help[8] ; + args_info->ipup_help = gengetopt_args_info_help[9] ; + args_info->ipdown_help = gengetopt_args_info_help[10] ; + args_info->dynip_help = gengetopt_args_info_help[11] ; + args_info->statip_help = gengetopt_args_info_help[12] ; + args_info->pcodns1_help = gengetopt_args_info_help[13] ; + args_info->pcodns2_help = gengetopt_args_info_help[14] ; + args_info->timelimit_help = gengetopt_args_info_help[15] ; + args_info->apn_help = gengetopt_args_info_help[16] ; + args_info->qos_help = gengetopt_args_info_help[17] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", CMDLINE_PARSER_PACKAGE, CMDLINE_PARSER_VERSION); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + printf("\n%s\n\n", gengetopt_args_info_usage); + 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); +} + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + + if (args_info->conf_arg) + { + free (args_info->conf_arg); /* free previous argument */ + args_info->conf_arg = 0; + } + if (args_info->conf_orig) + { + free (args_info->conf_orig); /* free previous argument */ + args_info->conf_orig = 0; + } + if (args_info->pidfile_arg) + { + free (args_info->pidfile_arg); /* free previous argument */ + args_info->pidfile_arg = 0; + } + if (args_info->pidfile_orig) + { + free (args_info->pidfile_orig); /* free previous argument */ + args_info->pidfile_orig = 0; + } + if (args_info->statedir_arg) + { + free (args_info->statedir_arg); /* free previous argument */ + args_info->statedir_arg = 0; + } + if (args_info->statedir_orig) + { + free (args_info->statedir_orig); /* free previous argument */ + args_info->statedir_orig = 0; + } + if (args_info->listen_arg) + { + free (args_info->listen_arg); /* free previous argument */ + args_info->listen_arg = 0; + } + if (args_info->listen_orig) + { + free (args_info->listen_orig); /* free previous argument */ + args_info->listen_orig = 0; + } + if (args_info->net_arg) + { + free (args_info->net_arg); /* free previous argument */ + args_info->net_arg = 0; + } + if (args_info->net_orig) + { + free (args_info->net_orig); /* free previous argument */ + args_info->net_orig = 0; + } + if (args_info->ipup_arg) + { + free (args_info->ipup_arg); /* free previous argument */ + args_info->ipup_arg = 0; + } + if (args_info->ipup_orig) + { + free (args_info->ipup_orig); /* free previous argument */ + args_info->ipup_orig = 0; + } + if (args_info->ipdown_arg) + { + free (args_info->ipdown_arg); /* free previous argument */ + args_info->ipdown_arg = 0; + } + if (args_info->ipdown_orig) + { + free (args_info->ipdown_orig); /* free previous argument */ + args_info->ipdown_orig = 0; + } + if (args_info->dynip_arg) + { + free (args_info->dynip_arg); /* free previous argument */ + args_info->dynip_arg = 0; + } + if (args_info->dynip_orig) + { + free (args_info->dynip_orig); /* free previous argument */ + args_info->dynip_orig = 0; + } + if (args_info->statip_arg) + { + free (args_info->statip_arg); /* free previous argument */ + args_info->statip_arg = 0; + } + if (args_info->statip_orig) + { + free (args_info->statip_orig); /* free previous argument */ + args_info->statip_orig = 0; + } + if (args_info->pcodns1_arg) + { + free (args_info->pcodns1_arg); /* free previous argument */ + args_info->pcodns1_arg = 0; + } + if (args_info->pcodns1_orig) + { + free (args_info->pcodns1_orig); /* free previous argument */ + args_info->pcodns1_orig = 0; + } + if (args_info->pcodns2_arg) + { + free (args_info->pcodns2_arg); /* free previous argument */ + args_info->pcodns2_arg = 0; + } + if (args_info->pcodns2_orig) + { + free (args_info->pcodns2_orig); /* free previous argument */ + args_info->pcodns2_orig = 0; + } + if (args_info->timelimit_orig) + { + free (args_info->timelimit_orig); /* free previous argument */ + args_info->timelimit_orig = 0; + } + if (args_info->apn_arg) + { + free (args_info->apn_arg); /* free previous argument */ + args_info->apn_arg = 0; + } + if (args_info->apn_orig) + { + free (args_info->apn_orig); /* free previous argument */ + args_info->apn_orig = 0; + } + if (args_info->qos_orig) + { + free (args_info->qos_orig); /* free previous argument */ + args_info->qos_orig = 0; + } + + clear_given (args_info); +} + +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; + } + + if (args_info->help_given) { + fprintf(outfile, "%s\n", "help"); + } + if (args_info->version_given) { + fprintf(outfile, "%s\n", "version"); + } + if (args_info->fg_given) { + fprintf(outfile, "%s\n", "fg"); + } + if (args_info->debug_given) { + fprintf(outfile, "%s\n", "debug"); + } + if (args_info->conf_given) { + if (args_info->conf_orig) { + fprintf(outfile, "%s=\"%s\"\n", "conf", args_info->conf_orig); + } else { + fprintf(outfile, "%s\n", "conf"); + } + } + if (args_info->pidfile_given) { + if (args_info->pidfile_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pidfile", args_info->pidfile_orig); + } else { + fprintf(outfile, "%s\n", "pidfile"); + } + } + if (args_info->statedir_given) { + if (args_info->statedir_orig) { + fprintf(outfile, "%s=\"%s\"\n", "statedir", args_info->statedir_orig); + } else { + fprintf(outfile, "%s\n", "statedir"); + } + } + if (args_info->listen_given) { + if (args_info->listen_orig) { + fprintf(outfile, "%s=\"%s\"\n", "listen", args_info->listen_orig); + } else { + fprintf(outfile, "%s\n", "listen"); + } + } + if (args_info->net_given) { + if (args_info->net_orig) { + fprintf(outfile, "%s=\"%s\"\n", "net", args_info->net_orig); + } else { + fprintf(outfile, "%s\n", "net"); + } + } + if (args_info->ipup_given) { + if (args_info->ipup_orig) { + fprintf(outfile, "%s=\"%s\"\n", "ipup", args_info->ipup_orig); + } else { + fprintf(outfile, "%s\n", "ipup"); + } + } + if (args_info->ipdown_given) { + if (args_info->ipdown_orig) { + fprintf(outfile, "%s=\"%s\"\n", "ipdown", args_info->ipdown_orig); + } else { + fprintf(outfile, "%s\n", "ipdown"); + } + } + if (args_info->dynip_given) { + if (args_info->dynip_orig) { + fprintf(outfile, "%s=\"%s\"\n", "dynip", args_info->dynip_orig); + } else { + fprintf(outfile, "%s\n", "dynip"); + } + } + if (args_info->statip_given) { + if (args_info->statip_orig) { + fprintf(outfile, "%s=\"%s\"\n", "statip", args_info->statip_orig); + } else { + fprintf(outfile, "%s\n", "statip"); + } + } + if (args_info->pcodns1_given) { + if (args_info->pcodns1_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pcodns1", args_info->pcodns1_orig); + } else { + fprintf(outfile, "%s\n", "pcodns1"); + } + } + if (args_info->pcodns2_given) { + if (args_info->pcodns2_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pcodns2", args_info->pcodns2_orig); + } else { + fprintf(outfile, "%s\n", "pcodns2"); + } + } + if (args_info->timelimit_given) { + if (args_info->timelimit_orig) { + fprintf(outfile, "%s=\"%s\"\n", "timelimit", args_info->timelimit_orig); + } else { + fprintf(outfile, "%s\n", "timelimit"); + } + } + if (args_info->apn_given) { + if (args_info->apn_orig) { + fprintf(outfile, "%s=\"%s\"\n", "apn", args_info->apn_orig); + } else { + fprintf(outfile, "%s\n", "apn"); + } + } + if (args_info->qos_given) { + if (args_info->qos_orig) { + fprintf(outfile, "%s=\"%s\"\n", "qos", args_info->qos_orig); + } else { + fprintf(outfile, "%s\n", "qos"); + } + } + + fclose (outfile); + + i = EXIT_SUCCESS; + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + + +/* gengetopt_strdup() */ +/* strdup.c replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = NULL; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +int +cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + + result = cmdline_parser_internal (argc, argv, args_info, override, initialize, check_required, NULL); + + 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) +{ + return EXIT_SUCCESS; +} + +int +cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error = 0; + struct gengetopt_args_info local_args_info; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); optarg = 0; - optind = 1; + optind = 0; opterr = 1; optopt = '?'; @@ -131,6 +536,7 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i { int option_index = 0; char *stop_char; + static struct option long_options[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'V' }, @@ -153,6 +559,7 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i { NULL, 0, NULL, 0 } }; + stop_char = 0; c = getopt_long (argc, argv, "hVfdc:l:n:a:q:", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ @@ -160,90 +567,131 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i switch (c) { case 'h': /* Print help and exit. */ - clear_args (); cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); exit (EXIT_SUCCESS); case 'V': /* Print version and exit. */ - clear_args (); cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); exit (EXIT_SUCCESS); case 'f': /* Run in foreground. */ - if (args_info->fg_given) + if (local_args_info.fg_given) { - fprintf (stderr, "%s: `--fg' (`-f') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--fg' (`-f') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->fg_given && ! override) + continue; + local_args_info.fg_given = 1; args_info->fg_given = 1; args_info->fg_flag = !(args_info->fg_flag); break; case 'd': /* Run in debug mode. */ - if (args_info->debug_given) + if (local_args_info.debug_given) { - fprintf (stderr, "%s: `--debug' (`-d') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--debug' (`-d') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->debug_given && ! override) + continue; + local_args_info.debug_given = 1; args_info->debug_given = 1; args_info->debug_flag = !(args_info->debug_flag); break; case 'c': /* Read configuration file. */ - if (args_info->conf_given) + if (local_args_info.conf_given) { - fprintf (stderr, "%s: `--conf' (`-c') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--conf' (`-c') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->conf_given && ! override) + continue; + local_args_info.conf_given = 1; args_info->conf_given = 1; - args_info->conf_arg = strdup (optarg); + if (args_info->conf_arg) + free (args_info->conf_arg); /* free previous string */ + args_info->conf_arg = gengetopt_strdup (optarg); + if (args_info->conf_orig) + free (args_info->conf_orig); /* free previous string */ + args_info->conf_orig = gengetopt_strdup (optarg); break; case 'l': /* Local interface. */ - if (args_info->listen_given) + if (local_args_info.listen_given) { - fprintf (stderr, "%s: `--listen' (`-l') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--listen' (`-l') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->listen_given && ! override) + continue; + local_args_info.listen_given = 1; args_info->listen_given = 1; - args_info->listen_arg = strdup (optarg); + if (args_info->listen_arg) + free (args_info->listen_arg); /* free previous string */ + args_info->listen_arg = gengetopt_strdup (optarg); + if (args_info->listen_orig) + free (args_info->listen_orig); /* free previous string */ + args_info->listen_orig = gengetopt_strdup (optarg); break; case 'n': /* Network. */ - if (args_info->net_given) + if (local_args_info.net_given) { - fprintf (stderr, "%s: `--net' (`-n') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--net' (`-n') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->net_given && ! override) + continue; + local_args_info.net_given = 1; args_info->net_given = 1; - args_info->net_arg = strdup (optarg); + if (args_info->net_arg) + free (args_info->net_arg); /* free previous string */ + args_info->net_arg = gengetopt_strdup (optarg); + if (args_info->net_orig) + free (args_info->net_orig); /* free previous string */ + args_info->net_orig = gengetopt_strdup (optarg); break; case 'a': /* Access point name. */ - if (args_info->apn_given) + if (local_args_info.apn_given) { - fprintf (stderr, "%s: `--apn' (`-a') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--apn' (`-a') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->apn_given && ! override) + continue; + local_args_info.apn_given = 1; args_info->apn_given = 1; - args_info->apn_arg = strdup (optarg); + if (args_info->apn_arg) + free (args_info->apn_arg); /* free previous string */ + args_info->apn_arg = gengetopt_strdup (optarg); + if (args_info->apn_orig) + free (args_info->apn_orig); /* free previous string */ + args_info->apn_orig = gengetopt_strdup (optarg); break; case 'q': /* Requested quality of service. */ - if (args_info->qos_given) + if (local_args_info.qos_given) { - fprintf (stderr, "%s: `--qos' (`-q') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--qos' (`-q') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->qos_given && ! override) + continue; + local_args_info.qos_given = 1; args_info->qos_given = 1; - args_info->qos_arg = strtol (optarg,&stop_char,0); + args_info->qos_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->qos_orig) + free (args_info->qos_orig); /* free previous string */ + args_info->qos_orig = gengetopt_strdup (optarg); break; @@ -251,444 +699,374 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i /* Filename of process id file. */ if (strcmp (long_options[option_index].name, "pidfile") == 0) { - if (args_info->pidfile_given) + if (local_args_info.pidfile_given) { - fprintf (stderr, "%s: `--pidfile' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pidfile' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pidfile_given && ! override) + continue; + local_args_info.pidfile_given = 1; args_info->pidfile_given = 1; - args_info->pidfile_arg = strdup (optarg); - break; + if (args_info->pidfile_arg) + free (args_info->pidfile_arg); /* free previous string */ + args_info->pidfile_arg = gengetopt_strdup (optarg); + if (args_info->pidfile_orig) + free (args_info->pidfile_orig); /* free previous string */ + args_info->pidfile_orig = gengetopt_strdup (optarg); } /* Directory of nonvolatile data. */ else if (strcmp (long_options[option_index].name, "statedir") == 0) { - if (args_info->statedir_given) + if (local_args_info.statedir_given) { - fprintf (stderr, "%s: `--statedir' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--statedir' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->statedir_given && ! override) + continue; + local_args_info.statedir_given = 1; args_info->statedir_given = 1; - args_info->statedir_arg = strdup (optarg); - break; + if (args_info->statedir_arg) + free (args_info->statedir_arg); /* free previous string */ + args_info->statedir_arg = gengetopt_strdup (optarg); + if (args_info->statedir_orig) + free (args_info->statedir_orig); /* free previous string */ + args_info->statedir_orig = gengetopt_strdup (optarg); } /* Script to run after link-up. */ else if (strcmp (long_options[option_index].name, "ipup") == 0) { - if (args_info->ipup_given) + if (local_args_info.ipup_given) { - fprintf (stderr, "%s: `--ipup' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--ipup' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->ipup_given && ! override) + continue; + local_args_info.ipup_given = 1; args_info->ipup_given = 1; - args_info->ipup_arg = strdup (optarg); - break; + if (args_info->ipup_arg) + free (args_info->ipup_arg); /* free previous string */ + args_info->ipup_arg = gengetopt_strdup (optarg); + if (args_info->ipup_orig) + free (args_info->ipup_orig); /* free previous string */ + args_info->ipup_orig = gengetopt_strdup (optarg); } /* Script to run after link-down. */ else if (strcmp (long_options[option_index].name, "ipdown") == 0) { - if (args_info->ipdown_given) + if (local_args_info.ipdown_given) { - fprintf (stderr, "%s: `--ipdown' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--ipdown' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->ipdown_given && ! override) + continue; + local_args_info.ipdown_given = 1; args_info->ipdown_given = 1; - args_info->ipdown_arg = strdup (optarg); - break; + if (args_info->ipdown_arg) + free (args_info->ipdown_arg); /* free previous string */ + args_info->ipdown_arg = gengetopt_strdup (optarg); + if (args_info->ipdown_orig) + free (args_info->ipdown_orig); /* free previous string */ + args_info->ipdown_orig = gengetopt_strdup (optarg); } /* Dynamic IP address pool. */ else if (strcmp (long_options[option_index].name, "dynip") == 0) { - if (args_info->dynip_given) + if (local_args_info.dynip_given) { - fprintf (stderr, "%s: `--dynip' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--dynip' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->dynip_given && ! override) + continue; + local_args_info.dynip_given = 1; args_info->dynip_given = 1; - args_info->dynip_arg = strdup (optarg); - break; + if (args_info->dynip_arg) + free (args_info->dynip_arg); /* free previous string */ + args_info->dynip_arg = gengetopt_strdup (optarg); + if (args_info->dynip_orig) + free (args_info->dynip_orig); /* free previous string */ + args_info->dynip_orig = gengetopt_strdup (optarg); } /* Static IP address pool. */ else if (strcmp (long_options[option_index].name, "statip") == 0) { - if (args_info->statip_given) + if (local_args_info.statip_given) { - fprintf (stderr, "%s: `--statip' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--statip' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->statip_given && ! override) + continue; + local_args_info.statip_given = 1; args_info->statip_given = 1; - args_info->statip_arg = strdup (optarg); - break; + if (args_info->statip_arg) + free (args_info->statip_arg); /* free previous string */ + args_info->statip_arg = gengetopt_strdup (optarg); + if (args_info->statip_orig) + free (args_info->statip_orig); /* free previous string */ + args_info->statip_orig = gengetopt_strdup (optarg); } /* PCO DNS Server 1. */ else if (strcmp (long_options[option_index].name, "pcodns1") == 0) { - if (args_info->pcodns1_given) + if (local_args_info.pcodns1_given) { - fprintf (stderr, "%s: `--pcodns1' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pcodns1' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pcodns1_given && ! override) + continue; + local_args_info.pcodns1_given = 1; args_info->pcodns1_given = 1; - args_info->pcodns1_arg = strdup (optarg); - break; + if (args_info->pcodns1_arg) + free (args_info->pcodns1_arg); /* free previous string */ + args_info->pcodns1_arg = gengetopt_strdup (optarg); + if (args_info->pcodns1_orig) + free (args_info->pcodns1_orig); /* free previous string */ + args_info->pcodns1_orig = gengetopt_strdup (optarg); } /* PCO DNS Server 2. */ else if (strcmp (long_options[option_index].name, "pcodns2") == 0) { - if (args_info->pcodns2_given) + if (local_args_info.pcodns2_given) { - fprintf (stderr, "%s: `--pcodns2' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pcodns2' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pcodns2_given && ! override) + continue; + local_args_info.pcodns2_given = 1; args_info->pcodns2_given = 1; - args_info->pcodns2_arg = strdup (optarg); - break; + if (args_info->pcodns2_arg) + free (args_info->pcodns2_arg); /* free previous string */ + args_info->pcodns2_arg = gengetopt_strdup (optarg); + if (args_info->pcodns2_orig) + free (args_info->pcodns2_orig); /* free previous string */ + args_info->pcodns2_orig = gengetopt_strdup (optarg); } /* Exit after timelimit seconds. */ else if (strcmp (long_options[option_index].name, "timelimit") == 0) { - if (args_info->timelimit_given) + if (local_args_info.timelimit_given) { - fprintf (stderr, "%s: `--timelimit' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--timelimit' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->timelimit_given && ! override) + continue; + local_args_info.timelimit_given = 1; args_info->timelimit_given = 1; - args_info->timelimit_arg = strtol (optarg,&stop_char,0); - break; + args_info->timelimit_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->timelimit_orig) + free (args_info->timelimit_orig); /* free previous string */ + args_info->timelimit_orig = gengetopt_strdup (optarg); } - + + break; case '?': /* Invalid option. */ /* `getopt_long' already printed an error message. */ - exit (EXIT_FAILURE); + goto failure; default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c\n", PACKAGE, c); + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); abort (); } /* switch */ } /* while */ - if ( missing_required_options ) - exit (EXIT_FAILURE); + + + cmdline_parser_release (&local_args_info); + + if ( error ) + return (EXIT_FAILURE); return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); } -#define CONFIGPARSERBUFSIZE 1024 +#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 "=" */ + +char my_argv[CONFIG_FILE_LINE_BUFFER_SIZE+1]; int -cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override) +cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) { FILE* file; - char linebuf[CONFIGPARSERBUFSIZE]; + char linebuf[CONFIG_FILE_LINE_SIZE]; int line_num = 0; - int len; - int fnum; - char fopt[CONFIGPARSERBUFSIZE], farg[CONFIGPARSERBUFSIZE]; - char *stop_char; + int i, result, equal; + char *fopt, *farg; + char *str_index; + size_t len, next_token; + char delimiter; + int my_argc = 0; + 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); if ((file = fopen(filename, "r")) == NULL) { fprintf (stderr, "%s: Error opening configuration file '%s'\n", - PACKAGE, filename); - exit (EXIT_FAILURE); + CMDLINE_PARSER_PACKAGE, filename); + result = EXIT_FAILURE; + goto conf_failure; } - while ((fgets(linebuf, CONFIGPARSERBUFSIZE, file)) != NULL) + while ((fgets(linebuf, CONFIG_FILE_LINE_SIZE, file)) != NULL) { ++line_num; + my_argv[0] = '\0'; len = strlen(linebuf); - if (len == CONFIGPARSERBUFSIZE-1) + if (len > (CONFIG_FILE_LINE_BUFFER_SIZE-1)) { - fprintf (stderr, "%s: Line longer than %d characters found in configuration file '%s'\n", - PACKAGE, CONFIGPARSERBUFSIZE, filename); - exit (EXIT_FAILURE); + fprintf (stderr, "%s:%s:%d: Line too long in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + goto conf_failure; } - if (linebuf[0] == '#') - continue; /* Line was a comment */ - - /* Get the option */ - if ((fnum = sscanf(linebuf, "%s %s", fopt, farg)) > 0) + /* 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 */ { - if (!strcmp(fopt, "help")) - { - if (override || !args_info->help_given) - { - args_info->help_given = 1; - - } - continue; - } - if (!strcmp(fopt, "version")) - { - if (override || !args_info->version_given) - { - args_info->version_given = 1; - - } - continue; - } - if (!strcmp(fopt, "fg")) - { - if (override || !args_info->fg_given) - { - args_info->fg_given = 1; - args_info->fg_flag = !(args_info->fg_flag); - } - continue; - } - if (!strcmp(fopt, "debug")) - { - if (override || !args_info->debug_given) - { - args_info->debug_given = 1; - args_info->debug_flag = !(args_info->debug_flag); - } - continue; - } - if (!strcmp(fopt, "conf")) - { - if (override || !args_info->conf_given) - { - args_info->conf_given = 1; - if (fnum == 2) - args_info->conf_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pidfile")) - { - if (override || !args_info->pidfile_given) - { - args_info->pidfile_given = 1; - if (fnum == 2) - args_info->pidfile_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "statedir")) - { - if (override || !args_info->statedir_given) - { - args_info->statedir_given = 1; - if (fnum == 2) - args_info->statedir_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "listen")) - { - if (override || !args_info->listen_given) - { - args_info->listen_given = 1; - if (fnum == 2) - args_info->listen_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "net")) - { - if (override || !args_info->net_given) - { - args_info->net_given = 1; - if (fnum == 2) - args_info->net_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "ipup")) - { - if (override || !args_info->ipup_given) - { - args_info->ipup_given = 1; - if (fnum == 2) - args_info->ipup_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "ipdown")) - { - if (override || !args_info->ipdown_given) - { - args_info->ipdown_given = 1; - if (fnum == 2) - args_info->ipdown_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "dynip")) - { - if (override || !args_info->dynip_given) - { - args_info->dynip_given = 1; - if (fnum == 2) - args_info->dynip_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "statip")) - { - if (override || !args_info->statip_given) - { - args_info->statip_given = 1; - if (fnum == 2) - args_info->statip_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pcodns1")) - { - if (override || !args_info->pcodns1_given) - { - args_info->pcodns1_given = 1; - if (fnum == 2) - args_info->pcodns1_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pcodns2")) - { - if (override || !args_info->pcodns2_given) - { - args_info->pcodns2_given = 1; - if (fnum == 2) - args_info->pcodns2_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "timelimit")) - { - if (override || !args_info->timelimit_given) - { - args_info->timelimit_given = 1; - if (fnum == 2) - args_info->timelimit_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "apn")) + farg = NULL; + 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) { - if (override || !args_info->apn_given) - { - args_info->apn_given = 1; - if (fnum == 2) - args_info->apn_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; + fprintf + (stderr, + "%s:%s:%d: unterminated string in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + goto conf_failure; } - if (!strcmp(fopt, "qos")) + } + 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 != '#') { - if (override || !args_info->qos_given) - { - args_info->qos_given = 1; - if (fnum == 2) - args_info->qos_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; + fprintf + (stderr, + "%s:%s:%d: malformed string in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + goto conf_failure; } - - - /* Tried all known options. This one is unknown! */ - fprintf (stderr, "%s: Unknown option '%s' found in %s\n", - PACKAGE, fopt, filename); - exit (EXIT_FAILURE); } + + noarg: + ++my_argc; + 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); + + 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 */ - fclose(file); /* No error checking on close */ - return 0; + ++my_argc; /* for program name */ + 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, override, initialize, check_required, additional_error); + + free (additional_error); + free (my_argv_arg); + +conf_failure: + if (file) + fclose(file); + + free_cmd_list(); + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; } diff --git a/ggsn/cmdline.h b/ggsn/cmdline.h index f083dbe..d9e3086 100644 --- a/ggsn/cmdline.h +++ b/ggsn/cmdline.h @@ -1,42 +1,78 @@ /* cmdline.h */ -/* File autogenerated by gengetopt version 2.8 */ +/* File autogenerated by gengetopt version 2.17 */ -#ifndef _cmdline_h -#define _cmdline_h +#ifndef CMDLINE_H +#define CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -/* Don't define PACKAGE and VERSION if we use automake. */ -#ifndef PACKAGE -#define PACKAGE "" +#ifndef CMDLINE_PARSER_PACKAGE +#define CMDLINE_PARSER_PACKAGE PACKAGE #endif -#ifndef VERSION -#define VERSION "" +#ifndef CMDLINE_PARSER_VERSION +#define CMDLINE_PARSER_VERSION VERSION #endif struct gengetopt_args_info { + const char *help_help; /* Print help and exit help description. */ + const char *version_help; /* Print version and exit help description. */ int fg_flag; /* Run in foreground (default=off). */ + const char *fg_help; /* Run in foreground help description. */ int debug_flag; /* Run in debug mode (default=off). */ + const char *debug_help; /* Run in debug mode help description. */ char * conf_arg; /* Read configuration file (default='/etc/ggsn.conf'). */ + char * conf_orig; /* Read configuration file original value given at command line. */ + const char *conf_help; /* Read configuration file help description. */ char * pidfile_arg; /* Filename of process id file (default='/var/run/ggsn.pid'). */ + char * pidfile_orig; /* Filename of process id file original value given at command line. */ + const char *pidfile_help; /* Filename of process id file help description. */ char * statedir_arg; /* Directory of nonvolatile data (default='/var/lib/ggsn/'). */ + char * statedir_orig; /* Directory of nonvolatile data original value given at command line. */ + const char *statedir_help; /* Directory of nonvolatile data help description. */ char * listen_arg; /* Local interface. */ + char * listen_orig; /* Local interface original value given at command line. */ + const char *listen_help; /* Local interface help description. */ char * net_arg; /* Network (default='192.168.0.0/24'). */ + char * net_orig; /* Network original value given at command line. */ + const char *net_help; /* Network help description. */ char * ipup_arg; /* Script to run after link-up. */ + char * ipup_orig; /* Script to run after link-up original value given at command line. */ + const char *ipup_help; /* Script to run after link-up help description. */ char * ipdown_arg; /* Script to run after link-down. */ + char * ipdown_orig; /* Script to run after link-down original value given at command line. */ + const char *ipdown_help; /* Script to run after link-down help description. */ char * dynip_arg; /* Dynamic IP address pool. */ + char * dynip_orig; /* Dynamic IP address pool original value given at command line. */ + const char *dynip_help; /* Dynamic IP address pool help description. */ char * statip_arg; /* Static IP address pool. */ + char * statip_orig; /* Static IP address pool original value given at command line. */ + const char *statip_help; /* Static IP address pool help description. */ char * pcodns1_arg; /* PCO DNS Server 1 (default='0.0.0.0'). */ + char * pcodns1_orig; /* PCO DNS Server 1 original value given at command line. */ + const char *pcodns1_help; /* PCO DNS Server 1 help description. */ char * pcodns2_arg; /* PCO DNS Server 2 (default='0.0.0.0'). */ + char * pcodns2_orig; /* PCO DNS Server 2 original value given at command line. */ + const char *pcodns2_help; /* PCO DNS Server 2 help description. */ int timelimit_arg; /* Exit after timelimit seconds (default='0'). */ + char * timelimit_orig; /* Exit after timelimit seconds original value given at command line. */ + const char *timelimit_help; /* Exit after timelimit seconds help description. */ char * apn_arg; /* Access point name (default='internet'). */ + char * apn_orig; /* Access point name original value given at command line. */ + const char *apn_help; /* Access point name help description. */ int qos_arg; /* Requested quality of service (default='0x0b921f'). */ - + char * qos_orig; /* Requested quality of service original value given at command line. */ + const char *qos_help; /* Requested quality of service help description. */ + int help_given ; /* Whether help was given. */ int version_given ; /* Whether version was given. */ int fg_given ; /* Whether fg was given. */ @@ -58,14 +94,33 @@ struct gengetopt_args_info } ; -int cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info); +extern const char *gengetopt_args_info_purpose; +extern const char *gengetopt_args_info_usage; +extern const char *gengetopt_args_info_help[]; + +int cmdline_parser (int argc, char * const *argv, + struct gengetopt_args_info *args_info); +int cmdline_parser2 (int argc, char * const *argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); void cmdline_parser_print_help(void); void cmdline_parser_print_version(void); -int cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override); +void cmdline_parser_init (struct gengetopt_args_info *args_info); +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +int cmdline_parser_configfile (char * const filename, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* _cmdline_h */ +#endif /* CMDLINE_H */ diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index 5f120f3..52a2022 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -261,7 +261,7 @@ int main(int argc, char **argv) /* Try out our new parser */ - if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0) != 0) + if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0, 0, 0) != 0) exit(1); if (args_info.debug_flag) { printf("cmdline_parser_configfile\n"); @@ -532,6 +532,7 @@ int main(int argc, char **argv) } + cmdline_parser_free(&args_info); ippool_free(ippool); gtp_free(gsn); tun_free(tun); diff --git a/sgsnemu/cmdline.c b/sgsnemu/cmdline.c index 08582c9..0bf6332 100644 --- a/sgsnemu/cmdline.c +++ b/sgsnemu/cmdline.c @@ -1,5 +1,5 @@ /* - File autogenerated by gengetopt version 2.8 + File autogenerated by gengetopt version 2.17 generated with the following command: gengetopt --conf-parser @@ -8,94 +8,97 @@ we make no copyright claims on it. */ - -#include -#include -#include /* If we use autoconf. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -/* Check for configure's getopt check result. */ -#ifndef HAVE_GETOPT_LONG -#include "getopt.h" -#else -#include -#endif -#ifndef HAVE_STRDUP -#define strdup gengetopt_strdup -#endif /* HAVE_STRDUP */ +#include +#include +#include + +#include "getopt.h" #include "cmdline.h" +const char *gengetopt_args_info_purpose = ""; -void -cmdline_parser_print_version (void) +const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [OPTIONS]..."; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -d, --debug Run in debug mode (default=off)", + " -c, --conf=STRING Read configuration file", + " --pidfile=STRING Filename of process id file (default=`./sgsnemu.pid')", + " --statedir=STRING Directory of nonvolatile data (default=`./')", + " --dns=STRING DNS Server to use", + " -l, --listen=STRING Local interface", + " -r, --remote=STRING Remote host", + " --contexts=INT Number of contexts (default=`1')", + " --timelimit=INT Exit after timelimit seconds (default=`0')", + " --gtpversion=INT GTP version to use (default=`1')", + " -a, --apn=STRING Access point name (default=`internet')", + " --selmode=INT Selection mode (default=`0x01')", + " -i, --imsi=STRING IMSI (default=`240010123456789')", + " --nsapi=INT NSAPI (default=`0')", + " -m, --msisdn=STRING Mobile Station ISDN number (default=`46702123456')", + " -q, --qos=INT Requested quality of service (default=`0x0b921f')", + " --charging=INT Charging characteristics (default=`0x0800')", + " -u, --uid=STRING Login user ID (default=`mig')", + " -p, --pwd=STRING Login password (default=`hemmelig')", + " --createif Create local network interface (default=off)", + " -n, --net=STRING Network address for local interface", + " --defaultroute Create default route (default=off)", + " --ipup=STRING Script to run after link-up", + " --ipdown=STRING Script to run after link-down", + " --pinghost=STRING Ping remote host", + " --pingrate=INT Number of ping req per second (default=`1')", + " --pingsize=INT Number of ping data bytes (default=`56')", + " --pingcount=INT Number of ping req to send (default=`0')", + " --pingquiet Do not print ping packet info (default=off)", + 0 +}; + +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 * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error); + +struct line_list { - printf ("%s %s\n", PACKAGE, VERSION); -} + char * string_arg; + struct line_list * next; +}; -void -cmdline_parser_print_help (void) +static struct line_list *cmd_line_list = 0; +static struct line_list *cmd_line_list_tmp = 0; + +static void +free_cmd_list(void) { - cmdline_parser_print_version (); - printf("\n" - "Usage: %s [OPTIONS]...\n", PACKAGE); - printf(" -h --help Print help and exit\n"); - printf(" -V --version Print version and exit\n"); - printf(" -d --debug Run in debug mode (default=off)\n"); - printf(" -cSTRING --conf=STRING Read configuration file\n"); - printf(" --pidfile=STRING Filename of process id file (default='./sgsnemu.pid')\n"); - printf(" --statedir=STRING Directory of nonvolatile data (default='./')\n"); - printf(" --dns=STRING DNS Server to use\n"); - printf(" -lSTRING --listen=STRING Local interface\n"); - printf(" -rSTRING --remote=STRING Remote host\n"); - printf(" --contexts=INT Number of contexts (default='1')\n"); - printf(" --timelimit=INT Exit after timelimit seconds (default='0')\n"); - printf(" --gtpversion=INT GTP version to use (default='1')\n"); - printf(" -aSTRING --apn=STRING Access point name (default='internet')\n"); - printf(" --selmode=INT Selection mode (default='0x01')\n"); - printf(" -iSTRING --imsi=STRING IMSI (default='240010123456789')\n"); - printf(" --nsapi=INT NSAPI (default='0')\n"); - printf(" -mSTRING --msisdn=STRING Mobile Station ISDN number (default='46702123456')\n"); - printf(" -qINT --qos=INT Requested quality of service (default='0x0b921f')\n"); - printf(" --charging=INT Charging characteristics (default='0x0800')\n"); - printf(" -uSTRING --uid=STRING Login user ID (default='mig')\n"); - printf(" -pSTRING --pwd=STRING Login password (default='hemmelig')\n"); - printf(" --createif Create local network interface (default=off)\n"); - printf(" -nSTRING --net=STRING Network address for local interface\n"); - printf(" --defaultroute Create default route (default=off)\n"); - printf(" --ipup=STRING Script to run after link-up\n"); - printf(" --ipdown=STRING Script to run after link-down\n"); - printf(" --pinghost=STRING Ping remote host\n"); - printf(" --pingrate=INT Number of ping req per second (default='1')\n"); - printf(" --pingsize=INT Number of ping data bytes (default='56')\n"); - printf(" --pingcount=INT Number of ping req to send (default='0')\n"); - printf(" --pingquiet Do not print ping packet info (default=off)\n"); + /* 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); + } + } } -#ifndef HAVE_STRDUP -/* gengetopt_strdup(): automatically generated from strdup.c. */ -/* strdup.c replacement of strdup, which is not standard */ static char * -gengetopt_strdup (const char *s) -{ - char *result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} -#endif /* HAVE_STRDUP */ +gengetopt_strdup (const char *s); -int -cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) +static +void clear_given (struct gengetopt_args_info *args_info) { - int c; /* Character of the parsed option. */ - int missing_required_options = 0; - args_info->help_given = 0 ; args_info->version_given = 0 ; args_info->debug_given = 0 ; @@ -127,42 +130,621 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i args_info->pingsize_given = 0 ; args_info->pingcount_given = 0 ; args_info->pingquiet_given = 0 ; -#define clear_args() { \ - args_info->debug_flag = 0;\ - args_info->conf_arg = NULL; \ - args_info->pidfile_arg = strdup("./sgsnemu.pid") ;\ - args_info->statedir_arg = strdup("./") ;\ - args_info->dns_arg = NULL; \ - args_info->listen_arg = NULL; \ - args_info->remote_arg = NULL; \ - args_info->contexts_arg = 1 ;\ - args_info->timelimit_arg = 0 ;\ - args_info->gtpversion_arg = 1 ;\ - args_info->apn_arg = strdup("internet") ;\ - args_info->selmode_arg = 0x01 ;\ - args_info->imsi_arg = strdup("240010123456789") ;\ - args_info->nsapi_arg = 0 ;\ - args_info->msisdn_arg = strdup("46702123456") ;\ - args_info->qos_arg = 0x0b921f ;\ - args_info->charging_arg = 0x0800 ;\ - args_info->uid_arg = strdup("mig") ;\ - args_info->pwd_arg = strdup("hemmelig") ;\ - args_info->createif_flag = 0;\ - args_info->net_arg = NULL; \ - args_info->defaultroute_flag = 0;\ - args_info->ipup_arg = NULL; \ - args_info->ipdown_arg = NULL; \ - args_info->pinghost_arg = NULL; \ - args_info->pingrate_arg = 1 ;\ - args_info->pingsize_arg = 56 ;\ - args_info->pingcount_arg = 0 ;\ - args_info->pingquiet_flag = 0;\ } - clear_args(); +static +void clear_args (struct gengetopt_args_info *args_info) +{ + args_info->debug_flag = 0; + args_info->conf_arg = NULL; + args_info->conf_orig = NULL; + args_info->pidfile_arg = gengetopt_strdup ("./sgsnemu.pid"); + args_info->pidfile_orig = NULL; + args_info->statedir_arg = gengetopt_strdup ("./"); + args_info->statedir_orig = NULL; + args_info->dns_arg = NULL; + args_info->dns_orig = NULL; + args_info->listen_arg = NULL; + args_info->listen_orig = NULL; + args_info->remote_arg = NULL; + args_info->remote_orig = NULL; + args_info->contexts_arg = 1; + args_info->contexts_orig = NULL; + args_info->timelimit_arg = 0; + args_info->timelimit_orig = NULL; + args_info->gtpversion_arg = 1; + args_info->gtpversion_orig = NULL; + args_info->apn_arg = gengetopt_strdup ("internet"); + args_info->apn_orig = NULL; + args_info->selmode_arg = 0x01; + args_info->selmode_orig = NULL; + args_info->imsi_arg = gengetopt_strdup ("240010123456789"); + args_info->imsi_orig = NULL; + args_info->nsapi_arg = 0; + args_info->nsapi_orig = NULL; + args_info->msisdn_arg = gengetopt_strdup ("46702123456"); + args_info->msisdn_orig = NULL; + args_info->qos_arg = 0x0b921f; + args_info->qos_orig = NULL; + args_info->charging_arg = 0x0800; + args_info->charging_orig = NULL; + args_info->uid_arg = gengetopt_strdup ("mig"); + args_info->uid_orig = NULL; + args_info->pwd_arg = gengetopt_strdup ("hemmelig"); + args_info->pwd_orig = NULL; + args_info->createif_flag = 0; + args_info->net_arg = NULL; + args_info->net_orig = NULL; + args_info->defaultroute_flag = 0; + args_info->ipup_arg = NULL; + args_info->ipup_orig = NULL; + args_info->ipdown_arg = NULL; + args_info->ipdown_orig = NULL; + args_info->pinghost_arg = NULL; + args_info->pinghost_orig = NULL; + args_info->pingrate_arg = 1; + args_info->pingrate_orig = NULL; + args_info->pingsize_arg = 56; + args_info->pingsize_orig = NULL; + args_info->pingcount_arg = 0; + args_info->pingcount_orig = NULL; + args_info->pingquiet_flag = 0; + +} + +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->debug_help = gengetopt_args_info_help[2] ; + args_info->conf_help = gengetopt_args_info_help[3] ; + args_info->pidfile_help = gengetopt_args_info_help[4] ; + args_info->statedir_help = gengetopt_args_info_help[5] ; + args_info->dns_help = gengetopt_args_info_help[6] ; + args_info->listen_help = gengetopt_args_info_help[7] ; + args_info->remote_help = gengetopt_args_info_help[8] ; + args_info->contexts_help = gengetopt_args_info_help[9] ; + args_info->timelimit_help = gengetopt_args_info_help[10] ; + args_info->gtpversion_help = gengetopt_args_info_help[11] ; + args_info->apn_help = gengetopt_args_info_help[12] ; + args_info->selmode_help = gengetopt_args_info_help[13] ; + args_info->imsi_help = gengetopt_args_info_help[14] ; + args_info->nsapi_help = gengetopt_args_info_help[15] ; + args_info->msisdn_help = gengetopt_args_info_help[16] ; + args_info->qos_help = gengetopt_args_info_help[17] ; + args_info->charging_help = gengetopt_args_info_help[18] ; + args_info->uid_help = gengetopt_args_info_help[19] ; + args_info->pwd_help = gengetopt_args_info_help[20] ; + args_info->createif_help = gengetopt_args_info_help[21] ; + args_info->net_help = gengetopt_args_info_help[22] ; + args_info->defaultroute_help = gengetopt_args_info_help[23] ; + args_info->ipup_help = gengetopt_args_info_help[24] ; + args_info->ipdown_help = gengetopt_args_info_help[25] ; + args_info->pinghost_help = gengetopt_args_info_help[26] ; + args_info->pingrate_help = gengetopt_args_info_help[27] ; + args_info->pingsize_help = gengetopt_args_info_help[28] ; + args_info->pingcount_help = gengetopt_args_info_help[29] ; + args_info->pingquiet_help = gengetopt_args_info_help[30] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", CMDLINE_PARSER_PACKAGE, CMDLINE_PARSER_VERSION); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + printf("\n%s\n\n", gengetopt_args_info_usage); + 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); +} + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + + if (args_info->conf_arg) + { + free (args_info->conf_arg); /* free previous argument */ + args_info->conf_arg = 0; + } + if (args_info->conf_orig) + { + free (args_info->conf_orig); /* free previous argument */ + args_info->conf_orig = 0; + } + if (args_info->pidfile_arg) + { + free (args_info->pidfile_arg); /* free previous argument */ + args_info->pidfile_arg = 0; + } + if (args_info->pidfile_orig) + { + free (args_info->pidfile_orig); /* free previous argument */ + args_info->pidfile_orig = 0; + } + if (args_info->statedir_arg) + { + free (args_info->statedir_arg); /* free previous argument */ + args_info->statedir_arg = 0; + } + if (args_info->statedir_orig) + { + free (args_info->statedir_orig); /* free previous argument */ + args_info->statedir_orig = 0; + } + if (args_info->dns_arg) + { + free (args_info->dns_arg); /* free previous argument */ + args_info->dns_arg = 0; + } + if (args_info->dns_orig) + { + free (args_info->dns_orig); /* free previous argument */ + args_info->dns_orig = 0; + } + if (args_info->listen_arg) + { + free (args_info->listen_arg); /* free previous argument */ + args_info->listen_arg = 0; + } + if (args_info->listen_orig) + { + free (args_info->listen_orig); /* free previous argument */ + args_info->listen_orig = 0; + } + if (args_info->remote_arg) + { + free (args_info->remote_arg); /* free previous argument */ + args_info->remote_arg = 0; + } + if (args_info->remote_orig) + { + free (args_info->remote_orig); /* free previous argument */ + args_info->remote_orig = 0; + } + if (args_info->contexts_orig) + { + free (args_info->contexts_orig); /* free previous argument */ + args_info->contexts_orig = 0; + } + if (args_info->timelimit_orig) + { + free (args_info->timelimit_orig); /* free previous argument */ + args_info->timelimit_orig = 0; + } + if (args_info->gtpversion_orig) + { + free (args_info->gtpversion_orig); /* free previous argument */ + args_info->gtpversion_orig = 0; + } + if (args_info->apn_arg) + { + free (args_info->apn_arg); /* free previous argument */ + args_info->apn_arg = 0; + } + if (args_info->apn_orig) + { + free (args_info->apn_orig); /* free previous argument */ + args_info->apn_orig = 0; + } + if (args_info->selmode_orig) + { + free (args_info->selmode_orig); /* free previous argument */ + args_info->selmode_orig = 0; + } + if (args_info->imsi_arg) + { + free (args_info->imsi_arg); /* free previous argument */ + args_info->imsi_arg = 0; + } + if (args_info->imsi_orig) + { + free (args_info->imsi_orig); /* free previous argument */ + args_info->imsi_orig = 0; + } + if (args_info->nsapi_orig) + { + free (args_info->nsapi_orig); /* free previous argument */ + args_info->nsapi_orig = 0; + } + if (args_info->msisdn_arg) + { + free (args_info->msisdn_arg); /* free previous argument */ + args_info->msisdn_arg = 0; + } + if (args_info->msisdn_orig) + { + free (args_info->msisdn_orig); /* free previous argument */ + args_info->msisdn_orig = 0; + } + if (args_info->qos_orig) + { + free (args_info->qos_orig); /* free previous argument */ + args_info->qos_orig = 0; + } + if (args_info->charging_orig) + { + free (args_info->charging_orig); /* free previous argument */ + args_info->charging_orig = 0; + } + if (args_info->uid_arg) + { + free (args_info->uid_arg); /* free previous argument */ + args_info->uid_arg = 0; + } + if (args_info->uid_orig) + { + free (args_info->uid_orig); /* free previous argument */ + args_info->uid_orig = 0; + } + if (args_info->pwd_arg) + { + free (args_info->pwd_arg); /* free previous argument */ + args_info->pwd_arg = 0; + } + if (args_info->pwd_orig) + { + free (args_info->pwd_orig); /* free previous argument */ + args_info->pwd_orig = 0; + } + if (args_info->net_arg) + { + free (args_info->net_arg); /* free previous argument */ + args_info->net_arg = 0; + } + if (args_info->net_orig) + { + free (args_info->net_orig); /* free previous argument */ + args_info->net_orig = 0; + } + if (args_info->ipup_arg) + { + free (args_info->ipup_arg); /* free previous argument */ + args_info->ipup_arg = 0; + } + if (args_info->ipup_orig) + { + free (args_info->ipup_orig); /* free previous argument */ + args_info->ipup_orig = 0; + } + if (args_info->ipdown_arg) + { + free (args_info->ipdown_arg); /* free previous argument */ + args_info->ipdown_arg = 0; + } + if (args_info->ipdown_orig) + { + free (args_info->ipdown_orig); /* free previous argument */ + args_info->ipdown_orig = 0; + } + if (args_info->pinghost_arg) + { + free (args_info->pinghost_arg); /* free previous argument */ + args_info->pinghost_arg = 0; + } + if (args_info->pinghost_orig) + { + free (args_info->pinghost_orig); /* free previous argument */ + args_info->pinghost_orig = 0; + } + if (args_info->pingrate_orig) + { + free (args_info->pingrate_orig); /* free previous argument */ + args_info->pingrate_orig = 0; + } + if (args_info->pingsize_orig) + { + free (args_info->pingsize_orig); /* free previous argument */ + args_info->pingsize_orig = 0; + } + if (args_info->pingcount_orig) + { + free (args_info->pingcount_orig); /* free previous argument */ + args_info->pingcount_orig = 0; + } + + clear_given (args_info); +} + +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; + } + + if (args_info->help_given) { + fprintf(outfile, "%s\n", "help"); + } + if (args_info->version_given) { + fprintf(outfile, "%s\n", "version"); + } + if (args_info->debug_given) { + fprintf(outfile, "%s\n", "debug"); + } + if (args_info->conf_given) { + if (args_info->conf_orig) { + fprintf(outfile, "%s=\"%s\"\n", "conf", args_info->conf_orig); + } else { + fprintf(outfile, "%s\n", "conf"); + } + } + if (args_info->pidfile_given) { + if (args_info->pidfile_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pidfile", args_info->pidfile_orig); + } else { + fprintf(outfile, "%s\n", "pidfile"); + } + } + if (args_info->statedir_given) { + if (args_info->statedir_orig) { + fprintf(outfile, "%s=\"%s\"\n", "statedir", args_info->statedir_orig); + } else { + fprintf(outfile, "%s\n", "statedir"); + } + } + if (args_info->dns_given) { + if (args_info->dns_orig) { + fprintf(outfile, "%s=\"%s\"\n", "dns", args_info->dns_orig); + } else { + fprintf(outfile, "%s\n", "dns"); + } + } + if (args_info->listen_given) { + if (args_info->listen_orig) { + fprintf(outfile, "%s=\"%s\"\n", "listen", args_info->listen_orig); + } else { + fprintf(outfile, "%s\n", "listen"); + } + } + if (args_info->remote_given) { + if (args_info->remote_orig) { + fprintf(outfile, "%s=\"%s\"\n", "remote", args_info->remote_orig); + } else { + fprintf(outfile, "%s\n", "remote"); + } + } + if (args_info->contexts_given) { + if (args_info->contexts_orig) { + fprintf(outfile, "%s=\"%s\"\n", "contexts", args_info->contexts_orig); + } else { + fprintf(outfile, "%s\n", "contexts"); + } + } + if (args_info->timelimit_given) { + if (args_info->timelimit_orig) { + fprintf(outfile, "%s=\"%s\"\n", "timelimit", args_info->timelimit_orig); + } else { + fprintf(outfile, "%s\n", "timelimit"); + } + } + if (args_info->gtpversion_given) { + if (args_info->gtpversion_orig) { + fprintf(outfile, "%s=\"%s\"\n", "gtpversion", args_info->gtpversion_orig); + } else { + fprintf(outfile, "%s\n", "gtpversion"); + } + } + if (args_info->apn_given) { + if (args_info->apn_orig) { + fprintf(outfile, "%s=\"%s\"\n", "apn", args_info->apn_orig); + } else { + fprintf(outfile, "%s\n", "apn"); + } + } + if (args_info->selmode_given) { + if (args_info->selmode_orig) { + fprintf(outfile, "%s=\"%s\"\n", "selmode", args_info->selmode_orig); + } else { + fprintf(outfile, "%s\n", "selmode"); + } + } + if (args_info->imsi_given) { + if (args_info->imsi_orig) { + fprintf(outfile, "%s=\"%s\"\n", "imsi", args_info->imsi_orig); + } else { + fprintf(outfile, "%s\n", "imsi"); + } + } + if (args_info->nsapi_given) { + if (args_info->nsapi_orig) { + fprintf(outfile, "%s=\"%s\"\n", "nsapi", args_info->nsapi_orig); + } else { + fprintf(outfile, "%s\n", "nsapi"); + } + } + if (args_info->msisdn_given) { + if (args_info->msisdn_orig) { + fprintf(outfile, "%s=\"%s\"\n", "msisdn", args_info->msisdn_orig); + } else { + fprintf(outfile, "%s\n", "msisdn"); + } + } + if (args_info->qos_given) { + if (args_info->qos_orig) { + fprintf(outfile, "%s=\"%s\"\n", "qos", args_info->qos_orig); + } else { + fprintf(outfile, "%s\n", "qos"); + } + } + if (args_info->charging_given) { + if (args_info->charging_orig) { + fprintf(outfile, "%s=\"%s\"\n", "charging", args_info->charging_orig); + } else { + fprintf(outfile, "%s\n", "charging"); + } + } + if (args_info->uid_given) { + if (args_info->uid_orig) { + fprintf(outfile, "%s=\"%s\"\n", "uid", args_info->uid_orig); + } else { + fprintf(outfile, "%s\n", "uid"); + } + } + if (args_info->pwd_given) { + if (args_info->pwd_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pwd", args_info->pwd_orig); + } else { + fprintf(outfile, "%s\n", "pwd"); + } + } + if (args_info->createif_given) { + fprintf(outfile, "%s\n", "createif"); + } + if (args_info->net_given) { + if (args_info->net_orig) { + fprintf(outfile, "%s=\"%s\"\n", "net", args_info->net_orig); + } else { + fprintf(outfile, "%s\n", "net"); + } + } + if (args_info->defaultroute_given) { + fprintf(outfile, "%s\n", "defaultroute"); + } + if (args_info->ipup_given) { + if (args_info->ipup_orig) { + fprintf(outfile, "%s=\"%s\"\n", "ipup", args_info->ipup_orig); + } else { + fprintf(outfile, "%s\n", "ipup"); + } + } + if (args_info->ipdown_given) { + if (args_info->ipdown_orig) { + fprintf(outfile, "%s=\"%s\"\n", "ipdown", args_info->ipdown_orig); + } else { + fprintf(outfile, "%s\n", "ipdown"); + } + } + if (args_info->pinghost_given) { + if (args_info->pinghost_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pinghost", args_info->pinghost_orig); + } else { + fprintf(outfile, "%s\n", "pinghost"); + } + } + if (args_info->pingrate_given) { + if (args_info->pingrate_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pingrate", args_info->pingrate_orig); + } else { + fprintf(outfile, "%s\n", "pingrate"); + } + } + if (args_info->pingsize_given) { + if (args_info->pingsize_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pingsize", args_info->pingsize_orig); + } else { + fprintf(outfile, "%s\n", "pingsize"); + } + } + if (args_info->pingcount_given) { + if (args_info->pingcount_orig) { + fprintf(outfile, "%s=\"%s\"\n", "pingcount", args_info->pingcount_orig); + } else { + fprintf(outfile, "%s\n", "pingcount"); + } + } + if (args_info->pingquiet_given) { + fprintf(outfile, "%s\n", "pingquiet"); + } + + fclose (outfile); + + i = EXIT_SUCCESS; + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + + +/* gengetopt_strdup() */ +/* strdup.c replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = NULL; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +int +cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + + result = cmdline_parser_internal (argc, argv, args_info, override, initialize, check_required, NULL); + + 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) +{ + return EXIT_SUCCESS; +} + +int +cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error = 0; + struct gengetopt_args_info local_args_info; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); optarg = 0; - optind = 1; + optind = 0; opterr = 1; optopt = '?'; @@ -170,6 +752,7 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i { int option_index = 0; char *stop_char; + static struct option long_options[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'V' }, @@ -205,6 +788,7 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i { NULL, 0, NULL, 0 } }; + stop_char = 0; c = getopt_long (argc, argv, "hVdc:l:r:a:i:m:q:u:p:n:", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ @@ -212,134 +796,208 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i switch (c) { case 'h': /* Print help and exit. */ - clear_args (); cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); exit (EXIT_SUCCESS); case 'V': /* Print version and exit. */ - clear_args (); cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); exit (EXIT_SUCCESS); case 'd': /* Run in debug mode. */ - if (args_info->debug_given) + if (local_args_info.debug_given) { - fprintf (stderr, "%s: `--debug' (`-d') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--debug' (`-d') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->debug_given && ! override) + continue; + local_args_info.debug_given = 1; args_info->debug_given = 1; args_info->debug_flag = !(args_info->debug_flag); break; case 'c': /* Read configuration file. */ - if (args_info->conf_given) + if (local_args_info.conf_given) { - fprintf (stderr, "%s: `--conf' (`-c') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--conf' (`-c') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->conf_given && ! override) + continue; + local_args_info.conf_given = 1; args_info->conf_given = 1; - args_info->conf_arg = strdup (optarg); + if (args_info->conf_arg) + free (args_info->conf_arg); /* free previous string */ + args_info->conf_arg = gengetopt_strdup (optarg); + if (args_info->conf_orig) + free (args_info->conf_orig); /* free previous string */ + args_info->conf_orig = gengetopt_strdup (optarg); break; case 'l': /* Local interface. */ - if (args_info->listen_given) + if (local_args_info.listen_given) { - fprintf (stderr, "%s: `--listen' (`-l') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--listen' (`-l') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->listen_given && ! override) + continue; + local_args_info.listen_given = 1; args_info->listen_given = 1; - args_info->listen_arg = strdup (optarg); + if (args_info->listen_arg) + free (args_info->listen_arg); /* free previous string */ + args_info->listen_arg = gengetopt_strdup (optarg); + if (args_info->listen_orig) + free (args_info->listen_orig); /* free previous string */ + args_info->listen_orig = gengetopt_strdup (optarg); break; case 'r': /* Remote host. */ - if (args_info->remote_given) + if (local_args_info.remote_given) { - fprintf (stderr, "%s: `--remote' (`-r') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--remote' (`-r') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->remote_given && ! override) + continue; + local_args_info.remote_given = 1; args_info->remote_given = 1; - args_info->remote_arg = strdup (optarg); + if (args_info->remote_arg) + free (args_info->remote_arg); /* free previous string */ + args_info->remote_arg = gengetopt_strdup (optarg); + if (args_info->remote_orig) + free (args_info->remote_orig); /* free previous string */ + args_info->remote_orig = gengetopt_strdup (optarg); break; case 'a': /* Access point name. */ - if (args_info->apn_given) + if (local_args_info.apn_given) { - fprintf (stderr, "%s: `--apn' (`-a') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--apn' (`-a') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->apn_given && ! override) + continue; + local_args_info.apn_given = 1; args_info->apn_given = 1; - args_info->apn_arg = strdup (optarg); + if (args_info->apn_arg) + free (args_info->apn_arg); /* free previous string */ + args_info->apn_arg = gengetopt_strdup (optarg); + if (args_info->apn_orig) + free (args_info->apn_orig); /* free previous string */ + args_info->apn_orig = gengetopt_strdup (optarg); break; case 'i': /* IMSI. */ - if (args_info->imsi_given) + if (local_args_info.imsi_given) { - fprintf (stderr, "%s: `--imsi' (`-i') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--imsi' (`-i') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->imsi_given && ! override) + continue; + local_args_info.imsi_given = 1; args_info->imsi_given = 1; - args_info->imsi_arg = strdup (optarg); + if (args_info->imsi_arg) + free (args_info->imsi_arg); /* free previous string */ + args_info->imsi_arg = gengetopt_strdup (optarg); + if (args_info->imsi_orig) + free (args_info->imsi_orig); /* free previous string */ + args_info->imsi_orig = gengetopt_strdup (optarg); break; case 'm': /* Mobile Station ISDN number. */ - if (args_info->msisdn_given) + if (local_args_info.msisdn_given) { - fprintf (stderr, "%s: `--msisdn' (`-m') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--msisdn' (`-m') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->msisdn_given && ! override) + continue; + local_args_info.msisdn_given = 1; args_info->msisdn_given = 1; - args_info->msisdn_arg = strdup (optarg); + if (args_info->msisdn_arg) + free (args_info->msisdn_arg); /* free previous string */ + args_info->msisdn_arg = gengetopt_strdup (optarg); + if (args_info->msisdn_orig) + free (args_info->msisdn_orig); /* free previous string */ + args_info->msisdn_orig = gengetopt_strdup (optarg); break; case 'q': /* Requested quality of service. */ - if (args_info->qos_given) + if (local_args_info.qos_given) { - fprintf (stderr, "%s: `--qos' (`-q') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--qos' (`-q') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->qos_given && ! override) + continue; + local_args_info.qos_given = 1; args_info->qos_given = 1; - args_info->qos_arg = strtol (optarg,&stop_char,0); + args_info->qos_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->qos_orig) + free (args_info->qos_orig); /* free previous string */ + args_info->qos_orig = gengetopt_strdup (optarg); break; case 'u': /* Login user ID. */ - if (args_info->uid_given) + if (local_args_info.uid_given) { - fprintf (stderr, "%s: `--uid' (`-u') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--uid' (`-u') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->uid_given && ! override) + continue; + local_args_info.uid_given = 1; args_info->uid_given = 1; - args_info->uid_arg = strdup (optarg); + if (args_info->uid_arg) + free (args_info->uid_arg); /* free previous string */ + args_info->uid_arg = gengetopt_strdup (optarg); + if (args_info->uid_orig) + free (args_info->uid_orig); /* free previous string */ + args_info->uid_orig = gengetopt_strdup (optarg); break; case 'p': /* Login password. */ - if (args_info->pwd_given) + if (local_args_info.pwd_given) { - fprintf (stderr, "%s: `--pwd' (`-p') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pwd' (`-p') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pwd_given && ! override) + continue; + local_args_info.pwd_given = 1; args_info->pwd_given = 1; - args_info->pwd_arg = strdup (optarg); + if (args_info->pwd_arg) + free (args_info->pwd_arg); /* free previous string */ + args_info->pwd_arg = gengetopt_strdup (optarg); + if (args_info->pwd_orig) + free (args_info->pwd_orig); /* free previous string */ + args_info->pwd_orig = gengetopt_strdup (optarg); break; case 'n': /* Network address for local interface. */ - if (args_info->net_given) + if (local_args_info.net_given) { - fprintf (stderr, "%s: `--net' (`-n') option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--net' (`-n') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->net_given && ! override) + continue; + local_args_info.net_given = 1; args_info->net_given = 1; - args_info->net_arg = strdup (optarg); + if (args_info->net_arg) + free (args_info->net_arg); /* free previous string */ + args_info->net_arg = gengetopt_strdup (optarg); + if (args_info->net_orig) + free (args_info->net_orig); /* free previous string */ + args_info->net_orig = gengetopt_strdup (optarg); break; @@ -347,755 +1005,546 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i /* Filename of process id file. */ if (strcmp (long_options[option_index].name, "pidfile") == 0) { - if (args_info->pidfile_given) + if (local_args_info.pidfile_given) { - fprintf (stderr, "%s: `--pidfile' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pidfile' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pidfile_given && ! override) + continue; + local_args_info.pidfile_given = 1; args_info->pidfile_given = 1; - args_info->pidfile_arg = strdup (optarg); - break; + if (args_info->pidfile_arg) + free (args_info->pidfile_arg); /* free previous string */ + args_info->pidfile_arg = gengetopt_strdup (optarg); + if (args_info->pidfile_orig) + free (args_info->pidfile_orig); /* free previous string */ + args_info->pidfile_orig = gengetopt_strdup (optarg); } /* Directory of nonvolatile data. */ else if (strcmp (long_options[option_index].name, "statedir") == 0) { - if (args_info->statedir_given) + if (local_args_info.statedir_given) { - fprintf (stderr, "%s: `--statedir' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--statedir' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->statedir_given && ! override) + continue; + local_args_info.statedir_given = 1; args_info->statedir_given = 1; - args_info->statedir_arg = strdup (optarg); - break; + if (args_info->statedir_arg) + free (args_info->statedir_arg); /* free previous string */ + args_info->statedir_arg = gengetopt_strdup (optarg); + if (args_info->statedir_orig) + free (args_info->statedir_orig); /* free previous string */ + args_info->statedir_orig = gengetopt_strdup (optarg); } /* DNS Server to use. */ else if (strcmp (long_options[option_index].name, "dns") == 0) { - if (args_info->dns_given) + if (local_args_info.dns_given) { - fprintf (stderr, "%s: `--dns' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--dns' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->dns_given && ! override) + continue; + local_args_info.dns_given = 1; args_info->dns_given = 1; - args_info->dns_arg = strdup (optarg); - break; + if (args_info->dns_arg) + free (args_info->dns_arg); /* free previous string */ + args_info->dns_arg = gengetopt_strdup (optarg); + if (args_info->dns_orig) + free (args_info->dns_orig); /* free previous string */ + args_info->dns_orig = gengetopt_strdup (optarg); } /* Number of contexts. */ else if (strcmp (long_options[option_index].name, "contexts") == 0) { - if (args_info->contexts_given) + if (local_args_info.contexts_given) { - fprintf (stderr, "%s: `--contexts' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--contexts' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->contexts_given && ! override) + continue; + local_args_info.contexts_given = 1; args_info->contexts_given = 1; - args_info->contexts_arg = strtol (optarg,&stop_char,0); - break; + args_info->contexts_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->contexts_orig) + free (args_info->contexts_orig); /* free previous string */ + args_info->contexts_orig = gengetopt_strdup (optarg); } /* Exit after timelimit seconds. */ else if (strcmp (long_options[option_index].name, "timelimit") == 0) { - if (args_info->timelimit_given) + if (local_args_info.timelimit_given) { - fprintf (stderr, "%s: `--timelimit' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--timelimit' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->timelimit_given && ! override) + continue; + local_args_info.timelimit_given = 1; args_info->timelimit_given = 1; - args_info->timelimit_arg = strtol (optarg,&stop_char,0); - break; + args_info->timelimit_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->timelimit_orig) + free (args_info->timelimit_orig); /* free previous string */ + args_info->timelimit_orig = gengetopt_strdup (optarg); } /* GTP version to use. */ else if (strcmp (long_options[option_index].name, "gtpversion") == 0) { - if (args_info->gtpversion_given) + if (local_args_info.gtpversion_given) { - fprintf (stderr, "%s: `--gtpversion' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--gtpversion' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->gtpversion_given && ! override) + continue; + local_args_info.gtpversion_given = 1; args_info->gtpversion_given = 1; - args_info->gtpversion_arg = strtol (optarg,&stop_char,0); - break; + args_info->gtpversion_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->gtpversion_orig) + free (args_info->gtpversion_orig); /* free previous string */ + args_info->gtpversion_orig = gengetopt_strdup (optarg); } /* Selection mode. */ else if (strcmp (long_options[option_index].name, "selmode") == 0) { - if (args_info->selmode_given) + if (local_args_info.selmode_given) { - fprintf (stderr, "%s: `--selmode' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--selmode' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->selmode_given && ! override) + continue; + local_args_info.selmode_given = 1; args_info->selmode_given = 1; - args_info->selmode_arg = strtol (optarg,&stop_char,0); - break; + args_info->selmode_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->selmode_orig) + free (args_info->selmode_orig); /* free previous string */ + args_info->selmode_orig = gengetopt_strdup (optarg); } /* NSAPI. */ else if (strcmp (long_options[option_index].name, "nsapi") == 0) { - if (args_info->nsapi_given) + if (local_args_info.nsapi_given) { - fprintf (stderr, "%s: `--nsapi' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--nsapi' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->nsapi_given && ! override) + continue; + local_args_info.nsapi_given = 1; args_info->nsapi_given = 1; - args_info->nsapi_arg = strtol (optarg,&stop_char,0); - break; + args_info->nsapi_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->nsapi_orig) + free (args_info->nsapi_orig); /* free previous string */ + args_info->nsapi_orig = gengetopt_strdup (optarg); } /* Charging characteristics. */ else if (strcmp (long_options[option_index].name, "charging") == 0) { - if (args_info->charging_given) + if (local_args_info.charging_given) { - fprintf (stderr, "%s: `--charging' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--charging' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->charging_given && ! override) + continue; + local_args_info.charging_given = 1; args_info->charging_given = 1; - args_info->charging_arg = strtol (optarg,&stop_char,0); - break; + args_info->charging_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->charging_orig) + free (args_info->charging_orig); /* free previous string */ + args_info->charging_orig = gengetopt_strdup (optarg); } /* Create local network interface. */ else if (strcmp (long_options[option_index].name, "createif") == 0) { - if (args_info->createif_given) + if (local_args_info.createif_given) { - fprintf (stderr, "%s: `--createif' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--createif' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->createif_given && ! override) + continue; + local_args_info.createif_given = 1; args_info->createif_given = 1; args_info->createif_flag = !(args_info->createif_flag); - break; } /* Create default route. */ else if (strcmp (long_options[option_index].name, "defaultroute") == 0) { - if (args_info->defaultroute_given) + if (local_args_info.defaultroute_given) { - fprintf (stderr, "%s: `--defaultroute' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--defaultroute' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->defaultroute_given && ! override) + continue; + local_args_info.defaultroute_given = 1; args_info->defaultroute_given = 1; args_info->defaultroute_flag = !(args_info->defaultroute_flag); - break; } /* Script to run after link-up. */ else if (strcmp (long_options[option_index].name, "ipup") == 0) { - if (args_info->ipup_given) + if (local_args_info.ipup_given) { - fprintf (stderr, "%s: `--ipup' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--ipup' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->ipup_given && ! override) + continue; + local_args_info.ipup_given = 1; args_info->ipup_given = 1; - args_info->ipup_arg = strdup (optarg); - break; + if (args_info->ipup_arg) + free (args_info->ipup_arg); /* free previous string */ + args_info->ipup_arg = gengetopt_strdup (optarg); + if (args_info->ipup_orig) + free (args_info->ipup_orig); /* free previous string */ + args_info->ipup_orig = gengetopt_strdup (optarg); } /* Script to run after link-down. */ else if (strcmp (long_options[option_index].name, "ipdown") == 0) { - if (args_info->ipdown_given) + if (local_args_info.ipdown_given) { - fprintf (stderr, "%s: `--ipdown' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--ipdown' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->ipdown_given && ! override) + continue; + local_args_info.ipdown_given = 1; args_info->ipdown_given = 1; - args_info->ipdown_arg = strdup (optarg); - break; + if (args_info->ipdown_arg) + free (args_info->ipdown_arg); /* free previous string */ + args_info->ipdown_arg = gengetopt_strdup (optarg); + if (args_info->ipdown_orig) + free (args_info->ipdown_orig); /* free previous string */ + args_info->ipdown_orig = gengetopt_strdup (optarg); } /* Ping remote host. */ else if (strcmp (long_options[option_index].name, "pinghost") == 0) { - if (args_info->pinghost_given) + if (local_args_info.pinghost_given) { - fprintf (stderr, "%s: `--pinghost' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pinghost' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pinghost_given && ! override) + continue; + local_args_info.pinghost_given = 1; args_info->pinghost_given = 1; - args_info->pinghost_arg = strdup (optarg); - break; + if (args_info->pinghost_arg) + free (args_info->pinghost_arg); /* free previous string */ + args_info->pinghost_arg = gengetopt_strdup (optarg); + if (args_info->pinghost_orig) + free (args_info->pinghost_orig); /* free previous string */ + args_info->pinghost_orig = gengetopt_strdup (optarg); } /* Number of ping req per second. */ else if (strcmp (long_options[option_index].name, "pingrate") == 0) { - if (args_info->pingrate_given) + if (local_args_info.pingrate_given) { - fprintf (stderr, "%s: `--pingrate' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pingrate' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pingrate_given && ! override) + continue; + local_args_info.pingrate_given = 1; args_info->pingrate_given = 1; - args_info->pingrate_arg = strtol (optarg,&stop_char,0); - break; + args_info->pingrate_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->pingrate_orig) + free (args_info->pingrate_orig); /* free previous string */ + args_info->pingrate_orig = gengetopt_strdup (optarg); } /* Number of ping data bytes. */ else if (strcmp (long_options[option_index].name, "pingsize") == 0) { - if (args_info->pingsize_given) + if (local_args_info.pingsize_given) { - fprintf (stderr, "%s: `--pingsize' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pingsize' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pingsize_given && ! override) + continue; + local_args_info.pingsize_given = 1; args_info->pingsize_given = 1; - args_info->pingsize_arg = strtol (optarg,&stop_char,0); - break; + args_info->pingsize_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->pingsize_orig) + free (args_info->pingsize_orig); /* free previous string */ + args_info->pingsize_orig = gengetopt_strdup (optarg); } /* Number of ping req to send. */ else if (strcmp (long_options[option_index].name, "pingcount") == 0) { - if (args_info->pingcount_given) + if (local_args_info.pingcount_given) { - fprintf (stderr, "%s: `--pingcount' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pingcount' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pingcount_given && ! override) + continue; + local_args_info.pingcount_given = 1; args_info->pingcount_given = 1; - args_info->pingcount_arg = strtol (optarg,&stop_char,0); - break; + args_info->pingcount_arg = strtol (optarg, &stop_char, 0); + if (!(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg); + goto failure; + } + if (args_info->pingcount_orig) + free (args_info->pingcount_orig); /* free previous string */ + args_info->pingcount_orig = gengetopt_strdup (optarg); } /* Do not print ping packet info. */ else if (strcmp (long_options[option_index].name, "pingquiet") == 0) { - if (args_info->pingquiet_given) + if (local_args_info.pingquiet_given) { - fprintf (stderr, "%s: `--pingquiet' option given more than once\n", PACKAGE); - clear_args (); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: `--pingquiet' option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; } + if (args_info->pingquiet_given && ! override) + continue; + local_args_info.pingquiet_given = 1; args_info->pingquiet_given = 1; args_info->pingquiet_flag = !(args_info->pingquiet_flag); - break; } - + + break; case '?': /* Invalid option. */ /* `getopt_long' already printed an error message. */ - exit (EXIT_FAILURE); + goto failure; default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c\n", PACKAGE, c); + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); abort (); } /* switch */ } /* while */ - if ( missing_required_options ) - exit (EXIT_FAILURE); + + + cmdline_parser_release (&local_args_info); + + if ( error ) + return (EXIT_FAILURE); return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); } -#define CONFIGPARSERBUFSIZE 1024 +#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 "=" */ + +char my_argv[CONFIG_FILE_LINE_BUFFER_SIZE+1]; int -cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override) +cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) { FILE* file; - char linebuf[CONFIGPARSERBUFSIZE]; + char linebuf[CONFIG_FILE_LINE_SIZE]; int line_num = 0; - int len; - int fnum; - char fopt[CONFIGPARSERBUFSIZE], farg[CONFIGPARSERBUFSIZE]; - char *stop_char; + int i, result, equal; + char *fopt, *farg; + char *str_index; + size_t len, next_token; + char delimiter; + int my_argc = 0; + 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); if ((file = fopen(filename, "r")) == NULL) { fprintf (stderr, "%s: Error opening configuration file '%s'\n", - PACKAGE, filename); - exit (EXIT_FAILURE); + CMDLINE_PARSER_PACKAGE, filename); + result = EXIT_FAILURE; + goto conf_failure; } - while ((fgets(linebuf, CONFIGPARSERBUFSIZE, file)) != NULL) + while ((fgets(linebuf, CONFIG_FILE_LINE_SIZE, file)) != NULL) { ++line_num; + my_argv[0] = '\0'; len = strlen(linebuf); - if (len == CONFIGPARSERBUFSIZE-1) + if (len > (CONFIG_FILE_LINE_BUFFER_SIZE-1)) { - fprintf (stderr, "%s: Line longer than %d characters found in configuration file '%s'\n", - PACKAGE, CONFIGPARSERBUFSIZE, filename); - exit (EXIT_FAILURE); + fprintf (stderr, "%s:%s:%d: Line too long in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + goto conf_failure; } - if (linebuf[0] == '#') - continue; /* Line was a comment */ - - /* Get the option */ - if ((fnum = sscanf(linebuf, "%s %s", fopt, farg)) > 0) + /* 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 */ { - if (!strcmp(fopt, "help")) - { - if (override || !args_info->help_given) - { - args_info->help_given = 1; - - } - continue; - } - if (!strcmp(fopt, "version")) - { - if (override || !args_info->version_given) - { - args_info->version_given = 1; - - } - continue; - } - if (!strcmp(fopt, "debug")) - { - if (override || !args_info->debug_given) - { - args_info->debug_given = 1; - args_info->debug_flag = !(args_info->debug_flag); - } - continue; - } - if (!strcmp(fopt, "conf")) - { - if (override || !args_info->conf_given) - { - args_info->conf_given = 1; - if (fnum == 2) - args_info->conf_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pidfile")) - { - if (override || !args_info->pidfile_given) - { - args_info->pidfile_given = 1; - if (fnum == 2) - args_info->pidfile_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "statedir")) - { - if (override || !args_info->statedir_given) - { - args_info->statedir_given = 1; - if (fnum == 2) - args_info->statedir_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "dns")) - { - if (override || !args_info->dns_given) - { - args_info->dns_given = 1; - if (fnum == 2) - args_info->dns_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "listen")) - { - if (override || !args_info->listen_given) - { - args_info->listen_given = 1; - if (fnum == 2) - args_info->listen_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "remote")) - { - if (override || !args_info->remote_given) - { - args_info->remote_given = 1; - if (fnum == 2) - args_info->remote_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "contexts")) - { - if (override || !args_info->contexts_given) - { - args_info->contexts_given = 1; - if (fnum == 2) - args_info->contexts_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "timelimit")) - { - if (override || !args_info->timelimit_given) - { - args_info->timelimit_given = 1; - if (fnum == 2) - args_info->timelimit_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "gtpversion")) - { - if (override || !args_info->gtpversion_given) - { - args_info->gtpversion_given = 1; - if (fnum == 2) - args_info->gtpversion_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "apn")) - { - if (override || !args_info->apn_given) - { - args_info->apn_given = 1; - if (fnum == 2) - args_info->apn_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "selmode")) - { - if (override || !args_info->selmode_given) - { - args_info->selmode_given = 1; - if (fnum == 2) - args_info->selmode_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "imsi")) - { - if (override || !args_info->imsi_given) - { - args_info->imsi_given = 1; - if (fnum == 2) - args_info->imsi_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "nsapi")) - { - if (override || !args_info->nsapi_given) - { - args_info->nsapi_given = 1; - if (fnum == 2) - args_info->nsapi_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "msisdn")) - { - if (override || !args_info->msisdn_given) - { - args_info->msisdn_given = 1; - if (fnum == 2) - args_info->msisdn_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "qos")) - { - if (override || !args_info->qos_given) - { - args_info->qos_given = 1; - if (fnum == 2) - args_info->qos_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "charging")) - { - if (override || !args_info->charging_given) - { - args_info->charging_given = 1; - if (fnum == 2) - args_info->charging_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "uid")) - { - if (override || !args_info->uid_given) - { - args_info->uid_given = 1; - if (fnum == 2) - args_info->uid_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pwd")) - { - if (override || !args_info->pwd_given) - { - args_info->pwd_given = 1; - if (fnum == 2) - args_info->pwd_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "createif")) - { - if (override || !args_info->createif_given) - { - args_info->createif_given = 1; - args_info->createif_flag = !(args_info->createif_flag); - } - continue; - } - if (!strcmp(fopt, "net")) - { - if (override || !args_info->net_given) - { - args_info->net_given = 1; - if (fnum == 2) - args_info->net_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "defaultroute")) - { - if (override || !args_info->defaultroute_given) - { - args_info->defaultroute_given = 1; - args_info->defaultroute_flag = !(args_info->defaultroute_flag); - } - continue; - } - if (!strcmp(fopt, "ipup")) - { - if (override || !args_info->ipup_given) - { - args_info->ipup_given = 1; - if (fnum == 2) - args_info->ipup_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "ipdown")) - { - if (override || !args_info->ipdown_given) - { - args_info->ipdown_given = 1; - if (fnum == 2) - args_info->ipdown_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pinghost")) - { - if (override || !args_info->pinghost_given) - { - args_info->pinghost_given = 1; - if (fnum == 2) - args_info->pinghost_arg = strdup (farg); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pingrate")) - { - if (override || !args_info->pingrate_given) - { - args_info->pingrate_given = 1; - if (fnum == 2) - args_info->pingrate_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pingsize")) - { - if (override || !args_info->pingsize_given) - { - args_info->pingsize_given = 1; - if (fnum == 2) - args_info->pingsize_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; - } - if (!strcmp(fopt, "pingcount")) + farg = NULL; + 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) { - if (override || !args_info->pingcount_given) - { - args_info->pingcount_given = 1; - if (fnum == 2) - args_info->pingcount_arg = strtol (farg,&stop_char,0); - else - { - fprintf (stderr, "%s:%d: required \n", - filename, line_num); - exit (EXIT_FAILURE); - } - } - continue; + fprintf + (stderr, + "%s:%s:%d: unterminated string in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + goto conf_failure; } - if (!strcmp(fopt, "pingquiet")) + } + 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 != '#') { - if (override || !args_info->pingquiet_given) - { - args_info->pingquiet_given = 1; - args_info->pingquiet_flag = !(args_info->pingquiet_flag); - } - continue; + fprintf + (stderr, + "%s:%s:%d: malformed string in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + goto conf_failure; } - - - /* Tried all known options. This one is unknown! */ - fprintf (stderr, "%s: Unknown option '%s' found in %s\n", - PACKAGE, fopt, filename); - exit (EXIT_FAILURE); } + + noarg: + ++my_argc; + 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); + + 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 */ - fclose(file); /* No error checking on close */ - return 0; + ++my_argc; /* for program name */ + 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, override, initialize, check_required, additional_error); + + free (additional_error); + free (my_argv_arg); + +conf_failure: + if (file) + fclose(file); + + free_cmd_list(); + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; } diff --git a/sgsnemu/cmdline.h b/sgsnemu/cmdline.h index 834d73c..a15480d 100644 --- a/sgsnemu/cmdline.h +++ b/sgsnemu/cmdline.h @@ -1,55 +1,115 @@ /* cmdline.h */ -/* File autogenerated by gengetopt version 2.8 */ +/* File autogenerated by gengetopt version 2.17 */ -#ifndef _cmdline_h -#define _cmdline_h +#ifndef CMDLINE_H +#define CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -/* Don't define PACKAGE and VERSION if we use automake. */ -#ifndef PACKAGE -#define PACKAGE "" +#ifndef CMDLINE_PARSER_PACKAGE +#define CMDLINE_PARSER_PACKAGE PACKAGE #endif -#ifndef VERSION -#define VERSION "" +#ifndef CMDLINE_PARSER_VERSION +#define CMDLINE_PARSER_VERSION VERSION #endif struct gengetopt_args_info { + const char *help_help; /* Print help and exit help description. */ + const char *version_help; /* Print version and exit help description. */ int debug_flag; /* Run in debug mode (default=off). */ + const char *debug_help; /* Run in debug mode help description. */ char * conf_arg; /* Read configuration file. */ + char * conf_orig; /* Read configuration file original value given at command line. */ + const char *conf_help; /* Read configuration file help description. */ char * pidfile_arg; /* Filename of process id file (default='./sgsnemu.pid'). */ + char * pidfile_orig; /* Filename of process id file original value given at command line. */ + const char *pidfile_help; /* Filename of process id file help description. */ char * statedir_arg; /* Directory of nonvolatile data (default='./'). */ + char * statedir_orig; /* Directory of nonvolatile data original value given at command line. */ + const char *statedir_help; /* Directory of nonvolatile data help description. */ char * dns_arg; /* DNS Server to use. */ + char * dns_orig; /* DNS Server to use original value given at command line. */ + const char *dns_help; /* DNS Server to use help description. */ char * listen_arg; /* Local interface. */ + char * listen_orig; /* Local interface original value given at command line. */ + const char *listen_help; /* Local interface help description. */ char * remote_arg; /* Remote host. */ + char * remote_orig; /* Remote host original value given at command line. */ + const char *remote_help; /* Remote host help description. */ int contexts_arg; /* Number of contexts (default='1'). */ + char * contexts_orig; /* Number of contexts original value given at command line. */ + const char *contexts_help; /* Number of contexts help description. */ int timelimit_arg; /* Exit after timelimit seconds (default='0'). */ + char * timelimit_orig; /* Exit after timelimit seconds original value given at command line. */ + const char *timelimit_help; /* Exit after timelimit seconds help description. */ int gtpversion_arg; /* GTP version to use (default='1'). */ + char * gtpversion_orig; /* GTP version to use original value given at command line. */ + const char *gtpversion_help; /* GTP version to use help description. */ char * apn_arg; /* Access point name (default='internet'). */ + char * apn_orig; /* Access point name original value given at command line. */ + const char *apn_help; /* Access point name help description. */ int selmode_arg; /* Selection mode (default='0x01'). */ + char * selmode_orig; /* Selection mode original value given at command line. */ + const char *selmode_help; /* Selection mode help description. */ char * imsi_arg; /* IMSI (default='240010123456789'). */ + char * imsi_orig; /* IMSI original value given at command line. */ + const char *imsi_help; /* IMSI help description. */ int nsapi_arg; /* NSAPI (default='0'). */ + char * nsapi_orig; /* NSAPI original value given at command line. */ + const char *nsapi_help; /* NSAPI help description. */ char * msisdn_arg; /* Mobile Station ISDN number (default='46702123456'). */ + char * msisdn_orig; /* Mobile Station ISDN number original value given at command line. */ + const char *msisdn_help; /* Mobile Station ISDN number help description. */ int qos_arg; /* Requested quality of service (default='0x0b921f'). */ + char * qos_orig; /* Requested quality of service original value given at command line. */ + const char *qos_help; /* Requested quality of service help description. */ int charging_arg; /* Charging characteristics (default='0x0800'). */ + char * charging_orig; /* Charging characteristics original value given at command line. */ + const char *charging_help; /* Charging characteristics help description. */ char * uid_arg; /* Login user ID (default='mig'). */ + char * uid_orig; /* Login user ID original value given at command line. */ + const char *uid_help; /* Login user ID help description. */ char * pwd_arg; /* Login password (default='hemmelig'). */ + char * pwd_orig; /* Login password original value given at command line. */ + const char *pwd_help; /* Login password help description. */ int createif_flag; /* Create local network interface (default=off). */ + const char *createif_help; /* Create local network interface help description. */ char * net_arg; /* Network address for local interface. */ + char * net_orig; /* Network address for local interface original value given at command line. */ + const char *net_help; /* Network address for local interface help description. */ int defaultroute_flag; /* Create default route (default=off). */ + const char *defaultroute_help; /* Create default route help description. */ char * ipup_arg; /* Script to run after link-up. */ + char * ipup_orig; /* Script to run after link-up original value given at command line. */ + const char *ipup_help; /* Script to run after link-up help description. */ char * ipdown_arg; /* Script to run after link-down. */ + char * ipdown_orig; /* Script to run after link-down original value given at command line. */ + const char *ipdown_help; /* Script to run after link-down help description. */ char * pinghost_arg; /* Ping remote host. */ - unsigned int pingrate_arg; /* Number of ping req per second (default='1'). */ - unsigned int pingsize_arg; /* Number of ping data bytes (default='56'). */ - unsigned int pingcount_arg; /* Number of ping req to send (default='0'). */ + char * pinghost_orig; /* Ping remote host original value given at command line. */ + const char *pinghost_help; /* Ping remote host help description. */ + int pingrate_arg; /* Number of ping req per second (default='1'). */ + char * pingrate_orig; /* Number of ping req per second original value given at command line. */ + const char *pingrate_help; /* Number of ping req per second help description. */ + int pingsize_arg; /* Number of ping data bytes (default='56'). */ + char * pingsize_orig; /* Number of ping data bytes original value given at command line. */ + const char *pingsize_help; /* Number of ping data bytes help description. */ + int pingcount_arg; /* Number of ping req to send (default='0'). */ + char * pingcount_orig; /* Number of ping req to send original value given at command line. */ + const char *pingcount_help; /* Number of ping req to send help description. */ int pingquiet_flag; /* Do not print ping packet info (default=off). */ - + const char *pingquiet_help; /* Do not print ping packet info help description. */ + int help_given ; /* Whether help was given. */ int version_given ; /* Whether version was given. */ int debug_given ; /* Whether debug was given. */ @@ -84,14 +144,33 @@ struct gengetopt_args_info } ; -int cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info); +extern const char *gengetopt_args_info_purpose; +extern const char *gengetopt_args_info_usage; +extern const char *gengetopt_args_info_help[]; + +int cmdline_parser (int argc, char * const *argv, + struct gengetopt_args_info *args_info); +int cmdline_parser2 (int argc, char * const *argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); void cmdline_parser_print_help(void); void cmdline_parser_print_version(void); -int cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override); +void cmdline_parser_init (struct gengetopt_args_info *args_info); +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +int cmdline_parser_configfile (char * const filename, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* _cmdline_h */ +#endif /* CMDLINE_H */ diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c index 7a3a700..9b5c2e2 100644 --- a/sgsnemu/sgsnemu.c +++ b/sgsnemu/sgsnemu.c @@ -245,7 +245,7 @@ int process_options(int argc, char **argv) { /* Try out our new parser */ if (args_info.conf_arg) { - if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0) != 0) + if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0, 0, 0) != 0) return -1; if (args_info.debug_flag) { printf("cmdline_parser_configfile\n"); -- cgit v1.2.3