smtp-client-command.c revision bd06411e6f2ffc9e0122824ba4edb774bb40c26f
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher/* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
f128b7b865062da662127712935dcc58bd022384Stephen Gallagherstatic const char *smtp_client_command_label
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher const unsigned char *p, *pend;
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher return "[plug]";
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher if (cmd->data == NULL || cmd->data->used == 0) {
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher return "[empty]";
60dceaee2014822717a3f22e1b65b228e20cc5f0Sumit Bose for (;p < pend; p++) {
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher t_str_ucase(t_strdup_until(cmd->data->data, p)));
f128b7b865062da662127712935dcc58bd022384Stephen Gallaghersmtp_client_command_debug(struct smtp_client_command *cmd,
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher const char *format, ...)
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher struct smtp_client_connection *conn = cmd->conn;
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher i_debug("%s-client: conn %s: command %s: %s",
f128b7b865062da662127712935dcc58bd022384Stephen Gallaghersmtp_client_command_error(struct smtp_client_command *cmd,
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher const char *format, ...)
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher struct smtp_client_connection *conn = cmd->conn;
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher i_error("%s-client: conn %s: command %s: %s",
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallaghersmtp_client_command_create(struct smtp_client_connection *conn,
36fc83f3f64bb16db7bef3e1cebe829424edacd1Sumit Bose smtp_client_command_callback_t *callback, void *context)
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallagher pool = pool_alloconly_create("smtp client command", 2048);
36fc83f3f64bb16db7bef3e1cebe829424edacd1Sumit Bose cmd = p_new(pool, struct smtp_client_command, 1);
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallaghersmtp_client_command_new(struct smtp_client_connection *conn,
36fc83f3f64bb16db7bef3e1cebe829424edacd1Sumit Bose smtp_client_command_callback_t *callback, void *context)
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallagher return smtp_client_command_create(conn, flags, callback, context);
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallaghersmtp_client_command_plug(struct smtp_client_connection *conn,
36fc83f3f64bb16db7bef3e1cebe829424edacd1Sumit Bose cmd = smtp_client_command_create(conn, 0, NULL, NULL);
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallagher smtp_client_command_submit_after(cmd, after);
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallaghervoid smtp_client_command_ref(struct smtp_client_command *cmd)
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallaghervoid smtp_client_command_unref(struct smtp_client_command **_cmd)
fd3714d0cf068f3c782c1fff32105fc51cc97a0eStephen Gallagher struct smtp_client_connection *conn = cmd->conn;
36fc83f3f64bb16db7bef3e1cebe829424edacd1Sumit Bose "(%u commands pending, %u commands queued)",
36fc83f3f64bb16db7bef3e1cebe829424edacd1Sumit Bose conn->cmd_wait_list_count, conn->cmd_send_queue_count);
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher i_assert(cmd->state >= SMTP_CLIENT_COMMAND_STATE_FINISHED);
f128b7b865062da662127712935dcc58bd022384Stephen Gallagherbool smtp_client_command_name_equals(struct smtp_client_command *cmd,
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher const unsigned char *data;
60dceaee2014822717a3f22e1b65b228e20cc5f0Sumit Bosevoid smtp_client_command_lock(struct smtp_client_command *cmd)
f128b7b865062da662127712935dcc58bd022384Stephen Gallaghervoid smtp_client_command_unlock(struct smtp_client_command *cmd)
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher smtp_client_connection_trigger_output(cmd->conn);
f128b7b865062da662127712935dcc58bd022384Stephen Gallaghervoid smtp_client_command_abort(struct smtp_client_command **_cmd)
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher struct smtp_client_connection *conn = cmd->conn;
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher enum smtp_client_command_state state = cmd->state;
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher (conn->state == SMTP_CLIENT_CONNECTION_STATE_DISCONNECTED);
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek (state >= SMTP_CLIENT_COMMAND_STATE_SUBMITTED) &&
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher if ((!disconnected && !cmd->plug && cmd->aborting) ||
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher if (disconnected || state <= SMTP_CLIENT_COMMAND_STATE_SUBMITTED) {
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce smtp_client_command_debug(cmd, "Abort (already sent)");
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce i_assert(state < SMTP_CLIENT_COMMAND_STATE_FINISHED);
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce i_assert(!cmd->plug || state <= SMTP_CLIENT_COMMAND_STATE_SUBMITTED);
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher /* it is being sent; cannot truly abort it now */
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher /* fall through */
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher /* not yet sent */
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher smtp_client_command_debug(cmd, "Removed from send queue");
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher (cmd->prev == NULL && cmd->next == NULL));
60dceaee2014822717a3f22e1b65b228e20cc5f0Sumit Bose /* we're expecting a reply; cannot truly abort it now */
60dceaee2014822717a3f22e1b65b228e20cc5f0Sumit Bose smtp_client_command_debug(cmd, "Removed from wait list");
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher state <= SMTP_CLIENT_COMMAND_STATE_SUBMITTED) {
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher /* can only destroy it when it is not pending */
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher if (!disconnected && waslocked && !conn->corked)
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher smtp_client_connection_trigger_output(conn);
f128b7b865062da662127712935dcc58bd022384Stephen Gallaghervoid smtp_client_command_fail_reply(struct smtp_client_command **_cmd,
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher struct smtp_client_command *cmd = *_cmd, *tmp_cmd;
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher struct smtp_client_connection *conn = cmd->conn;
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher enum smtp_client_command_state state = cmd->state;
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek smtp_client_command_callback_t *callback = cmd->callback;
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek if (state >= SMTP_CLIENT_COMMAND_STATE_FINISHED)
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorcevoid smtp_client_command_fail(struct smtp_client_command **_cmd,
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher struct smtp_client_command *cmds_list, unsigned int cmds_list_count,
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher ARRAY(struct smtp_client_command *) cmds_arr;
f128b7b865062da662127712935dcc58bd022384Stephen Gallagher unsigned int count, i;
for (i = 0; i < count; i++) {
unsigned int replies)
const char **error_r)
int ret;
switch (res) {
if (ret == 0)
i_unreached();
const char **error_r)
const char *data;
int ret;
if (sent < 0) {
if (ret < 0)
const char *cmd_str)
const char *cmd_fmt, ...)
int ret;
if (ret < 0) {
bool finished;
if (finished) {
if (finished) {
struct smtp_client_command *
return cmd;
struct smtp_client_command *
struct smtp_client_command *
void *context)
return cmd;
struct smtp_client_command *
void *context)
struct smtp_client_command *
return cmd;
struct smtp_client_command *
struct smtp_client_command *
return cmd;
struct smtp_client_command *
struct smtp_client_command *
return cmd;
struct smtp_client_command *
struct _cmd_data_context {
unsigned int count, i;
for (i = 0; i < count; i++) {
void *context)
unsigned int count;
void *context)
int ret;
if (ret < 0) {
unsigned int count;
} else if (count > 0) {
if (data_size > 0) {
struct smtp_client_command *
void *context)
return cmd_data;
struct smtp_client_command *