X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=tfc_random.c;h=321f97a6d1c3016e20e5e75048ad62bfa5db9929;hb=HEAD;hp=4b82aee99de018504f09a0686dd43afb1a24ab7e;hpb=efa545d64b910923248233618e774ca3b87efebb;p=tfcrypt.git diff --git a/tfc_random.c b/tfc_random.c index 4b82aee..321f97a 100644 --- a/tfc_random.c +++ b/tfc_random.c @@ -2,7 +2,7 @@ * 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: * @@ -28,6 +28,16 @@ #include "tfcrypt.h" +static void print_crypt_status_genrnd(int signal) +{ + print_crypt_status(signal); +} + +static void exit_sigterm_genrnd(int signal) +{ + exit_sigterm(signal); +} + static void get_urandom(const char *src, void *buf, size_t size) { tfc_byte *ubuf = buf; @@ -44,7 +54,7 @@ static void get_urandom(const char *src, void *buf, size_t size) 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; @@ -83,30 +93,34 @@ void tfc_getrandom(void *buf, size_t sz) 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; 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)); @@ -123,30 +137,49 @@ void gen_write_bytes(const char *foutname, tfc_fsize offset, tfc_fsize nrbytes) fd = 1; foutname = TFC_STDOUT_NAME; } - else fd = open(foutname, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags, 0666); - if (fd == -1) xerror(NO, NO, YES, "%s", foutname); + else fd = xopen(foutname, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags); 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 (do_edcrypt == TFC_DO_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)); - - if (ctr_mode != TFC_MODE_PLAIN) tfc_getrandom(srcblk, lblock); - - if (write(fd, srcblk, lblock) == -1) - xerror(NO, NO, YES, "%s", foutname); + pblk = srcblk; + lblock = lrem = blk_len_adj(nrbytes, total_processed_src, blksize); + + if (do_edcrypt != TFC_DO_PLAIN) tfc_getrandom(srcblk, lblock); + + 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; @@ -155,7 +188,10 @@ void gen_write_bytes(const char *foutname, tfc_fsize offset, tfc_fsize nrbytes) } if (verbose) tfc_esay("done!"); - if (verbose || status_timer) print_crypt_status(0); + if (verbose || status_timer) { + print_crypt_status(TFC_SIGSTAT); + tfc_esay("\n"); + } xclose(fd); xexit(0);