From 81c8e9e1043ae0912a77f188c941f38887084ab7 Mon Sep 17 00:00:00 2001 From: Graham Percival Date: Tue, 12 Dec 2023 12:32:45 -0700 Subject: [PATCH 1/4] Add ability to print archive hashes --- tar/bsdtar.c | 2 +- tar/bsdtar.h | 2 +- tar/glue/tape.c | 5 +++-- tar/multitape/multitape.h | 8 ++++--- tar/multitape/multitape_stats.c | 38 +++++++++++++++++++++++++++------ 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/tar/bsdtar.c b/tar/bsdtar.c index 61d318c4..e45508bc 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -1229,7 +1229,7 @@ main(int argc, char **argv) tarsnap_mode_recover(bsdtar, 0); break; case OPTION_LIST_ARCHIVES: - tarsnap_mode_list_archives(bsdtar); + tarsnap_mode_list_archives(bsdtar, 0); break; case OPTION_NUKE: tarsnap_mode_nuke(bsdtar); diff --git a/tar/bsdtar.h b/tar/bsdtar.h index 4bb9fb44..feeee3ed 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.h @@ -309,7 +309,7 @@ void tarsnap_mode_t(struct bsdtar *bsdtar); void tarsnap_mode_x(struct bsdtar *bsdtar); void tarsnap_mode_fsck(struct bsdtar *bsdtar, int prune, int whichkey); void tarsnap_mode_initialize_cachedir(struct bsdtar *bsdtar); -void tarsnap_mode_list_archives(struct bsdtar *bsdtar); +void tarsnap_mode_list_archives(struct bsdtar *bsdtar, int print_hashes); void tarsnap_mode_nuke(struct bsdtar *bsdtar); void tarsnap_mode_recover(struct bsdtar *bsdtar, int whichkey); int unmatched_inclusions(struct bsdtar *bsdtar); diff --git a/tar/glue/tape.c b/tar/glue/tape.c index c4a1a182..60308aa0 100644 --- a/tar/glue/tape.c +++ b/tar/glue/tape.c @@ -170,7 +170,7 @@ tarsnap_mode_print_stats(struct bsdtar *bsdtar) * Print the names of all the archives. */ void -tarsnap_mode_list_archives(struct bsdtar *bsdtar) +tarsnap_mode_list_archives(struct bsdtar *bsdtar, int print_hashes) { TAPE_S * d; @@ -179,7 +179,8 @@ tarsnap_mode_list_archives(struct bsdtar *bsdtar) goto err1; /* Ask for the list of archives to be printed. */ - if (statstape_printlist(d, bsdtar->verbose, bsdtar->option_null)) + if (statstape_printlist(d, bsdtar->verbose, bsdtar->option_null, + print_hashes)) goto err2; /* We're done. Close the archive set. */ diff --git a/tar/multitape/multitape.h b/tar/multitape/multitape.h index a3980da6..f941c671 100644 --- a/tar/multitape/multitape.h +++ b/tar/multitape/multitape.h @@ -172,14 +172,16 @@ int statstape_printglobal(TAPE_S *, const char *); int statstape_printall(TAPE_S *, const char *); /** - * statstape_printlist(d, verbose, print_nulls): + * statstape_printlist(d, verbose, print_nulls, print_hashes): * Print the names of each of the archives in a set. If ${verbose} > 0, print * the creation times; if ${verbose} > 1, print the argument vector of the * program invocation which created the archive. If ${print_nulls} > 0, print * null character(s) between archives names and fields instead of newlines, - * tabs, and spaces. + * tabs, and spaces. If ${print_hashes} > 0 and ${verbose} is 0, print hashes + * instead of archive names. If ${print_hashes} > 0 and ${verbose} > 0, print + * hashes in addition to the normal behaviour. */ -int statstape_printlist(TAPE_S *, int, int); +int statstape_printlist(TAPE_S *, int, int, int); /** * statstape_print(d, tapename, csv_filename): diff --git a/tar/multitape/multitape_stats.c b/tar/multitape/multitape_stats.c index d1401aef..3570d4cd 100644 --- a/tar/multitape/multitape_stats.c +++ b/tar/multitape/multitape_stats.c @@ -10,6 +10,7 @@ #include "chunks.h" #include "ctassert.h" +#include "hexify.h" #include "multitape_internal.h" #include "storage.h" #include "sysendian.h" @@ -243,22 +244,42 @@ print_sep(char sep, int nulls, int num) } /** - * statstape_printlist_item(d, tapehash, verbose, print_nulls): + * statstape_printlist_item(d, tapehash, verbose, print_nulls, print_hash): * Print the name of the archive with ${tapehash}. If ${verbose} > 0, print * the creation times; if ${verbose} > 1, print the argument vector of the * program invocation which created the archive. If ${print_nulls} > 0, print * null character(s) between archives names and fields instead of newlines, - * tabs, and spaces. + * tabs, and spaces. If ${print_hash} > 0 and ${verbose} is 0, print the hash + * instead of the archive name. If ${print_hash} > 0 and ${verbose} > 0, + * print hash in addition to the normal behaviour. */ static int statstape_printlist_item(TAPE_S * d, const uint8_t tapehash[32], int verbose, - int print_nulls) + int print_nulls, int print_hash) { struct tapemetadata tmd; + char hexstr[65]; struct tm * ltime; char datebuf[DATEBUFLEN]; int arg; + /* Print archive hash. */ + if (print_hash) { + hexify(tapehash, hexstr, 32); + fprintf(stdout, "%s", hexstr); + + if (verbose == 0) { + /* We're finished; print archive separator and quit. */ + if (print_sep('\n', print_nulls, 1)) + goto err1; + goto done; + } else { + /* We have more fields; print field separator. */ + if (print_sep('\t', print_nulls, 2)) + goto err1; + } + } + /* Read the tape metadata. */ if (multitape_metadata_get_byhash(d->SR, NULL, &tmd, tapehash, 0)) goto err0; @@ -317,6 +338,7 @@ statstape_printlist_item(TAPE_S * d, const uint8_t tapehash[32], int verbose, /* Free parsed metadata. */ multitape_metadata_free(&tmd); +done: /* Success! */ return (0); @@ -328,15 +350,17 @@ statstape_printlist_item(TAPE_S * d, const uint8_t tapehash[32], int verbose, } /** - * statstape_printlist(d, verbose, print_nulls): + * statstape_printlist(d, verbose, print_nulls, print_hashes): * Print the names of each of the archives in a set. If ${verbose} > 0, print * the creation times; if ${verbose} > 1, print the argument vector of the * program invocation which created the archive. If ${print_nulls} > 0, print * null character(s) between archives names and fields instead of newlines, - * tabs, and spaces. + * tabs, and spaces. If ${print_hashes} > 0 and ${verbose} is 0, print hashes + * instead of archive names. If ${print_hashes} > 0 and ${verbose} > 0, print + * hashes in addition to the normal behaviour. */ int -statstape_printlist(TAPE_S * d, int verbose, int print_nulls) +statstape_printlist(TAPE_S * d, int verbose, int print_nulls, int print_hashes) { uint8_t * flist; size_t nfiles; @@ -349,7 +373,7 @@ statstape_printlist(TAPE_S * d, int verbose, int print_nulls) /* Iterate through the files. */ for (file = 0; file < nfiles; file++) { if (statstape_printlist_item(d, &flist[file * 32], verbose, - print_nulls)) + print_nulls, print_hashes)) goto err1; } From fd6353097ec1b9bdf55ac99624e0f4ed1528d6d0 Mon Sep 17 00:00:00 2001 From: Graham Percival Date: Tue, 12 Dec 2023 12:32:46 -0700 Subject: [PATCH 2/4] Add --hashes --- tar/bsdtar.c | 5 ++++- tar/bsdtar.h | 2 ++ tar/cmdline.c | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tar/bsdtar.c b/tar/bsdtar.c index e45508bc..254d42c9 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -492,6 +492,9 @@ main(int argc, char **argv) /* Hack: -h by itself is the "help" command. */ possible_help_request = 1; break; + case OPTION_HASHES: /* tarsnap */ + bsdtar->option_hashes = 1; + break; case OPTION_HELP: /* GNU tar, others */ long_help(bsdtar); exit(0); @@ -1229,7 +1232,7 @@ main(int argc, char **argv) tarsnap_mode_recover(bsdtar, 0); break; case OPTION_LIST_ARCHIVES: - tarsnap_mode_list_archives(bsdtar, 0); + tarsnap_mode_list_archives(bsdtar, bsdtar->option_hashes); break; case OPTION_NUKE: tarsnap_mode_nuke(bsdtar); diff --git a/tar/bsdtar.h b/tar/bsdtar.h index feeee3ed..b43b1e48 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.h @@ -77,6 +77,7 @@ struct bsdtar { char option_dont_traverse_mounts; /* --one-file-system */ char option_dryrun; /* --dry-run */ char option_fast_read; /* --fast-read */ + int option_hashes; char option_honor_nodump; /* --nodump */ char option_interactive; /* -w */ char option_keep_going; /* --keep-going */ @@ -210,6 +211,7 @@ enum { OPTION_FSCK_DELETE, /* Operation mode, not a real option */ OPTION_FSCK_PRUNE, OPTION_FSCK_WRITE, /* Operation mode, not a real option */ + OPTION_HASHES, OPTION_HELP, OPTION_INCLUDE, OPTION_INITIALIZE_CACHEDIR, diff --git a/tar/cmdline.c b/tar/cmdline.c index f1cfbec8..984cb33d 100644 --- a/tar/cmdline.c +++ b/tar/cmdline.c @@ -95,6 +95,7 @@ static struct option { { "force-resources", 0, OPTION_FORCE_RESOURCES }, { "fsck", 0, OPTION_FSCK }, { "fsck-prune", 0, OPTION_FSCK_PRUNE }, + { "hashes", 0, OPTION_HASHES }, { "help", 0, OPTION_HELP }, { "humanize-numbers", 0, OPTION_HUMANIZE_NUMBERS }, { "include", 1, OPTION_INCLUDE }, From f4d51ee1149098fb4fd5311f0dd206b42ac13b4e Mon Sep 17 00:00:00 2001 From: Graham Percival Date: Tue, 12 Dec 2023 12:32:47 -0700 Subject: [PATCH 3/4] man, NEWS: --hashes --- NEWS.md | 4 ++++ misc/describe-options.txt | 1 + tar/tarsnap.1-mdoc.in | 8 ++++++++ 3 files changed, 13 insertions(+) diff --git a/NEWS.md b/NEWS.md index 0177e1c7..c03206b7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,10 @@ name with a null character (like `find -print0`). If one or more -v arguments are specified, multiple null characters are used to separate fields; see the man page for details. +- tarsnap now accepts --hashes, which causes --list-archives to print hashes + of archive names. If one or more -v arguments are specified, it will print + other metadata (as per --list-archives). This option is intended for the + GUI and is not needed for command-line usage. Tarsnap Releases diff --git a/misc/describe-options.txt b/misc/describe-options.txt index 0d541196..1fac4f42 100644 --- a/misc/describe-options.txt +++ b/misc/describe-options.txt @@ -20,6 +20,7 @@ --force-resources force the decryption of a passphrase-encrypted keyfile --fsck perform some integrity checks and reconstruct cache MODE --fsck-prune run as --fsck, but prune any corrupt archives MODE +--hashes make --list-archives print hashes --humanize-numbers use SI prefixes for --print-stats --include process only certain files or directories --initialize-cachedir create and initialize the cachedir MODE diff --git a/tar/tarsnap.1-mdoc.in b/tar/tarsnap.1-mdoc.in index c411c5ae..c4325b60 100644 --- a/tar/tarsnap.1-mdoc.in +++ b/tar/tarsnap.1-mdoc.in @@ -382,6 +382,14 @@ target of the link will be archived, not the link itself. (c mode only) Synonym for .Fl L . +.It Fl -hashes +(list-archives mode only) +Print hashes of archive names. +If the +.Fl v +flag is specified one or more times, print the archive name as well. +.Pp +This option is intended for the GUI and is not needed for command-line usage. .It Fl -humanize-numbers Use SI prefixes to make numbers printed by .Fl -print-stats From 46bda9960246f3b3bb6305fdaba19678c3961d7f Mon Sep 17 00:00:00 2001 From: Graham Percival Date: Tue, 12 Dec 2023 12:32:48 -0700 Subject: [PATCH 4/4] misc: run scripts --- misc/bash_completion.d/tarsnap | 6 +++--- misc/zsh_completion/_tarsnap | 1 + tar/tarsnap.1-man.in | 9 +++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/misc/bash_completion.d/tarsnap b/misc/bash_completion.d/tarsnap index 8b7ed4b1..2d81db07 100644 --- a/misc/bash_completion.d/tarsnap +++ b/misc/bash_completion.d/tarsnap @@ -53,9 +53,9 @@ _tarsnap () --check-links --checkpoint-bytes --chroot --configfile \ --creationtime --csv-file --disk-pause --dry-run \ --dump-config --exclude --fast-read --force-resources \ - --fsck --fsck-prune --humanize-numbers --include \ - --initialize-cachedir --insane-filesystems --iso-dates \ - --keep-going --keep-newer-files --keyfile \ + --fsck --fsck-prune --hashes --humanize-numbers \ + --include --initialize-cachedir --insane-filesystems \ + --iso-dates --keep-going --keep-newer-files --keyfile \ --list-archives --lowmem --maxbw --maxbw-rate \ --maxbw-rate-down --maxbw-rate-up --newer \ --newer-mtime --newer-than --newer-mtime-than \ diff --git a/misc/zsh_completion/_tarsnap b/misc/zsh_completion/_tarsnap index d5d54657..3b5cb06c 100644 --- a/misc/zsh_completion/_tarsnap +++ b/misc/zsh_completion/_tarsnap @@ -231,6 +231,7 @@ _shtab_tarsnap__initialize_cachedir_options=( _shtab_tarsnap__list_archives_options=( "(- : *)"{-h,--help}"[show this help message and exit]" + "--hashes[make --list-archives print hashes]" "-v[produce verbose output]" "--archive-names[read a list of archive names from a file]:filename:{_files}" "--configfile[add file to the list of configuration files to be read]:filename:{_files}" diff --git a/tar/tarsnap.1-man.in b/tar/tarsnap.1-man.in index 1c9eb7c3..8cf27e8a 100644 --- a/tar/tarsnap.1-man.in +++ b/tar/tarsnap.1-man.in @@ -403,6 +403,15 @@ target of the link will be archived, not the link itself. Synonym for \fB\-L\fP. .TP +\fB\--hashes\fP +(list-archives mode only) +Print hashes of archive names. +If the +\fB\-v\fP +flag is specified one or more times, print the archive name as well. +.PP +This option is intended for the GUI and is not needed for command-line usage. +.TP \fB\--humanize-numbers\fP Use SI prefixes to make numbers printed by \fB\--print-stats\fP