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. Commitc98f704874
("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:c98f704874
("move: enable MoveMessages from msgstore") Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
parent
8f8dee8303
commit
1c9fc7b6b1
1 changed files with 13 additions and 2 deletions
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue