diff --git a/src/console/main.vala b/src/console/main.vala index b114c7e3..01585986 100644 --- a/src/console/main.vala +++ b/src/console/main.vala @@ -290,13 +290,13 @@ class ImapConsole : Gtk.Window { private void capabilities(string cmd, string[] args) throws Error { check_connected(cmd, args, 0, null); - this.cx.send_command(new Geary.Imap.CapabilityCommand()); + this.cx.send_command(new Geary.Imap.CapabilityCommand(null)); } - private void noop(string cmd, string[] args) throws Error { + private void noop(string cmd, string[] args) throws GLib.Error { check_connected(cmd, args, 0, null); - this.cx.send_command(new Geary.Imap.NoopCommand()); + this.cx.send_command(new Geary.Imap.NoopCommand(null)); } private void connect_cmd(string cmd, string[] args) throws Error { @@ -370,7 +370,7 @@ class ImapConsole : Gtk.Window { } private async void do_starttls_async() throws Error { - Geary.Imap.StarttlsCommand cmd = new Geary.Imap.StarttlsCommand(); + Geary.Imap.StarttlsCommand cmd = new Geary.Imap.StarttlsCommand(null); this.cx.send_command(cmd); Geary.Imap.StatusResponse response = yield wait_for_response_async(cmd.tag); @@ -394,14 +394,18 @@ class ImapConsole : Gtk.Window { check_connected(cmd, args, 2, "user pass"); status("Logging in..."); - this.cx.send_command(new Geary.Imap.LoginCommand(args[0], args[1])); + this.cx.send_command( + new Geary.Imap.LoginCommand(args[0], args[1], null) + ); } private void logout(string cmd, string[] args) throws Error { check_connected(cmd, args, 0, null); status("Logging out..."); - this.cx.send_command(new Geary.Imap.LogoutCommand()); + this.cx.send_command( + new Geary.Imap.LogoutCommand(null) + ); } private void id(string cmd, string[] args) throws Error { @@ -413,14 +417,16 @@ class ImapConsole : Gtk.Window { fields.set("name", "geary-console"); fields.set("version", _VERSION); - this.cx.send_command(new Geary.Imap.IdCommand(fields)); + this.cx.send_command( + new Geary.Imap.IdCommand(fields, null) + ); } private void namespace(string cmd, string[] args) throws Error { check_connected(cmd, args, 0, null); status("Retrieving NAMESPACE..."); - this.cx.send_command(new Geary.Imap.NamespaceCommand()); + this.cx.send_command(new Geary.Imap.NamespaceCommand(null)); } private void list(string cmd, string[] args) throws Error { @@ -437,7 +443,8 @@ class ImapConsole : Gtk.Window { args[0], new Geary.Imap.MailboxSpecifier(args[1]), (cmd.down() == "xlist"), - return_param + return_param, + null ) ); } @@ -446,7 +453,12 @@ class ImapConsole : Gtk.Window { check_connected(cmd, args, 1, ""); status("Opening %s read-only".printf(args[0])); - this.cx.send_command(new Geary.Imap.ExamineCommand(new Geary.Imap.MailboxSpecifier(args[0]))); + this.cx.send_command( + new Geary.Imap.ExamineCommand( + new Geary.Imap.MailboxSpecifier(args[0]), + null + ) + ); } private void create(string cmd, string[] args) throws Error { @@ -455,7 +467,8 @@ class ImapConsole : Gtk.Window { status("Creating %s".printf(args[0])); this.cx.send_command( new Geary.Imap.CreateCommand( - new Geary.Imap.MailboxSpecifier(args[0]) + new Geary.Imap.MailboxSpecifier(args[0]), + null ) ); } @@ -466,7 +479,8 @@ class ImapConsole : Gtk.Window { status("Deleting %s".printf(args[0])); this.cx.send_command( new Geary.Imap.DeleteCommand( - new Geary.Imap.MailboxSpecifier(args[0]) + new Geary.Imap.MailboxSpecifier(args[0]), + null ) ); } @@ -487,7 +501,9 @@ class ImapConsole : Gtk.Window { data_items.add(data_type); } - this.cx.send_command(new Geary.Imap.FetchCommand(msg_set, data_items, null)); + this.cx.send_command( + new Geary.Imap.FetchCommand(msg_set, data_items, null, null) + ); } private void fetch_fields(string cmd, string[] args) throws Error { @@ -501,8 +517,11 @@ class ImapConsole : Gtk.Window { Gee.List list = new Gee.ArrayList(); list.add(fields); - this.cx.send_command(new Geary.Imap.FetchCommand( - new Geary.Imap.MessageSet.custom(args[0]), null, list)); + this.cx.send_command( + new Geary.Imap.FetchCommand( + new Geary.Imap.MessageSet.custom(args[0]), null, list, null + ) + ); } private void append(string cmd, string[] args) throws Error { @@ -510,8 +529,15 @@ class ImapConsole : Gtk.Window { status("Appending %s to %s".printf(args[1], args[0])); - this.cx.send_command(new Geary.Imap.AppendCommand(new Geary.Imap.MailboxSpecifier(args[0]), - null, null, new Geary.Memory.FileBuffer(File.new_for_path(args[1]), true))); + this.cx.send_command( + new Geary.Imap.AppendCommand( + new Geary.Imap.MailboxSpecifier(args[0]), + null, + null, + new Geary.Memory.FileBuffer(File.new_for_path(args[1]), true), + null + ) + ); } private void search(string cmd, string[] args) throws Error { @@ -525,9 +551,9 @@ class ImapConsole : Gtk.Window { Geary.Imap.SearchCommand search; if (cmd == "uid-search") - search = new Geary.Imap.SearchCommand.uid(criteria); + search = new Geary.Imap.SearchCommand.uid(criteria, null); else - search = new Geary.Imap.SearchCommand(criteria); + search = new Geary.Imap.SearchCommand(criteria, null); this.cx.send_command(search); } @@ -537,7 +563,9 @@ class ImapConsole : Gtk.Window { status("Closing"); - this.cx.send_command(new Geary.Imap.CloseCommand()); + this.cx.send_command( + new Geary.Imap.CloseCommand(null) + ); } private void folder_status(string cmd, string[] args) throws Error { @@ -551,8 +579,13 @@ class ImapConsole : Gtk.Window { data_items += Geary.Imap.StatusDataType.from_parameter(stringp); } - this.cx.send_command(new Geary.Imap.StatusCommand(new Geary.Imap.MailboxSpecifier(args[0]), - data_items)); + this.cx.send_command( + new Geary.Imap.StatusCommand( + new Geary.Imap.MailboxSpecifier(args[0]), + data_items, + null + ) + ); } private void preview(string cmd, string[] args) throws Error { @@ -567,8 +600,11 @@ class ImapConsole : Gtk.Window { Gee.ArrayList list = new Gee.ArrayList(); list.add(preview_data_type); - this.cx.send_command(new Geary.Imap.FetchCommand( - new Geary.Imap.MessageSet.custom(args[0]), null, list)); + this.cx.send_command( + new Geary.Imap.FetchCommand( + new Geary.Imap.MessageSet.custom(args[0]), null, list, null + ) + ); } private void quit(string cmd, string[] args) throws Error { diff --git a/src/engine/imap/api/imap-account-session.vala b/src/engine/imap/api/imap-account-session.vala index 7c12f4d1..238bd85c 100644 --- a/src/engine/imap/api/imap-account-session.vala +++ b/src/engine/imap/api/imap-account-session.vala @@ -97,9 +97,11 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject { ClientSession session = claim_session(); MailboxSpecifier mailbox = session.get_mailbox_for_path(path); bool can_create_special = session.capabilities.has_capability(Capabilities.CREATE_SPECIAL_USE); - CreateCommand cmd = (use != null && can_create_special) - ? new CreateCommand.special_use(mailbox, use) - : new CreateCommand(mailbox); + CreateCommand cmd = ( + use != null && can_create_special + ? new CreateCommand.special_use(mailbox, use, cancellable) + : new CreateCommand(mailbox, cancellable) + ); StatusResponse response = yield send_command_async( session, cmd, null, null, cancellable @@ -187,7 +189,9 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject { // Mailbox needs a SELECT info_map.set(mailbox_info.mailbox, mailbox_info); cmd_map.set( - new StatusCommand(mailbox_info.mailbox, StatusDataType.all()), + new StatusCommand( + mailbox_info.mailbox, StatusDataType.all(), cancellable + ), mailbox_info.mailbox ); } else { @@ -323,7 +327,10 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject { if (folder.is_root) { // List the server root cmd = new ListCommand.wildcarded( - "", new MailboxSpecifier("%"), use_xlist, return_param + "", new MailboxSpecifier("%"), + use_xlist, + return_param, + cancellable ); } else { // List either the given folder or its children @@ -335,7 +342,12 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject { } specifier = specifier + delim + "%"; } - cmd = new ListCommand(new MailboxSpecifier(specifier), use_xlist, return_param); + cmd = new ListCommand( + new MailboxSpecifier(specifier), + use_xlist, + return_param, + cancellable + ); } Gee.List list_results = new Gee.ArrayList(); @@ -372,7 +384,7 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject { Gee.List status_results = new Gee.ArrayList(); StatusResponse response = yield send_command_async( session, - new StatusCommand(mailbox, status_types), + new StatusCommand(mailbox, status_types, cancellable), null, status_results, cancellable diff --git a/src/engine/imap/api/imap-client-service.vala b/src/engine/imap/api/imap-client-service.vala index b20da56c..e0aad41b 100644 --- a/src/engine/imap/api/imap-client-service.vala +++ b/src/engine/imap/api/imap-client-service.vala @@ -430,7 +430,7 @@ public class Geary.Imap.ClientService : Geary.ClientService { try { debug("Sending NOOP when claiming a session"); yield target.send_command_async( - new NoopCommand(), this.close_cancellable + new NoopCommand(this.close_cancellable) ); } catch (Error err) { debug("Error sending NOOP: %s", err.message); diff --git a/src/engine/imap/api/imap-folder-session.vala b/src/engine/imap/api/imap-folder-session.vala index 9bc61aca..092c06cd 100644 --- a/src/engine/imap/api/imap-folder-session.vala +++ b/src/engine/imap/api/imap-folder-session.vala @@ -159,7 +159,7 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { public async void send_noop(GLib.Cancellable? cancellable) throws GLib.Error { yield exec_commands_async( - Collection.single(new NoopCommand()), + Collection.single(new NoopCommand(cancellable)), null, null, cancellable @@ -334,12 +334,13 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { } // Utility method for listing UIDs on the remote within the supplied range - public async Gee.Set? list_uids_async(MessageSet msg_set, Cancellable? cancellable) - throws Error { + public async Gee.Set? list_uids_async(MessageSet msg_set, + GLib.Cancellable? cancellable) + throws GLib.Error { // Although FETCH could be used, SEARCH is more efficient in returning pure UID results, // which is all we're interested in here SearchCriteria criteria = new SearchCriteria(SearchCriterion.message_set(msg_set)); - SearchCommand cmd = new SearchCommand.uid(criteria); + SearchCommand cmd = new SearchCommand.uid(criteria, cancellable); Gee.Set search_results = new Gee.HashSet(); yield exec_commands_async( @@ -355,6 +356,7 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { private Gee.Collection assemble_list_commands( Imap.MessageSet msg_set, Geary.Email.Field fields, + GLib.Cancellable? cancellable, out FetchBodyDataSpecifier[]? header_specifiers, out FetchBodyDataSpecifier? body_specifier, out FetchBodyDataSpecifier? preview_specifier, @@ -369,8 +371,13 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { // pulled down, not a guarantee); if request is for NONE, that guarantees that the // EmailIdentifier will be set, and so fetch UIDs (which looks funny but works when // listing a range for contents: UID FETCH x:y UID) - if (!msg_set.is_uid || fields == Geary.Email.Field.NONE) - cmds.add(new FetchCommand.data_type(msg_set, FetchDataSpecifier.UID)); + if (!msg_set.is_uid || fields == Geary.Email.Field.NONE) { + cmds.add( + new FetchCommand.data_type( + msg_set, FetchDataSpecifier.UID, cancellable + ) + ); + } // convert bulk of the "basic" fields into a one or two FETCH commands (some servers have // exhibited bugs or return NO when too many FETCH data types are combined on a single @@ -385,7 +392,9 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { // Add all simple data types as one FETCH command if (!basic_types.is_empty) { - cmds.add(new FetchCommand(msg_set, basic_types, null)); + cmds.add( + new FetchCommand(msg_set, basic_types, null, cancellable) + ); } // Add all header field requests as separate FETCH @@ -424,7 +433,11 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { if (this.quirks.fetch_header_part_no_space) { header.omit_request_header_fields_space(); } - cmds.add(new FetchCommand.body_data_type(msg_set, header)); + cmds.add( + new FetchCommand.body_data_type( + msg_set, header, cancellable + ) + ); } } } @@ -434,7 +447,11 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { body_specifier = new FetchBodyDataSpecifier.peek(FetchBodyDataSpecifier.SectionPart.TEXT, null, -1, -1, null); - cmds.add(new FetchCommand.body_data_type(msg_set, body_specifier)); + cmds.add( + new FetchCommand.body_data_type( + msg_set, body_specifier, cancellable + ) + ); } else { body_specifier = null; } @@ -453,12 +470,20 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { preview_specifier = new FetchBodyDataSpecifier.peek(FetchBodyDataSpecifier.SectionPart.NONE, { 1 }, 0, Geary.Email.MAX_PREVIEW_BYTES, null); - cmds.add(new FetchCommand.body_data_type(msg_set, preview_specifier)); + cmds.add( + new FetchCommand.body_data_type( + msg_set, preview_specifier, cancellable + ) + ); // Also get the character set to properly decode it preview_charset_specifier = new FetchBodyDataSpecifier.peek( FetchBodyDataSpecifier.SectionPart.MIME, { 1 }, -1, -1, null); - cmds.add(new FetchCommand.body_data_type(msg_set, preview_charset_specifier)); + cmds.add( + new FetchCommand.body_data_type( + msg_set, preview_charset_specifier, cancellable + ) + ); } else { preview_specifier = null; preview_charset_specifier = null; @@ -476,7 +501,7 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { if (fields.require(Geary.Email.Field.FLAGS)) data_types.add(FetchDataSpecifier.FLAGS); - cmds.add(new FetchCommand(msg_set, data_types, null)); + cmds.add(new FetchCommand(msg_set, data_types, null, cancellable)); } return cmds; @@ -498,6 +523,7 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { Gee.Collection cmds = assemble_list_commands( msg_set, fields, + cancellable, out header_specifiers, out body_specifier, out preview_specifier, @@ -593,7 +619,11 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { } Gee.List cmds = new Gee.ArrayList(); - cmds.add(new FetchCommand.data_type(msg_set, FetchDataSpecifier.UID)); + cmds.add( + new FetchCommand.data_type( + msg_set, FetchDataSpecifier.UID, cancellable + ) + ); Gee.HashMap fetched = new Gee.HashMap(); @@ -613,8 +643,9 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { return map; } - public async void remove_email_async(Gee.List msg_sets, Cancellable? cancellable) - throws Error { + public async void remove_email_async(Gee.List msg_sets, + GLib.Cancellable? cancellable) + throws GLib.Error { ClientSession session = claim_session(); Gee.List flags = new Gee.ArrayList(); flags.add(MessageFlag.DELETED); @@ -627,7 +658,9 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { if (!msg_set.is_uid) all_uid = false; - cmds.add(new StoreCommand(msg_set, flags, StoreCommand.Option.ADD_FLAGS)); + cmds.add( + new StoreCommand(msg_set, flags, StoreCommand.Option.ADD_FLAGS, cancellable) + ); } // TODO: Only use old-school EXPUNGE when closing folder (or rely on CLOSE to do that work @@ -638,10 +671,11 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { // shuts down, which means deleted messages return at application start. See: // http://redmine.yorba.org/issues/6865 if (all_uid && session.capabilities.supports_uidplus()) { - foreach (MessageSet msg_set in msg_sets) - cmds.add(new ExpungeCommand.uid(msg_set)); + foreach (MessageSet msg_set in msg_sets) { + cmds.add(new ExpungeCommand.uid(msg_set, cancellable)); + } } else { - cmds.add(new ExpungeCommand()); + cmds.add(new ExpungeCommand(cancellable)); } yield exec_commands_async(cmds, null, null, cancellable); @@ -659,11 +693,21 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { Gee.Collection cmds = new Gee.ArrayList(); foreach (MessageSet msg_set in msg_sets) { - if (msg_flags_add.size > 0) - cmds.add(new StoreCommand(msg_set, msg_flags_add, StoreCommand.Option.ADD_FLAGS)); + if (msg_flags_add.size > 0) { + cmds.add( + new StoreCommand( + msg_set, msg_flags_add, ADD_FLAGS, cancellable + ) + ); + } - if (msg_flags_remove.size > 0) - cmds.add(new StoreCommand(msg_set, msg_flags_remove, StoreCommand.Option.REMOVE_FLAGS)); + if (msg_flags_remove.size > 0) { + cmds.add( + new StoreCommand( + msg_set, msg_flags_remove, REMOVE_FLAGS, cancellable + ) + ); + } } yield exec_commands_async(cmds, null, null, cancellable); @@ -671,12 +715,14 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { // Returns a mapping of the source UID to the destination UID. If the MessageSet is not for // UIDs, then null is returned. If the server doesn't support COPYUID, null is returned. - public async Gee.Map? copy_email_async(MessageSet msg_set, FolderPath destination, - Cancellable? cancellable) throws Error { + public async Gee.Map? copy_email_async(MessageSet msg_set, + FolderPath destination, + GLib.Cancellable? cancellable) + throws GLib.Error { ClientSession session = claim_session(); MailboxSpecifier mailbox = session.get_mailbox_for_path(destination); - CopyCommand cmd = new CopyCommand(msg_set, mailbox); + CopyCommand cmd = new CopyCommand(msg_set, mailbox, cancellable); Gee.Map? responses = yield exec_commands_async( Geary.iterate(cmd).to_array_list(), null, null, cancellable); @@ -718,11 +764,12 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { return null; } - public async Gee.SortedSet? search_async(SearchCriteria criteria, Cancellable? cancellable) - throws Error { + public async Gee.SortedSet? search_async(SearchCriteria criteria, + GLib.Cancellable? cancellable) + throws GLib.Error { // always perform a UID SEARCH Gee.Collection cmds = new Gee.ArrayList(); - cmds.add(new SearchCommand.uid(criteria)); + cmds.add(new SearchCommand.uid(criteria, cancellable)); Gee.Set search_results = new Gee.HashSet(); yield exec_commands_async(cmds, null, search_results, cancellable); @@ -1044,12 +1091,22 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { return email; } - // Returns a no-message-id ImapDB.EmailIdentifier with the UID stored in it. - // This method does not take a cancellable; there is currently no way to tell if an email was - // created or not if exec_commands_async() is cancelled during the append. For atomicity's sake, - // callers need to remove the returned email ID if a cancel occurred. - public async Geary.EmailIdentifier? create_email_async(RFC822.Message message, Geary.EmailFlags? flags, - DateTime? date_received) throws Error { + /** + * Stores a new message in the remote mailbox. + * + * Returns a no-message-id ImapDB.EmailIdentifier with the UID + * stored in it. + * + * This method does not take a cancellable; there is currently no + * way to tell if an email was created or not if {@link + * exec_commands_async} is cancelled during the append. For + * atomicity's sake, callers need to remove the returned email ID + * if a cancel occurred. + */ + public async Geary.EmailIdentifier? create_email_async(RFC822.Message message, + Geary.EmailFlags? flags, + GLib.DateTime? date_received) + throws GLib.Error { ClientSession session = claim_session(); MessageFlags? msg_flags = null; @@ -1066,11 +1123,16 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { MailboxSpecifier mailbox = session.get_mailbox_for_path(this.folder.path); AppendCommand cmd = new AppendCommand( - mailbox, msg_flags, internaldate, message.get_rfc822_buffer() + mailbox, + msg_flags, + internaldate, + message.get_rfc822_buffer(), + null ); Gee.Map responses = yield exec_commands_async( - Geary.iterate(cmd).to_array_list(), null, null, null); + Geary.iterate(cmd).to_array_list(), null, null, null + ); // Grab the response and parse out the UID, if available. StatusResponse response = responses.get(cmd); diff --git a/src/engine/imap/command/imap-append-command.vala b/src/engine/imap/command/imap-append-command.vala index d0cc6c78..44dec83f 100644 --- a/src/engine/imap/command/imap-append-command.vala +++ b/src/engine/imap/command/imap-append-command.vala @@ -14,9 +14,12 @@ public class Geary.Imap.AppendCommand : Command { public const string NAME = "append"; - public AppendCommand(MailboxSpecifier mailbox, MessageFlags? flags, InternalDate? internal_date, - Memory.Buffer message) { - base (NAME); + public AppendCommand(MailboxSpecifier mailbox, + MessageFlags? flags, + InternalDate? internal_date, + Memory.Buffer message, + GLib.Cancellable? should_send) { + base(NAME, null, should_send); this.args.add(mailbox.to_parameter()); diff --git a/src/engine/imap/command/imap-authenticate-command.vala b/src/engine/imap/command/imap-authenticate-command.vala index 041de90e..a7a0c186 100644 --- a/src/engine/imap/command/imap-authenticate-command.vala +++ b/src/engine/imap/command/imap-authenticate-command.vala @@ -27,17 +27,21 @@ public class Geary.Imap.AuthenticateCommand : Command { private GLib.Cancellable error_cancellable = new GLib.Cancellable(); - private AuthenticateCommand(string method, string data) { - base(NAME, { method, data }); + private AuthenticateCommand(string method, + string data, + GLib.Cancellable? should_send) { + base(NAME, { method, data }, should_send); this.method = method; this.error_lock = new Geary.Nonblocking.Spinlock(this.error_cancellable); } - public AuthenticateCommand.oauth2(string user, string token) { + public AuthenticateCommand.oauth2(string user, + string token, + GLib.Cancellable? should_send) { string encoded_token = Base64.encode( OAUTH2_RESP.printf(user, token).data ); - this(OAUTH2_METHOD, encoded_token); + this(OAUTH2_METHOD, encoded_token, should_send); } internal override async void send(Serializer ser, diff --git a/src/engine/imap/command/imap-capability-command.vala b/src/engine/imap/command/imap-capability-command.vala index 0f353997..f3273155 100644 --- a/src/engine/imap/command/imap-capability-command.vala +++ b/src/engine/imap/command/imap-capability-command.vala @@ -11,10 +11,11 @@ */ public class Geary.Imap.CapabilityCommand : Command { + public const string NAME = "capability"; - public CapabilityCommand() { - base (NAME); + public CapabilityCommand(GLib.Cancellable? should_send) { + base(NAME, null, should_send); } -} +} diff --git a/src/engine/imap/command/imap-close-command.vala b/src/engine/imap/command/imap-close-command.vala index 1dac6a97..96f15427 100644 --- a/src/engine/imap/command/imap-close-command.vala +++ b/src/engine/imap/command/imap-close-command.vala @@ -9,10 +9,11 @@ */ public class Geary.Imap.CloseCommand : Command { + public const string NAME = "close"; - public CloseCommand() { - base (NAME); + public CloseCommand(GLib.Cancellable? should_send) { + base(NAME, null, should_send); } -} +} diff --git a/src/engine/imap/command/imap-command.vala b/src/engine/imap/command/imap-command.vala index 58163671..94d87762 100644 --- a/src/engine/imap/command/imap-command.vala +++ b/src/engine/imap/command/imap-command.vala @@ -60,6 +60,20 @@ public abstract class Geary.Imap.Command : BaseObject { /** The status response for the command, once it has been received. */ public StatusResponse? status { get; private set; default = null; } + /** + * A guard to allow cancelling a command before it is sent. + * + * Since IMAP does not allow commands that have been sent to the + * server to be cancelled, cancelling a command before sending it + * is the last opportunity to prevent it from being executed. A + * command queued to be sent will be sent as long as the + * connection it was queued is open and this cancellable is null + * or is not cancelled. + * + * @see Command.Command + */ + public GLib.Cancellable? should_send { get; private set; default = null; } + /** * The command's arguments as parameters. * @@ -93,11 +107,15 @@ public abstract class Geary.Imap.Command : BaseObject { * Constructs a new command with an unassigned tag. * * Any arguments provided here will be converted to appropriate - * string arguments + * string arguments. The given cancellable will be set as {@link + * should_send}. * * @see Tag + * @see should_send */ - protected Command(string name, string[]? args = null) { + protected Command(string name, + string[]? args, + GLib.Cancellable? should_send) { this.tag = Tag.get_unassigned(); this.name = name; if (args != null) { @@ -105,6 +123,7 @@ public abstract class Geary.Imap.Command : BaseObject { this.args.add(Parameter.get_for_string(arg)); } } + this.should_send = should_send; this.response_timer = new TimeoutManager.seconds( this._response_timeout, on_response_timeout @@ -269,6 +288,15 @@ public abstract class Geary.Imap.Command : BaseObject { this.status.to_string() ); } + + // If everything else looks fine, but sending was cancelled, + // throw an error here so the caller knows that was the case. + if (this.should_send != null && + this.should_send.is_cancelled()) { + throw new GLib.IOError.CANCELLED( + "Sent command was cancelled: %s", to_brief_string() + ); + } } public virtual string to_string() { diff --git a/src/engine/imap/command/imap-compress-command.vala b/src/engine/imap/command/imap-compress-command.vala index 98ca05ff..20ea0aa5 100644 --- a/src/engine/imap/command/imap-compress-command.vala +++ b/src/engine/imap/command/imap-compress-command.vala @@ -9,12 +9,14 @@ */ public class Geary.Imap.CompressCommand : Command { + public const string NAME = "compress"; public const string ALGORITHM_DEFLATE = "deflate"; - public CompressCommand(string algorithm) { - base (NAME, { algorithm }); - } -} + public CompressCommand(string algorithm, GLib.Cancellable? should_send) { + base(NAME, { algorithm }, should_send); + } + +} diff --git a/src/engine/imap/command/imap-copy-command.vala b/src/engine/imap/command/imap-copy-command.vala index 2b25264c..45a86475 100644 --- a/src/engine/imap/command/imap-copy-command.vala +++ b/src/engine/imap/command/imap-copy-command.vala @@ -13,8 +13,10 @@ public class Geary.Imap.CopyCommand : Command { public const string NAME = "copy"; public const string UID_NAME = "uid copy"; - public CopyCommand(MessageSet message_set, MailboxSpecifier destination) { - base(message_set.is_uid ? UID_NAME : NAME); + public CopyCommand(MessageSet message_set, + MailboxSpecifier destination, + GLib.Cancellable? should_send) { + base(message_set.is_uid ? UID_NAME : NAME, null, should_send); this.args.add(message_set.to_parameter()); this.args.add(destination.to_parameter()); diff --git a/src/engine/imap/command/imap-create-command.vala b/src/engine/imap/command/imap-create-command.vala index 3cbf3fee..4a56712b 100644 --- a/src/engine/imap/command/imap-create-command.vala +++ b/src/engine/imap/command/imap-create-command.vala @@ -55,15 +55,16 @@ public class Geary.Imap.CreateCommand : Command { } } - public CreateCommand(MailboxSpecifier mailbox) { - base(NAME_ATOM); + public CreateCommand(MailboxSpecifier mailbox, GLib.Cancellable? should_send) { + base(NAME_ATOM, null, should_send); this.mailbox = mailbox; this.args.add(mailbox.to_parameter()); } public CreateCommand.special_use(MailboxSpecifier mailbox, - Geary.Folder.SpecialUse use) { - this(mailbox); + Geary.Folder.SpecialUse use, + GLib.Cancellable? should_send) { + this(mailbox, should_send); this.use = use; MailboxAttribute? attr = get_special_folder_type(use); diff --git a/src/engine/imap/command/imap-delete-command.vala b/src/engine/imap/command/imap-delete-command.vala index e183f510..dc35f58c 100644 --- a/src/engine/imap/command/imap-delete-command.vala +++ b/src/engine/imap/command/imap-delete-command.vala @@ -18,8 +18,9 @@ public class Geary.Imap.DeleteCommand : Command { public const string NAME = "DELETE"; - public DeleteCommand(MailboxSpecifier mailbox) { - base(NAME); + public DeleteCommand(MailboxSpecifier mailbox, + GLib.Cancellable? should_send) { + base(NAME, null, should_send); this.args.add(mailbox.to_parameter()); } diff --git a/src/engine/imap/command/imap-examine-command.vala b/src/engine/imap/command/imap-examine-command.vala index 5b2e2837..4820bf33 100644 --- a/src/engine/imap/command/imap-examine-command.vala +++ b/src/engine/imap/command/imap-examine-command.vala @@ -16,8 +16,9 @@ public class Geary.Imap.ExamineCommand : Command { public MailboxSpecifier mailbox { get; private set; } - public ExamineCommand(MailboxSpecifier mailbox) { - base(NAME); + public ExamineCommand(MailboxSpecifier mailbox, + GLib.Cancellable? should_send) { + base(NAME, null, should_send); this.mailbox = mailbox; this.args.add(mailbox.to_parameter()); } diff --git a/src/engine/imap/command/imap-expunge-command.vala b/src/engine/imap/command/imap-expunge-command.vala index be5b3445..7eb53316 100644 --- a/src/engine/imap/command/imap-expunge-command.vala +++ b/src/engine/imap/command/imap-expunge-command.vala @@ -14,12 +14,13 @@ public class Geary.Imap.ExpungeCommand : Command { public const string NAME = "expunge"; public const string UID_NAME = "uid expunge"; - public ExpungeCommand() { - base(NAME); + public ExpungeCommand(GLib.Cancellable? should_send) { + base(NAME, null, should_send); } - public ExpungeCommand.uid(MessageSet message_set) { - base(UID_NAME); + public ExpungeCommand.uid(MessageSet message_set, + GLib.Cancellable? should_send) { + base(UID_NAME, null, should_send); assert(message_set.is_uid); this.args.add(message_set.to_parameter()); } diff --git a/src/engine/imap/command/imap-fetch-command.vala b/src/engine/imap/command/imap-fetch-command.vala index 498b6779..601494d7 100644 --- a/src/engine/imap/command/imap-fetch-command.vala +++ b/src/engine/imap/command/imap-fetch-command.vala @@ -34,9 +34,11 @@ public class Geary.Imap.FetchCommand : Command { public Gee.List for_body_data_specifiers { get; private set; default = new Gee.ArrayList(); } - public FetchCommand(MessageSet msg_set, Gee.List? data_items, - Gee.List? body_data_items) { - base (msg_set.is_uid ? UID_NAME : NAME); + public FetchCommand(MessageSet msg_set, + Gee.List? data_items, + Gee.List? body_data_items, + GLib.Cancellable? should_send) { + base(msg_set.is_uid ? UID_NAME : NAME, null, should_send); this.args.add(msg_set.to_parameter()); @@ -71,8 +73,10 @@ public class Geary.Imap.FetchCommand : Command { for_body_data_specifiers.add_all(body_data_items); } - public FetchCommand.data_type(MessageSet msg_set, FetchDataSpecifier data_type) { - base (msg_set.is_uid ? UID_NAME : NAME); + public FetchCommand.data_type(MessageSet msg_set, + FetchDataSpecifier data_type, + GLib.Cancellable? should_send) { + base(msg_set.is_uid ? UID_NAME : NAME, null, should_send); for_data_types.add(data_type); @@ -80,8 +84,10 @@ public class Geary.Imap.FetchCommand : Command { this.args.add(data_type.to_parameter()); } - public FetchCommand.body_data_type(MessageSet msg_set, FetchBodyDataSpecifier body_data_specifier) { - base (msg_set.is_uid ? UID_NAME : NAME); + public FetchCommand.body_data_type(MessageSet msg_set, + FetchBodyDataSpecifier body_data_specifier, + GLib.Cancellable? should_send) { + base(msg_set.is_uid ? UID_NAME : NAME, null, should_send); for_body_data_specifiers.add(body_data_specifier); diff --git a/src/engine/imap/command/imap-id-command.vala b/src/engine/imap/command/imap-id-command.vala index b3be2451..459c3c2f 100644 --- a/src/engine/imap/command/imap-id-command.vala +++ b/src/engine/imap/command/imap-id-command.vala @@ -12,8 +12,9 @@ public class Geary.Imap.IdCommand : Command { public const string NAME = "id"; - public IdCommand(Gee.HashMap fields) { - base(NAME); + public IdCommand(Gee.HashMap fields, + GLib.Cancellable? should_send) { + base(NAME, null, should_send); ListParameter list = new ListParameter(); foreach (string key in fields.keys) { @@ -24,8 +25,8 @@ public class Geary.Imap.IdCommand : Command { this.args.add(list); } - public IdCommand.nil() { - base(NAME); + public IdCommand.nil(GLib.Cancellable? should_send) { + base(NAME, null, should_send); this.args.add(NilParameter.instance); } diff --git a/src/engine/imap/command/imap-idle-command.vala b/src/engine/imap/command/imap-idle-command.vala index 069bea5b..df36b2df 100644 --- a/src/engine/imap/command/imap-idle-command.vala +++ b/src/engine/imap/command/imap-idle-command.vala @@ -25,8 +25,8 @@ public class Geary.Imap.IdleCommand : Command { private GLib.Cancellable? exit_cancellable = new GLib.Cancellable(); - public IdleCommand() { - base(NAME); + public IdleCommand(GLib.Cancellable? should_send) { + base(NAME, null, should_send); this.exit_lock = new Geary.Nonblocking.Semaphore(this.exit_cancellable); } diff --git a/src/engine/imap/command/imap-list-command.vala b/src/engine/imap/command/imap-list-command.vala index 48eba332..5ca6d232 100644 --- a/src/engine/imap/command/imap-list-command.vala +++ b/src/engine/imap/command/imap-list-command.vala @@ -38,16 +38,22 @@ public class Geary.Imap.ListCommand : Command { * * See [[http://redmine.yorba.org/issues/7624]] for more information. */ - public ListCommand(MailboxSpecifier mailbox, bool use_xlist, ListReturnParameter? return_param) { - base(use_xlist ? XLIST_NAME : NAME, { "" }); + public ListCommand(MailboxSpecifier mailbox, + bool use_xlist, + ListReturnParameter? return_param, + GLib.Cancellable? should_send) { + base(use_xlist ? XLIST_NAME : NAME, { "" }, should_send); this.args.add(mailbox.to_parameter()); add_return_parameter(return_param); } - public ListCommand.wildcarded(string reference, MailboxSpecifier mailbox, bool use_xlist, - ListReturnParameter? return_param) { - base(use_xlist ? XLIST_NAME : NAME, { reference }); + public ListCommand.wildcarded(string reference, + MailboxSpecifier mailbox, + bool use_xlist, + ListReturnParameter? return_param, + GLib.Cancellable? should_send) { + base(use_xlist ? XLIST_NAME : NAME, { reference }, should_send); this.args.add(mailbox.to_parameter()); add_return_parameter(return_param); diff --git a/src/engine/imap/command/imap-login-command.vala b/src/engine/imap/command/imap-login-command.vala index c3114780..48bb4d8e 100644 --- a/src/engine/imap/command/imap-login-command.vala +++ b/src/engine/imap/command/imap-login-command.vala @@ -9,14 +9,17 @@ */ public class Geary.Imap.LoginCommand : Command { + public const string NAME = "login"; - public LoginCommand(string user, string pass) { - base (NAME, { user, pass }); + public LoginCommand(string user, + string pass, + GLib.Cancellable? should_send) { + base(NAME, { user, pass }, should_send); } public override string to_string() { return "%s %s ".printf(tag.to_string(), name); } -} +} diff --git a/src/engine/imap/command/imap-logout-command.vala b/src/engine/imap/command/imap-logout-command.vala index 7e81fc54..9ff7d83c 100644 --- a/src/engine/imap/command/imap-logout-command.vala +++ b/src/engine/imap/command/imap-logout-command.vala @@ -9,10 +9,11 @@ */ public class Geary.Imap.LogoutCommand : Command { + public const string NAME = "logout"; - public LogoutCommand() { - base (NAME); + public LogoutCommand(GLib.Cancellable? should_send) { + base(NAME, null, should_send); } -} +} diff --git a/src/engine/imap/command/imap-namespace-command.vala b/src/engine/imap/command/imap-namespace-command.vala index 8cf26b26..8e80a5d0 100644 --- a/src/engine/imap/command/imap-namespace-command.vala +++ b/src/engine/imap/command/imap-namespace-command.vala @@ -17,8 +17,8 @@ public class Geary.Imap.NamespaceCommand : Command { public const string NAME = "NAMESPACE"; - public NamespaceCommand() { - base(NAME); + public NamespaceCommand(GLib.Cancellable? should_send) { + base(NAME, null, should_send); } } diff --git a/src/engine/imap/command/imap-noop-command.vala b/src/engine/imap/command/imap-noop-command.vala index 4d894723..ccf440b7 100644 --- a/src/engine/imap/command/imap-noop-command.vala +++ b/src/engine/imap/command/imap-noop-command.vala @@ -11,10 +11,11 @@ */ public class Geary.Imap.NoopCommand : Command { + public const string NAME = "noop"; - public NoopCommand() { - base (NAME); + public NoopCommand(GLib.Cancellable? should_send) { + base(NAME, null, should_send); } -} +} diff --git a/src/engine/imap/command/imap-search-command.vala b/src/engine/imap/command/imap-search-command.vala index 86448b74..4ea44f80 100644 --- a/src/engine/imap/command/imap-search-command.vala +++ b/src/engine/imap/command/imap-search-command.vala @@ -15,8 +15,9 @@ public class Geary.Imap.SearchCommand : Command { public const string NAME = "search"; public const string UID_NAME = "uid search"; - public SearchCommand(SearchCriteria criteria) { - base(NAME); + public SearchCommand(SearchCriteria criteria, + GLib.Cancellable? should_send) { + base(NAME, null, should_send); // Extend rather than append the criteria, so the top-level // criterion appear in the top-level list and not as a child @@ -24,8 +25,9 @@ public class Geary.Imap.SearchCommand : Command { this.args.extend(criteria); } - public SearchCommand.uid(SearchCriteria criteria) { - base(UID_NAME); + public SearchCommand.uid(SearchCriteria criteria, + GLib.Cancellable? should_send) { + base(UID_NAME, null, should_send); // Extend rather than append the criteria, so the top-level // criterion appear in the top-level list and not as a child diff --git a/src/engine/imap/command/imap-select-command.vala b/src/engine/imap/command/imap-select-command.vala index 5e7013a0..cb6844ba 100644 --- a/src/engine/imap/command/imap-select-command.vala +++ b/src/engine/imap/command/imap-select-command.vala @@ -16,8 +16,9 @@ public class Geary.Imap.SelectCommand : Command { public MailboxSpecifier mailbox { get; private set; } - public SelectCommand(MailboxSpecifier mailbox) { - base(NAME); + public SelectCommand(MailboxSpecifier mailbox, + GLib.Cancellable? should_send) { + base(NAME, null, should_send); this.mailbox = mailbox; this.args.add(mailbox.to_parameter()); } diff --git a/src/engine/imap/command/imap-starttls-command.vala b/src/engine/imap/command/imap-starttls-command.vala index 74e5ad71..24ba4d70 100644 --- a/src/engine/imap/command/imap-starttls-command.vala +++ b/src/engine/imap/command/imap-starttls-command.vala @@ -9,10 +9,11 @@ */ public class Geary.Imap.StarttlsCommand : Command { + public const string NAME = "STARTTLS"; - public StarttlsCommand() { - base (NAME); + public StarttlsCommand(GLib.Cancellable? should_send) { + base(NAME, null, should_send); } -} +} diff --git a/src/engine/imap/command/imap-status-command.vala b/src/engine/imap/command/imap-status-command.vala index 388588b5..da2b3c23 100644 --- a/src/engine/imap/command/imap-status-command.vala +++ b/src/engine/imap/command/imap-status-command.vala @@ -18,8 +18,10 @@ public class Geary.Imap.StatusCommand : Command { public const string NAME = "STATUS"; - public StatusCommand(MailboxSpecifier mailbox, StatusDataType[] data_items) { - base (NAME); + public StatusCommand(MailboxSpecifier mailbox, + StatusDataType[] data_items, + GLib.Cancellable? should_send) { + base(NAME, null, should_send); this.args.add(mailbox.to_parameter()); diff --git a/src/engine/imap/command/imap-store-command.vala b/src/engine/imap/command/imap-store-command.vala index 4264e03b..4fbd614a 100644 --- a/src/engine/imap/command/imap-store-command.vala +++ b/src/engine/imap/command/imap-store-command.vala @@ -30,8 +30,11 @@ public class Geary.Imap.StoreCommand : Command { SILENT } - public StoreCommand(MessageSet message_set, Gee.List flag_list, Option options) { - base (message_set.is_uid ? UID_NAME : NAME); + public StoreCommand(MessageSet message_set, + Gee.List flag_list, + Option options, + GLib.Cancellable? should_send) { + base(message_set.is_uid ? UID_NAME : NAME, null, should_send); bool add_flag = (options & Option.ADD_FLAGS) != 0; bool silent = (options & Option.SILENT) != 0; diff --git a/src/engine/imap/transport/imap-client-connection.vala b/src/engine/imap/transport/imap-client-connection.vala index 927ac3bd..82822d31 100644 --- a/src/engine/imap/transport/imap-client-connection.vala +++ b/src/engine/imap/transport/imap-client-connection.vala @@ -576,8 +576,8 @@ public class Geary.Imap.ClientConnection : BaseObject, Logging.Source { private void on_idle_timeout() { debug("Initiating IDLE"); try { - this.send_command(new IdleCommand()); } catch (ImapError err) { + this.send_command(new IdleCommand(this.open_cancellable)); warning("Error sending IDLE: %s", err.message); } } diff --git a/src/engine/imap/transport/imap-client-session.vala b/src/engine/imap/transport/imap-client-session.vala index 6edbacf0..f42112f2 100644 --- a/src/engine/imap/transport/imap-client-session.vala +++ b/src/engine/imap/transport/imap-client-session.vala @@ -159,10 +159,13 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { this.cmd = cmd; } - public override async Object? execute_async(Cancellable? cancellable) throws Error { - response = yield owner.command_transaction_async(cmd, cancellable); - - return response; + public override async Object? execute_async(GLib.Cancellable? cancellable) + throws GLib.Error { + // The command's should_send cancellable will be used to + // cancel the command if needed, so don't need to check or + // pass this method's cancellable through. + this.response = yield owner.submit_command(cmd); + return this.response; } } @@ -903,7 +906,9 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { switch (credentials.supported_method) { case Geary.Credentials.Method.PASSWORD: cmd = new LoginCommand( - credentials.user, credentials.token + credentials.user, + credentials.token, + cancellable ); break; @@ -915,7 +920,9 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { ); } cmd = new AuthenticateCommand.oauth2( - credentials.user, credentials.token + credentials.user, + credentials.token, + cancellable ); break; @@ -936,10 +943,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // should always proceed; only an Error could change this assert(params.proceed); - StatusResponse response = yield command_transaction_async( - cmd, cancellable - ); - + StatusResponse response = yield submit_command(cmd); if (response.status != Status.OK) { // Throw an error indicating auth failed here, unless // there is a status response and it indicates that the @@ -987,7 +991,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { throws GLib.Error { // If no capabilities available, get them now if (this.capabilities.is_empty()) { - yield send_command_async(new CapabilityCommand(), cancellable); + yield send_command_async(new CapabilityCommand(cancellable)); } var last_capabilities = this.capabilities.revision; @@ -1000,7 +1004,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { debug("Attempting STARTTLS..."); StatusResponse resp = yield send_command_async( - new StarttlsCommand(), cancellable + new StarttlsCommand(cancellable) ); if (resp.status == Status.OK) { @@ -1021,7 +1025,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // mitigate main-in-the-middle attacks. If the TLS // command response did not update capabilities, // explicitly do so now. - yield send_command_async(new CapabilityCommand(), cancellable); + yield send_command_async(new CapabilityCommand(cancellable)); last_capabilities = this.capabilities.revision; } } @@ -1031,7 +1035,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // if new capabilities not offered after login, get them now if (last_capabilities == capabilities.revision) { - yield send_command_async(new CapabilityCommand(), cancellable); + yield send_command_async(new CapabilityCommand(cancellable)); } var list_results = new Gee.ArrayList(); @@ -1041,8 +1045,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { try { // Determine what this connection calls the inbox Imap.StatusResponse response = yield send_command_async( - new ListCommand(MailboxSpecifier.inbox, false, null), - cancellable + new ListCommand(MailboxSpecifier.inbox, false, null, cancellable) ); if (response.status == Status.OK && !list_results.is_empty) { this.inbox = list_results[0]; @@ -1055,8 +1058,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // Try to determine what the connection's namespaces are if (this.capabilities.has_capability(Capabilities.NAMESPACE)) { response = yield send_command_async( - new NamespaceCommand(), - cancellable + new NamespaceCommand(cancellable) ); if (response.status != Status.OK) { warning("NAMESPACE command failed"); @@ -1082,8 +1084,12 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // it. In particular, uw-imap sends a null prefix // for the inbox. response = yield send_command_async( - new ListCommand(new MailboxSpecifier(prefix), false, null), - cancellable + new ListCommand( + new MailboxSpecifier(prefix), + false, + null, + cancellable + ) ); if (response.status == Status.OK && !list_results.is_empty) { MailboxInformation list = list_results[0]; @@ -1243,7 +1249,10 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // is now dead keepalive_id = 0; - send_command_async.begin(new NoopCommand(), null, on_keepalive_completed); + send_command_async.begin( + new NoopCommand(null), + on_keepalive_completed + ); debug("Sending keepalive..."); // No need to reschedule keepalive, as the notification that the command was sent should @@ -1264,8 +1273,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // send commands // - public async StatusResponse send_command_async(Command cmd, - GLib.Cancellable? cancellable) + public async StatusResponse send_command_async(Command cmd) throws GLib.Error { check_unsupported_send_command(cmd); @@ -1277,7 +1285,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { assert(params.proceed); - return yield command_transaction_async(cmd, cancellable); + return yield submit_command(cmd); } public async Gee.Map @@ -1402,9 +1410,9 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // Ternary troubles Command cmd; if (is_select) - cmd = new SelectCommand(mailbox); + cmd = new SelectCommand(mailbox, cancellable); else - cmd = new ExamineCommand(mailbox); + cmd = new ExamineCommand(mailbox, cancellable); MachineParams params = new MachineParams(cmd); fsm.issue(Event.SELECT, null, params); @@ -1414,7 +1422,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { assert(params.proceed); - return yield command_transaction_async(cmd, cancellable); + return yield submit_command(cmd); } private uint on_select(uint state, uint event, void *user, Object? object) { @@ -1471,7 +1479,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { public async StatusResponse close_mailbox_async(GLib.Cancellable? cancellable) throws GLib.Error { - CloseCommand cmd = new CloseCommand(); + CloseCommand cmd = new CloseCommand(cancellable); MachineParams params = new MachineParams(cmd); fsm.issue(Event.CLOSE_MAILBOX, null, params); @@ -1479,7 +1487,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { if (params.err != null) throw params.err; - return yield command_transaction_async(cmd, cancellable); + return yield submit_command(cmd); } private uint on_close_mailbox(uint state, uint event, void *user, Object? object) { @@ -1527,7 +1535,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { */ public async void logout_async(GLib.Cancellable? cancellable) throws GLib.Error { - LogoutCommand cmd = new LogoutCommand(); + LogoutCommand cmd = new LogoutCommand(cancellable); MachineParams params = new MachineParams(cmd); fsm.issue(Event.LOGOUT, null, params); @@ -1536,7 +1544,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { throw params.err; if (params.proceed) { - yield command_transaction_async(cmd, cancellable); + yield submit_command(cmd); yield do_disconnect(DisconnectReason.LOCAL_CLOSE); } } @@ -1779,11 +1787,13 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source { // command submission // - private async StatusResponse command_transaction_async(Command cmd, Cancellable? cancellable) - throws Error { - if (this.cx == null) - throw new ImapError.NOT_CONNECTED("Not connected to %s", imap_endpoint.to_string()); - + private async StatusResponse submit_command(Command cmd) + throws GLib.Error { + if (this.cx == null) { + throw new ImapError.NOT_CONNECTED( + "Not connected to %s", imap_endpoint.to_string() + ); + } this.cx.send_command(cmd); // Once a command has been sent over the wire, it can't be diff --git a/test/engine/imap/command/imap-create-command-test.vala b/test/engine/imap/command/imap-create-command-test.vala index 91933c7a..03cd9b63 100644 --- a/test/engine/imap/command/imap-create-command-test.vala +++ b/test/engine/imap/command/imap-create-command-test.vala @@ -16,7 +16,7 @@ class Geary.Imap.CreateCommandTest : TestCase { public void basic_create() throws Error { assert_equal( - new CreateCommand(new MailboxSpecifier("owatagusiam/")).to_string(), + new CreateCommand(new MailboxSpecifier("owatagusiam/"), null).to_string(), "---- create owatagusiam/" ); } @@ -25,7 +25,8 @@ class Geary.Imap.CreateCommandTest : TestCase { assert_equal( new CreateCommand.special_use( new MailboxSpecifier("Everything"), - ALL_MAIL + ALL_MAIL, + null ).to_string(), "---- create Everything (use (\\All))" ); diff --git a/test/engine/imap/command/imap-fetch-command-test.vala b/test/engine/imap/command/imap-fetch-command-test.vala index fdb56d4d..8731943c 100644 --- a/test/engine/imap/command/imap-fetch-command-test.vala +++ b/test/engine/imap/command/imap-fetch-command-test.vala @@ -30,7 +30,7 @@ class Geary.Imap.FetchCommandTest : TestCase { data_items.add(FetchDataSpecifier.UID); assert_equal( - new FetchCommand(this.msg_set, data_items, null).to_string(), + new FetchCommand(this.msg_set, data_items, null, null).to_string(), "---- fetch 1 uid" ); } @@ -45,7 +45,7 @@ class Geary.Imap.FetchCommandTest : TestCase { ); assert_equal( - new FetchCommand(this.msg_set, null, body_items).to_string(), + new FetchCommand(this.msg_set, null, body_items, null).to_string(), "---- fetch 1 body[text]" ); } @@ -57,7 +57,7 @@ class Geary.Imap.FetchCommandTest : TestCase { data_items.add(FetchDataSpecifier.BODY); assert_equal( - new FetchCommand(this.msg_set, data_items, null).to_string(), + new FetchCommand(this.msg_set, data_items, null, null).to_string(), "---- fetch 1 (uid body)" ); } @@ -77,7 +77,7 @@ class Geary.Imap.FetchCommandTest : TestCase { ); assert_equal( - new FetchCommand(this.msg_set, null, body_items).to_string(), + new FetchCommand(this.msg_set, null, body_items, null).to_string(), "---- fetch 1 (body[header] body[text])" ); } @@ -102,7 +102,7 @@ class Geary.Imap.FetchCommandTest : TestCase { ); assert_equal( - new FetchCommand(this.msg_set, data_items, body_items).to_string(), + new FetchCommand(this.msg_set, data_items, body_items, null).to_string(), "---- fetch 1 (uid flags body[header] body[text])" ); } diff --git a/test/engine/imap/transport/imap-client-connection-test.vala b/test/engine/imap/transport/imap-client-connection-test.vala index 9bc745da..2038221f 100644 --- a/test/engine/imap/transport/imap-client-connection-test.vala +++ b/test/engine/imap/transport/imap-client-connection-test.vala @@ -11,7 +11,7 @@ class Geary.Imap.ClientConnectionTest : TestCase { private class TestCommand : Command { public TestCommand() { - base("TEST"); + base("TEST", null, null); } }