diff options
author | Tim Culverhouse <tim@timculverhouse.com> | 2022-08-24 09:49:32 -0500 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-08-24 17:00:44 +0200 |
commit | 1c9fc7b6b1550f2eb556e9c7248496c5f41e57af (patch) | |
tree | 0e260f615fe7db796ae41b4b8dfb2d4f86e62c04 /worker/maildir | |
parent | 8f8dee83035d30e4b82c370489ceabec687eb6ad (diff) | |
download | aerc-1c9fc7b6b1550f2eb556e9c7248496c5f41e57af.tar.gz |
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>
Diffstat (limited to 'worker/maildir')
-rw-r--r-- | worker/maildir/container.go | 15 |
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) } |