private void EXAMINE(string cmdTag,string cmdText) { /* RFC 3501 6.3.2. EXAMINE Command. Arguments: mailbox name Responses: REQUIRED untagged responses: FLAGS, EXISTS, RECENT REQUIRED OK untagged responses: UNSEEN, PERMANENTFLAGS, UIDNEXT, UIDVALIDITY Result: OK - examine completed, now in selected state NO - examine failure, now in authenticated state: no such mailbox, can't access mailbox BAD - command unknown or arguments invalid The EXAMINE command is identical to SELECT and returns the same output; however, the selected mailbox is identified as read-only. No changes to the permanent state of the mailbox, including per-user state, are permitted; in particular, EXAMINE MUST NOT cause messages to lose the \Recent flag. The text of the tagged OK response to the EXAMINE command MUST begin with the "[READ-ONLY]" response code. Example: C: A932 EXAMINE blurdybloop S: * 17 EXISTS S: * 2 RECENT S: * OK [UNSEEN 8] Message 8 is first unseen S: * OK [UIDVALIDITY 3857529045] UIDs valid S: * OK [UIDNEXT 4392] Predicted next UID S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) S: * OK [PERMANENTFLAGS ()] No permanent flags permitted S: A932 OK [READ-ONLY] EXAMINE completed */ /* 5738 3.2. UTF8 Parameter to SELECT and EXAMINE The "UTF8=ACCEPT" capability also indicates that the server supports the "UTF8" parameter to SELECT and EXAMINE. When a mailbox is selected with the "UTF8" parameter, it alters the behavior of all IMAP commands related to message sizes, message headers, and MIME body headers so they refer to the message with UTF-8 headers. If the mailstore is not UTF-8 header native and the SELECT or EXAMINE command with UTF-8 header modifier succeeds, then the server MUST return results as if the mailstore were UTF-8 header native with upconversion requirements as described in Section 8. The server MAY reject the SELECT or EXAMINE command with the [NOT-UTF-8] response code, unless the "UTF8=ALL" or "UTF8=ONLY" capability is advertised. Servers MAY include mailboxes that can only be selected or examined if the "UTF8" parameter is provided. However, such mailboxes MUST NOT be included in the output of an unextended LIST, LSUB, or equivalent command. If a client attempts to SELECT or EXAMINE such mailboxes without the "UTF8" parameter, the server MUST reject the command with a [UTF-8-ONLY] response code. As a result, such mailboxes will not be accessible by IMAP clients written prior to this specification and are discouraged unless the server advertises "UTF8=ONLY" or the server implements IMAP4 LIST Command Extensions utf8-select-param = "UTF8" ;; Conforms to <select-param> from RFC 4466 C: a SELECT newmailbox (UTF8) S: ... S: a OK SELECT completed C: b FETCH 1 (SIZE ENVELOPE BODY) S: ... < UTF-8 header native results > S: b OK FETCH completed C: c EXAMINE legacymailbox (UTF8) S: c NO [NOT-UTF-8] Mailbox does not support UTF-8 access */ if(!this.IsAuthenticated){ m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"NO","Authentication required.")); return; } // Store start time long startTime = DateTime.Now.Ticks; // Unselect folder if any selected. if(m_pSelectedFolder != null){ m_pSelectedFolder = null; } string[] args = TextUtils.SplitQuotedString(cmdText,' '); if(args.Length >= 2){ // At moment we don't support UTF-8 mailboxes. if(string.Equals(args[1],"(UTF8)",StringComparison.InvariantCultureIgnoreCase)){ m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"NO",new IMAP_t_orc_Unknown("NOT-UTF-8"),"Mailbox does not support UTF-8 access.")); } else{ m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"BAD","Error in arguments.")); } return; } string folder = TextUtils.UnQuoteString(IMAP_Utils.DecodeMailbox(cmdText)); IMAP_e_Select e = OnSelect(cmdTag,folder); if(e.ErrorResponse == null){ IMAP_e_MessagesInfo eMessagesInfo = OnGetMessagesInfo(folder); m_pResponseSender.SendResponseAsync(new IMAP_r_u_Exists(eMessagesInfo.Exists)); m_pResponseSender.SendResponseAsync(new IMAP_r_u_Recent(eMessagesInfo.Recent)); if(eMessagesInfo.FirstUnseen > -1){ m_pResponseSender.SendResponseAsync(new IMAP_r_u_ServerStatus("OK",new IMAP_t_orc_Unseen(eMessagesInfo.FirstUnseen),"Message " + eMessagesInfo.FirstUnseen + " is the first unseen.")); } m_pResponseSender.SendResponseAsync(new IMAP_r_u_ServerStatus("OK",new IMAP_t_orc_UidNext((int)eMessagesInfo.UidNext),"Predicted next message UID.")); m_pResponseSender.SendResponseAsync(new IMAP_r_u_ServerStatus("OK",new IMAP_t_orc_UidValidity(e.FolderUID),"Folder UID value.")); m_pResponseSender.SendResponseAsync(new IMAP_r_u_Flags(e.Flags.ToArray())); m_pResponseSender.SendResponseAsync(new IMAP_r_u_ServerStatus("OK",new IMAP_t_orc_PermanentFlags(e.PermanentFlags.ToArray()),"Avaliable permanent flags.")); m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"OK",new IMAP_t_orc_ReadOnly(),"EXAMINE completed in " + ((DateTime.Now.Ticks - startTime) / (decimal)10000000).ToString("f2") + " seconds.")); m_pSelectedFolder = new _SelectedFolder(folder,e.IsReadOnly,eMessagesInfo.MessagesInfo); m_pSelectedFolder.Reindex(); } else{ m_pResponseSender.SendResponseAsync(e.ErrorResponse); } }
private void SELECT(string cmdTag,string cmdText) { /* RFC 3501 6.3.1. SELECT Command. Arguments: mailbox name Responses: REQUIRED untagged responses: FLAGS, EXISTS, RECENT REQUIRED OK untagged responses: UNSEEN, PERMANENTFLAGS, UIDNEXT, UIDVALIDITY Result: OK - select completed, now in selected state NO - select failure, now in authenticated state: no such mailbox, can't access mailbox BAD - command unknown or arguments invalid The SELECT command selects a mailbox so that messages in the mailbox can be accessed. Before returning an OK to the client, the server MUST send the following untagged data to the client. Note that earlier versions of this protocol only required the FLAGS, EXISTS, and RECENT untagged data; consequently, client implementations SHOULD implement default behavior for missing data as discussed with the individual item. FLAGS Defined flags in the mailbox. See the description of the FLAGS response for more detail. <n> EXISTS The number of messages in the mailbox. See the description of the EXISTS response for more detail. <n> RECENT The number of messages with the \Recent flag set. See the description of the RECENT response for more detail. OK [UNSEEN <n>] The message sequence number of the first unseen message in the mailbox. If this is missing, the client can not make any assumptions about the first unseen message in the mailbox, and needs to issue a SEARCH command if it wants to find it. OK [PERMANENTFLAGS (<list of flags>)] A list of message flags that the client can change permanently. If this is missing, the client should assume that all flags can be changed permanently. OK [UIDNEXT <n>] The next unique identifier value. Refer to section 2.3.1.1 for more information. If this is missing, the client can not make any assumptions about the next unique identifier value. OK [UIDVALIDITY <n>] The unique identifier validity value. Refer to section 2.3.1.1 for more information. If this is missing, the server does not support unique identifiers. Only one mailbox can be selected at a time in a connection; simultaneous access to multiple mailboxes requires multiple connections. The SELECT command automatically deselects any currently selected mailbox before attempting the new selection. Consequently, if a mailbox is selected and a SELECT command that fails is attempted, no mailbox is selected. If the client is permitted to modify the mailbox, the server SHOULD prefix the text of the tagged OK response with the "[READ-WRITE]" response code. If the client is not permitted to modify the mailbox but is permitted read access, the mailbox is selected as read-only, and the server MUST prefix the text of the tagged OK response to SELECT with the "[READ-ONLY]" response code. Read-only access through SELECT differs from the EXAMINE command in that certain read-only mailboxes MAY permit the change of permanent state on a per-user (as opposed to global) basis. Netnews messages marked in a server-based .newsrc file are an example of such per-user permanent state that can be modified with read-only mailboxes. Example: C: A142 SELECT INBOX S: * 172 EXISTS S: * 1 RECENT S: * OK [UNSEEN 12] Message 12 is first unseen S: * OK [UIDVALIDITY 3857529045] UIDs valid S: * OK [UIDNEXT 4392] Predicted next UID S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited S: A142 OK [READ-WRITE] SELECT completed */ /* 5738 3.2. UTF8 Parameter to SELECT and EXAMINE The "UTF8=ACCEPT" capability also indicates that the server supports the "UTF8" parameter to SELECT and EXAMINE. When a mailbox is selected with the "UTF8" parameter, it alters the behavior of all IMAP commands related to message sizes, message headers, and MIME body headers so they refer to the message with UTF-8 headers. If the mailstore is not UTF-8 header native and the SELECT or EXAMINE command with UTF-8 header modifier succeeds, then the server MUST return results as if the mailstore were UTF-8 header native with upconversion requirements as described in Section 8. The server MAY reject the SELECT or EXAMINE command with the [NOT-UTF-8] response code, unless the "UTF8=ALL" or "UTF8=ONLY" capability is advertised. Servers MAY include mailboxes that can only be selected or examined if the "UTF8" parameter is provided. However, such mailboxes MUST NOT be included in the output of an unextended LIST, LSUB, or equivalent command. If a client attempts to SELECT or EXAMINE such mailboxes without the "UTF8" parameter, the server MUST reject the command with a [UTF-8-ONLY] response code. As a result, such mailboxes will not be accessible by IMAP clients written prior to this specification and are discouraged unless the server advertises "UTF8=ONLY" or the server implements IMAP4 LIST Command Extensions utf8-select-param = "UTF8" ;; Conforms to <select-param> from RFC 4466 C: a SELECT newmailbox (UTF8) S: ... S: a OK SELECT completed C: b FETCH 1 (SIZE ENVELOPE BODY) S: ... < UTF-8 header native results > S: b OK FETCH completed C: c EXAMINE legacymailbox (UTF8) S: c NO [NOT-UTF-8] Mailbox does not support UTF-8 access */ // Store start time long startTime = DateTime.Now.Ticks; if(!this.IsAuthenticated){ m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"NO","Authentication required.")); return; } // Unselect folder if any selected. if(m_pSelectedFolder != null){ m_pSelectedFolder = null; } string[] args = TextUtils.SplitQuotedString(cmdText,' '); if(args.Length >= 2){ // At moment we don't support UTF-8 mailboxes. if(string.Equals(args[1],"(UTF8)",StringComparison.InvariantCultureIgnoreCase)){ m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"NO",new IMAP_t_orc_Unknown("NOT-UTF-8"),"Mailbox does not support UTF-8 access.")); } else{ m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"BAD","Error in arguments.")); } return; } try{ string folder = TextUtils.UnQuoteString(IMAP_Utils.DecodeMailbox(cmdText)); IMAP_e_Select e = OnSelect(cmdTag,folder); if(e.ErrorResponse == null){ IMAP_e_MessagesInfo eMessagesInfo = OnGetMessagesInfo(folder); m_pResponseSender.SendResponseAsync(new IMAP_r_u_Exists(eMessagesInfo.Exists)); m_pResponseSender.SendResponseAsync(new IMAP_r_u_Recent(eMessagesInfo.Recent)); if(eMessagesInfo.FirstUnseen > -1){ m_pResponseSender.SendResponseAsync(new IMAP_r_u_ServerStatus("OK",new IMAP_t_orc_Unseen(eMessagesInfo.FirstUnseen),"Message " + eMessagesInfo.FirstUnseen + " is the first unseen.")); } m_pResponseSender.SendResponseAsync(new IMAP_r_u_ServerStatus("OK",new IMAP_t_orc_UidNext((int)eMessagesInfo.UidNext),"Predicted next message UID.")); m_pResponseSender.SendResponseAsync(new IMAP_r_u_ServerStatus("OK",new IMAP_t_orc_UidValidity(e.FolderUID),"Folder UID value.")); m_pResponseSender.SendResponseAsync(new IMAP_r_u_Flags(e.Flags.ToArray())); m_pResponseSender.SendResponseAsync(new IMAP_r_u_ServerStatus("OK",new IMAP_t_orc_PermanentFlags(e.PermanentFlags.ToArray()),"Avaliable permanent flags.")); m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"OK",new IMAP_t_orc_Unknown(e.IsReadOnly ? "READ-ONLY" : "READ-WRITE"),"SELECT completed in " + ((DateTime.Now.Ticks - startTime) / (decimal)10000000).ToString("f2") + " seconds.")); m_pSelectedFolder = new _SelectedFolder(folder,e.IsReadOnly,eMessagesInfo.MessagesInfo); m_pSelectedFolder.Reindex(); } else{ m_pResponseSender.SendResponseAsync(e.ErrorResponse); } } catch(Exception x){ m_pResponseSender.SendResponseAsync(new IMAP_r_ServerStatus(cmdTag,"NO","NO Error: " + x.Message)); } }