mirror of
https://github.com/mjl-/mox.git
synced 2025-07-12 22:14:40 +03:00
Before moving message files in imapserver and webmail API, ensure the message destination directory for the newly assigned IDs exist.
Example symptom, when deleting a message in the webmail (which moves to Trash): l=error m="duplicating message in old mailbox for current sessions" err="link data/accounts/mjl/msg/I/368638 data/accounts/mjl/msg/J/368640: no such file or directory" pkg=webmail Problem introduced a few weeks ago, where moving messages starting duplicating the message first, and the copy is erased once all references (in IMAP sessions) to the old mailbox have been removed.
This commit is contained in:
@ -8,6 +8,7 @@ import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"time"
|
||||
@ -451,6 +452,8 @@ func (x XOps) MessageMoveTx(ctx context.Context, log mlog.Log, acc *store.Accoun
|
||||
nkeywords := len(mbDst.Keywords)
|
||||
now := time.Now()
|
||||
|
||||
syncDirs := map[string]struct{}{}
|
||||
|
||||
for _, om := range l {
|
||||
if om.MailboxID != mbSrc.ID {
|
||||
if mbSrc.ID != 0 {
|
||||
@ -494,7 +497,14 @@ func (x XOps) MessageMoveTx(ctx context.Context, log mlog.Log, acc *store.Accoun
|
||||
err = tx.Insert(&om)
|
||||
x.Checkf(ctx, err, "inserting expunged message in old mailbox")
|
||||
|
||||
err = moxio.LinkOrCopy(log, acc.MessagePath(om.ID), acc.MessagePath(nm.ID), nil, false)
|
||||
dstPath := acc.MessagePath(om.ID)
|
||||
dstDir := filepath.Dir(dstPath)
|
||||
if _, ok := syncDirs[dstDir]; !ok {
|
||||
os.MkdirAll(dstDir, 0770)
|
||||
syncDirs[dstDir] = struct{}{}
|
||||
}
|
||||
|
||||
err = moxio.LinkOrCopy(log, dstPath, acc.MessagePath(nm.ID), nil, false)
|
||||
x.Checkf(ctx, err, "duplicating message in old mailbox for current sessions")
|
||||
newIDs = append(newIDs, nm.ID)
|
||||
// We don't sync the directory. In case of a crash and files disappearing, the
|
||||
@ -520,6 +530,11 @@ func (x XOps) MessageMoveTx(ctx context.Context, log mlog.Log, acc *store.Accoun
|
||||
changes = append(changes, nm.ChangeAddUID())
|
||||
}
|
||||
|
||||
for dir := range syncDirs {
|
||||
err := moxio.SyncDir(log, dir)
|
||||
x.Checkf(ctx, err, "sync directory")
|
||||
}
|
||||
|
||||
xflushMailbox()
|
||||
|
||||
changes = append(changes, mbDst.ChangeCounts())
|
||||
|
Reference in New Issue
Block a user