SIGTERM, SIGINT: exit immediately, don't try to postprocess even in verbose mode.
[tfcrypt.git] / tfcrypt.c
index 7e9ef8c16915ddb15f7a718516f0ca9cdd518730..83f6c69869a689b2505b691abf8b07c92dc2cca1 100644 (file)
--- a/tfcrypt.c
+++ b/tfcrypt.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:
  *
@@ -128,6 +128,12 @@ int main(int argc, char **argv)
 _baddfname:
        memset(s, 0, n);
 
+       if (!strcmp(progname, "iotool")) {
+               do_edcrypt = TFC_DO_PLAIN;
+               password = YES;
+               ctr_mode = TFC_MODE_PLAIN;
+       }
+
        opterr = 0;
        while ((c = getopt(argc, argv, "L:s:aU:C:r:K:t:Pkzxc:l:qedn:vV:pwE:O:S:AmM:R:Z:WHD:")) != -1) {
                switch (c) {
@@ -149,6 +155,29 @@ _baddfname:
                                        counter_opt = TFC_CTR_RAND;
                                else if (!strcasecmp(optarg, "zero"))
                                        counter_opt = TFC_CTR_ZERO;
+                               else if (strchr(optarg, ':')) {
+                                       char *ss, chr;
+
+                                       counter_opt = TFC_CTR_SSET;
+                                       n = sizeof(ctr);
+
+                                       s = d = optarg; t = NULL;
+                                       while ((s = strtok_r(d, ",", &t))) {
+                                               if (d) d = NULL;
+
+                                               if (n == 0) break;
+                                               ss = strchr(s, ':');
+                                               if (!ss) continue;
+                                               *ss = 0; ss++;
+                                               chr = (char)strtoul(s, &stoi, 16);
+                                               if (!str_empty(stoi)) continue;
+                                               x = (size_t)strtoul(ss, &stoi, 10);
+                                               if (!str_empty(stoi)) continue;
+                                               if (x > n) x = n;
+                                               memset(ctr+(sizeof(ctr)-n), (int)chr, x);
+                                               n -= x;
+                                       }
+                               }
                                else counter_file = sksum_hashlist_file = optarg;
                                break;
                        case 'C':
@@ -172,10 +201,10 @@ _baddfname:
                                ctr_mode = TFC_MODE_PLAIN;
                                break;
                        case 'e':
-                               do_edcrypt = TFC_DO_ENCRYPT;
+                               if (do_edcrypt != TFC_DO_PLAIN) do_edcrypt = TFC_DO_ENCRYPT;
                                break;
                        case 'd':
-                               do_edcrypt = TFC_DO_DECRYPT;
+                               if (do_edcrypt != TFC_DO_PLAIN) do_edcrypt = TFC_DO_DECRYPT;
                                break;
                        case 'D':
                                macbits = strtoul(optarg, &stoi, 10);
@@ -402,14 +431,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;
@@ -605,7 +641,7 @@ _nosalt:
                        lrem = lblock = sizeof(tmpdata);
                        if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(mkfd);
 _mkragain:             lio = xread(mkfd, pblk, lrem);
-                       if (lio == 0) do_stop = YES;
+                       if (lio == 0 && do_stop == NO) do_stop = YES;
                        if (lio != NOSIZE) ldone += lio;
                        else {
                                if (errno != EIO && catch_all_errors != YES)
@@ -1079,7 +1115,7 @@ _ctrwagain:       lio = xwrite(dfd, pblk, lrem);
                lrem = lblock = blk_len_adj(maxlen, total_processed_src, blksize);
                if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd);
 _ragain:       lio = xread(sfd, pblk, lrem);
-               if (lio == 0) do_stop = TFC_STOP_BEGAN;
+               if (lio == 0) do_stop = YES;
                if (lio != NOSIZE) ldone += lio;
                else {
                        if (errno != EIO && catch_all_errors != YES)
@@ -1159,8 +1195,6 @@ _nowrite: total_processed_dst += ldone;
                if (maxlen != NOFSIZE && total_processed_src >= maxlen) break;
        }
 
-       if (do_stop == TFC_STOP_FULL) goto _nomac;
-
        errno = 0;
        if (do_mac >= TFC_MAC_VRFY) {
                if (!do_mac_file) {
@@ -1305,12 +1339,14 @@ _macwagain:             lio = xwrite(dfd, pblk, lrem);
                memset(tmpdata, 0, sizeof(tmpdata));
        }
 
-_nomac:
-       if (verbose || status_timer || do_stop == TFC_STOP_FULL) print_crypt_status(0);
+       if (verbose || status_timer || do_stop == YES) print_crypt_status(0);
 
        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);