agent: Fix segv running in --server mode
[gnupg.git] / common / argparse.c
index 2540894..331998b 100644 (file)
@@ -1,32 +1,23 @@
-/* [argparse.c wk 17.06.97] Argument Parser for option handling
- * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc.
+/* argparse.c - Argument Parser for option handling
  * Copyright (C) 1997-2001, 2006-2008, 2013-2017 Werner Koch
+ * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2015-2017 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
- * GnuPG is free software; you can redistribute and/or modify this
- * part of GnuPG under the terms of either
- *
- *   - the GNU Lesser General Public License as published by the Free
- *     Software Foundation; either version 3 of the License, or (at
- *     your option) any later version.
- *
- * or
- *
- *   - the GNU General Public License as published by the Free
- *     Software Foundation; either version 2 of the License, or (at
- *     your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
  *
- * or both in parallel, as here.
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * GnuPG is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copies of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, see <https://gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
  */
 
 /* This file may be used as part of GnuPG or standalone.  A GnuPG
@@ -71,7 +62,7 @@
 #else /* Used by GnuPG  */
 
 # define ARGPARSE_GPL_VERSION      3
-# define ARGPARSE_CRIGHT_STR "Copyright (C) 2017 Free Software Foundation, Inc."
+# define ARGPARSE_CRIGHT_STR "Copyright (C) 2018 Free Software Foundation, Inc."
 
 #endif /*GNUPG_MAJOR_VERSION*/
 
@@ -918,6 +909,46 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
   char *s, *s2;
   int i;
 
+  /* Fill in missing standard options: help, version, warranty and
+   * dump-options.  */
+  ARGPARSE_OPTS help_opt
+    = ARGPARSE_s_n (ARGPARSE_SHORTOPT_HELP, "help", "@");
+  ARGPARSE_OPTS version_opt
+    = ARGPARSE_s_n (ARGPARSE_SHORTOPT_VERSION, "version", "@");
+  ARGPARSE_OPTS warranty_opt
+    = ARGPARSE_s_n (ARGPARSE_SHORTOPT_WARRANTY, "warranty", "@");
+  ARGPARSE_OPTS dump_options_opt
+    = ARGPARSE_s_n(ARGPARSE_SHORTOPT_DUMP_OPTIONS, "dump-options", "@");
+  int seen_help = 0;
+  int seen_version = 0;
+  int seen_warranty = 0;
+  int seen_dump_options = 0;
+
+  i = 0;
+  while (opts[i].short_opt)
+    {
+      if (opts[i].long_opt)
+       {
+         if (!strcmp(opts[i].long_opt, help_opt.long_opt))
+           seen_help = 1;
+         else if (!strcmp(opts[i].long_opt, version_opt.long_opt))
+           seen_version = 1;
+         else if (!strcmp(opts[i].long_opt, warranty_opt.long_opt))
+           seen_warranty = 1;
+         else if (!strcmp(opts[i].long_opt, dump_options_opt.long_opt))
+           seen_dump_options = 1;
+       }
+      i++;
+    }
+  if (! seen_help)
+    opts[i++] = help_opt;
+  if (! seen_version)
+    opts[i++] = version_opt;
+  if (! seen_warranty)
+    opts[i++] = warranty_opt;
+  if (! seen_dump_options)
+    opts[i++] = dump_options_opt;
+
   initialize( arg, NULL, NULL );
   argc = *arg->argc;
   argv = *arg->argv;
@@ -974,9 +1005,9 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
       if ( argpos )
         *argpos = '=';
 
-      if ( i < 0 && !strcmp ( "help", s+2) )
+      if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_HELP)
         show_help (opts, arg->flags);
-      else if ( i < 0 && !strcmp ( "version", s+2) )
+      else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_VERSION)
         {
           if (!(arg->flags & ARGPARSE_FLAG_NOVERSION))
             {
@@ -984,20 +1015,18 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
               exit(0);
             }
        }
-      else if ( i < 0 && !strcmp( "warranty", s+2))
+      else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_WARRANTY)
         {
           writestrings (0, strusage (16), "\n", NULL);
           exit (0);
        }
-      else if ( i < 0 && !strcmp( "dump-options", s+2) )
+      else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_DUMP_OPTIONS)
         {
           for (i=0; opts[i].short_opt; i++ )
             {
               if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
                 writestrings (0, "--", opts[i].long_opt, "\n", NULL);
            }
-          writestrings (0, "--dump-options\n--help\n--version\n--warranty\n",
-                        NULL);
           exit (0);
        }