imapserver: always send special-use attributes for mailboxes

even if not asked for with the "return (special-use)" extended list parameter.
macos x mail does not request the special-use flags, but will use them when present.

for issue #66, thanks x8x for providing the imap protocol transcript that
showed how it is done!
This commit is contained in:
Mechiel Lukkien 2023-09-23 21:00:26 +02:00
parent f19f16bd8b
commit 55febe304e
No known key found for this signature in database
2 changed files with 7 additions and 6 deletions

View file

@ -58,7 +58,7 @@ func (c *conn) cmdList(tag, cmd string, p *parser) {
p.xspace() p.xspace()
patterns, isList := p.xmboxOrPat() patterns, isList := p.xmboxOrPat()
isExtended = isExtended || isList isExtended = isExtended || isList
var retSubscribed, retChildren, retSpecialUse bool var retSubscribed, retChildren bool
var retStatusAttrs []string var retStatusAttrs []string
if p.take(" RETURN (") { if p.take(" RETURN (") {
isExtended = true isExtended = true
@ -79,7 +79,8 @@ func (c *conn) cmdList(tag, cmd string, p *parser) {
retChildren = true retChildren = true
case "SPECIAL-USE": case "SPECIAL-USE":
// ../rfc/6154:478 // ../rfc/6154:478
retSpecialUse = true // We always include special-use mailbox flags. Mac OS X Mail 16.0 (sept 2023) does
// not ask for the flags, but does use them when given. ../rfc/6154:146
case "STATUS": case "STATUS":
// ../rfc/9051:7072 ../rfc/5819:181 // ../rfc/9051:7072 ../rfc/5819:181
p.xspace() p.xspace()
@ -189,7 +190,7 @@ func (c *conn) cmdList(tag, cmd string, p *parser) {
if !listSubscribed && retSubscribed && info.subscribed { if !listSubscribed && retSubscribed && info.subscribed {
flags = append(flags, bare(`\Subscribed`)) flags = append(flags, bare(`\Subscribed`))
} }
if retSpecialUse && info.mailbox != nil { if info.mailbox != nil {
if info.mailbox.Archive { if info.mailbox.Archive {
flags = append(flags, bare(`\Archive`)) flags = append(flags, bare(`\Archive`))
} }

View file

@ -27,13 +27,13 @@ func TestListBasic(t *testing.T) {
tc.xuntagged(ulist("Inbox")) tc.xuntagged(ulist("Inbox"))
tc.last(tc.client.List("%")) tc.last(tc.client.List("%"))
tc.xuntagged(ulist("Archive"), ulist("Drafts"), ulist("Inbox"), ulist("Junk"), ulist("Sent"), ulist("Trash")) tc.xuntagged(ulist("Archive", `\Archive`), ulist("Drafts", `\Drafts`), ulist("Inbox"), ulist("Junk", `\Junk`), ulist("Sent", `\Sent`), ulist("Trash", `\Trash`))
tc.last(tc.client.List("*")) tc.last(tc.client.List("*"))
tc.xuntagged(ulist("Archive"), ulist("Drafts"), ulist("Inbox"), ulist("Junk"), ulist("Sent"), ulist("Trash")) tc.xuntagged(ulist("Archive", `\Archive`), ulist("Drafts", `\Drafts`), ulist("Inbox"), ulist("Junk", `\Junk`), ulist("Sent", `\Sent`), ulist("Trash", `\Trash`))
tc.last(tc.client.List("A*")) tc.last(tc.client.List("A*"))
tc.xuntagged(ulist("Archive")) tc.xuntagged(ulist("Archive", `\Archive`))
tc.client.Create("Inbox/todo") tc.client.Create("Inbox/todo")