* tfcrypt -- high security Threefish encryption tool.
*
* tfcrypt is copyrighted:
- * Copyright (C) 2012-2018 Andrey Rys. All rights reserved.
+ * Copyright (C) 2012-2019 Andrey Rys. All rights reserved.
*
* tfcrypt is licensed to you under the terms of std. MIT/X11 license:
*
#include "tfcrypt.h"
+static void print_crypt_status_genrnd(int signal)
+{
+ if (signal == SIGTERM || signal == SIGINT) {
+ if (xexit_no_nl == YES) xexit_no_nl = NO;
+ }
+ print_crypt_status(signal);
+}
+
+static void exit_sigterm_genrnd(int signal)
+{
+ if (xexit_no_nl == YES) xexit_no_nl = NO;
+ exit_sigterm(signal);
+}
+
static void get_urandom(const char *src, void *buf, size_t size)
{
tfc_byte *ubuf = buf;
if (fd == -1) fd = open("/dev/random", O_RDONLY);
if (fd == -1) xerror(NO, YES, YES, "random source is required (tried %s)", src);
-_again: rd = read(fd, ubuf, sz);
+_again: rd = xread(fd, ubuf, sz);
if (rd < sz && rd != NOSIZE) {
ubuf += rd;
sz -= rd;
void gen_write_bytes(const char *foutname, tfc_fsize offset, tfc_fsize nrbytes)
{
+ static tfc_fsize wrpos = NOFSIZE;
int fd, x;
- size_t lblock;
+ size_t lblock, lio, lrem;
+ tfc_byte *pblk;
+
+ xexit_no_nl = YES;
for (x = 1; x < NSIG; x++) signal(x, SIG_IGN);
memset(&sigact, 0, sizeof(sigact));
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = print_crypt_status;
sigaction(SIGUSR1, &sigact, NULL);
- sigaction(SIGTSTP, &sigact, NULL);
sigaction(SIGALRM, &sigact, NULL);
- if (status_timer) setup_next_alarm(status_timer);
+ if (status_timer) setup_next_alarm(status_timer > 1000000 ? 1000000 : status_timer);
sigact.sa_handler = change_status_width;
sigaction(SIGQUIT, &sigact, NULL);
sigact.sa_handler = change_status_timer;
sigaction(SIGUSR2, &sigact, NULL);
if (quiet == NO) {
- sigact.sa_handler = print_crypt_status;
+ sigact.sa_handler = print_crypt_status_genrnd;
sigaction(SIGINT, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
+ sigaction(SIGTSTP, &sigact, NULL);
}
else {
- sigact.sa_handler = exit_sigterm;
+ sigact.sa_handler = exit_sigterm_genrnd;
sigaction(SIGINT, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
+ sigact.sa_handler = handle_sigtstp;
+ sigaction(SIGTSTP, &sigact, NULL);
}
memset(&sigact, 0, sizeof(struct sigaction));
if (offset) {
if (lseek(fd, offset, SEEK_SET) == -1)
- xerror(YES, NO, NO, "%s: seek failed", foutname);
+ xerror(ignore_seek_errors, NO, NO, "%s: seek failed", foutname);
}
if (ctr_mode == TFC_MODE_PLAIN) memset(srcblk, 0, sizeof(srcblk));
if (verbose) tfc_nfsay(stderr, "%s: writing %lld bytes to %s ... ",
- progname, nrbytes, foutname);
+ tfc_format_pid(progname), nrbytes, foutname);
errno = 0;
do_stop = NO;
while (1) {
if (do_stop) break;
- lblock = blk_len_adj(nrbytes, total_processed_src, sizeof(srcblk));
+ pblk = srcblk;
+ lblock = lrem = blk_len_adj(nrbytes, total_processed_src, blksize);
if (ctr_mode != TFC_MODE_PLAIN) tfc_getrandom(srcblk, lblock);
- if (write(fd, srcblk, lblock) == -1)
- xerror(NO, NO, YES, "%s", foutname);
+ if (error_action == TFC_ERRACT_SYNC) wrpos = tfc_fdgetpos(fd);
+_wagain: lio = xwrite(fd, pblk, lrem);
+ if (lio == NOSIZE) {
+ if (errno != EIO && catch_all_errors != YES)
+ xerror(NO, NO, YES, "%s", foutname);
+ switch (error_action) {
+ case TFC_ERRACT_CONT: xerror(YES, NO, YES, "%s", foutname); goto _wagain; break;
+ case TFC_ERRACT_SYNC:
+ case TFC_ERRACT_LSYNC:
+ xerror(YES, NO, YES, "%s", foutname);
+ if (wrpos == NOFSIZE) lseek(fd, lblock, SEEK_CUR);
+ else lseek(fd, wrpos + lblock, SEEK_SET);
+ break;
+ default: xerror(NO, NO, YES, "%s", foutname); break;
+ }
+ }
if (do_fsync && fsync(fd) == -1) xerror(NO, NO, YES, "%s", foutname);
+ if (lio < lrem) {
+ pblk += lio;
+ lrem -= lio;
+ goto _wagain;
+ }
total_processed_src += lblock;
delta_processed += lblock;
}
if (verbose) tfc_esay("done!");
- if (verbose || status_timer) print_crypt_status(0);
+ if (verbose || status_timer) {
+ print_crypt_status(0);
+ tfc_esay("\n");
+ }
xclose(fd);
xexit(0);