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
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.");
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;
}
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;
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);
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;
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