Use newer gengetopt which also frees memory

Taken from http://sourceforge.net/tracker/index.php?func=detail&aid=1811521&group_id=68956&atid=522957
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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 /* 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 <getopt.h>
-#endif
 
-#ifndef HAVE_STRDUP
-#define strdup gengetopt_strdup
-#endif /* HAVE_STRDUP */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "getopt.h"
 
 #include "cmdline.h"
 
+const char *gengetopt_args_info_purpose = "";
 
-void
-cmdline_parser_print_version (void)
-{
-  printf ("%s %s\n", PACKAGE, VERSION);
-}
+const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [OPTIONS]...";
 
-void
-cmdline_parser_print_help (void)
+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
 {
-  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");
+  char * string_arg;
+  struct line_list * next;
+};
+
+static struct line_list *cmd_line_list = 0;
+static struct line_list *cmd_line_list_tmp = 0;
+
+static void
+free_cmd_list(void)
+{
+  /* free the list of a previous call */
+  if (cmd_line_list)
+    {
+      while (cmd_line_list) {
+        cmd_line_list_tmp = cmd_line_list;
+        cmd_line_list = cmd_line_list->next;
+        free (cmd_line_list_tmp->string_arg);
+        free (cmd_line_list_tmp);
+      }
+    }
 }
 
 
-#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 @@
   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 @@
     {
       int option_index = 0;
       char *stop_char;
+
       static struct option long_options[] = {
         { "help",	0, NULL, 'h' },
         { "version",	0, NULL, 'V' },
@@ -153,6 +559,7 @@
         { 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 @@
       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 @@
           /* 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)
-        {
-          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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\n",
-                               filename, line_num);
-                      exit (EXIT_FAILURE);
-                    }
-                }
-              continue;
-            }
-          
+      /* find first non-whitespace character in the line */
+      next_token = strspn ( linebuf, " \t\r\n");
+      str_index  = linebuf + next_token;
 
-          /* Tried all known options. This one is unknown! */
-          fprintf (stderr, "%s: Unknown option '%s' found in %s\n",
-                   PACKAGE, fopt, filename);
-          exit (EXIT_FAILURE);
+      if ( str_index[0] == '\0' || str_index[0] == '#')
+        continue; /* empty line or comment line is skipped */
+
+      fopt = str_index;
+
+      /* truncate fopt at the end of the first non-valid character */
+      next_token = strcspn (fopt, " \t\r\n=");
+
+      if (fopt[next_token] == '\0') /* the line is over */
+        {
+          farg  = 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)
+            {
+              fprintf
+                (stderr,
+                 "%s:%s:%d: unterminated string in configuration file\n",
+                 CMDLINE_PARSER_PACKAGE, filename, line_num);
+              result = EXIT_FAILURE;
+              goto conf_failure;
+            }
+        }
+      else
+        { /* read up the remaining part up to a delimiter */
+          next_token = strcspn (farg, " \t\r\n#\'\"");
+          str_index += next_token;
+        }
+
+      /* truncate farg at the delimiter and store it for further check */
+      delimiter = *str_index, *str_index++ = '\0';
+
+      /* everything but comment is illegal at the end of line */
+      if (delimiter != '\0' && delimiter != '#')
+        {
+          str_index += strspn(str_index, " \t\r\n");
+          if (*str_index != '\0' && *str_index != '#')
+            {
+              fprintf
+                (stderr,
+                 "%s:%s:%d: malformed string in configuration file\n",
+                 CMDLINE_PARSER_PACKAGE, filename, line_num);
+              result = EXIT_FAILURE;
+              goto conf_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 @@
 
 } ;
 
-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 @@
 
   /* 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 @@
     
   }
 
+  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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 /* 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 <getopt.h>
-#endif
 
-#ifndef HAVE_STRDUP
-#define strdup gengetopt_strdup
-#endif /* HAVE_STRDUP */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "getopt.h"
 
 #include "cmdline.h"
 
+const char *gengetopt_args_info_purpose = "";
 
-void
-cmdline_parser_print_version (void)
-{
-  printf ("%s %s\n", PACKAGE, VERSION);
-}
+const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [OPTIONS]...";
 
-void
-cmdline_parser_print_help (void)
+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
 {
-  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");
+  char * string_arg;
+  struct line_list * next;
+};
+
+static struct line_list *cmd_line_list = 0;
+static struct line_list *cmd_line_list_tmp = 0;
+
+static void
+free_cmd_list(void)
+{
+  /* free the list of a previous call */
+  if (cmd_line_list)
+    {
+      while (cmd_line_list) {
+        cmd_line_list_tmp = cmd_line_list;
+        cmd_line_list = cmd_line_list->next;
+        free (cmd_line_list_tmp->string_arg);
+        free (cmd_line_list_tmp);
+      }
+    }
 }
 
 
-#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 @@
   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 @@
     {
       int option_index = 0;
       char *stop_char;
+
       static struct option long_options[] = {
         { "help",	0, NULL, 'h' },
         { "version",	0, NULL, 'V' },
@@ -205,6 +788,7 @@
         { 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 @@
       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 @@
           /* 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)
-        {
-          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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\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 <option_name> <option_val>\n",
-                               filename, line_num);
-                      exit (EXIT_FAILURE);
-                    }
-                }
-              continue;
-            }
-          if (!strcmp(fopt, "pingcount"))
-            {
-              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 <option_name> <option_val>\n",
-                               filename, line_num);
-                      exit (EXIT_FAILURE);
-                    }
-                }
-              continue;
-            }
-          if (!strcmp(fopt, "pingquiet"))
-            {
-              if (override || !args_info->pingquiet_given)
-                {
-                  args_info->pingquiet_given = 1;
-                  args_info->pingquiet_flag = !(args_info->pingquiet_flag);
-                }
-              continue;
-            }
-          
+      /* find first non-whitespace character in the line */
+      next_token = strspn ( linebuf, " \t\r\n");
+      str_index  = linebuf + next_token;
 
-          /* Tried all known options. This one is unknown! */
-          fprintf (stderr, "%s: Unknown option '%s' found in %s\n",
-                   PACKAGE, fopt, filename);
-          exit (EXIT_FAILURE);
+      if ( str_index[0] == '\0' || str_index[0] == '#')
+        continue; /* empty line or comment line is skipped */
+
+      fopt = str_index;
+
+      /* truncate fopt at the end of the first non-valid character */
+      next_token = strcspn (fopt, " \t\r\n=");
+
+      if (fopt[next_token] == '\0') /* the line is over */
+        {
+          farg  = 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)
+            {
+              fprintf
+                (stderr,
+                 "%s:%s:%d: unterminated string in configuration file\n",
+                 CMDLINE_PARSER_PACKAGE, filename, line_num);
+              result = EXIT_FAILURE;
+              goto conf_failure;
+            }
+        }
+      else
+        { /* read up the remaining part up to a delimiter */
+          next_token = strcspn (farg, " \t\r\n#\'\"");
+          str_index += next_token;
+        }
+
+      /* truncate farg at the delimiter and store it for further check */
+      delimiter = *str_index, *str_index++ = '\0';
+
+      /* everything but comment is illegal at the end of line */
+      if (delimiter != '\0' && delimiter != '#')
+        {
+          str_index += strspn(str_index, " \t\r\n");
+          if (*str_index != '\0' && *str_index != '#')
+            {
+              fprintf
+                (stderr,
+                 "%s:%s:%d: malformed string in configuration file\n",
+                 CMDLINE_PARSER_PACKAGE, filename, line_num);
+              result = EXIT_FAILURE;
+              goto conf_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 @@
 
 } ;
 
-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 @@
   /* 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");