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.
Subclasses implement each command (e.g. Noop implements Noop), this class provides the overall framework.
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:
setGroup() and group() provide the IMAP class with information about which Commands can be executed concurrently.
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 and ties it to i. create() doesn't need this, but maybe, just maybe, there is a world beyond create().
Constructs a simple Command, entirely empty.
Reimplements EventHandler::EventHandler().
Parses an IMAP astring and returns that string. In case of error, astring() calls error() appropriately and returns an empty string.
Parses an IMAP atom and returns it as a string. Calls error() and turns an empty string in case of error.
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.
This virtual function is responsible for executing the command, as appopriate, and setting state() to Finished when it is. It is called by IMAP after parse() finishes, and only if parse() succeeds.
If state() is still Executing after a call to execute(), IMAP will call it again later.
Reimplements EventHandler::execute().
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.
This helper returns s, quoted such that an IMAP client will recover s. The quoted string fits the IMAP productions astring, nstring or string, depending on mode. The default is string.
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 one or more consecutive list-chars (ATOM-CHAR/list-wildcards/ resp-specials) and returns them as a EString. Calls error() and returns an empty string in case of error.
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 an IMAP nstring and returns that string. If the nstring is NIL, an empty string is returned and error() is called.
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.
If this function (or a reimplementation) is called and does not call error() or set the command's state, IMAP changes the state to Executing afterwards.
The default implementation is suitable for argumentless commands such as logout, capability and starttls.
Returns a pointer to the ImapParser object that was set by setParser() (usually by create()).
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().
Notes that this command requires r on m. execute() should proceed only if and when permitted() is true.
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).
If the returned Session isn't active any longer, then ImapResponse will make sure the command's results aren't displayed.
Parses an IMAP set and returns the corresponding IntegerSet object. The set always contains UIDs; this function creates an UID set even if parseMsns is true.
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 Blocked state means that execute() cannot be called until all currently executing commands have finished. parse() and read() both may be called.
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.
Parses an IMAP string and returns it. If there is none, error() is called appropriately.
Returns the tag of this command. Useful for logging.
Returns this Command's Transaction, if any was set using setTransaction(). Returns a null pointer if not.
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.
Reimplements EventHandler::~EventHandler().
This web page based on source code belonging to The Archiveopteryx Developers. All rights reserved.