-E sync: reform logic. Prequery file position, jump over error hole.
authorAndrey Rys <rys@lynxlynx.ru>
Fri, 25 Jan 2019 08:45:51 +0000 (15:45 +0700)
committerAndrey Rys <rys@lynxlynx.ru>
Fri, 25 Jan 2019 08:45:51 +0000 (15:45 +0700)
Add -E lsync to turn on older version.
tfc_fdsize: properly return NOFSIZE on errors.

VERSION
tfc_base64.c
tfc_error.c
tfc_misc.c
tfc_skein.c
tfc_vars.c
tfcrypt.c
tfcrypt.h

diff --git a/VERSION b/VERSION
index 00750edc07d6415dcc07ae0351e9397b0222b7ba..b8626c4cff2849624fb67f87cd0ad72b163671ad 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3
+4
index b92ac9676a3bc567aaf97f167201cb1bb1b0e8d0..2498004d7211e13c164f9839022b0f8686b9815e 100644 (file)
@@ -68,6 +68,7 @@ void do_edbase64(char **fargv)
                pblk = srcblk;
                lblock = lrem = do_edcrypt == TFC_DO_DECRYPT ? TFC_B64_DWIDTH : TFC_B64_EWIDTH;
                ldone = 0;
+               if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd);
 _again:                lio = read(sfd, pblk, lrem);
                if (lio == 0) do_stop = YES;
                if (lio != NOSIZE) ldone += lio;
@@ -77,10 +78,12 @@ _again:             lio = read(sfd, pblk, lrem);
                        switch (error_action) {
                                case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", fargv[0]); goto _again; break;
                                case TFC_ERRACT_SYNC:
+                               case TFC_ERRACT_LSYNC:
                                        xerror(YES, NO, NO, "%s", fargv[0]);
                                        lio = ldone = lrem = lblock;
                                        memset(srcblk, 0, lio);
-                                       lseek(sfd, lio, SEEK_CUR);
+                                       if (rdpos == NOFSIZE) lseek(sfd, lio, SEEK_CUR);
+                                       else lseek(sfd, rdpos + lio, SEEK_SET);
                                        break;
                                default: xerror(NO, NO, NO, "%s", fargv[0]); break;
                        }
index 048c0bb480a17e618f0161cf88426e090d234150..e33131504fa1051b22b1f419202fd137b0d23a97 100644 (file)
@@ -212,9 +212,13 @@ void usage(void)
        tfc_say("    cont: print error if not quiet, then continue,");
        tfc_say("      no action to pad missing data is attempted.");
        tfc_say("      may be dangerous when working with block devices.");
-       tfc_say("    sync: print error if not quiet, then continue.");
+       tfc_say("    sync: print error if not quiet, then continue,");
        tfc_say("      pad missing data block with zeroes.");
-       tfc_say("      note that sync works only with read errors!");
+       tfc_say("    lsync: same as sync, but does not use SEEK_SET logic,");
+       tfc_say("      lsync uses only relative seek operations, and does not prequery");
+       tfc_say("      the current file position for exact offsets, which maybe unsafe.");
+       tfc_say("      For this reason, it is HIGHLY recommended to use sync instead!");
+       tfc_say("      Note that both sync and lsync work only with read errors!");
        tfc_say("  default error action is exit with printing status if not quiet.");
        tfc_say("  -E xall: turn on error actions above for all errors, not just EIO errors.");
        tfc_say("    This must be a separate option given before usual -E how option.");
index d1bb78368d2126bfa1a1b411178b1b79561a6d9f..e6af46ada39ca1b324649aa927c75c4c92411369 100644 (file)
@@ -100,14 +100,23 @@ tfc_fsize tfc_fdsize(int fd)
 
        cur = lseek(fd, 0L, SEEK_CUR);
        l = lseek(fd, 0L, SEEK_SET);
-       if (l == -1) return -1;
+       if (l == -1) return NOFSIZE;
        l = lseek(fd, 0L, SEEK_END);
-       if (l == -1) return -1;
+       if (l == -1) return NOFSIZE;
        lseek(fd, cur, SEEK_SET);
 
        return (tfc_fsize)l;
 }
 
+tfc_fsize tfc_fdgetpos(int fd)
+{
+       off_t t;
+
+       t = lseek(fd, 0L, SEEK_CUR);
+       if (t == -1) return NOFSIZE;
+       return (tfc_fsize)t;
+}
+
 tfc_fsize tfc_fnamesize(char *fname, tfc_yesno noexit)
 {
        int fnmfd;
index 369fc234bf2fe06e0335e032faa6e3a02822aa1e..6c595e1bcd206339a44ad9c84682853ce642ac65 100644 (file)
@@ -77,6 +77,7 @@ tfc_yesno skeinfd(void *hash, size_t bits, const void *key, int fd, tfc_fsize re
                pblk = skblk;
                lblock = lrem = blk_len_adj(readto, total, TFC_BLKSIZE);
                ldone = 0;
+               if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(fd);
 _again:                lio = read(fd, pblk, lrem);
                if (lio == 0) stop = YES;
                if (lio != NOSIZE) ldone += lio;
@@ -85,11 +86,13 @@ _again:             lio = read(fd, pblk, lrem);
                        switch (error_action) {
                                case TFC_ERRACT_CONT: xerror(YES, NO, NO, "skeinfd: %d", fd); goto _again; break;
                                case TFC_ERRACT_SYNC:
+                               case TFC_ERRACT_LSYNC:
                                        xerror(YES, NO, NO, "skeinfd: %d", fd);
                                        lio = lrem = ldone = lblock;
                                        total += lio;
                                        memset(skblk, 0, lio);
-                                       lseek(fd, lio, SEEK_CUR);
+                                       if (rdpos == NOFSIZE) lseek(fd, lio, SEEK_CUR);
+                                       else lseek(fd, rdpos + lio, SEEK_SET);
                                        break;
                                default: goto _fail; break;
                        }
index 498633425c722475543e0cf98533876245aabd0f..5f75952bdad9601aa0fbad0108eb1250ffe9f626 100644 (file)
@@ -45,6 +45,7 @@ tfc_fsize iseek_blocks, iseek, oseek, maxlen = NOFSIZE;
 tfc_fsize total_processed_src, total_processed_dst;
 tfc_fsize delta_processed;
 tfc_fsize genrandom_nr_bytes, genzero_nr_bytes;
+tfc_fsize rdpos = NOFSIZE;
 int sfd, kfd = -1, dfd = 1;
 struct stat s_stat;
 size_t blksize = TFC_BLKSIZE, xtsblocks = TFC_XTSBLOCKS;
index c544cfd01ee256be65a17ae622f1aab07e4ffc3a..07939a74ddbd8de92cf40b8cfeab539bdb0b0e8a 100644 (file)
--- a/tfcrypt.c
+++ b/tfcrypt.c
@@ -177,6 +177,8 @@ int main(int argc, char **argv)
                                        error_action = TFC_ERRACT_CONT;
                                else if (!strcmp(optarg, "sync"))
                                        error_action = TFC_ERRACT_SYNC;
+                               else if (!strcmp(optarg, "lsync"))
+                                       error_action = TFC_ERRACT_LSYNC;
                                else xerror(NO, YES, YES, "invalid error action %s specified", optarg);
                                break;
                        case 'O':
@@ -503,6 +505,7 @@ _nosalt:
                        pblk = tmpdata;
                        ldone = 0;
                        lrem = lblock = sizeof(tmpdata);
+                       if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(mkfd);
 _mkragain:             lio = read(mkfd, pblk, lrem);
                        if (lio == 0) do_stop = YES;
                        if (lio != NOSIZE) ldone += lio;
@@ -512,10 +515,12 @@ _mkragain:                lio = read(mkfd, pblk, lrem);
                                switch (error_action) {
                                        case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", mackeyf); goto _mkragain; break;
                                        case TFC_ERRACT_SYNC:
+                                       case TFC_ERRACT_LSYNC:
                                                xerror(YES, NO, NO, "%s", mackeyf);
                                                lio = ldone = lrem = lblock;
                                                memset(tmpdata, 0, lio);
-                                               lseek(mkfd, lio, SEEK_CUR);
+                                               if (rdpos == NOFSIZE) lseek(mkfd, lio, SEEK_CUR);
+                                               else lseek(mkfd, rdpos + lio, SEEK_SET);
                                                break;
                                        default: xerror(NO, NO, NO, "%s", mackeyf); break;
                                }
@@ -646,6 +651,7 @@ _nokeyfd:
                pblk = ctr;
                ldone = 0;
                lrem = lblock = ctrsz;
+               if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd);
 _ctrragain:    lio = read(sfd, pblk, lrem);
                if (lio != NOSIZE) ldone += lio;
                else {
@@ -654,10 +660,12 @@ _ctrragain:       lio = read(sfd, pblk, lrem);
                        switch (error_action) {
                                case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", srcfname); goto _ctrragain; break;
                                case TFC_ERRACT_SYNC:
+                               case TFC_ERRACT_LSYNC:
                                        xerror(YES, NO, NO, "%s", srcfname);
                                        lio = ldone = lrem = lblock;
                                        memset(ctr, 0, lio);
-                                       lseek(sfd, lio, SEEK_CUR);
+                                       if (rdpos == NOFSIZE) lseek(sfd, lio, SEEK_CUR);
+                                       else lseek(sfd, rdpos + lio, SEEK_SET);
                                        break;
                                default: xerror(NO, NO, NO, "%s", srcfname); break;
                        }
@@ -688,6 +696,7 @@ _ctrskip1:
                pblk = key;
 _xts2key:      ldone = 0;
                lrem = lblock = TF_FROM_BITS(TFC_KEY_BITS);
+               if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(kfd);
 _keyragain:    lio = read(kfd, pblk, lrem);
                if (lio != NOSIZE) ldone += lio;
                else {
@@ -696,10 +705,12 @@ _keyragain:       lio = read(kfd, pblk, lrem);
                        switch (error_action) {
                                case TFC_ERRACT_CONT: xerror(YES, NO, NO, "reading key"); goto _keyragain; break;
                                case TFC_ERRACT_SYNC:
+                               case TFC_ERRACT_LSYNC:
                                        xerror(YES, NO, NO, "reading key");
                                        lio = ldone = lrem = lblock;
                                        memset(key, 0, lio);
-                                       lseek(kfd, lio, SEEK_CUR);
+                                       if (rdpos == NOFSIZE) lseek(kfd, lio, SEEK_CUR);
+                                       else lseek(kfd, rdpos + lio, SEEK_SET);
                                        break;
                                default: xerror(NO, NO, NO, "reading key"); break;
                        }
@@ -969,6 +980,7 @@ _ctrwagain: lio = write(dfd, pblk, lrem);
                pblk = srcblk;
                ldone = 0;
                lrem = lblock = blk_len_adj(maxlen, total_processed_src, blksize);
+               if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd);
 _ragain:       lio = read(sfd, pblk, lrem);
                if (lio == 0) do_stop = TFC_STOP_BEGAN;
                if (lio != NOSIZE) ldone += lio;
@@ -978,10 +990,12 @@ _ragain:  lio = read(sfd, pblk, lrem);
                        switch (error_action) {
                                case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", srcfname); goto _ragain; break;
                                case TFC_ERRACT_SYNC:
+                               case TFC_ERRACT_LSYNC:
                                        xerror(YES, NO, NO, "%s", srcfname);
                                        lio = ldone = lrem = lblock;
                                        memset(srcblk, 0, lio);
-                                       lseek(sfd, lio, SEEK_CUR);
+                                       if (rdpos == NOFSIZE) lseek(sfd, lio, SEEK_CUR);
+                                       else lseek(sfd, rdpos + lio, SEEK_SET);
                                        break;
                                default: xerror(NO, NO, NO, "%s", srcfname); break;
                        }
@@ -1056,6 +1070,7 @@ _nowrite: total_processed_dst += ldone;
                        pblk = macvrfy;
                        ldone = 0;
                        lrem = lblock = TF_FROM_BITS(macbits);
+                       if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd);
 _macragain:            lio = read(sfd, pblk, lrem);
                        if (lio != NOSIZE) ldone += lio;
                        else {
@@ -1064,10 +1079,12 @@ _macragain:             lio = read(sfd, pblk, lrem);
                                switch (error_action) {
                                        case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", srcfname); goto _macragain; break;
                                        case TFC_ERRACT_SYNC:
+                                       case TFC_ERRACT_LSYNC:
                                                xerror(YES, NO, NO, "%s", srcfname);
                                                lio = ldone = lrem = lblock;
                                                memset(macvrfy, 0, lio);
-                                               lseek(sfd, lio, SEEK_CUR);
+                                               if (rdpos == NOFSIZE) lseek(sfd, lio, SEEK_CUR);
+                                               else lseek(sfd, rdpos + lio, SEEK_SET);
                                                break;
                                        default: xerror(NO, NO, NO, "%s", srcfname); break;
                                }
index fcc75eea79c54a518fb6c5c3379a1b73152ce458..6efb5e3c841ecb9cb834c321f24fe4ffeda84cfa 100644 (file)
--- a/tfcrypt.h
+++ b/tfcrypt.h
@@ -132,6 +132,7 @@ extern tfc_fsize iseek_blocks, iseek, oseek, maxlen;
 extern tfc_fsize total_processed_src, total_processed_dst;
 extern tfc_fsize delta_processed;
 extern tfc_fsize genrandom_nr_bytes, genzero_nr_bytes;
+extern tfc_fsize rdpos;
 extern int sfd, kfd, dfd;
 extern struct stat s_stat;
 extern size_t blksize, xtsblocks;
@@ -174,6 +175,7 @@ void xclose(int fd);
 const char *tfc_modename(int mode);
 void tfc_getcurtime(tfc_useconds *tx);
 tfc_fsize tfc_fdsize(int fd);
+tfc_fsize tfc_fdgetpos(int fd);
 tfc_fsize tfc_fnamesize(char *fname, tfc_yesno noexit);
 tfc_fsize tfc_modifysize(tfc_fsize szmodify, const char *szspec);
 void fcopy_matime(int fd, const struct stat *st);
@@ -198,7 +200,7 @@ void do_benchmark(tfc_useconds useconds, double dseconds);
 
 enum { NO, YES };
 
-enum { TFC_ERRACT_EXIT, TFC_ERRACT_CONT, TFC_ERRACT_SYNC };
+enum { TFC_ERRACT_EXIT, TFC_ERRACT_CONT, TFC_ERRACT_SYNC, TFC_ERRACT_LSYNC };
 enum { TFC_STOP_BEGAN = 1, TFC_STOP_FULL };
 enum { TFC_DO_PLAIN, TFC_DO_ENCRYPT, TFC_DO_DECRYPT };
 enum { TFC_MAC_DROP = -1, TFC_MAC_SIGN = 1, TFC_MAC_VRFY, TFC_MAC_JUST_VRFY };