Forked the emersion/go-imap v1 project.
This commit is contained in:
125
imapserver/status.go
Normal file
125
imapserver/status.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user