mirror of
https://github.com/mjl-/mox.git
synced 2025-06-28 05:08:14 +03:00
Cleanup temporary files created during IMAP APPEND command.
Since a recent change (likely since implementing MULTIAPPEND), the temporary files weren't removed any more. When changing it, I must have had the wrong mental model about the MessageAdd method, assuming it would remove the temp file. Noticed during tests.
This commit is contained in:
parent
0857e81a6c
commit
a553a107f0
@ -166,7 +166,7 @@ func (c *conn) cmdxReplace(isUID bool, tag, cmd string, p *parser) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var file *os.File
|
var file *os.File
|
||||||
var newMsgPath string
|
var newID int64 // Delivered message ID, file removed on error.
|
||||||
var f io.Writer
|
var f io.Writer
|
||||||
var commit bool
|
var commit bool
|
||||||
|
|
||||||
@ -186,17 +186,14 @@ func (c *conn) cmdxReplace(isUID bool, tag, cmd string, p *parser) {
|
|||||||
var err error
|
var err error
|
||||||
file, err = store.CreateMessageTemp(c.log, "imap-replace")
|
file, err = store.CreateMessageTemp(c.log, "imap-replace")
|
||||||
xcheckf(err, "creating temp file for message")
|
xcheckf(err, "creating temp file for message")
|
||||||
newMsgPath = file.Name()
|
defer store.CloseRemoveTempFile(c.log, file, "temporary message file")
|
||||||
f = file
|
f = file
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if file != nil {
|
if !commit && newID != 0 {
|
||||||
err := file.Close()
|
p := c.account.MessagePath(newID)
|
||||||
c.xsanity(err, "close temporary file for replace")
|
err := os.Remove(p)
|
||||||
}
|
c.xsanity(err, "remove message file for replace after error")
|
||||||
if newMsgPath != "" && !commit {
|
|
||||||
err := os.Remove(newMsgPath)
|
|
||||||
c.xsanity(err, "remove temporary file for replace")
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -289,8 +286,7 @@ func (c *conn) cmdxReplace(isUID bool, tag, cmd string, p *parser) {
|
|||||||
|
|
||||||
err = c.account.MessageAdd(c.log, tx, &mbDst, &nm, file, store.AddOpts{})
|
err = c.account.MessageAdd(c.log, tx, &mbDst, &nm, file, store.AddOpts{})
|
||||||
xcheckf(err, "delivering message")
|
xcheckf(err, "delivering message")
|
||||||
// Update path to what is stored in the account. We may still have to clean it up on errors.
|
newID = nm.ID
|
||||||
newMsgPath = c.account.MessagePath(nm.ID)
|
|
||||||
|
|
||||||
changes = append(changes, nm.ChangeAddUID(), mbDst.ChangeCounts())
|
changes = append(changes, nm.ChangeAddUID(), mbDst.ChangeCounts())
|
||||||
if nkeywords != len(mbDst.Keywords) {
|
if nkeywords != len(mbDst.Keywords) {
|
||||||
|
@ -3275,24 +3275,19 @@ func (c *conn) cmdAppend(tag, cmd string, p *parser) {
|
|||||||
time time.Time
|
time time.Time
|
||||||
|
|
||||||
file *os.File // Message file we are appending. Can be nil if we are writing to a nopWriteCloser due to being over quota.
|
file *os.File // Message file we are appending. Can be nil if we are writing to a nopWriteCloser due to being over quota.
|
||||||
path string // Path if an actual file, either a temporary file, or of the message file stored in the account.
|
|
||||||
|
|
||||||
mw *message.Writer
|
mw *message.Writer
|
||||||
m store.Message
|
m store.Message // New message. Delivered file for m.ID is removed on error.
|
||||||
}
|
}
|
||||||
|
|
||||||
var appends []*appendMsg
|
var appends []*appendMsg
|
||||||
var commit bool
|
var commit bool
|
||||||
defer func() {
|
defer func() {
|
||||||
for _, a := range appends {
|
for _, a := range appends {
|
||||||
if a.file != nil {
|
if !commit && a.m.ID != 0 {
|
||||||
err := a.file.Close()
|
p := c.account.MessagePath(a.m.ID)
|
||||||
c.xsanity(err, "closing APPEND temporary file")
|
err := os.Remove(p)
|
||||||
}
|
c.xsanity(err, "cleaning up temporary append file after error")
|
||||||
|
|
||||||
if !commit && a.path != "" {
|
|
||||||
err := os.Remove(a.path)
|
|
||||||
c.xsanity(err, "removing APPEND temporary file")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -3385,7 +3380,7 @@ func (c *conn) cmdAppend(tag, cmd string, p *parser) {
|
|||||||
var err error
|
var err error
|
||||||
a.file, err = store.CreateMessageTemp(c.log, "imap-append")
|
a.file, err = store.CreateMessageTemp(c.log, "imap-append")
|
||||||
xcheckf(err, "creating temp file for message")
|
xcheckf(err, "creating temp file for message")
|
||||||
a.path = a.file.Name()
|
defer store.CloseRemoveTempFile(c.log, a.file, "temporary message file")
|
||||||
f = a.file
|
f = a.file
|
||||||
|
|
||||||
c.writelinef("+ ")
|
c.writelinef("+ ")
|
||||||
@ -3398,7 +3393,7 @@ func (c *conn) cmdAppend(tag, cmd string, p *parser) {
|
|||||||
var err error
|
var err error
|
||||||
a.file, err = store.CreateMessageTemp(c.log, "imap-append")
|
a.file, err = store.CreateMessageTemp(c.log, "imap-append")
|
||||||
xcheckf(err, "creating temp file for message")
|
xcheckf(err, "creating temp file for message")
|
||||||
a.path = a.file.Name()
|
defer store.CloseRemoveTempFile(c.log, a.file, "temporary message file")
|
||||||
f = a.file
|
f = a.file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3483,12 +3478,10 @@ func (c *conn) cmdAppend(tag, cmd string, p *parser) {
|
|||||||
// todo: do a single junk training
|
// todo: do a single junk training
|
||||||
err = c.account.MessageAdd(c.log, tx, &mb, &a.m, a.file, store.AddOpts{SkipDirSync: true})
|
err = c.account.MessageAdd(c.log, tx, &mb, &a.m, a.file, store.AddOpts{SkipDirSync: true})
|
||||||
xcheckf(err, "delivering message")
|
xcheckf(err, "delivering message")
|
||||||
// Update path to what is stored in the account. We may still have to clean it up on errors.
|
|
||||||
a.path = c.account.MessagePath(a.m.ID)
|
|
||||||
|
|
||||||
changes = append(changes, a.m.ChangeAddUID())
|
changes = append(changes, a.m.ChangeAddUID())
|
||||||
|
|
||||||
msgDirs[filepath.Dir(a.path)] = struct{}{}
|
msgDirs[filepath.Dir(c.account.MessagePath(a.m.ID))] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
changes = append(changes, mb.ChangeCounts())
|
changes = append(changes, mb.ChangeCounts())
|
||||||
|
@ -2043,6 +2043,11 @@ type AddOpts struct {
|
|||||||
|
|
||||||
// MessageAdd delivers a mail message to the account.
|
// MessageAdd delivers a mail message to the account.
|
||||||
//
|
//
|
||||||
|
// The file is hardlinked or copied, the caller must clean up the original file. If
|
||||||
|
// this call succeeds, but the database transaction with the change can't be
|
||||||
|
// committed, the caller must clean up the delivered message file identified by
|
||||||
|
// m.ID.
|
||||||
|
//
|
||||||
// If the message does not fit in the quota, an error with ErrOverQuota is returned
|
// If the message does not fit in the quota, an error with ErrOverQuota is returned
|
||||||
// and the mailbox and message are unchanged and the transaction can continue. For
|
// and the mailbox and message are unchanged and the transaction can continue. For
|
||||||
// other errors, the caller must abort the transaction.
|
// other errors, the caller must abort the transaction.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user