--- /dev/null
+$Id: imap-response.txt,v 1.1 2000/05/08 13:49:06 cph Exp $
+
+Notes on IMAP server responses
+
++ <resp-text> ;continuation response
++ <base64> ;continuation response
+
+* OK <resp-text> ;status condition
+* NO <resp-text> ;status condition
+* BAD <resp-text> ;status condition
+* BYE <resp-text> ;fatal if not response to LOGOUT
+
+* FLAGS (#<flag>)
+* LIST (#<flag>) <delim> <mailbox>
+* LSUB (#<flag>) <delim> <mailbox>
+* SEARCH <nz-number> ...
+* STATUS <mailbox> (<status-attribute> <number> ...)
+* <number> EXISTS
+* <number> RECENT
+* <nz-number> EXPUNGE
+* <nz-number> FETCH (<message-attribute> <message-attribute> ...)
+* CAPABILITY <capability> ... IMAP4rev1 <capability> ...
+
+<tag> OK <resp-text> ;end of response to tagged command
+<tag> NO <resp-text> ;end of response to tagged command
+<tag> BAD <resp-text> ;end of response to tagged command
+
+
+<resp-text>
+ = <text>
+ = <text-mime2>
+ = [<resp-text-code>] <text>
+ = [<resp-text-code>] <text-mime2>
+
+<resp-text-code>
+ = ALERT
+ = PARSE
+ = PERMANENTFLAGS (#<pflag>)
+ = READ-ONLY
+ = READ-WRITE
+ = TRYCREATE
+ = UIDVALIDITY <nz-number>
+ = UNSEEN <nz-number>
+ = <atom>
+ = <atom> <text-except-close-bracket>
+
+<pflag>
+ = <flag>
+ = \*
+
+<flag>
+ = \<atom>
+ = <atom>
+
+<delim>
+ = "<quoted-char>"
+ = NIL
+
+<mailbox>
+ = INBOX
+ = <astring>
+
+<status-attribute>
+ = MESSAGES
+ = RECENT
+ = UIDNEXT
+ = UIDVALIDITY
+ = UNSEEN
+
+<message-attribute>
+ = ENVELOPE <envelope>
+ = FLAGS (<flag> ...)
+ = INTERNALDATE <date-time>
+ = RFC822 <nstring>
+ = RFC822.HEADER <nstring>
+ = RFC822.TEXT <nstring>
+ = RFC822.SIZE <number>
+ = BODY <body>
+ = BODYSTRUCTURE <body>
+ = BODY <section> <nstring>
+ = BODY <section> <number> <nstring>
+ = UID <nz-number>
+
+<envelope>
+ = (<nstring> ;date
+ <nstring> ;subject
+ <address-list> ;from
+ <address-list> ;sender
+ <address-list> ;reply-to
+ <address-list> ;to
+ <address-list> ;cc
+ <address-list> ;bcc
+ <nstring> ;in-reply-to
+ <nstring> ;message-id
+ )
+
+<address-list>
+ = (<address> <address> ...)
+ = NIL
+
+<address>
+ = (<nstring> ;name
+ <nstring> ;route-addr
+ <nstring> ;local-part
+ <nstring> ;domain-name
+ )
+
+<date-time> = "<date-day-fixed>-<month>-<4digit> <time> <zone>"
+<date-day-fixed>
+ = <digit>
+ = <2digit>
+<month>
+ = Jan
+ = Feb
+ = Mar
+ = Apr
+ = May
+ = Jun
+ = Jul
+ = Aug
+ = Sep
+ = Oct
+ = Nov
+ = Dec
+
+<time> = <2digit>:<2digit>:<2digit>
+<zone> = <sign><4digit>
+
+<body>
+ = (<body-type-1part>)
+ = (<body-type-mpart>)
+
+<body-type-mpart>
+ = <body><body> ... <string>
+ = <body><body> ... <string> <body-ext-mpart>
+<body-ext-mpart>
+ = <body-field-param>
+ = <body-field-param> <body-field-dsp> <body-field-lang> <body-extension> ...
+
+<body-type-1part>
+ = <body-type-basic>
+ = <body-type-basic> <body-ext-1part>
+ = <body-type-msg>
+ = <body-type-msg> <body-ext-1part>
+ = <body-type-text>
+ = <body-type-text> <body-ext-1part>
+<body-type-basic> = <string> <string> <body-fields>
+<body-type-msg> = "MESSAGE" "RFC822" <body-fields> <envelope> <body> <number>
+<body-type-text> = "TEXT" <string> <body-fields> <number>
+<body-ext-1part>
+ = <nstring>
+ = <nstring> <body-field-dsp>
+ = <nstring> <body-field-dsp> <body-field-lang> <body-extension> ...
+<body-field-dsp>
+ = (<string> <body-field-param>)
+ = NIL
+<body-field-lang>
+ = <nstring>
+ = (<astring> <astring> ...)
+<body-extension>
+ = <nstring>
+ = <number>
+ = (<body-extension> <body-extension> ...)
+<body-fields> = <body-field-param> <nstring> <nstring> <body-field-enc> <number>
+<body-field-param>
+ = (<string> <string> ...) ;even number of <string>s
+ = NIL
+
+
+<section>
+ = [<section-text>]
+ = [<nz-number>.<nz-number>. ... <section-text>]
+ = [<nz-number>.<nz-number>. ... MIME]
+<section-text>
+ = HEADER
+ = HEADER.FIELDS <header-list>
+ = HEADER.FIELDS.NOT <header-list>
+ = TEXT
+<header-list> = (<astring> <astring> ...)
+
+
+
+<capability>
+ = AUTH=<atom>
+ = <atom>
+
+
+
+<astring>
+ = <atom>
+ = <string>
+
+<nstring>
+ = NIL
+ = <string>
+
+<string>
+ = <quoted-string>
+ = <literal>
+
+
+;;; Base syntax types:
+
+<quoted-string> = "<quoted-char>..."
+<literal> = {<number>}\r\n<byte>...
+<atom> = <atom-char><atom-char>...
+<text> = <text-char><text-char>...
+<text-mime2> = =?<charset>?<encoding>?<encoded-text>?=
+<base64> = ;base64 characters
+<number> = <digit><digit>...
+<nz-number> = <number> ;not 0
+\f
+<server-response>
+ = (BAD <string-or-false> <response-text>)
+ | (BYE <response-text>)
+ | (CAPABILITY <symbol>*)
+ | (CONTINUE <response-text>)
+ | (EXISTS <nonnegative-exact-integer>)
+ | (EXPUNGE <nonnegative-exact-integer>)
+ | (FETCH <fetch-response>+)
+ | (FLAGS <symbol>*)
+ | (LIST <string-or-false> <string> <symbol>*)
+ | (LSUB <string-or-false> <string> <symbol>*)
+ | (NO <string-or-false> <response-text>)
+ | (OK <string-or-false> <response-text>)
+ | (PREAUTH <response-text>)
+ | (RECENT <nonnegative-exact-integer>)
+ | (SEARCH <positive-exact-integer>+)
+ | (STATUS <string> (<symbol> . <positive-exact-integer>)*)
+
+<response-text>
+ = <response-text-code> <string>
+ | <response-text-code>
+ (<string> ;charset
+ <string> ;encoding
+ <string>) ;encoded text
+
+<response-text-code>
+ = #F
+ | (ALERT)
+ | (BADCHARSET <string>*)
+ | (NEWNAME <string> <string>) ;old-name new-name
+ | (PARSE)
+ | (READ-ONLY)
+ | (READ-WRITE)
+ | (TRYCREATE)
+ | (UIDNEXT <positive-exact-integer>)
+ | (UIDVALIDITY <positive-exact-integer>)
+ | (UNSEEN <positive-exact-integer>)
+ | (PERMANENTFLAGS <symbol>*)
+ | (<symbol>)
+ | (<symbol> <string>)
+
+<fetch-response>
+ = (ENVELOPE <envelope>)
+ | (FLAGS (<symbol>*))
+ | (INTERNALDATE <string>)
+ | (RFC822 <string-or-false>)
+ | (RFC822.HEADER <string-or-false>)
+ | (RFC822.TEXT <string-or-false>)
+ | (RFC822.SIZE <nonnegative-exact-integer>)
+ | (BODY <body>)
+ | (BODY (<section> <string-or-false>))
+ | (BODY (<section> <nonnegative-exact-integer> <string-or-false>))
+ | (BODYSTRUCTURE <body>)
+ | (UID <positive-exact-integer>)
+
+<section>
+ = (<positive-exact-integer>+)
+ | (<positive-exact-integer>+ MIME)
+ | (<positive-exact-integer>* HEADER)
+ | (<positive-exact-integer>* TEXT)
+ | (<positive-exact-integer>* HEADER.FIELDS <header>+)
+ | (<positive-exact-integer>* HEADER.FIELDS.NOT <header>+)
+
+<envelope>
+ = (<string-or-false> ;date
+ <string-or-false> ;subject
+ <addr-list> ;from
+ <addr-list> ;sender
+ <addr-list> ;reply-to
+ <addr-list> ;to
+ <addr-list> ;cc
+ <addr-list> ;bcc
+ <string-or-false> ;in-reply-to
+ <string-or-false> ;message-id
+ )
+<addr-list>
+ = (<string-or-false> ;personal name
+ <string-or-false> ;source route
+ <string> ;mailbox name
+ <string> ;host name
+ )
+ | (#f #f <string> #f) ;start of group
+ | (#f #f #f #f) ;end of group
+
+<body> ;too complicated to describe
+\f
+Notes about handling responses:
+
+* Check CAPABILITY for IMAP4rev1 and refuse to deal if not present.
+
+* MUST record the following: FLAGS, EXISTS, RECENT, EXPUNGE. However,
+ we won't use RECENT, so ignore it.
+
+* Setup sequence:
+
+ 1. Select mailbox. Record FLAGS, PERMANENTFLAGS, EXISTS, and
+ UIDVALIDITY.
+
+ 2. For each message in mailbox, do FETCH ALL and record the results.
+
+ 3. Build summary buffer based on this information.
+
+* When user selects a message, do FETCH RFC822 and present it in the
+ buffer.
+
+* When EXISTS is received and doesn't match the current length, or
+ When UIDVALIDITY received and doesn't match the current value,
+ rebuild our model of the mailbox. Redo #1, #2, #3. Match up the
+ UID numbers with the stored message objects and adjust as needed.
+
+* When FLAGS or PERMANENTFLAGS received, record them.
+
+* When EXPUNGE received, delete the corresponding message object.
+
+* Probably should do something with READ-ONLY and READ-WRITE; ignore
+ them for now.
+\f
+(define conn (open-imap-socket "localhost" "cph-imap" "foobar"))
+* OK zurich Cyrus IMAP4 v1.5.19 server ready
+A0000 LOGIN cph-imap foobar
+(ok "A0000" () "User logged in")
+;Value: conn
+
+(imap-command conn "select" "inbox")
+A0001 select inbox
+(flags \answered \flagged \draft \deleted \seen)
+(ok () (permanentflags \answered \flagged \draft \deleted \seen \*) "")
+(exists 4)
+(recent 0)
+(ok () (uidvalidity 947120402) "")
+(ok "A0001" read-write "Completed")
+;Unspecified return value
+
+(imap-command conn "fetch" "1" "envelope")
+*** output flushed ***
+;Unspecified return value
+
+(imap-command conn "fetch" "1" "(envelope uid)")
+*** output flushed ***
+;Unspecified return value
+
+(imap-command conn "fetch" "1" "(envelope uid rfc822.size)")
+A0004 fetch 1 (envelope uid rfc822.size)
+(fetch
+ (uid 1)
+ (rfc822.size 639)
+ (envelope "Wed, 05 Jan 2000 20:01:10 -0500"
+ "test 1"
+ (("Chris Hanson" () "cph" "zurich.ai.mit.edu"))
+ (("Chris Hanson" () "cph" "zurich.ai.mit.edu"))
+ (("Chris Hanson" () "cph" "zurich.ai.mit.edu"))
+ ((() () "cph-imap" "zurich.ai.mit.edu"))
+ ()
+ ()
+ ()
+ "<E1261Ic-0001M8-00@flenser.ai.mit.edu>"))
+(ok "A0004" () "Completed")
+;Unspecified return value
+
+(imap-command conn "fetch" "1" "rfc822.header")
+*** output flushed ***
+;Unspecified return value
+
+(imap-command conn "fetch" "1" "all")
+A0006 fetch 1 all
+(fetch
+ (flags \answered \seen)
+ (internaldate " 5-Jan-2000 20:01:10 -0500")
+ (rfc822.size 639)
+ (envelope "Wed, 05 Jan 2000 20:01:10 -0500"
+ "test 1"
+ (("Chris Hanson" () "cph" "zurich.ai.mit.edu"))
+ (("Chris Hanson" () "cph" "zurich.ai.mit.edu"))
+ (("Chris Hanson" () "cph" "zurich.ai.mit.edu"))
+ ((() () "cph-imap" "zurich.ai.mit.edu"))
+ ()
+ ()
+ ()
+ "<E1261Ic-0001M8-00@flenser.ai.mit.edu>"))
+(ok "A0006" () "Completed")
+;Unspecified return value