agent: Avoid appending a '\0' byte to the response of READKEY
[gnupg.git] / tools / gpgtar.c
index 90fee05..2757ab0 100644 (file)
@@ -14,7 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 /* GnuPG comes with a shell script gpg-zip which creates archive files
    gpg.  So here we go.  */
 
 #include <config.h>
-#include <assuan.h>
 #include <ctype.h>
 #include <errno.h>
-#include <npth.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 
-#include "util.h"
-#include "i18n.h"
-#include "sysutils.h"
-#include "../common/asshelp.h"
+#include "../common/util.h"
+#include "../common/i18n.h"
+#include "../common/sysutils.h"
 #include "../common/openpgpdefs.h"
 #include "../common/init.h"
 #include "../common/strlist.h"
@@ -51,6 +48,8 @@
 enum cmd_and_opt_values
   {
     aNull = 0,
+    aCreate = 600,
+    aExtract,
     aEncrypt    = 'e',
     aDecrypt    = 'd',
     aSign       = 's',
@@ -77,6 +76,9 @@ enum cmd_and_opt_values
     /* Compatibility with gpg-zip.  */
     oGpgArgs,
     oTarArgs,
+
+    /* Debugging.  */
+    oDryRun,
   };
 
 
@@ -84,8 +86,10 @@ enum cmd_and_opt_values
 static ARGPARSE_OPTS opts[] = {
   ARGPARSE_group (300, N_("@Commands:\n ")),
 
-  ARGPARSE_c (aEncrypt,   "encrypt", N_("create an archive")),
-  ARGPARSE_c (aDecrypt,   "decrypt", N_("extract an archive")),
+  ARGPARSE_c (aCreate,    "create",  N_("create an archive")),
+  ARGPARSE_c (aExtract,   "extract", N_("extract an archive")),
+  ARGPARSE_c (aEncrypt,   "encrypt", N_("create an encrypted archive")),
+  ARGPARSE_c (aDecrypt,   "decrypt", N_("extract an encrypted archive")),
   ARGPARSE_c (aSign,      "sign",    N_("create a signed archive")),
   ARGPARSE_c (aList,      "list-archive", N_("list an archive")),
 
@@ -100,6 +104,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oQuiet,        "quiet",  N_("be somewhat more quiet")),
   ARGPARSE_s_s (oGpgProgram, "gpg", "@"),
   ARGPARSE_s_n (oSkipCrypto, "skip-crypto", N_("skip the crypto processing")),
+  ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
   ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
   ARGPARSE_s_n (oOpenPGP, "openpgp", "@"),
   ARGPARSE_s_n (oCMS, "cms", "@"),
@@ -132,7 +137,7 @@ static ARGPARSE_OPTS tar_opts[] = {
 
 
 \f
-/* Print usage information and and provide strings for help. */
+/* Print usage information and provide strings for help. */
 static const char *
 my_strusage( int level )
 {
@@ -274,15 +279,15 @@ shell_parse_argv (const char *s, int *r_argc, char ***r_argv)
     return 1;
 
   for (i = 0; list; i++)
-    (*r_argv)[i] = list->d, list = list->next;
+    {
+      gpgrt_annotate_leaked_object (list);
+      (*r_argv)[i] = list->d;
+      list = list->next;
+    }
+  gpgrt_annotate_leaked_object (*r_argv);
   return 0;
 }
 \f
-/* Define Assuan hooks for NPTH.  */
-
-ASSUAN_SYSTEM_NPTH_IMPL;
-
-\f
 /* Global flags.  */
 enum cmd_and_opt_values cmd = 0;
 int skip_crypto = 0;
@@ -316,17 +321,25 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
           set_cmd (&cmd, pargs->r_opt);
          break;
 
+        case aCreate:
+          set_cmd (&cmd, aEncrypt);
+          skip_crypto = 1;
+          break;
+
+        case aExtract:
+          set_cmd (&cmd, aDecrypt);
+          skip_crypto = 1;
+          break;
+
         case oRecipient:
           add_to_strlist (&opt.recipients, pargs->r.ret_str);
           break;
 
         case oUser:
-          log_info ("note: ignoring option --user\n");
           opt.user = pargs->r.ret_str;
           break;
 
         case oSymmetric:
-          log_info ("note: ignoring option --symmetric\n");
           set_cmd (&cmd, aEncrypt);
           opt.symmetric = 1;
           break;
@@ -343,38 +356,46 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
         case oCMS:     /* Dummy option for now.  */ break;
 
         case oGpgArgs:;
-          strlist_t list;
-          if (shell_parse_stringlist (pargs->r.ret_str, &list))
-            log_error ("failed to parse gpg arguments '%s'\n",
-                       pargs->r.ret_str);
-          else
-            {
-              if (opt.gpg_arguments)
-                strlist_last (opt.gpg_arguments)->next = list;
-              else
-                opt.gpg_arguments = list;
-            }
+          {
+            strlist_t list;
+            if (shell_parse_stringlist (pargs->r.ret_str, &list))
+              log_error ("failed to parse gpg arguments '%s'\n",
+                         pargs->r.ret_str);
+            else
+              {
+                if (opt.gpg_arguments)
+                  strlist_last (opt.gpg_arguments)->next = list;
+                else
+                  opt.gpg_arguments = list;
+              }
+          }
           break;
 
         case oTarArgs:;
-          int tar_argc;
-          char **tar_argv;
+          {
+            int tar_argc;
+            char **tar_argv;
+
+            if (shell_parse_argv (pargs->r.ret_str, &tar_argc, &tar_argv))
+              log_error ("failed to parse tar arguments '%s'\n",
+                         pargs->r.ret_str);
+            else
+              {
+                ARGPARSE_ARGS tar_args;
+                tar_args.argc = &tar_argc;
+                tar_args.argv = &tar_argv;
+                tar_args.flags = ARGPARSE_FLAG_ARG0;
+                parse_arguments (&tar_args, tar_opts);
+                if (tar_args.err)
+                  log_error ("unsupported tar arguments '%s'\n",
+                             pargs->r.ret_str);
+                pargs->err = tar_args.err;
+              }
+          }
+          break;
 
-          if (shell_parse_argv (pargs->r.ret_str, &tar_argc, &tar_argv))
-            log_error ("failed to parse tar arguments '%s'\n",
-                       pargs->r.ret_str);
-          else
-            {
-              ARGPARSE_ARGS tar_args;
-              tar_args.argc = &tar_argc;
-              tar_args.argv = &tar_argv;
-              tar_args.flags = ARGPARSE_FLAG_ARG0;
-              parse_arguments (&tar_args, tar_opts);
-              if (tar_args.err)
-                log_error ("unsupported tar arguments '%s'\n",
-                           pargs->r.ret_str);
-              pargs->err = tar_args.err;
-            }
+        case oDryRun:
+          opt.dry_run = 1;
           break;
 
         default: pargs->err = 2; break;
@@ -395,16 +416,11 @@ main (int argc, char **argv)
 
   gnupg_reopen_std (GPGTAR_NAME);
   set_strusage (my_strusage);
-  log_set_prefix (GPGTAR_NAME, 1);
+  log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init();
   init_common_subsystems (&argc, &argv);
-  npth_init ();
-  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
-  assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
-  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
-  assuan_sock_init ();
 
   /* Parse the command line. */
   pargs.argc  = &argc;
@@ -430,9 +446,11 @@ main (int argc, char **argv)
           log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
     }
 
+  if (! opt.gpg_program)
+    opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG);
+
   if (opt.verbose > 1)
     opt.debug_level = 1024;
-  setup_libassuan_logging (&opt.debug_level);
 
   switch (cmd)
     {
@@ -450,12 +468,17 @@ main (int argc, char **argv)
       break;
 
     case aEncrypt:
+    case aSign:
+    case aSignEncrypt:
       if ((!argc && !null_names)
           || (argc && null_names))
         usage (1);
       if (opt.filename)
         log_info ("note: ignoring option --set-filename\n");
-      err = gpgtar_create (null_names? NULL :argv, !skip_crypto);
+      err = gpgtar_create (null_names? NULL :argv,
+                           !skip_crypto
+                           && (cmd == aEncrypt || cmd == aSignEncrypt),
+                           cmd == aSign || cmd == aSignEncrypt);
       if (err && log_get_errorcount (0) == 0)
         log_error ("creating archive failed: %s\n", gpg_strerror (err));
       break;
@@ -484,7 +507,7 @@ main (int argc, char **argv)
 
 /* Read the next record from STREAM.  RECORD is a buffer provided by
    the caller and must be at leadt of size RECORDSIZE.  The function
-   return 0 on success and and error code on failure; a diagnostic
+   return 0 on success and error code on failure; a diagnostic
    printed as well.  Note that there is no need for an EOF indicator
    because a tarball has an explicit EOF record. */
 gpg_error_t