diff options
author | Werner Koch <[email protected]> | 2019-03-06 16:46:40 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2019-03-06 16:46:40 +0000 |
commit | 72feb8fa8280aba674573a1afc955a92e8065242 (patch) | |
tree | db50444e2af494ac8842f1a864953bdcf3da2e73 /tools/gpgtar-list.c | |
parent | agent: Default to extended key format. (diff) | |
download | gnupg-72feb8fa8280aba674573a1afc955a92e8065242.tar.gz gnupg-72feb8fa8280aba674573a1afc955a92e8065242.zip |
gpgtar: Improve error messages.
* tools/gpgtar.h (struct tarinfo_s): New.
* tools/gpgtar.c (cmd, skip_crypto, files_from, null_names): Move
global vars more to the top.
(set_cmd): Rename 'cmd' to 'c'.
* tools/gpgtar-list.c (parse_header): Add arg 'info' and improve error
messages.
(read_header): Add arg 'info' and update counter.
(skip_data): Ditto.
(gpgtar_list): Pass info object to read functions.
(gpgtar_read_header): Add arg 'info'.
* tools/gpgtar-extract.c (gpgtar_extract): add arg 'info' and pass on.
(extract_regular): Add arg 'info' and update counter.
--
This now prints the block number of a header with error.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'tools/gpgtar-list.c')
-rw-r--r-- | tools/gpgtar-list.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c index 0e10be8a0..396e837f4 100644 --- a/tools/gpgtar-list.c +++ b/tools/gpgtar-list.c @@ -77,12 +77,15 @@ parse_xoctal (const void *data, size_t length, const char *filename) static tar_header_t -parse_header (const void *record, const char *filename) +parse_header (const void *record, const char *filename, tarinfo_t info) { const struct ustar_raw_header *raw = record; size_t n, namelen, prefixlen; tar_header_t header; int use_prefix; + int anyerror = 0; + + info->headerblock = info->nblocks - 1; use_prefix = (!memcmp (raw->magic, "ustar", 5) && (raw->magic[5] == ' ' || !raw->magic[5])); @@ -91,27 +94,31 @@ parse_header (const void *record, const char *filename) for (namelen=0; namelen < sizeof raw->name && raw->name[namelen]; namelen++) ; if (namelen == sizeof raw->name) - log_info ("%s: warning: name not terminated by a nul byte\n", filename); + { + log_info ("%s: warning: name not terminated by a nul\n", filename); + anyerror = 1; + } for (n=namelen+1; n < sizeof raw->name; n++) if (raw->name[n]) { log_info ("%s: warning: garbage after name\n", filename); + anyerror = 1; break; } - if (use_prefix && raw->prefix[0]) { for (prefixlen=0; (prefixlen < sizeof raw->prefix && raw->prefix[prefixlen]); prefixlen++) ; if (prefixlen == sizeof raw->prefix) - log_info ("%s: warning: prefix not terminated by a nul byte\n", - filename); + log_info ("%s: warning: prefix not terminated by a nul (block %llu)\n", + filename, info->headerblock); for (n=prefixlen+1; n < sizeof raw->prefix; n++) if (raw->prefix[n]) { log_info ("%s: warning: garbage after prefix\n", filename); + anyerror = 1; break; } } @@ -156,25 +163,32 @@ parse_header (const void *record, const char *filename) default: header->typeflag = TF_UNKNOWN; break; } - /* Compute the number of data records following this header. */ if (header->typeflag == TF_REGULAR || header->typeflag == TF_UNKNOWN) header->nrecords = (header->size + RECORDSIZE-1)/RECORDSIZE; else header->nrecords = 0; + if (anyerror) + { + log_info ("%s: header block %llu is corrupt" + " (size=%llu type=%d nrec=%llu)\n", + filename, info->headerblock, + header->size, header->typeflag, header->nrecords); + /* log_printhex (record, RECORDSIZE, " "); */ + } return header; } -/* Read the next block, assming it is a tar header. Returns a header +/* Read the next block, assuming it is a tar header. Returns a header 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 gpg_error_t -read_header (estream_t stream, tar_header_t *r_header) +read_header (estream_t stream, tarinfo_t info, tar_header_t *r_header) { gpg_error_t err; char record[RECORDSIZE]; @@ -183,6 +197,7 @@ read_header (estream_t stream, tar_header_t *r_header) err = read_record (stream, record); if (err) return err; + info->nblocks++; for (i=0; i < RECORDSIZE && !record[i]; i++) ; @@ -193,6 +208,7 @@ read_header (estream_t stream, tar_header_t *r_header) err = read_record (stream, record); if (err) return err; + info->nblocks++; for (i=0; i < RECORDSIZE && !record[i]; i++) ; @@ -207,7 +223,7 @@ read_header (estream_t stream, tar_header_t *r_header) } } - *r_header = parse_header (record, es_fname_get (stream)); + *r_header = parse_header (record, es_fname_get (stream), info); return *r_header ? 0 : gpg_error_from_syserror (); } @@ -215,7 +231,7 @@ read_header (estream_t stream, tar_header_t *r_header) /* Skip the data records according to HEADER. Prints an error message on error and return -1. */ static int -skip_data (estream_t stream, tar_header_t header) +skip_data (estream_t stream, tarinfo_t info, tar_header_t header) { char record[RECORDSIZE]; unsigned long long n; @@ -224,6 +240,7 @@ skip_data (estream_t stream, tar_header_t header) { if (read_record (stream, record)) return -1; + info->nblocks++; } return 0; @@ -278,6 +295,10 @@ gpgtar_list (const char *filename, int decrypt) estream_t stream; estream_t cipher_stream = NULL; tar_header_t header = NULL; + struct tarinfo_s tarinfo_buffer; + tarinfo_t tarinfo = &tarinfo_buffer; + + memset (&tarinfo_buffer, 0, sizeof tarinfo_buffer); if (filename) { @@ -339,13 +360,13 @@ gpgtar_list (const char *filename, int decrypt) for (;;) { - err = read_header (stream, &header); + err = read_header (stream, tarinfo, &header); if (err || header == NULL) goto leave; print_header (header, es_stdout); - if (skip_data (stream, header)) + if (skip_data (stream, tarinfo, header)) goto leave; xfree (header); header = NULL; @@ -362,9 +383,9 @@ gpgtar_list (const char *filename, int decrypt) } gpg_error_t -gpgtar_read_header (estream_t stream, tar_header_t *r_header) +gpgtar_read_header (estream_t stream, tarinfo_t info, tar_header_t *r_header) { - return read_header (stream, r_header); + return read_header (stream, info, r_header); } void |