Forked the emersion/go-imap v1 project.

This commit is contained in:
2025-05-01 11:58:18 +03:00
commit bcc3f95e8e
107 changed files with 16268 additions and 0 deletions

125
imapserver/status.go Normal file
View File

@@ -0,0 +1,125 @@
package imapserver
import (
"strings"
"github.com/emersion/go-imap/v2"
"github.com/emersion/go-imap/v2/internal/imapwire"
)
func (c *Conn) handleStatus(dec *imapwire.Decoder) error {
var mailbox string
if !dec.ExpectSP() || !dec.ExpectMailbox(&mailbox) || !dec.ExpectSP() {
return dec.Err()
}
var options imap.StatusOptions
err := dec.ExpectList(func() error {
err := readStatusItem(dec, &options)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
if !dec.ExpectCRLF() {
return dec.Err()
}
if options.NumRecent && !c.server.options.caps().Has(imap.CapIMAP4rev1) {
return &imap.Error{
Type: imap.StatusResponseTypeBad,
Text: "Unknown STATUS data item",
}
}
if err := c.checkState(imap.ConnStateAuthenticated); err != nil {
return err
}
data, err := c.session.Status(mailbox, &options)
if err != nil {
return err
}
return c.writeStatus(data, &options)
}
func (c *Conn) writeStatus(data *imap.StatusData, options *imap.StatusOptions) error {
enc := newResponseEncoder(c)
defer enc.end()
enc.Atom("*").SP().Atom("STATUS").SP().Mailbox(data.Mailbox).SP()
listEnc := enc.BeginList()
if options.NumMessages {
listEnc.Item().Atom("MESSAGES").SP().Number(*data.NumMessages)
}
if options.UIDNext {
listEnc.Item().Atom("UIDNEXT").SP().UID(data.UIDNext)
}
if options.UIDValidity {
listEnc.Item().Atom("UIDVALIDITY").SP().Number(data.UIDValidity)
}
if options.NumUnseen {
listEnc.Item().Atom("UNSEEN").SP().Number(*data.NumUnseen)
}
if options.NumDeleted {
listEnc.Item().Atom("DELETED").SP().Number(*data.NumDeleted)
}
if options.Size {
listEnc.Item().Atom("SIZE").SP().Number64(*data.Size)
}
if options.AppendLimit {
listEnc.Item().Atom("APPENDLIMIT").SP()
if data.AppendLimit != nil {
enc.Number(*data.AppendLimit)
} else {
enc.NIL()
}
}
if options.DeletedStorage {
listEnc.Item().Atom("DELETED-STORAGE").SP().Number64(*data.DeletedStorage)
}
if options.NumRecent {
listEnc.Item().Atom("RECENT").SP().Number(*data.NumRecent)
}
listEnc.End()
return enc.CRLF()
}
func readStatusItem(dec *imapwire.Decoder, options *imap.StatusOptions) error {
var name string
if !dec.ExpectAtom(&name) {
return dec.Err()
}
switch strings.ToUpper(name) {
case "MESSAGES":
options.NumMessages = true
case "UIDNEXT":
options.UIDNext = true
case "UIDVALIDITY":
options.UIDValidity = true
case "UNSEEN":
options.NumUnseen = true
case "DELETED":
options.NumDeleted = true
case "SIZE":
options.Size = true
case "APPENDLIMIT":
options.AppendLimit = true
case "DELETED-STORAGE":
options.DeletedStorage = true
case "RECENT":
options.NumRecent = true
default:
return &imap.Error{
Type: imap.StatusResponseTypeBad,
Text: "Unknown STATUS data item",
}
}
return nil
}