gpgtar: Print a result status with skiupped files.

* tools/gpgtar.h (struct tarinfo_s): Add new fields.
* tools/gpgtar-extract.c (check_suspicious_name): Add arg info.
(extract_regular): Count files.
(gpgtar_extract): Print stats.
This commit is contained in:
Werner Koch 2023-03-15 11:18:29 +01:00
parent 5118beeec1
commit 56b65f33d2
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 69 additions and 10 deletions

View File

@ -1183,6 +1183,17 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
send to the client instead of this status line. Such an inquiry
may be used to sync with Pinentry
*** GPGTAR_EXTRACT <tot> <skp> <bad> <sus> <sym> <hrd> <oth>
This status line is emitted after gpgtar has extracted files.
- tot :: Total number of files extracted and stored
- skp :: Total number of files skipped during extraction
- bad :: Number of files skipped due to a bad file name
- sus :: Number of files skipped due to a suspicious file name
- sym :: Number of symlinks not restored
- hrd :: Number of hard links not restored
- oth :: Number of files not extracted due to other reasons.
** Obsolete status codes
*** SIGEXPIRED
Removed on 2011-02-04. This is deprecated in favor of KEYEXPIRED.

View File

@ -37,7 +37,7 @@
#include "gpgtar.h"
static gpg_error_t
check_suspicious_name (const char *name)
check_suspicious_name (const char *name, tarinfo_t info)
{
size_t n;
@ -47,6 +47,7 @@ check_suspicious_name (const char *name)
{
log_error ("filename '%s' contains a backslash - "
"can't extract on this system\n", name);
info->skipped_badname++;
return gpg_error (GPG_ERR_INV_NAME);
}
#endif /*HAVE_DOSISH_SYSTEM*/
@ -59,6 +60,7 @@ check_suspicious_name (const char *name)
{
log_error ("filename '%s' has suspicious parts - not extracting\n",
name);
info->skipped_suspicious++;
return gpg_error (GPG_ERR_INV_NAME);
}
@ -83,7 +85,7 @@ extract_regular (estream_t stream, const char *dirname,
if (sl->flags == 1)
fname = sl->d;
err = check_suspicious_name (fname);
err = check_suspicious_name (fname, info);
if (err)
goto leave;
@ -131,8 +133,12 @@ extract_regular (estream_t stream, const char *dirname,
/* Fixme: Set permissions etc. */
leave:
if (!err && opt.verbose)
log_info ("extracted '%s'\n", fname);
if (!err)
{
if (opt.verbose)
log_info ("extracted '%s'\n", fname);
info->nextracted++;
}
es_fclose (outfp);
if (err && fname && outfp)
{
@ -146,7 +152,8 @@ extract_regular (estream_t stream, const char *dirname,
static gpg_error_t
extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr)
extract_directory (const char *dirname, tarinfo_t info,
tar_header_t hdr, strlist_t exthdr)
{
gpg_error_t err;
const char *name;
@ -158,7 +165,7 @@ extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr)
if (sl->flags == 1)
name = sl->d;
err = check_suspicious_name (name);
err = check_suspicious_name (name, info);
if (err)
goto leave;
@ -230,13 +237,19 @@ extract (estream_t stream, const char *dirname, tarinfo_t info,
if (hdr->typeflag == TF_REGULAR || hdr->typeflag == TF_UNKNOWN)
err = extract_regular (stream, dirname, info, hdr, exthdr);
else if (hdr->typeflag == TF_DIRECTORY)
err = extract_directory (dirname, hdr, exthdr);
err = extract_directory (dirname, info, hdr, exthdr);
else
{
char record[RECORDSIZE];
log_info ("unsupported file type %d for '%s' - skipped\n",
(int)hdr->typeflag, hdr->name);
if (hdr->typeflag == TF_SYMLINK)
info->skipped_symlinks++;
else if (hdr->typeflag == TF_HARDLINK)
info->skipped_hardlinks++;
else
info->skipped_other++;
for (err = 0, n=0; !err && n < hdr->nrecords; n++)
{
err = read_record (stream, record);
@ -328,7 +341,7 @@ gpgtar_extract (const char *filename, int decrypt)
tarinfo_t tarinfo = &tarinfo_buffer;
pid_t pid = (pid_t)(-1);
char *logfilename = NULL;
unsigned long long notextracted;
memset (&tarinfo_buffer, 0, sizeof tarinfo_buffer);
@ -478,8 +491,37 @@ gpgtar_extract (const char *filename, int decrypt)
}
}
leave:
notextracted = tarinfo->skipped_badname;
notextracted += tarinfo->skipped_suspicious;
notextracted += tarinfo->skipped_symlinks;
notextracted += tarinfo->skipped_hardlinks;
notextracted += tarinfo->skipped_other;
if (opt.status_stream)
es_fprintf (opt.status_stream, "[GNUPG:] GPGTAR_EXTRACT"
" %llu %llu %lu %lu %lu %lu %lu\n",
tarinfo->nextracted,
notextracted,
tarinfo->skipped_badname,
tarinfo->skipped_suspicious,
tarinfo->skipped_symlinks,
tarinfo->skipped_hardlinks,
tarinfo->skipped_other);
if (notextracted && !opt.quiet)
{
log_info ("Number of files not extracted: %llu\n", notextracted);
if (tarinfo->skipped_badname)
log_info (" invalid name: %lu\n", tarinfo->skipped_badname);
if (tarinfo->skipped_suspicious)
log_info (" suspicious name: %lu\n", tarinfo->skipped_suspicious);
if (tarinfo->skipped_symlinks)
log_info (" symlink: %lu\n", tarinfo->skipped_symlinks);
if (tarinfo->skipped_hardlinks)
log_info (" hardlink: %lu\n", tarinfo->skipped_hardlinks);
if (tarinfo->skipped_other)
log_info (" other reason: %lu\n", tarinfo->skipped_other);
}
free_strlist (extheader);
xfree (header);
xfree (dirname);

View File

@ -54,8 +54,14 @@ struct
/* An info structure to avoid global variables. */
struct tarinfo_s
{
unsigned long long nblocks; /* Count of processed blocks. */
unsigned long long nblocks; /* Count of processed blocks. */
unsigned long long headerblock; /* Number of current header block. */
unsigned long long nextracted; /* Number of extracted files. */
unsigned long skipped_badname;
unsigned long skipped_suspicious;
unsigned long skipped_symlinks;
unsigned long skipped_hardlinks;
unsigned long skipped_other;
};
typedef struct tarinfo_s *tarinfo_t;