aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/gpgconf.c10
-rw-r--r--tools/gpgtar-create.c120
-rw-r--r--tools/gpgtar-extract.c61
-rw-r--r--tools/gpgtar.c63
-rw-r--r--tools/gpgtar.h9
-rw-r--r--tools/send-mail.c7
6 files changed, 231 insertions, 39 deletions
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index bb9ac5419..46489df1f 100644
--- a/tools/gpgconf.c
+++ b/tools/gpgconf.c
@@ -1515,6 +1515,11 @@ show_configs (estream_t outfp)
static const char *names[] = { "common.conf", "gpg-agent.conf",
"scdaemon.conf", "dirmngr.conf",
"gpg.conf", "gpgsm.conf" };
+ static const char *envvars[] = { "PATH",
+ "http_proxy", "HTTP_PROXY",
+ "https_proxy", "HTTPS_PROXY",
+ "LD_LIBRARY_PATH", "LD_PRELOAD",
+ "LD_AUDIT", "LD_ORIGIN_PATH" };
gpg_error_t err;
int idx;
char *fname;
@@ -1545,6 +1550,11 @@ show_configs (estream_t outfp)
list_dirs (outfp, NULL, 1);
es_fprintf (outfp, "\n");
+ for (idx=0; idx < DIM(envvars); idx++)
+ if ((s = getenv (envvars[idx])))
+ es_fprintf (outfp, "%s=%s\n", envvars[idx], s);
+ es_fprintf (outfp, "\n");
+
fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL);
if (!gnupg_access (fname, F_OK))
{
diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c
index ebcfc5229..c239b0fc6 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;
gnupg_process_t proc = NULL;
+ unsigned int skipped_open = 0;
memset (scanctrl, 0, sizeof *scanctrl);
scanctrl->flist_tail = &scanctrl->flist;
@@ -1137,6 +1213,17 @@ 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;
@@ -1227,17 +1314,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 (proc)
{
@@ -1260,6 +1350,12 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
proc = NULL;
}
+ 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)
{
diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c
index 9d5abd33d..c8e4a4571 100644
--- a/tools/gpgtar-extract.c
+++ b/tools/gpgtar-extract.c
@@ -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;
@@ -198,6 +205,8 @@ extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr)
{
*p = 0;
rc = gnupg_mkdir (fname, "-rwx------");
+ if (gpg_err_code (rc) == GPG_ERR_EEXIST)
+ rc = 0;
*p = '/';
if (rc)
break;
@@ -228,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);
@@ -326,7 +341,7 @@ gpgtar_extract (const char *filename, int decrypt)
tarinfo_t tarinfo = &tarinfo_buffer;
gnupg_process_t proc;
char *logfilename = NULL;
-
+ unsigned long long notextracted;
memset (&tarinfo_buffer, 0, sizeof tarinfo_buffer);
@@ -479,6 +494,36 @@ 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);
diff --git a/tools/gpgtar.c b/tools/gpgtar.c
index 8461666b9..64e5306b2 100644
--- a/tools/gpgtar.c
+++ b/tools/gpgtar.c
@@ -459,7 +459,7 @@ main (int argc, char **argv)
gnupg_reopen_std (GPGTAR_NAME);
gpgrt_set_strusage (my_strusage);
- log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX);
+ log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX|GPGRT_LOG_NO_REGISTRY);
/* Make sure that our subsystems are ready. */
i18n_init();
@@ -491,6 +491,36 @@ main (int argc, char **argv)
log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
}
+ /* Set status stream for our own use of --status-fd. The original
+ * status fd is passed verbatim to gpg. */
+ if (opt.status_fd != -1)
+ {
+ int fd = translate_sys2libc_fd_int (opt.status_fd, 1);
+
+ if (!gnupg_fd_valid (fd))
+ log_fatal ("status-fd is invalid: %s\n", strerror (errno));
+
+ if (fd == 1)
+ {
+ opt.status_stream = es_stdout;
+ if (!skip_crypto)
+ log_fatal ("using stdout for the status-fd is not possible\n");
+ }
+ else if (fd == 2)
+ opt.status_stream = es_stderr;
+ else
+ {
+ opt.status_stream = es_fdopen (fd, "w");
+ if (opt.status_stream)
+ es_setvbuf (opt.status_stream, NULL, _IOLBF, 0);
+ }
+ if (!opt.status_stream)
+ {
+ log_fatal ("can't open fd %d for status output: %s\n",
+ fd, strerror (errno));
+ }
+ }
+
if (! opt.gpg_program)
opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG);
@@ -499,17 +529,27 @@ main (int argc, char **argv)
switch (cmd)
{
+ case aDecrypt:
case aList:
if (argc > 1)
gpgrt_usage (1);
- fname = argc ? *argv : NULL;
+ fname = (argc && strcmp (*argv, "-"))? *argv : NULL;
if (opt.filename)
log_info ("note: ignoring option --set-filename\n");
if (files_from)
log_info ("note: ignoring option --files-from\n");
- err = gpgtar_list (fname, !skip_crypto);
- if (err && log_get_errorcount (0) == 0)
- log_error ("listing archive failed: %s\n", gpg_strerror (err));
+ if (cmd == aDecrypt)
+ {
+ err = gpgtar_extract (fname, !skip_crypto);
+ if (err && !log_get_errorcount (0))
+ log_error ("extracting archive failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ err = gpgtar_list (fname, !skip_crypto);
+ if (err && !log_get_errorcount (0))
+ log_error ("listing archive failed: %s\n", gpg_strerror (err));
+ }
break;
case aEncrypt:
@@ -530,19 +570,6 @@ main (int argc, char **argv)
log_error ("creating archive failed: %s\n", gpg_strerror (err));
break;
- case aDecrypt:
- if (argc != 1)
- gpgrt_usage (1);
- if (opt.outfile)
- log_info ("note: ignoring option --output\n");
- if (files_from)
- log_info ("note: ignoring option --files-from\n");
- fname = argc ? *argv : NULL;
- 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:
log_error (_("invalid command (there is no implicit command)\n"));
break;
diff --git a/tools/gpgtar.h b/tools/gpgtar.h
index 0854064fb..9177fcfcb 100644
--- a/tools/gpgtar.h
+++ b/tools/gpgtar.h
@@ -45,6 +45,7 @@ struct
int answer_yes;
int answer_no;
int status_fd;
+ estream_t status_stream;
int require_compliance;
int with_log;
} opt;
@@ -53,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;
diff --git a/tools/send-mail.c b/tools/send-mail.c
index 6492c43c1..d348f28cb 100644
--- a/tools/send-mail.c
+++ b/tools/send-mail.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h> /* for X_OK */
#include "../common/util.h"
#include "../common/exectool.h"
@@ -36,6 +37,12 @@ run_sendmail (estream_t data)
const char pgmname[] = NAME_OF_SENDMAIL;
const char *argv[3];
+ if (!*pgmname || gnupg_access (pgmname, X_OK))
+ {
+ log_error ("sendmail tool '%s' is not correctly installed\n", pgmname);
+ return gpg_error (GPG_ERR_ENOENT);
+ }
+
argv[0] = "-oi";
argv[1] = "-t";
argv[2] = NULL;