From: Andrey Rys Date: Fri, 13 Dec 2019 23:46:30 +0000 (+0100) Subject: -O ftrunc=tail: trim unused tail after processing actual data. X-Git-Url: https://jxself.org/git/?a=commitdiff_plain;h=c0dc5614a87ed6d0eed4906447171ef4c73b306e;p=tfcrypt.git -O ftrunc=tail: trim unused tail after processing actual data. This is a hack actually, it's not much useful in everyday life. It is for compressing files in place, exploiting stream compressors like this: xz -9c -T 4 < file.tar | tfcrypt -P -O ftrunc=tail - file.tar , or more safer way (since tfcrypt does not buffer): tfcrypt -P file.tar | xz -9c -T 4 | tfcrypt -P -O ftrunc=tail - file.tar --- diff --git a/VERSION b/VERSION index a787364..8f92bfd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -34 +35 diff --git a/tfc_error.c b/tfc_error.c index 905ae40..a40ab0a 100644 --- a/tfc_error.c +++ b/tfc_error.c @@ -266,6 +266,7 @@ void usage(void) tfc_say(" oseek=val: seek destination file/device by these val bytes."); tfc_say(" count=val: process only these val bytes, both input and output."); tfc_say(" ftrunc=val: truncate output file to these val bytes before closing it."); + tfc_say(" ftrunc=tail: truncate output's tail, leaving only processed data."); tfc_say(" xkey=val: take only val bytes from user keyfile."); tfc_say(" okey=val: seek the key before reading it (usually a device)."); tfc_say(" xctr=val: specify size in bytes of initial counter prepended or read."); diff --git a/tfc_vars.c b/tfc_vars.c index 4ca3785..1a65ac3 100644 --- a/tfc_vars.c +++ b/tfc_vars.c @@ -62,7 +62,7 @@ size_t sksum_turns; int do_edcrypt = TFC_DO_ENCRYPT, do_stop, quiet, error_action; int counter_opt, mackey_opt, do_mac, do_outfmt = TFC_OUTFMT_B64, rawkey; int idx, write_flags; -tfc_yesno catch_all_errors, ignore_seek_errors, password, overwrite_source, do_fsync, do_pad; +tfc_yesno catch_all_errors, ignore_seek_errors, password, overwrite_source, do_fsync, do_pad, do_ftrunc = TFC_NO_FTRUNC; tfc_yesno do_preserve_time, do_stats_in_gibs, do_statline_dynamic = YES, do_less_stats; tfc_yesno no_repeat, do_full_hexdump = YES, verbose, statline_was_shown, show_secrets; char *srcfname = TFC_STDIN_NAME, *dstfname = TFC_STDOUT_NAME, *do_mac_file, *counter_file, *sksum_hashlist_file; diff --git a/tfcrypt.c b/tfcrypt.c index d673d38..fb3dfb9 100644 --- a/tfcrypt.c +++ b/tfcrypt.c @@ -425,14 +425,21 @@ _baddfname: } else if (!strncmp(s, "ftrunc", 6) && *(s+6) == '=') { s += 7; - ftrunc_dfd = tfc_humanfsize(s, &stoi); - if (!str_empty(stoi)) { - ftrunc_dfd = tfc_fnamesize(s, YES); - ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':')); - if (ftrunc_dfd == NOFSIZE) xerror(NO, YES, YES, - "%s: invalid ftrunc value", s); + if (!strcmp(s, "tail")) { + do_ftrunc = TFC_FTRUNC_TAIL; + ftrunc_dfd = NOFSIZE; + } + else { + do_ftrunc = TFC_DO_FTRUNC; + ftrunc_dfd = tfc_humanfsize(s, &stoi); + if (!str_empty(stoi)) { + ftrunc_dfd = tfc_fnamesize(s, YES); + ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':')); + if (ftrunc_dfd == NOFSIZE) xerror(NO, YES, YES, + "%s: invalid ftrunc value", s); + } + else ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':')); } - else ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':')); } else if (!strncmp(s, "xkey", 4) && *(s+4) == '=') { s += 5; @@ -1333,7 +1340,10 @@ _nomac: if (do_preserve_time) fcopy_matime(dfd, &s_stat); xclose(sfd); - if (ftrunc_dfd != NOFSIZE) if (ftruncate(dfd, (off_t)ftrunc_dfd) == -1) xerror(YES, NO, YES, "ftruncate(%d)", dfd); + if (do_ftrunc > TFC_NO_FTRUNC) { + if (do_ftrunc == TFC_FTRUNC_TAIL) ftrunc_dfd = total_processed_dst; + if (ftruncate(dfd, (off_t)ftrunc_dfd) == -1) xerror(YES, NO, YES, "ftruncate(%d)", dfd); + } xclose(dfd); xexit(exitcode); diff --git a/tfcrypt.h b/tfcrypt.h index a313b33..85ed79a 100644 --- a/tfcrypt.h +++ b/tfcrypt.h @@ -155,7 +155,7 @@ extern size_t sksum_turns; extern int do_edcrypt, do_stop, quiet, error_action; extern int counter_opt, mackey_opt, do_mac, do_outfmt, rawkey; extern int idx, write_flags; -extern tfc_yesno catch_all_errors, ignore_seek_errors, password, overwrite_source, do_fsync, do_pad; +extern tfc_yesno catch_all_errors, ignore_seek_errors, password, overwrite_source, do_fsync, do_pad, do_ftrunc; extern tfc_yesno do_preserve_time, do_stats_in_gibs, do_statline_dynamic, do_less_stats; extern tfc_yesno no_repeat, do_full_hexdump, verbose, statline_was_shown, show_secrets; extern char *srcfname, *dstfname, *do_mac_file, *counter_file, *sksum_hashlist_file; @@ -229,5 +229,6 @@ enum { TFC_MODE_STREAM, TFC_MODE_XTS, TFC_MODE_ECB, TFC_MODE_CBC, TFC_MODE_OCB }; enum { TFC_CTR_SHOW = 1, TFC_CTR_HEAD, TFC_CTR_RAND, TFC_CTR_ZERO, TFC_CTR_SSET }; +enum { TFC_NO_FTRUNC, TFC_DO_FTRUNC, TFC_FTRUNC_TAIL }; #endif