Inherits EventHandler. Inherited by Acl, Append, Authenticate, Capability, Check, Compress, Copy, Create, Delete, Enable, Expunge, Fetch, GenUrlauth, GetQuota, Id, Idle, Listext, Login, Logout, Namespace, Noop, Notify, Rename, ResetKey, Search, Select, SetQuota, SetQuotaRoot, StartTLS, Status, Store, Subscribe, Unselect, Unsubscribe and UrlFetch.
The Command class represents a single IMAP command.
It contains convenience functions to parse the various arguments, such as atom(), astring(), set and so on, as well as utility functions for the Command subclasses and, naturally, some functions that are tightly bound with the Commands, viz:
setState() and state() decribe a command's state, which is either Blocked (waiting until IMAP permits executing this command), Executing (Command subclass working), Finished (done, but no response sent) or Retired (done, responses sent).
respond(), emitResponses(), error() and ok() all help sending responses to the IMAP client. respond() is mostly used for untagged responses, error() for tagged NO/BAD responses. If neither respond() nor error() is called, a tagged OK is sent by default when emitResponses() is called at the end of processing. Finally, ok() returns false if anything has happened to warrant NO/BAD, and true if everything is still OK.
Constructs a simple Command, entirely empty.
Checks that everything we waitFor() has been sent.
This static function creates an instance of the right subclass of Command, depending on name and the state of imap.
args is a pointer to the ImapParser object for the command; it is expected to point to the first character after the command's tag and name, so that it may be used to parse any arguments. Command assumes ownership of args, which must be non-zero.
If name is not a valid command, create() return a null pointer.
Parses from min to max digits and returns them in string form. If fewer than min digits are available, error() is called.
Dumps all responses issued during the command's parsing and execution to the write buffer. This may turn out to be insufficient, but for the moment it guarantees that each command's untagged responses and final tagged response come together.
Asserts that the end of parsing has been reached. If the IMAP client has supplied more text, that text is a parse error and results in a BAD response.
Sets the command's status code to be e and the attendant debugging message to be t, provided no status code has been set yet.
Only the first call to error() has any effect, and only if it's before the call to emitResponses(); subsequent calls are ignored entirely.
t should not be CRLF-terminated.
Sets this Command's state to ::Finished and emit any queued responses as soon as possible.
Parses a flag name and returns it as a string, or calls error() if no valid flag name was present. The return value may contain both upper and lower case letters.
This private utility function returns a const string of no more than 15 characters containing the first unparsed bits of input.
Returns the command group of this Command. Commands in group 0 may only be executed singly, commands in other groups may be executed concurrently with other commands in the same group.
The initial value is 0. setGroup() defines the available groups.
Returns a pointer to the IMAP session to which this command belongs.
Returns the name of m in the right format for sending to the client. The result is relative to r (if it is supplied), encoded using mUTF-7 if necessary, quoted appropriately, etc.
If r is null (this is the default), a user is logged in, and the mailbox is within the user's own namespace, then the result may be relative or absolute, depending on whether the client seems to prefer relative or absolute mailbox names.
We avoid using the escape characters and unusual atoms. "\"" is a legal one-character string. But we're easy on the poor client parser, and we make life easy for ourselves too.
Parses from min to max letters and returns them in string form. If fewer than min letters are available, error() is called.
Parses and returns a list-mailbox. This is the same as an atom(), except that the three additional characters %, * and ] are accepted. The return value has been mutf-7 decoded.
Parses an IMAP literal and returns the relevant string. Returns an empty string in case of error.
Parses a mailbox name and returns a pointer to the relevant mailbox, which is guaranteed to be either a real mailbox or a view.
In case of error, mailbox() returns a null pointer and calls error() appropriately.
Guesses whether this command is part of a client loop processing group of mailboxes, and returns a pointer to the mailbox group if that seems to be the case. Returns a null pointer if not.
Parse a mailbox name and returns either it or the fully qualified name of the same name. Returns an empty string and calls error() in case there is a parse problem.
Parses a single MSN and returns the accompanying UID.
Returns the name of this command, e.g. 'uid fetch', in lower case.
Returns the next, unparsed character, without consuming it. Returns 0 in case of error, but does not emit any error messages.
Checks that the atom "nil" is next at the parse position, and steps past.
Parses a single number and returns it.
Parses a single nzNumber and returns it.
Returns true if there haven't been any errors so far during parsing or execution of this command.
Calling error() makes this function return false.
This virtual function is responsible for parsing the entire command. It may not return any value; instead, it may set an error by calling error(). It may also not do any database lookups or other "slow" work.
The default implementation is suitable for argumentless commands such as logout, capability and starttls.
Returns true if this command is permitted to proceed, and false if it either must abort due to lack of rights or wait until Permissions has fetched more information.
If permitted() denies permission, it also sets a suitable error message.
Checks whether the next characters in the input match s. If so, present() steps past the matching characters and returns true. If not, it returns false without changing the input.
Note that the match is completely case insensitive.
Parses an IMAP quoted string and return the relevant string. In case of error an empty string is returned.
Note that any character can be quoted. IMAP properly allows only the quote character and the backslash to be quoted. In this respect, we deviate from the standard.
This virtual function is responsible for reading from the IMAP stream and eventually releasing a reservation. Most subclasses will not need to implement this; only those that call IMAP::reserve() to the IMAP input stream do.
Verifies that the next characters in the input match s (case insensitively), and removes whatever matches. If input isn't as required, require() calls error().
Adds r to the list of strings to be sent to the client. Neither the leading star-space nor the trailing CRLF should be included in r.
Returns a pointer to the Session for this Command. The Session is the one that applied when the Command started running. If there isn't one, then session() logs an error and throws an exception (which in turn closes the IMAP connection).
Records that this Command may be executed in state s. The default is none, or what create() set.
Sets this command to belong to group g. If g is 0, the command must be executed singly. If g is nonzero, IMAP may try to execute this command concurrently with any other commands whose group is g.
The groups are (subject to later change):
0) Most commands. All commands which change state() or expunge messages must be here.
1) UID SEARCH and UID FETCH.
2) FETCH and SEARCH.
3) STORE and UID STORE. (Note that for this group to work, the server cannot emit side-effect expunges during UID STORE processing.) This group exists because a fetch after a store could otherwise fetch old data.
4) STATUS, LIST. Perhaps other read-only commands that look at mailboxes.
The initial value is 0.
Instructs this command to parse itself using p. Most commands expect that nextChar() will return the space after the command name, before the first argument.
Remembers that when the time comes to send a tagged OK, s should be sent as resp-text-code. s should not contain , emitResponses() adds those itself.
Sets the state of this command to s. The state is always one of three values, Blocked, Executing and Finished. The initial value is Executing. execute() must set it to Finished when done.
The Executing state means that execute() should be called (again).
The Finished state means that the command is done. IMAP rechecks the state after calling execute.
Records that this Command uses t for its database work.
Shrinks set by removing expunged and nonexistent UIDs. Quiet: Does not emit any kind of error or response.
Checks that a single space is next at the parse position, and steps past it if all is ok.
This command accepts more than one space, and gives a warning. This is to tolerate broken clients, while giving client authors a strong hint.
Returns the state of this command, which may be Blocked, Executing or Finished. See setState().
Steps past n characters of the unparsed arguments.
Returns the tag of this command. Useful for logging.
Returns true if this command has parsed at least one MSN, and false if it has not (ie. it returns false before parse()).
Make sure that this command's tagged OK is not sent until response has been sent.
Destroys the object and frees any allocated resources.
This web page based on source code belonging to The Archiveopteryx Developers. All rights reserved.