tools/gpgtar: Improve error handling.
authorJustus Winter <justus@g10code.com>
Wed, 25 Nov 2015 12:39:50 +0000 (13:39 +0100)
committerJustus Winter <justus@g10code.com>
Wed, 25 Nov 2015 13:34:16 +0000 (14:34 +0100)
* tools/gpgtar-create.c (gpgtar_create): Return an error code, fix
error handling.
* tools/gpgtar-extract.c (gpgtar_extract): Likewise.
* tools/gpgtar-list.c (read_header): Return an error code.
(gpgtar_list): Return an error code, fix error handling.
(gpgtar_read_header): Return an error code.
* tools/gpgtar.c: Add missing include.
(main): Print an generic error message if a command failed and no
error has been printed yet.
* tools/gpgtar.h (gpgtar_{create,extract,list,read_header}): Fix the
prototypes accordingly.

Signed-off-by: Justus Winter <justus@g10code.com>
tools/gpgtar-create.c
tools/gpgtar-extract.c
tools/gpgtar-list.c
tools/gpgtar.c
tools/gpgtar.h

index 59b88bf..69ba440 100644 (file)
@@ -740,7 +740,7 @@ write_eof_mark (estream_t stream)
 /* Create a new tarball using the names in the array INPATTERN.  If
    INPATTERN is NULL take the pattern as null terminated strings from
    stdin.  */
-void
+gpg_error_t
 gpgtar_create (char **inpattern, int encrypt)
 {
   gpg_error_t err = 0;
@@ -903,16 +903,19 @@ gpgtar_create (char **inpattern, int encrypt)
  leave:
   if (!err)
     {
+      gpg_error_t first_err;
       if (outstream != es_stdout)
-        err = es_fclose (outstream);
+        first_err = es_fclose (outstream);
       else
-        err = es_fflush (outstream);
+        first_err = es_fflush (outstream);
       outstream = NULL;
       if (cipher_stream != es_stdout)
         err = es_fclose (cipher_stream);
       else
         err = es_fflush (cipher_stream);
       cipher_stream = NULL;
+      if (! err)
+        err = first_err;
     }
   if (err)
     {
@@ -931,4 +934,5 @@ gpgtar_create (char **inpattern, int encrypt)
       scanctrl->flist = hdr->next;
       xfree (hdr);
     }
+  return err;
 }
index 19db0eb..594f257 100644 (file)
@@ -265,7 +265,7 @@ create_directory (const char *dirprefix)
 
 
 \f
-void
+gpg_error_t
 gpgtar_extract (const char *filename, int decrypt)
 {
   gpg_error_t err;
@@ -285,7 +285,7 @@ gpgtar_extract (const char *filename, int decrypt)
         {
           err = gpg_error_from_syserror ();
           log_error ("error opening '%s': %s\n", filename, gpg_strerror (err));
-          return;
+          return err;
         }
     }
   else
@@ -344,11 +344,12 @@ gpgtar_extract (const char *filename, int decrypt)
 
   for (;;)
     {
-      header = gpgtar_read_header (stream);
-      if (!header)
+      err = gpgtar_read_header (stream, &header);
+      if (err || header == NULL)
         goto leave;
 
-      if (extract (stream, dirname, header))
+      err = extract (stream, dirname, header);
+      if (err)
         goto leave;
       xfree (header);
       header = NULL;
@@ -362,5 +363,5 @@ gpgtar_extract (const char *filename, int decrypt)
     es_fclose (stream);
   if (stream != cipher_stream)
     es_fclose (cipher_stream);
-  return;
+  return err;
 }
index 41e08db..1f917ad 100644 (file)
@@ -169,10 +169,11 @@ parse_header (const void *record, const char *filename)
 
 \f
 /* Read the next block, assming it is a tar header.  Returns a header
-   object on success or NULL one error.  In case of an error an error
+   object on success in R_HEADER, or an error.  If the stream is
+   consumed, R_HEADER is set to NULL.  In case of an error an error
    message has been printed.  */
-static tar_header_t
-read_header (estream_t stream)
+static gpg_error_t
+read_header (estream_t stream, tar_header_t *r_header)
 {
   gpg_error_t err;
   char record[RECORDSIZE];
@@ -180,7 +181,7 @@ read_header (estream_t stream)
 
   err = read_record (stream, record);
   if (err)
-    return NULL;
+    return err;
 
   for (i=0; i < RECORDSIZE && !record[i]; i++)
     ;
@@ -190,8 +191,8 @@ read_header (estream_t stream)
          end of archive mark.  */
       err = read_record (stream, record);
       if (err)
-        return NULL;
-      
+        return err;
+
       for (i=0; i < RECORDSIZE && !record[i]; i++)
         ;
       if (i != RECORDSIZE)
@@ -200,11 +201,13 @@ read_header (estream_t stream)
       else
         {
           /* End of archive - FIXME: we might want to check for garbage.  */
-          return NULL;
+          *r_header = NULL;
+          return 0;
         }
     }
 
-  return parse_header (record, es_fname_get (stream));
+  *r_header = parse_header (record, es_fname_get (stream));
+  return *r_header ? 0 : gpg_error_from_syserror ();
 }
 
 
@@ -267,13 +270,13 @@ print_header (tar_header_t header, estream_t out)
 \f
 /* List the tarball FILENAME or, if FILENAME is NULL, the tarball read
    from stdin.  */
-void
+gpg_error_t
 gpgtar_list (const char *filename, int decrypt)
 {
   gpg_error_t err;
   estream_t stream;
   estream_t cipher_stream = NULL;
-  tar_header_t header;
+  tar_header_t header = NULL;
 
   if (filename)
     {
@@ -285,7 +288,7 @@ gpgtar_list (const char *filename, int decrypt)
         {
           err = gpg_error_from_syserror ();
           log_error ("error opening '%s': %s\n", filename, gpg_strerror (err));
-          return;
+          return err;
         }
     }
   else
@@ -314,12 +317,12 @@ gpgtar_list (const char *filename, int decrypt)
 
   for (;;)
     {
-      header = read_header (stream);
-      if (!header)
+      err = read_header (stream, &header);
+      if (err || header == NULL)
         goto leave;
-      
+
       print_header (header, es_stdout);
-      
+
       if (skip_data (stream, header))
         goto leave;
       xfree (header);
@@ -333,14 +336,13 @@ gpgtar_list (const char *filename, int decrypt)
     es_fclose (stream);
   if (stream != cipher_stream)
     es_fclose (cipher_stream);
-  return;
+  return err;
 }
 
-tar_header_t
-gpgtar_read_header (estream_t stream)
+gpg_error_t
+gpgtar_read_header (estream_t stream, tar_header_t *r_header)
 {
-  /*FIXME: Change to return an error code.  */
-  return read_header (stream);
+  return read_header (stream, r_header);
 }
 
 void
index a86aafe..714b216 100644 (file)
@@ -38,6 +38,7 @@
 #include "util.h"
 #include "i18n.h"
 #include "sysutils.h"
+#include "../common/asshelp.h"
 #include "../common/openpgpdefs.h"
 #include "../common/init.h"
 
@@ -158,6 +159,7 @@ ASSUAN_SYSTEM_NPTH_IMPL;
 int
 main (int argc, char **argv)
 {
+  gpg_error_t err;
   ARGPARSE_ARGS pargs;
   const char *fname;
   int no_more_options = 0;
@@ -262,7 +264,9 @@ main (int argc, char **argv)
         log_info ("note: ignoring option --set-filename\n");
       if (files_from)
         log_info ("note: ignoring option --files-from\n");
-      gpgtar_list (fname, !skip_crypto);
+      err = gpgtar_list (fname, !skip_crypto);
+      if (err && log_get_errorcount (0) == 0)
+        log_error ("listing archive failed: %s\n", gpg_strerror (err));
       break;
 
     case aEncrypt:
@@ -271,7 +275,9 @@ main (int argc, char **argv)
         usage (1);
       if (opt.filename)
         log_info ("note: ignoring option --set-filename\n");
-      gpgtar_create (null_names? NULL :argv, !skip_crypto);
+      err = gpgtar_create (null_names? NULL :argv, !skip_crypto);
+      if (err && log_get_errorcount (0) == 0)
+        log_error ("creating archive failed: %s\n", gpg_strerror (err));
       break;
 
     case aDecrypt:
@@ -282,7 +288,9 @@ main (int argc, char **argv)
       if (files_from)
         log_info ("note: ignoring option --files-from\n");
       fname = argc ? *argv : NULL;
-      gpgtar_extract (fname, !skip_crypto);
+      err = gpgtar_extract (fname, !skip_crypto);
+      if (err && log_get_errorcount (0) == 0)
+        log_error ("extracting archive failed: %s\n", gpg_strerror (err));
       break;
 
     default:
index a96ee09..ab2ccec 100644 (file)
@@ -115,14 +115,14 @@ gpg_error_t read_record (estream_t stream, void *record);
 gpg_error_t write_record (estream_t stream, const void *record);
 
 /*-- gpgtar-create.c --*/
-void gpgtar_create (char **inpattern, int encrypt);
+gpg_error_t gpgtar_create (char **inpattern, int encrypt);
 
 /*-- gpgtar-extract.c --*/
-void gpgtar_extract (const char *filename, int decrypt);
+gpg_error_t gpgtar_extract (const char *filename, int decrypt);
 
 /*-- gpgtar-list.c --*/
-void gpgtar_list (const char *filename, int decrypt);
-tar_header_t gpgtar_read_header (estream_t stream);
+gpg_error_t gpgtar_list (const char *filename, int decrypt);
+gpg_error_t gpgtar_read_header (estream_t stream, tar_header_t *r_header);
 void gpgtar_print_header (tar_header_t header, estream_t out);