diff options
Diffstat (limited to 'tools/gpgtar-create.c')
-rw-r--r-- | tools/gpgtar-create.c | 128 |
1 files changed, 115 insertions, 13 deletions
diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index e642da0..8cb65c7 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -1,5 +1,5 @@ /* gpgtar-create.c - Create a TAR archive - * Copyright (C) 2016-2017, 2019-2022 g10 Code GmbH + * Copyright (C) 2016-2017, 2019-2023 g10 Code GmbH * Copyright (C) 2010, 2012, 2013 Werner Koch * Copyright (C) 2010 Free Software Foundation, Inc. * @@ -49,10 +49,19 @@ #define lstat(a,b) gnupg_stat ((a), (b)) #endif +/* Number of files to be write. */ +static unsigned long global_total_files; + +/* Count the number of written file and thus headers. Extended + * headers are not counted. */ +static unsigned long global_written_files; + +/* Total data expected to be written. */ +static unsigned long long global_total_data; + +/* Number of data bytes written so far. */ +static unsigned long long global_written_data; -/* Count the number of written headers. Extended headers are not - * counted. */ -static unsigned long global_header_count; /* Object to control the file scanning. */ @@ -62,10 +71,62 @@ struct scanctrl_s { tar_header_t flist; tar_header_t *flist_tail; + unsigned long file_count; int nestlevel; }; +/* See ../g10/progress.c:write_status_progress for some background. */ +static void +write_progress (int countmode, unsigned long long current, + unsigned long long total_arg) +{ + char units[] = "BKMGTPEZY?"; + int unitidx = 0; + uint64_t total = total_arg; + + if (!opt.status_stream) + return; /* Not enabled. */ + + if (countmode) + { + if (total && current > total) + current = total; + } + else if (total) /* Size mode: This may use units. */ + { + if (current > total) + current = total; + + while (total > 1024*1024) + { + total /= 1024; + current /= 1024; + unitidx++; + } + } + else /* Size mode */ + { + while (current > 1024*1024) + { + current /= 1024; + unitidx++; + } + } + + if (unitidx > sizeof units - 1) + unitidx = sizeof units - 1; + + if (countmode) + es_fprintf (opt.status_stream, "[GNUPG:] PROGRESS gpgtar c %zu %zu\n", + (size_t)current, (size_t)total); + else + es_fprintf (opt.status_stream, "[GNUPG:] PROGRESS gpgtar s %zu %zu %c%s\n", + (size_t)current, (size_t)total, + units[unitidx], + unitidx? "iB" : ""); +} + /* On Windows convert name to UTF8 and return it; caller must release * the result. On Unix or if ALREADY_UTF8 is set, this function is a @@ -300,6 +361,12 @@ add_entry (const char *dname, const char *entryname, scanctrl_t scanctrl) gpgtar_print_header (hdr, NULL, log_get_stream ()); *scanctrl->flist_tail = hdr; scanctrl->flist_tail = &hdr->next; + scanctrl->file_count++; + /* Print a progress line during scnanning in increments of 5000 + * and not of 100 as we doing during write: Scanning is of + * course much faster. */ + if (!(scanctrl->file_count % 5000)) + write_progress (1, scanctrl->file_count, 0); } return 0; @@ -709,7 +776,7 @@ build_header (void *record, tar_header_t hdr, strlist_t *r_exthdr) * will do. To ease testing we also put in the PID. The * count is bumped after the header has been written. */ snprintf (raw->name, sizeof raw->name-1, "_@paxheader.%u.%lu", - (unsigned int)getpid(), global_header_count + 1); + (unsigned int)getpid(), global_written_files + 1); } } @@ -881,7 +948,7 @@ write_extended_header (estream_t stream, const void *record, strlist_t exthdr) static gpg_error_t -write_file (estream_t stream, tar_header_t hdr) +write_file (estream_t stream, tar_header_t hdr, unsigned int *skipped_open) { gpg_error_t err; char record[RECORDSIZE]; @@ -895,7 +962,7 @@ write_file (estream_t stream, tar_header_t hdr) { if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED) { - log_info ("skipping unsupported file '%s'\n", hdr->name); + log_info ("silently skipping unsupported file '%s'\n", hdr->name); err = 0; } return err; @@ -907,9 +974,12 @@ write_file (estream_t stream, tar_header_t hdr) if (!infp) { err = gpg_error_from_syserror (); - log_error ("can't open '%s': %s - skipped\n", + log_info ("can't open '%s': %s - skipped\n", hdr->name, gpg_strerror (err)); - return err; + ++*skipped_open; + if (!*skipped_open) /* Protect against overflow. */ + --*skipped_open; + return 0; } } else @@ -920,7 +990,9 @@ write_file (estream_t stream, tar_header_t hdr) err = write_record (stream, record); if (err) goto leave; - global_header_count++; + global_written_files++; + if (!(global_written_files % 100)) + write_progress (1, global_written_files, global_total_files); if (hdr->typeflag == TF_REGULAR) { @@ -946,6 +1018,9 @@ write_file (estream_t stream, tar_header_t hdr) err = write_record (stream, record); if (err) goto leave; + global_written_data += nbytes; + if (!((global_written_data/nbytes) % (2048*100))) + write_progress (0, global_written_data, global_total_data); } nread = es_fread (record, 1, 1, infp); if (nread) @@ -995,6 +1070,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, estream_t outstream = NULL; int eof_seen = 0; pid_t pid = (pid_t)(-1); + unsigned int skipped_open = 0; memset (scanctrl, 0, sizeof *scanctrl); scanctrl->flist_tail = &scanctrl->flist; @@ -1147,10 +1223,22 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, if (files_from_stream && files_from_stream != es_stdin) es_fclose (files_from_stream); + global_total_files = global_total_data = 0; + global_written_files = global_written_data = 0; + for (hdr = scanctrl->flist; hdr; hdr = hdr->next) + { + global_total_files++; + global_total_data += hdr->size; + } + write_progress (1, 0, global_total_files); + write_progress (0, 0, global_total_data); + + if (encrypt || sign) { strlist_t arg; ccparray_t ccp; + int except[2] = { -1, -1 }; const char **argv; /* '--encrypt' may be combined with '--symmetric', but 'encrypt' @@ -1174,6 +1262,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%d", opt.status_fd); ccparray_put (&ccp, tmpbuf); + except[0] = opt.status_fd; } ccparray_put (&ccp, "--output"); @@ -1194,6 +1283,8 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, ccparray_put (&ccp, "--recipient"); ccparray_put (&ccp, arg->d); } + if (opt.no_compress) + ccparray_put (&ccp, "-z0"); for (arg = opt.gpg_arguments; arg; arg = arg->next) ccparray_put (&ccp, arg->d); @@ -1205,7 +1296,9 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, goto leave; } - err = gnupg_spawn_process (opt.gpg_program, argv, NULL, NULL, + err = gnupg_spawn_process (opt.gpg_program, argv, + except[0] == -1? NULL : except, + NULL, (GNUPG_SPAWN_KEEP_STDOUT | GNUPG_SPAWN_KEEP_STDERR), &outstream, NULL, NULL, &pid); @@ -1235,17 +1328,20 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, es_set_binary (outstream); } - + skipped_open = 0; for (hdr = scanctrl->flist; hdr; hdr = hdr->next) { - err = write_file (outstream, hdr); + err = write_file (outstream, hdr, &skipped_open); if (err) goto leave; } + err = write_eof_mark (outstream); if (err) goto leave; + write_progress (1, global_written_files, global_total_files); + write_progress (0, global_written_data, global_total_data); if (pid != (pid_t)(-1)) { @@ -1266,6 +1362,12 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, } } + if (skipped_open) + { + log_info ("number of skipped files: %u\n", skipped_open); + log_error ("exiting with failure status due to previous errors\n"); + } + leave: if (!err) { |