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);
}
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 =
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;
}
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);
}
#include "doveadm-settings.h"
#include "server-connection.h"
+#include <sysexits.h>
#include <unistd.h>
#define MAX_INBUF_SIZE (1024*32)
}
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)
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) {
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);
}
}
- 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();
#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);