Once a mailbox has been selected via either a SELECT or an EXAMINE command, the IMAP session enters the selected state. From here, the client may operate on mail messages themselves. If the mailbox has been selected for writing, the client can make permanent changes to the messages in the mailbox.
Commands available in the Selected State give the client the ability to gain access to message contents, search messages or parts of messages for strings, change the values of certain message parts, and copy messages. Additionally, some housekeeping commands (CHECK and CLOSE) exist in this state to allow for implementation dependent actions and to close the mailbox. The CHECK command can be issued to a server to allow the server to write files to disk (if it needs to do so) or take any other sort of action that it deems necessary. The CLOSE command closes a mailbox, which should be done before another mailbox is opened. A server can close a mailbox automatically if a new mailbox is selected.
Because messages that are compliant with the MIME standard can be quite complex, having many nested entities, the FETCH and SEARCH commands are themselves complex. This complexity exists in order to allow clients to download or search only parts of messages in order to speed actions across slow network connections. For example, one might not want to download a 3 MB attachment over a modem. IMAP allows for clients to operate on messages at a distance without having access to all message parts.
The STORE command may be used to set message flags. As we will see, this is important since flags are used to both provide display clues to clients and control message status.
The STORE command takes several arguments: a
message set (meaning a message sequence number or a colon
(:)
separated range of message sequence numbers), a
data item name, and a data item value. The valid data item names
are:
Replaces the current flags with the ones given
Adds the given flags to the ones already set
Deletes the given flags from the ones already set
Each of these data items may be appended with the string” .silent” in order to tell the server not to echo the updated values in its response. So, the following would set the Deleted flag on message numbers 3 and 4 in the currently selected mailbox:
Client: SD8F STORE 3:4 +FLAGS (Deleted) Server: * 3 FETCH FLAGS (Deleted) Server: * 4 FETCH FLAGS (Answered Deleted) Server: SD8F OK STORE completed
If the client did not want to see the updated flag values for the messages, the” .silent” option could have been used:
Client: SD8F STORE 3:4 +FLAGS.silent (Deleted) Server: SD8F OK STORE completed
The EXPUNGE command may be used to delete messages in a mailbox. Specifically, this command permanently removes all messages in the selected mailbox that have the Deleted flag set. This means, of course, that deleting messages is a two-step process: first one must set the Deleted flag on a message (using the STORE command), then one must issue an EXPUNGE command.
The server responds by sending a response for each message that it deletes, followed by a result line. For example, if a mailbox was selected and an EXPUNGE command was sent when messages number 7 and 11 had Deleted flags set:
Client: FGHJ EXPUNGE Server: * 7 EXPUNGE Server: * 10 EXPUNGE Server: FGHJ OK EXPUNGE completed
The SEARCH command looks scary, especially when one looks at the search keys listed in Table 11-8. However, it is a simple command that just has a lot of potential parameters. If you take the time to read the next few paragraphs, the fear should mostly disappear.
The purpose of the SEARCH command is to determine which messages in the currently selected mailbox match a list of criteria. The arguments to the command are an optional character set specification and some search criteria. The search criteria is made up of search keys, which are shown in Table 11-8. Any number of search keys may be used.
Key | Description |
<message set> | Returns the message numbers listed in the set. |
ALL | |
ANSWERED | Returns all message numbers that have been answered (i.e., have the Answered flag set). |
BCC <string> | Returns message numbers whose BCC header contains the given string. |
BEFORE <date> | Returns message numbers whose date is before the given date. |
BODY <string> | Returns all message numbers whose body contains the given string. |
CC <string> | Returns message numbers whose CC header contains the given string. |
DELETED | Returns message numbers that have been marked as deleted (i.e., have the Deleted flag set). |
DRAFT | Returns message numbers that are in draft (i.e., have the Draft flag set). |
FLAGGED | Returns message numbers that have any flags set. |
FROM <string> | Returns message numbers whose From header contains the given string. |
HEADER <header name> <header value> | Returns message numbers whose named header contains the given string. |
KEYWORD <flag> | Returns message numbers that have the given flag set. |
LARGER <n> | Returns message numbers that are larger than n octets. |
NEW | Returns message numbers that are new (i.e., have the Recent flag set but not the Seen flag). |
NOT <search key> | Returns the opposite of what the given search key would return. |
OLD | Returns message numbers that are not “recent” (i.e., do not have the Recent flag set). |
ON <date> | Returns message numbers that have a date within the given date (i.e., on the same day). |
OR <search keyl> <search key2> | Returns message numbers that match either of the two search results. |
RECENT | Returns message numbers that are “recent” (i.e., have the Recent flag set). |
SEEN | Returns message numbers that have been seen (i.e., have the Seen flag set). |
SENTBEFORE <date> | Returns message numbers that were sent before the given date. |
SENTON <date> | Returns message numbers that were sent on the given date. |
SENTSINCE <date> | Returns message numbers that were sent since the given date. |
SINCE <date> | Returns message numbers that have a date since the given date. |
SMALLER <n> | Returns message numbers that are smaller than n octets. |
SUBJECT <string> | Returns all message numbers whose Subject header contains the given string. |
TEXT <string> | Returns all message numbers whose headers or body contains the given string. |
TO <string> | Returns message numbers whose To header contains the given string. |
UID <uid set> | Returns message numbers whose unique identifiers are in the given set. |
UNANSWERED | Returns message numbers that have not been answered (i.e., do not have the Answered flag set). |
UNDELETED | Returns message numbers that have not been marked for deletion (i.e., do not have the Deleted flag set). |
UNDRAFT | Returns message numbers that are not in draft (i.e., do not have the Draft flag set). |
UNFLAGGED | Returns message numbers that do not have any flags set. |
UNKEYWORD <flag> | Returns message numbers that do not have the given flag set. |
UNSEEN | Returns message numbers that have not been seen (i.e., do not have the Seen flag set). |
Search keys exist to determine the contents of message headers, bodies, and flags. Specific keys exist to easily deal with dates.
The server responds to a search request with a list of message numbers that match the search criteria. Simple, huh?
Here’s an example: Suppose that we have a lot of messages in a Sent mailbox. This is common since most people don’t regularly archive their sent mail. We know that we have sent messages to the kind folks at [email protected], but we don’t want to look through our huge Sent box to find the messages. We could select the Sent mailbox, then use the SEARCH command to look for all messages that have the string “tools” in the To header:
Client: lk98 SEARCH TO tools Server: * SEARCH 51 52 67 Server: lk98 OK SEARCH completed
The server’s response shows that message sequence numbers 51, 52, and 67 match our search. In other words, these messages were all addressed to someone with “tools” as part of their email address. We can now use the FETCH command to retrieve all or part of those messages. The FETCH command is covered next.
The FETCH command is the most important (and complicated) command in the IMAP4rev1 protocol. It is the heart of it all, since it allows a client to retrieve messages, either in whole or in part.
The FETCH command takes a message set and message data items as arguments. The message set is either a message sequence number or a range of numbers for messages in the currently selected mailbox. The message data items are keywords that allow specific parts of messages to be returned. Any number of message data items may be given. The message data items are given in parentheses as a list.
All of the currently defined message data items that can be used with the FETCH command are listed in Table 11-9. Date items exist that allow a client to be extremely selective about which parts of a message it wants to see. For example, a mobile telephone that acts as an MUA probably would not wish to view (or even download) large binary attachments. Using IMAP, the MUA could use the FETCH command to download just some of the message headers, for use in a list display. Once a message has been selected by the user, the MUA could again use FETCH to download just the textual body of a message, leaving any attachments for later resolution when the user is accessing the mailbox with more bandwidth.
Name | Description |
ALL | A macro, equivalent to FLAGS INTERNALDATE RFC822. SIZE ENVELOPE |
BODY | Returns the body structure of the message like BODYSTRUCTURE, but not extensible for multiple MIME parts. |
BODY [<section>]<<partial>> | The text of a particular body section. Sections may be one of HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, TEXT, or a part number. A partial section may be returned. |
BODY.PEEK [<section>]<<partial>> | Like BODY [<section>], except the Seen flag is not set. |
BODYSTRUCTURE | The MIME body structure of the message. |
ENVELOPE | The message’s envelope information, gained by parsing the message headers. |
FAST | A macro, equivalent to FLAGS INTERNALDATE RFC822. SIZE |
FLAGS | The flags that are set for this message. |
FULL | A macro, equivalent to FLAGS INTERNALDATE RFC822. SIZE ENVELOPE BODY. |
INTERNALDATE | The internal date of the message. |
RFC822 | The entire body of the message. |
RFC822.HEADER | All message headers. |
RFC822.SIZE | The size of the message. |
RFC822.TEXT | The textual body of the message. |
UID | The message’s unique identifier. |
As a simple example, consider the mobile telephone that acts as an MUA. Suppose the appropriate mailbox has already been selected and showed that three messages were in the box. The mobile phone MUA wants to download the message size and the From and Subject headers for all messages in the currently selected mailbox. It will use these headers to create a list so that the user can choose the messages that he wants to see. The FETCH command might look like this:
Client: DF56 FETCH 1:3 (RFC822.SIZE BODY[HEADER.FIELDS (FROM SUBJECT)]) Server: * 1 FETCH (RFC822.SIZE 1924 BODY[HEADER.FIELDS ("FROM" "SUBJECT")] {69} Server: From: "Plugged In Sales" <[email protected]> Server: Subject: New Order Server: Server: ) Server: * 2 FETCH (RFC822.SIZE 3085 BODY[HEADER.FIELDS ("FROM" "SUBJECT")] {74} Server: From: "Brad Marshall" <[email protected]> Server: Subject: new pam_ldap module Server: Server: ) Server: * 3 FETCH (RFC822.SIZE 4972 BODY[HEADER.FIELDS ("FROM" "SUBJECT")] {127} Server: From: "Chris Ryan" <[email protected]> Server: Subject: RedHat as an out-of-the-box database entry/server system Server: Server: ) Server: * 1 FETCH (FLAGS (Seen)) Server: * 2 FETCH (FLAGS (Seen)) Server: * 3 FETCH (FLAGS (Seen)) Server: DF56 OK FETCH completed
In this example, note that the server was requested to get both
the message size and some headers. It returned the data (first size in a
FETCH
line, then headers) for each message in turn.
It then returned the flags set for each message in turn even though they
were not asked for. Some implementations will provide extra information
in command responses, such as NOOP, STATUS, and
FETCH.
A client may use the BODY[] or RFC822 message data items to retrieve the entire body of a message. However, since some messages might have a complex structure with many parts, the body structure of the message can be retrieved with the BODYSTRUCTURE data item, allowing clients to parse the body themselves or request it element by element.
Another example of the FETCH command is shown at the end of this chapter, in the sample IMAP session.
The COPY command is used to copy a message from one mailbox to another. It takes a message set and a mailbox name as arguments. The message set is the list of messages in the currently selected mailbox to copy, and the mailbox name is the destination mailbox. Copied messages are appended to the end of the destination mailbox.
To copy message 13 to a mailbox called “Friday”:
Client: R456 COpy 13 Friday Server: R456 OK COPY completed
Sometimes it is difficult or inappropriate to use message sequence numbers when issuing commands that manipulate messages. It would be nice to have a way to refer to messages by their unique identifiers as well. The UID command provides this functionality.
The UID command can be used to issue COPY, FETCH, STORE, or SEARCH commands with unique identifiers instead of message sequence numbers.
For COPY, FETCH, and STORE commands, the commands and their arguments are given exactly as normal, except any message sequence numbers are replaced by unique identifiers. For example, a simple command to fetch message flags for a range of messages might look like this:
Client: HJK9 UID FETCH 90:91 FLAGS Server: * 1 FETCH (FLAGS (Answered Seen) UID 90) Server: * 2 FETCH (FLAGS (Seen)) Server: HJK9 OK UID FETCH completed
In the preceding case, the two messages in the range had unique identifiers of 90 and 91 but message sequence numbers of 1 and 2, respectively.
A SEARCH command can be used with UID, except the message numbers that are returned are unique identifiers instead of the normal message sequence numbers.
The CHECK command is not often used and may in fact be equivalent to a NOOP. It can be used by specific implementations to perform internal housekeeping duties on the server that aren’t covered as part of other commands. It takes no arguments and really isn’t very exciting:
Client: WERT CHECK Server: WERT OK CHECK completed
Finally, the CLOSE command is used to close, or unselect, the currently selected mailbox. This should be used to inform the server that the client is finished with a mailbox. When this command is executed, the server permanently removes all messages from the mailbox that have theDelete flag set. This is equivalent to an EXPUNGE command being issued by the client.
If a client selects another mailbox or logs out of the server with a mailbox still selected, the server will close the currently selected mailbox first before running the given command.
Closing a mailbox returns the client to the Authenticated State.
To close a user’s Inbox:
Client: RT56 CLOSE Server: RT56 OK CLOSE completed
Table 11-10 lists the IMAP commands that are valid in the Selected State.
18.226.4.239