]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Command sending API changed to be more extensible.
authorTimo Sirainen <tss@iki.fi>
Fri, 7 Oct 2011 17:10:11 +0000 (20:10 +0300)
committerTimo Sirainen <tss@iki.fi>
Fri, 7 Oct 2011 17:10:11 +0000 (20:10 +0300)
src/lib-imap-client/imapc-client-private.h
src/lib-imap-client/imapc-client.c
src/lib-imap-client/imapc-client.h
src/lib-imap-client/imapc-connection.c
src/lib-imap-client/imapc-connection.h
src/lib-storage/index/imapc/imapc-list.c
src/lib-storage/index/imapc/imapc-mail-fetch.c
src/lib-storage/index/imapc/imapc-mail.c
src/lib-storage/index/imapc/imapc-save.c
src/lib-storage/index/imapc/imapc-storage.c
src/lib-storage/index/imapc/imapc-sync.c

index 419565f9fd29464aa05d21071e43f34536a17c41..1a40270f8887547987cedd6c03df9053ea0c430e 100644 (file)
@@ -37,4 +37,7 @@ struct imapc_client_mailbox {
 void imapc_client_ref(struct imapc_client *client);
 void imapc_client_unref(struct imapc_client **client);
 
+void imapc_command_set_mailbox(struct imapc_command *cmd,
+                              struct imapc_client_mailbox *box);
+
 #endif
index b9246b07054acd68508417e37bb16eb01f1b298e..a1144b1186f06cf49108e86b7b2d5aaffd1e0cba 100644 (file)
 
 #include <unistd.h>
 
-struct imapc_client_command_context {
-       struct imapc_client_mailbox *box;
-
-       imapc_command_callback_t *callback;
-       void *context;
-};
-
 const struct imapc_capability_name imapc_capability_names[] = {
        { "SASL-IR", IMAPC_CAPABILITY_SASL_IR },
        { "LITERAL+", IMAPC_CAPABILITY_LITERALPLUS },
@@ -203,18 +196,14 @@ imapc_client_find_connection(struct imapc_client *client)
        return (*connp)->conn;
 }
 
-void imapc_client_cmdf(struct imapc_client *client,
-                      imapc_command_callback_t *callback, void *context,
-                      const char *cmd_fmt, ...)
+struct imapc_command *
+imapc_client_cmd(struct imapc_client *client,
+                imapc_command_callback_t *callback, void *context)
 {
        struct imapc_connection *conn;
-       va_list args;
 
        conn = imapc_client_find_connection(client);
-
-       va_start(args, cmd_fmt);
-       imapc_connection_cmdvf(conn, FALSE, callback, context, cmd_fmt, args);
-       va_end(args);
+       return imapc_connection_cmd(conn, callback, context);
 }
 
 static struct imapc_client_connection *
@@ -292,36 +281,30 @@ void imapc_client_mailbox_close(struct imapc_client_mailbox **_box)
        *_box = NULL;
 }
 
-static void imapc_client_mailbox_cmd_cb(const struct imapc_command_reply *reply,
-                                       void *context)
+struct imapc_command *
+imapc_client_mailbox_cmd(struct imapc_client_mailbox *box,
+                        imapc_command_callback_t *callback, void *context)
 {
-       struct imapc_client_command_context *ctx = context;
-
-       ctx->box->pending_box_command_count--;
+       struct imapc_command *cmd;
 
-       ctx->callback(reply, ctx->context);
-       i_free(ctx);
+       cmd = imapc_connection_cmd(box->conn, callback, context);
+       imapc_command_set_mailbox(cmd, box);
+       return cmd;
 }
 
-static struct imapc_client_command_context *
-imapc_client_mailbox_cmd_common(struct imapc_client_mailbox *box,
-                               imapc_command_callback_t *callback,
-                               void *context)
+struct imapc_msgmap *
+imapc_client_mailbox_get_msgmap(struct imapc_client_mailbox *box)
 {
-       struct imapc_client_command_context *ctx;
-
-       ctx = i_new(struct imapc_client_command_context, 1);
-       ctx->box = box;
-       ctx->callback = callback;
-       ctx->context = context;
+       return box->msgmap;
+}
 
-       box->pending_box_command_count++;
-       return ctx;
+void imapc_client_mailbox_idle(struct imapc_client_mailbox *box)
+{
+       if (imapc_client_mailbox_is_connected(box))
+               imapc_connection_idle(box->conn);
 }
 
-static bool
-imapc_client_mailbox_is_selected(struct imapc_client_mailbox *box,
-                                struct imapc_command_reply *reply_r)
+bool imapc_client_mailbox_is_connected(struct imapc_client_mailbox *box)
 {
        struct imapc_client_mailbox *selected_box;
 
@@ -330,78 +313,13 @@ imapc_client_mailbox_is_selected(struct imapc_client_mailbox *box,
        if (selected_box == box)
                return TRUE;
 
-       memset(reply_r, 0, sizeof(*reply_r));
-       reply_r->state = IMAPC_COMMAND_STATE_DISCONNECTED;
-       if (selected_box == NULL) {
-               reply_r->text_full = "Disconnected from server";
-       } else {
+       if (selected_box != NULL)
                i_error("imapc: Selected mailbox changed unexpectedly");
-               reply_r->text_full = "Internal error";
-       }
-       reply_r->text_without_resp = reply_r->text_full;
 
        box->conn = NULL;
        return FALSE;
 }
 
-void imapc_client_mailbox_cmd(struct imapc_client_mailbox *box,
-                             imapc_command_callback_t *callback,
-                             void *context, const char *cmd)
-{
-       struct imapc_client_command_context *ctx;
-       struct imapc_command_reply reply;
-
-       if (!imapc_client_mailbox_is_selected(box, &reply)) {
-               callback(&reply, context);
-               return;
-       }
-
-       ctx = imapc_client_mailbox_cmd_common(box, callback, context);
-       imapc_connection_cmd(box->conn, TRUE, cmd,
-                            imapc_client_mailbox_cmd_cb, ctx);
-}
-
-void imapc_client_mailbox_cmdf(struct imapc_client_mailbox *box,
-                              imapc_command_callback_t *callback,
-                              void *context, const char *cmd_fmt, ...)
-{
-       struct imapc_client_command_context *ctx;
-       va_list args;
-       struct imapc_command_reply reply;
-
-       if (!imapc_client_mailbox_is_selected(box, &reply)) {
-               callback(&reply, context);
-               return;
-       }
-
-       ctx = imapc_client_mailbox_cmd_common(box, callback, context);
-       va_start(args, cmd_fmt);
-       imapc_connection_cmdvf(box->conn, TRUE, imapc_client_mailbox_cmd_cb,
-                              ctx, cmd_fmt, args);
-       va_end(args);
-}
-
-struct imapc_msgmap *
-imapc_client_mailbox_get_msgmap(struct imapc_client_mailbox *box)
-{
-       return box->msgmap;
-}
-
-void imapc_client_mailbox_idle(struct imapc_client_mailbox *box)
-{
-       struct imapc_command_reply reply;
-
-       if (imapc_client_mailbox_is_selected(box, &reply))
-               imapc_connection_idle(box->conn);
-}
-
-bool imapc_client_mailbox_is_connected(struct imapc_client_mailbox *box)
-{
-       struct imapc_command_reply reply;
-
-       return imapc_client_mailbox_is_selected(box, &reply);
-}
-
 enum imapc_capability
 imapc_client_get_capabilities(struct imapc_client *client)
 {
index d23aacedd4d17ab5c85e1635c502fa371c1f6c84..5e9afa7395eaf86c1bb8bf5a465f4bc775435835 100644 (file)
@@ -109,9 +109,14 @@ void imapc_client_deinit(struct imapc_client **client);
 void imapc_client_login(struct imapc_client *client,
                        imapc_command_callback_t *callback, void *context);
 
-void imapc_client_cmdf(struct imapc_client *client,
-                      imapc_command_callback_t *callback, void *context,
-                      const char *cmd_fmt, ...) ATTR_FORMAT(4, 5);
+struct imapc_command *
+imapc_client_cmd(struct imapc_client *client,
+                imapc_command_callback_t *callback, void *context);
+void imapc_command_send(struct imapc_command *cmd, const char *cmd_str);
+void imapc_command_sendf(struct imapc_command *cmd, const char *cmd_fmt, ...)
+       ATTR_FORMAT(2, 3);
+void imapc_command_sendvf(struct imapc_command *cmd,
+                         const char *cmd_fmt, va_list args) ATTR_FORMAT(2, 0);
 
 void imapc_client_register_untagged(struct imapc_client *client,
                                    imapc_untagged_callback_t *callback,
@@ -132,13 +137,9 @@ imapc_client_mailbox_open(struct imapc_client *client,
                          void *untagged_box_context);
 void imapc_client_mailbox_close(struct imapc_client_mailbox **box);
 void imapc_client_mailbox_disconnect(struct imapc_client_mailbox *box);
-void imapc_client_mailbox_cmd(struct imapc_client_mailbox *box,
-                             imapc_command_callback_t *callback,
-                             void *context, const char *cmd);
-void imapc_client_mailbox_cmdf(struct imapc_client_mailbox *box,
-                              imapc_command_callback_t *callback,
-                              void *context, const char *cmd_fmt, ...)
-       ATTR_FORMAT(4, 5);
+struct imapc_command *
+imapc_client_mailbox_cmd(struct imapc_client_mailbox *box,
+                        imapc_command_callback_t *callback, void *context);
 struct imapc_msgmap *
 imapc_client_mailbox_get_msgmap(struct imapc_client_mailbox *box);
 
index a50c34ee91565888bffdd5ead4c6e5e450e4635b..dd0b208b81c833e3833b68e63ceb18b09d023acf 100644 (file)
@@ -47,13 +47,19 @@ struct imapc_command {
        unsigned int send_pos;
        unsigned int tag;
 
+       struct imapc_connection *conn;
+       /* If non-NULL, points to the mailbox where this command should be
+          executed */
+       struct imapc_client_mailbox *box;
+
        ARRAY_DEFINE(streams, struct imapc_command_stream);
 
        imapc_command_callback_t *callback;
        void *context;
 
+       /* This is the IDLE command */
        unsigned int idle:1;
-       unsigned int mailboxcmd:1;
+       /* Waiting for '+' literal reply before we can continue */
        unsigned int wait_for_literal:1;
 };
 
@@ -657,7 +663,7 @@ imapc_connection_get_sasl_plain_request(struct imapc_connection *conn)
 static void imapc_connection_authenticate(struct imapc_connection *conn)
 {
        const struct imapc_client_settings *set = &conn->client->set;
-       const char *cmd;
+       struct imapc_command *cmd;
 
        if (conn->client->set.debug) {
                if (set->master_user == NULL) {
@@ -669,23 +675,21 @@ static void imapc_connection_authenticate(struct imapc_connection *conn)
                }
        }
 
+       cmd = imapc_connection_cmd(conn, imapc_connection_login_cb,
+                                  conn);
+
        if ((set->master_user == NULL &&
             need_literal(set->username) && need_literal(set->password)) ||
            (conn->capabilities & IMAPC_CAPABILITY_AUTH_PLAIN) == 0) {
                /* We can use LOGIN command */
-               imapc_connection_cmdf(conn, FALSE, imapc_connection_login_cb,
-                                     conn, "LOGIN %s %s",
-                                     set->username, set->password);
+               imapc_command_sendf(cmd, "LOGIN %s %s",
+                                   set->username, set->password);
        } else if ((conn->capabilities & IMAPC_CAPABILITY_SASL_IR) != 0) {
-               cmd = t_strdup_printf("AUTHENTICATE PLAIN %s",
+               imapc_command_sendf(cmd, "AUTHENTICATE PLAIN %1s",
                        imapc_connection_get_sasl_plain_request(conn));
-               imapc_connection_cmd(conn, FALSE, cmd,
-                                    imapc_connection_login_cb, conn);
        } else {
-               cmd = t_strdup_printf("AUTHENTICATE PLAIN\r\n%s",
+               imapc_command_sendf(cmd, "AUTHENTICATE PLAIN\r\n%1s",
                        imapc_connection_get_sasl_plain_request(conn));
-               imapc_connection_cmd(conn, FALSE, cmd,
-                                    imapc_connection_login_cb, conn);
        }
 }
 
@@ -709,6 +713,8 @@ imapc_connection_starttls_cb(const struct imapc_command_reply *reply,
 
 static void imapc_connection_starttls(struct imapc_connection *conn)
 {
+       struct imapc_command *cmd;
+
        if (conn->client->set.ssl_mode == IMAPC_CLIENT_SSL_MODE_STARTTLS &&
            conn->ssl_iostream == NULL) {
                if ((conn->capabilities & IMAPC_CAPABILITY_STARTTLS) == 0) {
@@ -718,8 +724,9 @@ static void imapc_connection_starttls(struct imapc_connection *conn)
                        imapc_connection_disconnect(conn);
                        return;
                }
-               imapc_connection_cmd(conn, FALSE, "STARTTLS",
-                                    imapc_connection_starttls_cb, conn);
+               cmd = imapc_connection_cmd(conn, imapc_connection_starttls_cb,
+                                          conn);
+               imapc_command_send(cmd, "STARTTLS");
                return;
        }
        imapc_connection_authenticate(conn);
@@ -746,6 +753,7 @@ static int imapc_connection_input_banner(struct imapc_connection *conn)
 {
        const struct imap_arg *imap_args;
        const char *key, *value;
+       struct imapc_command *cmd;
        int ret;
 
        if ((ret = imapc_connection_read_line(conn, &imap_args)) <= 0)
@@ -758,8 +766,9 @@ static int imapc_connection_input_banner(struct imapc_connection *conn)
 
        if (conn->capabilities == 0) {
                /* capabilities weren't sent in the banner. ask for them. */
-               imapc_connection_cmd(conn, FALSE, "CAPABILITY",
-                                    imapc_connection_capability_cb, conn);
+               cmd = imapc_connection_cmd(conn, imapc_connection_capability_cb,
+                                          conn);
+               imapc_command_send(cmd, "CAPABILITY");
        } else {
                imapc_connection_starttls(conn);
        }
@@ -864,6 +873,15 @@ static int imapc_connection_input_plus(struct imapc_connection *conn)
        return 1;
 }
 
+static void
+imapc_command_reply_free(struct imapc_command *cmd,
+                        const struct imapc_command_reply *reply)
+{
+       if (cmd->callback != NULL)
+               cmd->callback(reply, cmd->context);
+       imapc_command_free(cmd);
+}
+
 static int imapc_connection_input_tagged(struct imapc_connection *conn)
 {
        struct imapc_command *const *cmds, *cmd = NULL;
@@ -951,9 +969,7 @@ static int imapc_connection_input_tagged(struct imapc_connection *conn)
        }
 
        imapc_connection_input_reset(conn);
-       if (cmd->callback != NULL)
-               cmd->callback(&reply, cmd->context);
-       imapc_command_free(cmd);
+       imapc_command_reply_free(cmd, &reply);
        return 1;
 }
 
@@ -1165,12 +1181,13 @@ imapc_reidle_callback(const struct imapc_command_reply *reply ATTR_UNUSED,
 
 static void imapc_connection_reset_idle(struct imapc_connection *conn)
 {
+       struct imapc_command *cmd;
+
        if (!conn->idling)
-               imapc_connection_cmd(conn, FALSE, "NOOP", NULL, NULL);
-       else {
-               imapc_connection_cmd(conn, FALSE, "NOOP",
-                                    imapc_reidle_callback, conn);
-       }
+               cmd = imapc_connection_cmd(conn, NULL, NULL);
+       else
+               cmd = imapc_connection_cmd(conn, imapc_reidle_callback, conn);
+       imapc_command_send(cmd, "NOOP");
 }
 
 static void imapc_connection_connect_next_ip(struct imapc_connection *conn)
@@ -1407,6 +1424,7 @@ static int imapc_command_try_send_stream(struct imapc_connection *conn,
 static void imapc_command_send_more(struct imapc_connection *conn,
                                    struct imapc_command *cmd)
 {
+       struct imapc_command_reply reply;
        const unsigned char *p, *data;
        unsigned int seek_pos, start_pos, end_pos, size;
        int ret;
@@ -1414,6 +1432,15 @@ static void imapc_command_send_more(struct imapc_connection *conn,
        i_assert(!cmd->wait_for_literal);
        i_assert(cmd->send_pos < cmd->data->used);
 
+       if (cmd->box != NULL && !imapc_client_mailbox_is_connected(cmd->box)) {
+               /* shouldn't normally happen */
+               memset(&reply, 0, sizeof(reply));
+               reply.text_without_resp = reply.text_full = "Mailbox not open";
+               reply.state = IMAPC_COMMAND_STATE_BAD;
+               imapc_command_reply_free(cmd, &reply);
+               return;
+       }
+
        timeout_reset(conn->to_output);
        if ((ret = imapc_command_try_send_stream(conn, cmd)) == 0)
                return;
@@ -1475,9 +1502,10 @@ static void imapc_connection_send_idle_done(struct imapc_connection *conn)
        }
 }
 
-static void imapc_command_send(struct imapc_connection *conn,
-                              struct imapc_command *cmd)
+static void imapc_connection_cmd_send(struct imapc_command *cmd)
 {
+       struct imapc_connection *conn = cmd->conn;
+
        imapc_connection_send_idle_done(conn);
        switch (conn->state) {
        case IMAPC_CONNECTION_STATE_AUTHENTICATING:
@@ -1530,51 +1558,47 @@ static int imapc_connection_output(struct imapc_connection *conn)
        return ret;
 }
 
-static struct imapc_command *
-imapc_connection_cmd_build(const char *cmdline,
-                          imapc_command_callback_t *callback, void *context)
+struct imapc_command *
+imapc_connection_cmd(struct imapc_connection *conn,
+                    imapc_command_callback_t *callback, void *context)
 {
        struct imapc_command *cmd;
-       unsigned int len = strlen(cmdline);
 
        cmd = imapc_command_begin(callback, context);
-       cmd->data = str_new(cmd->pool, 6 + len + 2);
-       str_printfa(cmd->data, "%u %s\r\n", cmd->tag, cmdline);
+       cmd->conn = conn;
        return cmd;
 }
 
-void imapc_connection_cmd(struct imapc_connection *conn, bool mailboxcmd,
-                         const char *cmdline,
-                         imapc_command_callback_t *callback, void *context)
+void imapc_command_set_mailbox(struct imapc_command *cmd,
+                              struct imapc_client_mailbox *box)
 {
-       struct imapc_command *cmd;
+       cmd->box = box;
+       box->pending_box_command_count++;
+}
+
+void imapc_command_send(struct imapc_command *cmd, const char *cmd_str)
+{
+       unsigned int len = strlen(cmd_str);
 
-       cmd = imapc_connection_cmd_build(cmdline, callback, context);
-       cmd->mailboxcmd = mailboxcmd;
-       imapc_command_send(conn, cmd);
+       cmd->data = str_new(cmd->pool, 6 + len + 2);
+       str_printfa(cmd->data, "%u %s\r\n", cmd->tag, cmd_str);
+       imapc_connection_cmd_send(cmd);
 }
 
-void imapc_connection_cmdf(struct imapc_connection *conn, bool mailboxcmd,
-                          imapc_command_callback_t *callback, void *context,
-                          const char *cmd_fmt, ...)
+void imapc_command_sendf(struct imapc_command *cmd, const char *cmd_fmt, ...)
 {
        va_list args;
 
        va_start(args, cmd_fmt);
-       imapc_connection_cmdvf(conn, mailboxcmd, callback, context,
-                              cmd_fmt, args);
+       imapc_command_sendvf(cmd, cmd_fmt, args);
        va_end(args);
 }
 
-void imapc_connection_cmdvf(struct imapc_connection *conn, bool mailboxcmd,
-                          imapc_command_callback_t *callback, void *context,
-                          const char *cmd_fmt, va_list args)
+void imapc_command_sendvf(struct imapc_command *cmd,
+                         const char *cmd_fmt, va_list args)
 {
-       struct imapc_command *cmd;
        unsigned int i;
 
-       cmd = imapc_command_begin(callback, context);
-       cmd->mailboxcmd = mailboxcmd;
        cmd->data = str_new(cmd->pool, 128);
        str_printfa(cmd->data, "%u ", cmd->tag);
 
@@ -1615,7 +1639,7 @@ void imapc_connection_cmdvf(struct imapc_connection *conn, bool mailboxcmd,
 
                        if (!need_literal(arg))
                                imap_dquote_append(cmd->data, arg);
-                       else if ((conn->capabilities &
+                       else if ((cmd->conn->capabilities &
                                  IMAPC_CAPABILITY_LITERALPLUS) != 0) {
                                str_printfa(cmd->data, "{%"PRIuSIZE_T"+}\r\n%s",
                                            strlen(arg), arg);
@@ -1637,7 +1661,7 @@ void imapc_connection_cmdvf(struct imapc_connection *conn, bool mailboxcmd,
        }
        str_append(cmd->data, "\r\n");
 
-       imapc_command_send(conn, cmd);
+       imapc_connection_cmd_send(cmd);
 }
 
 enum imapc_connection_state
@@ -1657,6 +1681,7 @@ void imapc_connection_select(struct imapc_client_mailbox *box,
                             imapc_command_callback_t *callback, void *context)
 {
        struct imapc_connection *conn = box->conn;
+       struct imapc_command *cmd;
 
        i_assert(conn->selecting_box == NULL);
 
@@ -1671,8 +1696,8 @@ void imapc_connection_select(struct imapc_client_mailbox *box,
                conn->selected_box = box;
        }
 
-       imapc_connection_cmdf(conn, FALSE, callback, context,
-                             examine ? "EXAMINE %s" : "SELECT %s", name);
+       cmd = imapc_connection_cmd(conn, callback, context);
+       imapc_command_sendf(cmd, examine ? "EXAMINE %s" : "SELECT %s", name);
 }
 
 void imapc_connection_unselect(struct imapc_client_mailbox *box)
@@ -1692,7 +1717,7 @@ void imapc_connection_unselect(struct imapc_client_mailbox *box)
        imapc_connection_send_idle_done(conn);
 
        array_foreach(&conn->cmd_wait_list, cmdp) {
-               if ((*cmdp)->callback != NULL && (*cmdp)->mailboxcmd) {
+               if ((*cmdp)->callback != NULL && (*cmdp)->box != NULL) {
                        (*cmdp)->callback(&reply, (*cmdp)->context);
                        (*cmdp)->callback = NULL;
                }
@@ -1700,7 +1725,7 @@ void imapc_connection_unselect(struct imapc_client_mailbox *box)
        for (i = 0; i < array_count(&conn->cmd_send_queue); ) {
                cmdp = array_idx(&conn->cmd_send_queue, i);
                cmd = *cmdp;
-               if (!cmd->mailboxcmd)
+               if (cmd->box == NULL)
                        i++;
                else {
                        array_delete(&conn->cmd_send_queue, i, 1);
@@ -1750,8 +1775,7 @@ void imapc_connection_idle(struct imapc_connection *conn)
            (conn->capabilities & IMAPC_CAPABILITY_IDLE) == 0)
                return;
 
-       cmd = imapc_connection_cmd_build("IDLE", imapc_connection_idle_callback,
-                                        conn);
+       cmd = imapc_connection_cmd(conn, imapc_connection_idle_callback, conn);
        cmd->idle = TRUE;
-       imapc_command_send(conn, cmd);
+       imapc_command_send(cmd, "IDLE");
 }
index 7dcb7f1db39919b11b586db9884741a2915bd988..3f550e9771501f61276a9f48d25945c61a59666a 100644 (file)
@@ -28,16 +28,10 @@ void imapc_connection_disconnect(struct imapc_connection *conn);
 void imapc_connection_ioloop_changed(struct imapc_connection *conn);
 void imapc_connection_input_pending(struct imapc_connection *conn);
 
-void imapc_connection_cmd(struct imapc_connection *conn, bool mailboxcmd,
-                         const char *cmdline,
-                         imapc_command_callback_t *callback, void *context);
-void imapc_connection_cmdf(struct imapc_connection *conn, bool mailboxcmd,
-                          imapc_command_callback_t *callback, void *context,
-                          const char *cmd_fmt, ...) ATTR_FORMAT(5, 6);
-void imapc_connection_cmdvf(struct imapc_connection *conn, bool mailboxcmd,
-                           imapc_command_callback_t *callback, void *context,
-                           const char *cmd_fmt, va_list args)
-       ATTR_FORMAT(5, 0);
+struct imapc_command *
+imapc_connection_cmd(struct imapc_connection *conn,
+                    imapc_command_callback_t *callback, void *context);
+
 void imapc_connection_select(struct imapc_client_mailbox *box,
                             const char *name, bool examine,
                             imapc_command_callback_t *callback, void *context);
index aa49ae5b708415f900ac3e71ca7931dfd9fd231a..9854d9f10c014952624ef98a43141644d5fe4399 100644 (file)
@@ -278,8 +278,18 @@ imapc_list_join_refpattern(struct mailbox_list *list ATTR_UNUSED,
        return t_strconcat(ref, pattern, NULL);
 }
 
+static struct imapc_command *
+imapc_list_simple_context_init(struct imapc_simple_context *ctx,
+                              struct imapc_mailbox_list *list)
+{
+       imapc_simple_context_init(ctx, list->storage);
+       return imapc_client_cmd(list->storage->client,
+                               imapc_list_simple_callback, ctx);
+}
+
 static int imapc_list_refresh(struct imapc_mailbox_list *list)
 {
+       struct imapc_command *cmd;
        struct imapc_simple_context ctx;
 
        i_assert(list->sep != '\0');
@@ -287,9 +297,8 @@ static int imapc_list_refresh(struct imapc_mailbox_list *list)
        if (list->refreshed_mailboxes)
                return 0;
 
-       imapc_simple_context_init(&ctx, list->storage);
-       imapc_client_cmdf(list->storage->client,
-                         imapc_list_simple_callback, &ctx, "LIST \"\" *");
+       cmd = imapc_list_simple_context_init(&ctx, list);
+       imapc_command_send(cmd, "LIST \"\" *");
        mailbox_tree_deinit(&list->mailboxes);
        list->mailboxes = mailbox_tree_init(list->sep);
 
@@ -434,6 +443,7 @@ imapc_list_subscriptions_refresh(struct mailbox_list *_src_list,
        struct imapc_mailbox_list *src_list =
                (struct imapc_mailbox_list *)_src_list;
        struct imapc_simple_context ctx;
+       struct imapc_command *cmd;
        char sep;
 
        i_assert(src_list->tmp_subscriptions == NULL);
@@ -452,10 +462,8 @@ imapc_list_subscriptions_refresh(struct mailbox_list *_src_list,
 
        src_list->tmp_subscriptions = mailbox_tree_init(src_list->sep);
 
-       imapc_simple_context_init(&ctx, src_list->storage);
-       imapc_client_cmdf(src_list->storage->client,
-                         imapc_list_simple_callback, &ctx,
-                         "LSUB \"\" *");
+       cmd = imapc_list_simple_context_init(&ctx, src_list);
+       imapc_command_send(cmd, "LSUB \"\" *");
        imapc_simple_run(&ctx);
 
        /* replace subscriptions tree in destination */
@@ -474,12 +482,11 @@ static int imapc_list_set_subscribed(struct mailbox_list *_list,
                                     const char *name, bool set)
 {
        struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
+       struct imapc_command *cmd;
        struct imapc_simple_context ctx;
 
-       imapc_simple_context_init(&ctx, list->storage);
-       imapc_client_cmdf(list->storage->client,
-                         imapc_list_simple_callback, &ctx,
-                         set ? "SUBSCRIBE %s" : "UNSUBSCRIBE %s", name);
+       cmd = imapc_list_simple_context_init(&ctx, list);
+       imapc_command_sendf(cmd, set ? "SUBSCRIBE %s" : "UNSUBSCRIBE %s", name);
        imapc_simple_run(&ctx);
        return ctx.ret;
 }
@@ -498,11 +505,11 @@ static int
 imapc_list_delete_mailbox(struct mailbox_list *_list, const char *name)
 {
        struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
+       struct imapc_command *cmd;
        struct imapc_simple_context ctx;
 
-       imapc_simple_context_init(&ctx, list->storage);
-       imapc_client_cmdf(list->storage->client,
-                         imapc_list_simple_callback, &ctx, "DELETE %s", name);
+       cmd = imapc_list_simple_context_init(&ctx, list);
+       imapc_command_sendf(cmd, "DELETE %s", name);
        imapc_simple_run(&ctx);
        return ctx.ret;
 }
@@ -535,6 +542,7 @@ imapc_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
 {
        struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)oldlist;
        struct mailbox_list *fs_list = imapc_list_get_fs(list);
+       struct imapc_command *cmd;
        struct imapc_simple_context ctx;
 
        if (!rename_children) {
@@ -549,10 +557,8 @@ imapc_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
                return -1;
        }
 
-       imapc_simple_context_init(&ctx, list->storage);
-       imapc_client_cmdf(list->storage->client,
-                         imapc_list_simple_callback, &ctx,
-                         "RENAME %s %s", oldname, newname);
+       cmd = imapc_list_simple_context_init(&ctx, list);
+       imapc_command_sendf(cmd, "RENAME %s %s", oldname, newname);
        imapc_simple_run(&ctx);
        if (ctx.ret == 0 && fs_list != NULL && oldlist == newlist) {
                oldname = imapc_list_get_fs_name(list, oldname);
@@ -568,6 +574,7 @@ int imapc_list_get_mailbox_flags(struct mailbox_list *_list, const char *name,
                                 enum mailbox_info_flags *flags_r)
 {
        struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
+       struct imapc_command *cmd;
        struct imapc_simple_context sctx;
        struct mailbox_node *node;
        const char *vname;
@@ -580,9 +587,8 @@ int imapc_list_get_mailbox_flags(struct mailbox_list *_list, const char *name,
                node->flags |= MAILBOX_NONEXISTENT;
 
        /* refresh the mailbox flags */
-       imapc_simple_context_init(&sctx, list->storage);
-       imapc_client_cmdf(list->storage->client, imapc_simple_callback,
-                         &sctx, "LIST \"\" %s", name);
+       cmd = imapc_list_simple_context_init(&sctx, list);
+       imapc_command_sendf(cmd, "LIST \"\" %s", name);
        imapc_simple_run(&sctx);
        if (sctx.ret < 0)
                return -1;
index a8ffea859b426d936ed388a0022f65f55afe94cd..acb374c532d854049f6309a779cb5ddc02cfd3db 100644 (file)
@@ -56,6 +56,7 @@ imapc_mail_send_fetch(struct mail *_mail, enum mail_fetch_field fields)
 {
        struct imapc_mail *mail = (struct imapc_mail *)_mail;
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
+       struct imapc_command *cmd;
        struct mail_index_view *view;
        string_t *str;
        uint32_t seq;
@@ -106,9 +107,9 @@ imapc_mail_send_fetch(struct mail *_mail, enum mail_fetch_field fields)
        if (mail->fetch_count++ == 0)
                array_append(&mbox->fetch_mails, &mail, 1);
 
-       imapc_client_mailbox_cmd(mbox->client_box,
-                                imapc_mail_prefetch_callback,
-                                mail, str_c(str));
+       cmd = imapc_client_mailbox_cmd(mbox->client_box,
+                                      imapc_mail_prefetch_callback, mail);
+       imapc_command_send(cmd, str_c(str));
        mail->imail.data.prefetch_sent = TRUE;
        return 0;
 }
index 5feff137ba799d9e333fcdf2b41746c10ea4ce10..c974ca12694298469695b4b70e375949622a3d54 100644 (file)
@@ -30,6 +30,7 @@ static bool imapc_mail_is_expunged(struct mail *_mail)
 {
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
        struct imapc_msgmap *msgmap;
+       struct imapc_command *cmd;
        struct imapc_simple_context sctx;
        uint32_t lseq, rseq;
 
@@ -47,8 +48,9 @@ static bool imapc_mail_is_expunged(struct mail *_mail)
        /* we may be running against a server that hasn't bothered sending
           us an EXPUNGE. see if NOOP sends it. */
        imapc_simple_context_init(&sctx, mbox->storage);
-       imapc_client_mailbox_cmd(mbox->client_box,
-                                imapc_simple_callback, &sctx, "NOOP");
+       cmd = imapc_client_mailbox_cmd(mbox->client_box,
+                                      imapc_simple_callback, &sctx);
+       imapc_command_send(cmd, "NOOP");
        imapc_simple_run(&sctx);
 
        return !imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq);
index 8f34ff36cbb4301371d757b86afa1f141455e3fd..3933f47e32159097ad240d0cb19949a7d92983b2 100644 (file)
@@ -200,6 +200,7 @@ imapc_append_keywords(string_t *str, struct mail_keywords *kw)
 static int imapc_save_append(struct imapc_save_context *ctx)
 {
        struct mail_save_context *_ctx = &ctx->ctx;
+       struct imapc_command *cmd;
        struct imapc_save_cmd_context sctx;
        struct istream *input;
        const char *flags = "", *internaldate = "";
@@ -222,9 +223,10 @@ static int imapc_save_append(struct imapc_save_context *ctx)
        input = i_stream_create_fd(ctx->fd, IO_BLOCK_SIZE, FALSE);
        sctx.ctx = ctx;
        sctx.ret = -2;
-       imapc_client_cmdf(ctx->mbox->storage->client,
-                         imapc_save_callback, &sctx, "APPEND %s%1s%1s %p",
-                         ctx->mbox->box.name, flags, internaldate, input);
+       cmd = imapc_client_cmd(ctx->mbox->storage->client,
+                              imapc_save_callback, &sctx);
+       imapc_command_sendf(cmd, "APPEND %s%1s%1s %p",
+                           ctx->mbox->box.name, flags, internaldate, input);
        i_stream_unref(&input);
        while (sctx.ret == -2)
                imapc_storage_run(ctx->mbox->storage);
@@ -373,6 +375,7 @@ int imapc_copy(struct mail_save_context *_ctx, struct mail *mail)
        struct imapc_save_context *ctx = (struct imapc_save_context *)_ctx;
        struct mailbox_transaction_context *_t = _ctx->transaction;
        struct imapc_mailbox *src_mbox = (struct imapc_mailbox *)mail->box;
+       struct imapc_command *cmd;
        struct imapc_save_cmd_context sctx;
 
        i_assert((_t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
@@ -381,10 +384,10 @@ int imapc_copy(struct mail_save_context *_ctx, struct mail *mail)
                /* same server, we can use COPY for the mail */
                sctx.ret = -2;
                sctx.ctx = ctx;
-               imapc_client_mailbox_cmdf(src_mbox->client_box,
-                                         imapc_copy_callback, &sctx,
-                                         "UID COPY %u %s",
-                                         mail->uid, _t->box->name);
+               cmd = imapc_client_mailbox_cmd(src_mbox->client_box,
+                                              imapc_copy_callback, &sctx);
+               imapc_command_sendf(cmd, "UID COPY %u %s",
+                                   mail->uid, _t->box->name);
                while (sctx.ret == -2)
                        imapc_storage_run(src_mbox->storage);
                ctx->finished = TRUE;
index 54b807f593ce7aa6d151a26f8ccc99d4fd7c1afb..f0ef3222d33411928fa5b7d2eeca4cc060f3be0d 100644 (file)
@@ -209,11 +209,12 @@ static int
 imapc_storage_get_hierarchy_sep(struct imapc_storage *storage,
                                const char **error_r)
 {
+       struct imapc_command *cmd;
        struct imapc_simple_context sctx;
 
        imapc_simple_context_init(&sctx, storage);
-       imapc_client_cmdf(storage->client, imapc_simple_callback, &sctx,
-                         "LIST \"\" \"\"");
+       cmd = imapc_client_cmd(storage->client, imapc_simple_callback, &sctx);
+       imapc_command_send(cmd, "LIST \"\" \"\"");
        imapc_simple_run(&sctx);
 
        if (sctx.ret < 0) {
@@ -474,6 +475,7 @@ imapc_mailbox_create(struct mailbox *box,
                     bool directory)
 {
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
+       struct imapc_command *cmd;
        struct imapc_simple_context sctx;
        const char *name = box->name;
 
@@ -482,8 +484,9 @@ imapc_mailbox_create(struct mailbox *box,
                                mailbox_list_get_hierarchy_sep(box->list));
        }
        imapc_simple_context_init(&sctx, mbox->storage);
-       imapc_client_cmdf(mbox->storage->client, imapc_simple_callback, &sctx,
-                         "CREATE %s", name);
+       cmd = imapc_client_cmd(mbox->storage->client,
+                              imapc_simple_callback, &sctx);
+       imapc_command_sendf(cmd, "CREATE %s", name);
        imapc_simple_run(&sctx);
        return sctx.ret;
 }
@@ -551,6 +554,7 @@ static int imapc_mailbox_get_status(struct mailbox *box,
                                    struct mailbox_status *status_r)
 {
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
+       struct imapc_command *cmd;
        struct imapc_simple_context sctx;
        string_t *str;
 
@@ -593,8 +597,9 @@ static int imapc_mailbox_get_status(struct mailbox *box,
        imapc_simple_context_init(&sctx, mbox->storage);
        mbox->storage->cur_status_box = mbox;
        mbox->storage->cur_status = status_r;
-       imapc_client_cmdf(mbox->storage->client, imapc_simple_callback, &sctx,
-                         "STATUS %s (%1s)", box->name, str_c(str)+1);
+       cmd = imapc_client_cmd(mbox->storage->client,
+                              imapc_simple_callback, &sctx);
+       imapc_command_sendf(cmd, "STATUS %s (%1s)", box->name, str_c(str)+1);
        imapc_simple_run(&sctx);
        mbox->storage->cur_status_box = NULL;
        mbox->storage->cur_status = NULL;
@@ -617,8 +622,11 @@ static int imapc_mailbox_get_metadata(struct mailbox *box,
 
 static void imapc_idle_timeout(struct imapc_mailbox *mbox)
 {
-       imapc_client_mailbox_cmd(mbox->client_box,
-                                imapc_noop_callback, mbox->storage, "NOOP");
+       struct imapc_command *cmd;
+
+       cmd = imapc_client_mailbox_cmd(mbox->client_box,
+                                      imapc_noop_callback, mbox->storage);
+       imapc_command_send(cmd, "NOOP");
 }
 
 static void imapc_idle_noop_callback(const struct imapc_command_reply *reply,
@@ -634,6 +642,7 @@ static void imapc_idle_noop_callback(const struct imapc_command_reply *reply,
 static void imapc_notify_changes(struct mailbox *box)
 {
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
+       struct imapc_command *cmd;
        enum imapc_capability capa;
 
        if (box->notify_min_interval == 0) {
@@ -648,9 +657,9 @@ static void imapc_notify_changes(struct mailbox *box)
                   don't notice changes immediately, we'll force them to check
                   here by sending a NOOP. this helps with clients that break
                   IDLE when clicking "get mail". */
-               imapc_client_mailbox_cmd(mbox->client_box,
-                                        imapc_idle_noop_callback, mbox,
-                                        "NOOP");
+               cmd = imapc_client_mailbox_cmd(mbox->client_box,
+                                              imapc_idle_noop_callback, mbox);
+               imapc_command_send(cmd, "NOOP");
        } else {
                /* remote server doesn't support IDLE.
                   check for changes with NOOP every once in a while. */
index 3885bbc4126538d947bdba5fac355751a3c7c79e..9a3bd2d9a441c60108e8cb4c99f3cbbc5dd645aa 100644 (file)
@@ -36,11 +36,14 @@ static void imapc_sync_callback(const struct imapc_command_reply *reply,
                imapc_client_stop(ctx->mbox->storage->client);
 }
 
-static void imapc_sync_cmd(struct imapc_sync_context *ctx, const char *cmd)
+static void imapc_sync_cmd(struct imapc_sync_context *ctx, const char *cmd_str)
 {
+       struct imapc_command *cmd;
+
        ctx->sync_command_count++;
-       imapc_client_mailbox_cmd(ctx->mbox->client_box,
-                                imapc_sync_callback, ctx, cmd);
+       cmd = imapc_client_mailbox_cmd(ctx->mbox->client_box,
+                                      imapc_sync_callback, ctx);
+       imapc_command_send(cmd, cmd_str);
 }
 
 static void
@@ -387,6 +390,7 @@ struct mailbox_sync_context *
 imapc_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
 {
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
+       struct imapc_command *cmd;
        enum imapc_capability capabilities;
        bool changes;
        int ret = 0;
@@ -400,9 +404,10 @@ imapc_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        if ((capabilities & IMAPC_CAPABILITY_IDLE) == 0) {
                /* IDLE not supported. do NOOP to get latest changes
                   before starting sync. */
-               imapc_client_mailbox_cmd(mbox->client_box,
-                                        imapc_noop_stop_callback,
-                                        mbox->storage, "NOOP");
+               cmd = imapc_client_mailbox_cmd(mbox->client_box,
+                                              imapc_noop_stop_callback,
+                                              mbox->storage);
+               imapc_command_send(cmd, "NOOP");
                imapc_storage_run(mbox->storage);
        }