summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Culverhouse <tim@timculverhouse.com>2022-08-24 09:49:32 -0500
committerRobin Jarry <robin@jarry.cc>2022-08-24 17:00:44 +0200
commit1c9fc7b6b1550f2eb556e9c7248496c5f41e57af (patch)
tree0e260f615fe7db796ae41b4b8dfb2d4f86e62c04
parent8f8dee83035d30e4b82c370489ceabec687eb6ad (diff)
downloadaerc-1c9fc7b6b1550f2eb556e9c7248496c5f41e57af.tar.gz
aerc-1c9fc7b6b1550f2eb556e9c7248496c5f41e57af.zip
maildir: remove filename encoded UID when moving messages
The built-in maildir.Dir.Move method performs an OS level file rename, which allows for preserving file creation time. Commit c98f70487417 ("move: enable MoveMessages from msgstore") enabled the use of the Move method for maildir. One particular maildir synchronizer (isync/mbsync) encodes the UID within the filename of the email and cannot recover if the UID is preserved during a move. mbsync encodes filenames like so: /path/to/email/{maildir-key},U={uid}:2,S OfflineIMAP encodes the UID within the filename, but also encodes a hash of the originating folder so that it can recover from a move without a rename of the underlying file. OfflineIMAP encodes like so: /path/to/email{maildir-key},U={uid},FMD5={folder-hash}:2,S Remove encoded UIDs of the form `,U={uid}` from filenames to prevent sync issues. Fixes: https://todo.sr.ht/~rjarry/aerc/75 Fixes: c98f70487417 ("move: enable MoveMessages from msgstore") Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--worker/maildir/container.go15
1 files changed, 13 insertions, 2 deletions
diff --git a/worker/maildir/container.go b/worker/maildir/container.go
index c5ac04ac..52bbf837 100644
--- a/worker/maildir/container.go
+++ b/worker/maildir/container.go
@@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
+ "regexp"
"sort"
"strings"
@@ -12,6 +13,10 @@ import (
"git.sr.ht/~rjarry/aerc/lib/uidstore"
)
+// uidReg matches filename encoded UIDs in maildirs synched with mbsync or
+// OfflineIMAP
+var uidReg = regexp.MustCompile(`,U=\d+`)
+
// A Container is a directory which contains other directories which adhere to
// the Maildir spec
type Container struct {
@@ -222,6 +227,12 @@ func (c *Container) moveMessage(dest maildir.Dir, src maildir.Dir, uid uint32) e
if !ok {
return fmt.Errorf("could not find key for message id %d", uid)
}
- err := src.Move(dest, key)
- return err
+ path, err := src.Filename(key)
+ if err != nil {
+ return fmt.Errorf("could not find path for message id %d", uid)
+ }
+ // Remove encoded UID information from the key to prevent sync issues
+ name := uidReg.ReplaceAllString(filepath.Base(path), "")
+ destPath := filepath.Join(string(dest), "cur", name)
+ return os.Rename(path, destPath)
}