]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Pass through the exit code from doveadm-server to client.
authorTimo Sirainen <tss@iki.fi>
Thu, 13 Jun 2013 01:35:06 +0000 (04:35 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 13 Jun 2013 01:35:06 +0000 (04:35 +0300)
src/doveadm/client-connection.c
src/doveadm/doveadm-mail-server.c
src/doveadm/dsync/doveadm-dsync.c
src/doveadm/server-connection.c
src/doveadm/server-connection.h

index ce4e6aeea300c6b96b2f9f649b7e8a6fbae9b0e5..3195fac6e8be935ef0ebd3bab3f9929ea1ccacb9 100644 (file)
@@ -127,7 +127,8 @@ doveadm_mail_cmd_server_run(struct client_connection *conn,
                o_stream_nsend_str(conn->output, "\n-NOUSER\n");
        } else if (ctx->exit_code != 0) {
                /* maybe not an error, but not a full success either */
-               o_stream_nsend(conn->output, "\n-\n", 3);
+               o_stream_nsend_str(conn->output,
+                                  t_strdup_printf("\n-%u\n", ctx->exit_code));
        } else {
                o_stream_nsend(conn->output, "\n+\n", 3);
        }
index 4460cac84727b73d1cdb9de9965796f7e94f6eac..41e7edc1dd5e9cc349ed219fdbd31dad3b229ce9 100644 (file)
@@ -81,7 +81,7 @@ static bool doveadm_server_have_used_connections(struct doveadm_server *server)
        return FALSE;
 }
 
-static void doveadm_cmd_callback(enum server_cmd_reply reply, void *context)
+static void doveadm_cmd_callback(int exit_code, void *context)
 {
        struct doveadm_mail_server_cmd *servercmd = context;
        struct doveadm_server *server =
@@ -91,21 +91,22 @@ static void doveadm_cmd_callback(enum server_cmd_reply reply, void *context)
        i_free(servercmd->username);
        i_free(servercmd);
 
-       switch (reply) {
-       case SERVER_CMD_REPLY_INTERNAL_FAILURE:
+       switch (exit_code) {
+       case 0:
+               break;
+       case SERVER_EXIT_CODE_DISCONNECTED:
                i_error("%s: Internal failure for %s", server->name, username);
                internal_failure = TRUE;
                master_service_stop(master_service);
                return;
-       case SERVER_CMD_REPLY_UNKNOWN_USER:
+       case EX_NOUSER:
                i_error("%s: No such user: %s", server->name, username);
                if (cmd_ctx->exit_code == 0)
                        cmd_ctx->exit_code = EX_NOUSER;
                break;
-       case SERVER_CMD_REPLY_FAIL:
-               doveadm_mail_failed_error(cmd_ctx, MAIL_ERROR_TEMP);
-               break;
-       case SERVER_CMD_REPLY_OK:
+       default:
+               if (cmd_ctx->exit_code == 0 || exit_code == EX_TEMPFAIL)
+                       cmd_ctx->exit_code = exit_code;
                break;
        }
 
index cd28ed2ee2f3d52c015c2692b82d6cb97e13b881..b8196e0063185ed4e4e10f997b05eb9412faed15 100644 (file)
@@ -615,27 +615,26 @@ cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
        return ret;
 }
 
-static void dsync_connected_callback(enum server_cmd_reply reply, void *context)
+static void dsync_connected_callback(int exit_code, void *context)
 {
        struct dsync_cmd_context *ctx = context;
 
-       switch (reply) {
-       case SERVER_CMD_REPLY_UNKNOWN_USER:
-               ctx->error = "Unknown user in remote";
-               ctx->ctx.exit_code = EX_NOUSER;
-               break;
-       case SERVER_CMD_REPLY_FAIL:
-               ctx->error = "Failed to start dsync-server command";
-               break;
-       case SERVER_CMD_REPLY_OK:
+       ctx->ctx.exit_code = exit_code;
+       switch (exit_code) {
+       case 0:
                server_connection_extract(ctx->tcp_conn, &ctx->input,
                                          &ctx->output, &ctx->ssl_iostream);
                break;
-       case SERVER_CMD_REPLY_INTERNAL_FAILURE:
+       case SERVER_EXIT_CODE_DISCONNECTED:
                ctx->error = "Disconnected from remote";
                break;
+       case EX_NOUSER:
+               ctx->error = "Unknown user in remote";
+               break;
        default:
-               i_unreached();
+               ctx->error = p_strdup_printf(ctx->ctx.pool,
+                       "Failed to start dsync-server command: %u", exit_code);
+               break;
        }
        io_loop_stop(current_ioloop);
 }
index 69a35385b23405dea9f1abdd1ef3206d6ef983ed..06f476781a10434efd7391865fe6c54e964ccef5 100644 (file)
@@ -19,6 +19,7 @@
 #include "doveadm-settings.h"
 #include "server-connection.h"
 
+#include <sysexits.h>
 #include <unistd.h>
 
 #define MAX_INBUF_SIZE (1024*32)
@@ -78,13 +79,12 @@ static void print_connection_released(void)
 }
 
 static void
-server_connection_callback(struct server_connection *conn,
-                          enum server_cmd_reply reply)
+server_connection_callback(struct server_connection *conn, int exit_code)
 {
        server_cmd_callback_t *callback = conn->callback;
 
        conn->callback = NULL;
-       callback(reply, conn->context);
+       callback(exit_code, conn->context);
 }
 
 static void stream_data(string_t *str, const unsigned char *data, size_t size)
@@ -203,7 +203,7 @@ static void server_connection_input(struct server_connection *conn)
        const unsigned char *data;
        size_t size;
        const char *line;
-       enum server_cmd_reply reply;
+       int exit_code;
 
        if (!conn->handshaked) {
                if ((line = i_stream_read_next_line(conn->input)) == NULL) {
@@ -266,12 +266,16 @@ static void server_connection_input(struct server_connection *conn)
                if (line == NULL)
                        return;
                if (line[0] == '+')
-                       server_connection_callback(conn, SERVER_CMD_REPLY_OK);
+                       server_connection_callback(conn, 0);
                else if (line[0] == '-') {
-                       reply = strcmp(line+1, "NOUSER") == 0 ?
-                               SERVER_CMD_REPLY_UNKNOWN_USER :
-                               SERVER_CMD_REPLY_FAIL;
-                       server_connection_callback(conn, reply);
+                       line++;
+                       if (strcmp(line, "NOUSER") == 0)
+                               exit_code = EX_NOUSER;
+                       else if (str_to_int(line, &exit_code) < 0) {
+                               /* old doveadm-server */
+                               exit_code = EX_TEMPFAIL;
+                       }
+                       server_connection_callback(conn, exit_code);
                } else {
                        i_error("doveadm server sent broken input "
                                "(expected cmd reply): %s", line);
@@ -413,10 +417,8 @@ void server_connection_destroy(struct server_connection **_conn)
                }
        }
 
-       if (conn->callback != NULL) {
-               server_connection_callback(conn,
-                                          SERVER_CMD_REPLY_INTERNAL_FAILURE);
-       }
+       if (conn->callback != NULL)
+               server_connection_callback(conn, SERVER_EXIT_CODE_DISCONNECTED);
        if (printing_conn == conn)
                print_connection_released();
 
index 0b431d3e634593ac21586e00e31711e3690d3cb6..8cf7f86b8ae45bdb207861a631b38e6da4f8b7f5 100644 (file)
@@ -1,18 +1,13 @@
 #ifndef SERVER_CONNECTION_H
 #define SERVER_CONNECTION_H
 
-enum server_cmd_reply {
-       SERVER_CMD_REPLY_INTERNAL_FAILURE,
-       SERVER_CMD_REPLY_UNKNOWN_USER,
-       SERVER_CMD_REPLY_FAIL,
-       SERVER_CMD_REPLY_OK
-};
+#define SERVER_EXIT_CODE_DISCONNECTED 1000
 
 struct doveadm_server;
 struct server_connection;
 struct ssl_iostream;
 
-typedef void server_cmd_callback_t(enum server_cmd_reply reply, void *context);
+typedef void server_cmd_callback_t(int exit_code, void *context);
 
 int server_connection_create(struct doveadm_server *server,
                             struct server_connection **conn_r);