Hi

On Sun, Mar 25, 2018 at 10:10:23AM +0200, Salvatore Bonaccorso wrote:
[...]
> so updating via stretch-pu syncmaildir to have it fixed at next point
> release time would be possible.

The attached debdiff could be used in such case and guess the same can
be done for oldstable/jessie as well which would have the same problem
if using syncmaildir remote on a jessie running host.

Regards,
Salvatore
diff -Nru syncmaildir-1.2.6.2/debian/changelog 
syncmaildir-1.2.6.2/debian/changelog
--- syncmaildir-1.2.6.2/debian/changelog        2015-11-18 09:51:40.000000000 
+0100
+++ syncmaildir-1.2.6.2/debian/changelog        2018-03-25 10:33:27.000000000 
+0200
@@ -1,3 +1,14 @@
+syncmaildir (1.2.6.2-1+deb9u1) stretch; urgency=medium
+
+  * Non-maintainer upload.
+  * syncmaildir: recover from interrupt before renaming *.db.new.
+    Makes syncmaildir compatible with syncmaildir uploaded to unstable as
+    1.3.0-1 and bumping protocol version to fix the recovering issue when
+    syncmaildir was interrupted just before renaming *.db.new file.
+    Cf. #893998
+
+ -- Salvatore Bonaccorso <car...@debian.org>  Sun, 25 Mar 2018 10:33:27 +0200
+
 syncmaildir (1.2.6.2-1) unstable; urgency=medium
 
   * New upstream bugfix release (Closes: #800872)
diff -Nru syncmaildir-1.2.6.2/debian/patches/series 
syncmaildir-1.2.6.2/debian/patches/series
--- syncmaildir-1.2.6.2/debian/patches/series   2015-11-18 09:51:40.000000000 
+0100
+++ syncmaildir-1.2.6.2/debian/patches/series   2018-03-25 10:33:27.000000000 
+0200
@@ -1 +1,2 @@
 #link-against-gthread2
+syncmaildir-recover-from-interrupt-before-renaming-..patch
diff -Nru 
syncmaildir-1.2.6.2/debian/patches/syncmaildir-recover-from-interrupt-before-renaming-..patch
 
syncmaildir-1.2.6.2/debian/patches/syncmaildir-recover-from-interrupt-before-renaming-..patch
--- 
syncmaildir-1.2.6.2/debian/patches/syncmaildir-recover-from-interrupt-before-renaming-..patch
       1970-01-01 01:00:00.000000000 +0100
+++ 
syncmaildir-1.2.6.2/debian/patches/syncmaildir-recover-from-interrupt-before-renaming-..patch
       2018-03-25 10:33:27.000000000 +0200
@@ -0,0 +1,178 @@
+From: Enrico Tassi <ga...@fettunta.org>
+Date: Sat, 17 Mar 2018 15:23:23 +0100
+Subject: syncmaildir: recover from interrupt before renaming *.db.new
+Origin: https://git.kernel.org/linus/eed14208c795afa0cab796b3c10116f5bf0e0f78
+
+---
+
+diff --git a/DESIGN b/DESIGN
+index b1cd676..8bc9974 100644
+--- a/DESIGN
++++ b/DESIGN
+@@ -110,11 +110,22 @@ The protocol
+ The protocol is line oriented for commands, chunk oriented for data
+ transmission.
+ 
+-1. Both client and server send the following two messages, and check that
+-   they are equal to the ones sent by the other endpoint
++1. Both client and server send the following message, and check that
++   it is equal to the one sent by the other endpoint
+ 
+         protocol NUMBER
+-        dbfile SHA1
++
++   Then both client and server send the following message, where the
++   first SHA1 is the sha1 of the dbfile, while the second one is
++   the SHA1 of the "dbfile.new".
++
++        dbfile SHA1 SHA1
++
++   If "dbfile.new" is absent, then "-" is sent in place of a SHA1.
++
++   The "dbfile.new" is present only if the protocol is interrupted between
++   steps 4 and 5. Client and server pick the rightmost SHA1 the have in common
++   and rename the corresponding file "dbfile".   
+ 
+    This part of the protocol is called handshake
+ 
+diff --git a/smd-client b/smd-client
+index bf49a9e..59f9fdf 100755
+--- a/smd-client
++++ b/smd-client
+@@ -699,7 +699,7 @@ function main()
+       log_progress('Phase 0: handshake')
+       if firsttime then log_progress(' This phase opens the ssh connection.') 
end
+ 
+-      handshake(dbfile)
++      handshake(dbfile,newdb)
+       
+       -- receive and process commands
+       local commands = receive_delta(io.stdin, firsttime)
+diff --git a/smd-server b/smd-server
+index c5aa9ff..947a057 100755
+--- a/smd-server
++++ b/smd-server
+@@ -115,7 +115,7 @@ function main()
+ 
+ 
+       -- we check the protocol version and dbfile fingerprint
+-      handshake(dbfile)
++      handshake(dbfile,newdb)
+       
+       -- run mddiff and send the output to the client
+       local r = io.popen(mddiff,"r")
+diff --git a/syncmaildir.lua b/syncmaildir.lua
+index 677961d..33177f2 100644
+--- a/syncmaildir.lua
++++ b/syncmaildir.lua
+@@ -4,7 +4,7 @@
+ --
+ -- common code for smd-client/server
+ 
+-local PROTOCOL_VERSION="1.2"
++local PROTOCOL_VERSION="1.3"
+ 
+ local verbose = false
+ local dryrun = false
+@@ -302,7 +302,7 @@ function receive(inf,outfile)
+       return total
+ end
+ 
+-function handshake(dbfile)
++function handshake(dbfile,newdb)
+       -- send the protocol version and the dbfile sha1 sum
+       io.write('protocol ',PROTOCOL_VERSION,'\n')
+ 
+@@ -321,7 +321,18 @@ function handshake(dbfile)
+       if db_sha == 'ERROR' then
+               log_internal_error_and_fail('unreadable db file: '.. 
quote(dbfile),'handshake')
+       end
+-      io.write('dbfile ',db_sha,'\n')
++
++    -- if present, we read the sha1 of newdb
++      local ndb_sha = "-"
++      if io.open(newdb,'r') then
++        local inf = io.popen(MDDIFF..' --sha1sum '.. quote(newdb),'r')
++        ndb_sha, _ = inf:read('*a'):match('^(%S+)(.*)$')
++        inf:close()
++      end
++      if ndb_sha == 'ERROR' then ndb_sha = "-" end
++
++      -- we send both db SHA1
++      io.write('dbfile ',db_sha,' ',ndb_sha,'\n')
+       io.flush()
+ 
+       -- but if the file was not there and --dry-run, we should not create it
+@@ -351,8 +362,16 @@ function handshake(dbfile)
+               log_error "The client disconnected during handshake"
+               log_tags_and_fail('Network error',"handshake", 
"network",false,"retry")
+       end
+-      local sha = line:match('^dbfile (%S+)$')
+-      if sha ~= db_sha then
++      local sha, nsha = line:match('^dbfile (%S+) (%S+)$')
++
++      if nsha == db_sha then
++              -- db here more recent, the other endpoint will update
++      elseif sha == ndb_sha then
++              -- db more recent there, we rename here
++              os.rename(newdb,dbfile)
++      elseif sha == db_sha then
++              -- all good
++      else
+               log_error('Local dbfile and remote db file differ.')
+               log_error('Remove both files and push/pull again.')
+               log_tags_and_fail('Database mismatch',
+diff --git a/tests.d/pull-push/29-kill-before-rename-server 
b/tests.d/pull-push/29-kill-before-rename-server
+new file mode 100644
+index 0000000..52d950b
+--- /dev/null
++++ b/tests.d/pull-push/29-kill-before-rename-server
+@@ -0,0 +1,19 @@
++#!/bin/sh
++
++mpull -t
++assert $? 0 "failed mpull -t"
++echo DEBUG=true >> target/.smd/config.default
++
++mpull
++assert $? 0 "failed mpull"
++test_eq Mail target/Mail 
++
++for f in target/.smd/*.db.*; do
++      mv $f ${f}.new
++      echo 0 > $f
++done
++
++mpull
++assert $? 0 "failed mpull with .new files around"
++test_eq Mail target/Mail 
++
+diff --git a/tests.d/pull-push/30-kill-before-rename-client 
b/tests.d/pull-push/30-kill-before-rename-client
+new file mode 100644
+index 0000000..5b09e40
+--- /dev/null
++++ b/tests.d/pull-push/30-kill-before-rename-client
+@@ -0,0 +1,20 @@
++#!/bin/sh
++
++mpull -t
++assert $? 0 "failed mpull -t"
++echo DEBUG=true >> target/.smd/config.default
++
++mpull
++assert $? 0 "failed mpull"
++test_eq Mail target/Mail 
++
++for f in .smd/*.db.*; do
++      mv $f ${f}.new
++      echo 0 > $f
++done
++
++
++mpull
++assert $? 0 "failed mpull with .new files around"
++test_eq Mail target/Mail 
++
+-- 
+2.16.3
+

Reply via email to