dovecot-2.1: doveadm: Improved error handling. Failures should n...

dovecot at dovecot.org dovecot at dovecot.org
Sun Feb 12 21:10:42 EET 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/0a5951b08478
changeset: 14137:0a5951b08478
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Feb 12 21:10:22 2012 +0200
description:
doveadm: Improved error handling. Failures should now always have non-zero exit code.
doveadm now uses sysexits.h exit codes in most places, although there are
still a lot of places where it simply returns EX_TEMPFAIL even though
something else might be better.

diffstat:

 src/doveadm/Makefile.am                   |    4 +-
 src/doveadm/client-connection.c           |    2 +-
 src/doveadm/doveadm-auth.c                |   26 +--
 src/doveadm/doveadm-director.c            |  111 +++++++++++++------
 src/doveadm/doveadm-dump.c                |    8 +-
 src/doveadm/doveadm-instance.c            |    7 +-
 src/doveadm/doveadm-kick.c                |    7 +-
 src/doveadm/doveadm-log.c                 |    4 +-
 src/doveadm/doveadm-mail-altmove.c        |   36 ++++--
 src/doveadm/doveadm-mail-expunge.c        |   33 +++--
 src/doveadm/doveadm-mail-fetch.c          |   35 ++++--
 src/doveadm/doveadm-mail-import.c         |   34 ++++--
 src/doveadm/doveadm-mail-index.c          |   43 +++++--
 src/doveadm/doveadm-mail-iter.c           |   11 +-
 src/doveadm/doveadm-mail-iter.h           |    4 +-
 src/doveadm/doveadm-mail-list-iter.c      |  152 ----------------------------
 src/doveadm/doveadm-mail-list-iter.h      |   19 ---
 src/doveadm/doveadm-mail-mailbox-status.c |   40 ++++--
 src/doveadm/doveadm-mail-mailbox.c        |  103 +++++++++++++-----
 src/doveadm/doveadm-mail-move.c           |   50 +++++---
 src/doveadm/doveadm-mail-search.c         |   29 +++--
 src/doveadm/doveadm-mail-server.c         |    4 +-
 src/doveadm/doveadm-mail.c                |  117 +++++++++++++++++----
 src/doveadm/doveadm-mail.h                |   15 ++-
 src/doveadm/doveadm-mailbox-list-iter.c   |  162 ++++++++++++++++++++++++++++++
 src/doveadm/doveadm-mailbox-list-iter.h   |   23 ++++
 src/doveadm/doveadm.c                     |   25 ++++-
 src/doveadm/doveadm.h                     |    6 +
 src/doveadm/dsync/doveadm-dsync.c         |   13 +-
 src/doveadm/main.c                        |    1 +
 src/plugins/acl/doveadm-acl.c             |   86 ++++++++++-----
 src/plugins/fts/doveadm-fts.c             |   28 +++-
 src/plugins/quota/doveadm-quota.c         |   20 ++-
 33 files changed, 805 insertions(+), 453 deletions(-)

diffs (truncated from 2839 to 300 lines):

diff -r 7c36dea5605a -r 0a5951b08478 src/doveadm/Makefile.am
--- a/src/doveadm/Makefile.am	Sun Feb 12 19:20:03 2012 +0200
+++ b/src/doveadm/Makefile.am	Sun Feb 12 21:10:22 2012 +0200
@@ -72,7 +72,7 @@
 	doveadm-mail-mailbox.c \
 	doveadm-mail-mailbox-status.c \
 	doveadm-mail-move.c \
-	doveadm-mail-list-iter.c \
+	doveadm-mailbox-list-iter.c \
 	doveadm-mail-search.c \
 	doveadm-mail-server.c \
 	doveadm-print.c \
@@ -121,7 +121,7 @@
 	doveadm-dump.h \
 	doveadm-mail.h \
 	doveadm-mail-iter.h \
-	doveadm-mail-list-iter.h \
+	doveadm-mailbox-list-iter.h \
 	doveadm-print.h \
 	doveadm-print-private.h \
 	doveadm-server.h \
diff -r 7c36dea5605a -r 0a5951b08478 src/doveadm/client-connection.c
--- a/src/doveadm/client-connection.c	Sun Feb 12 19:20:03 2012 +0200
+++ b/src/doveadm/client-connection.c	Sun Feb 12 21:10:22 2012 +0200
@@ -114,7 +114,7 @@
 	ctx->v.deinit(ctx);
 	doveadm_print_flush();
 	mail_storage_service_deinit(&ctx->storage_service);
-	ret = !ctx->failed;
+	ret = ctx->exit_code == 0;
 	pool_unref(&ctx->pool);
 
 	return ret;
diff -r 7c36dea5605a -r 0a5951b08478 src/doveadm/doveadm-auth.c
--- a/src/doveadm/doveadm-auth.c	Sun Feb 12 19:20:03 2012 +0200
+++ b/src/doveadm/doveadm-auth.c	Sun Feb 12 21:10:22 2012 +0200
@@ -44,9 +44,9 @@
 				      pool, &username, &fields);
 	if (ret < 0) {
 		if (fields[0] == NULL)
-			i_fatal("userdb lookup failed for %s", input->username);
+			i_error("userdb lookup failed for %s", input->username);
 		else {
-			i_fatal("userdb lookup failed for %s: %s",
+			i_error("userdb lookup failed for %s: %s",
 				input->username, fields[0]);
 		}
 	} else if (ret == 0) {
@@ -139,7 +139,7 @@
 				      auth_callback, input);
 }
 
-static int
+static void
 cmd_auth_input(const char *auth_socket_path, struct authtest_input *input)
 {
 	struct auth_client *client;
@@ -157,7 +157,6 @@
 
 	auth_client_set_connect_notify(client, NULL, NULL);
 	auth_client_deinit(&client);
-	return 0;
 }
 
 static void auth_user_info_parse(struct auth_user_info *info, const char *arg)
@@ -206,10 +205,8 @@
 		if (users[i] != NULL)
 			printf("%s\n", username);
 	}
-	if (auth_master_user_list_deinit(&ctx) < 0) {
-		i_error("user listing failed");
-		exit(1);
-	}
+	if (auth_master_user_list_deinit(&ctx) < 0)
+		i_fatal("user listing failed");
 	auth_master_deinit(&conn);
 }
 
@@ -243,10 +240,9 @@
 		t_askpass("Password: ");
 	if (argv[optind] != NULL)
 			i_fatal("Unexpected parameter: %s", argv[optind]);
-	if (cmd_auth_input(auth_socket_path, &input) < 0)
-		exit(FATAL_DEFAULT);
+	cmd_auth_input(auth_socket_path, &input);
 	if (!input.success)
-		exit(1);
+		doveadm_exit_code = EX_NOPERM;
 }
 
 static void cmd_user(int argc, char *argv[])
@@ -293,7 +289,6 @@
 		cmd_user_list(auth_socket_path, &input, argv + optind);
 	else {
 		bool first = TRUE;
-		bool notfound = FALSE;
 
 		while ((input.username = argv[optind++]) != NULL) {
 			if (first)
@@ -303,14 +298,13 @@
 			switch (cmd_user_input(auth_socket_path, &input,
 					       show_field)) {
 			case -1:
-				exit(1);
+				doveadm_exit_code = EX_TEMPFAIL;
+				break;
 			case 0:
-				notfound = TRUE;
+				doveadm_exit_code = EX_NOUSER;
 				break;
 			}
 		}
-		if (notfound)
-			exit(2);
 	}
 }
 
diff -r 7c36dea5605a -r 0a5951b08478 src/doveadm/doveadm-director.c
--- a/src/doveadm/doveadm-director.c	Sun Feb 12 19:20:03 2012 +0200
+++ b/src/doveadm/doveadm-director.c	Sun Feb 12 21:10:22 2012 +0200
@@ -65,8 +65,9 @@
 		}
 	}
 	if (!version_string_verify(line, "director-doveadm", 1)) {
-		i_fatal("%s not a compatible director-doveadm socket",
-			ctx->socket_path);
+		i_fatal_status(EX_PROTOCOL,
+			       "%s not a compatible director-doveadm socket",
+			       ctx->socket_path);
 	}
 }
 
@@ -114,14 +115,16 @@
 	director_send(ctx, t_strdup_printf("USER-LOOKUP\t%s\n", user));
 	line = i_stream_read_next_line(ctx->input);
 	if (line == NULL) {
-		printf("Lookup failed\n");
+		i_error("Lookup failed");
+		doveadm_exit_code = EX_TEMPFAIL;
 		return;
 	}
 
 	args = t_strsplit(line, "\t");
 	if (str_array_length(args) != 4 ||
 	    str_to_uint(args[1], &expires) < 0) {
-		printf("Invalid reply from director\n");
+		i_error("Invalid reply from director");
+		doveadm_exit_code = EX_PROTOCOL;
 		return;
 	}
 
@@ -167,6 +170,10 @@
 			}
 		} T_END;
 	}
+	if (line == NULL) {
+		i_error("Director disconnected unexpectedly");
+		doveadm_exit_code = EX_TEMPFAIL;
+	}
 	director_disconnect(ctx);
 }
 
@@ -216,7 +223,7 @@
 		user_list_add(username, pool, users);
 	if (auth_master_user_list_deinit(&ctx) < 0) {
 		i_error("user listing failed");
-		exit(1);
+		doveadm_exit_code = EX_TEMPFAIL;
 	}
 	auth_master_deinit(&conn);
 }
@@ -241,14 +248,18 @@
 			      unsigned int *ips_count_r)
 {
 	struct ip_addr ip;
+	int ret;
 
 	if (net_addr2ip(host, &ip) == 0) {
 		*ips_r = t_new(struct ip_addr, 1);
 		**ips_r = ip;
 		*ips_count_r = 1;
 	} else {
-		if (net_gethostbyname(host, ips_r, ips_count_r) < 0)
-			i_fatal("gethostname(%s) failed: %m", host);
+		ret = net_gethostbyname(host, ips_r, ips_count_r);
+		if (ret != 0) {
+			i_fatal("gethostname(%s) failed: %s", host,
+				net_gethosterror(ret));
+		}
 	}
 }
 
@@ -308,9 +319,10 @@
 			if (str_array_length(args) < 3 ||
 			    str_to_uint(args[0], &user_hash) < 0 ||
 			    str_to_uint(args[1], &expires) < 0 ||
-			    net_addr2ip(args[2], &user_ip) < 0)
+			    net_addr2ip(args[2], &user_ip) < 0) {
 				i_error("Invalid USER-LIST reply: %s", line);
-			else if (ips_count == 0 ||
+				doveadm_exit_code = EX_PROTOCOL;
+			} else if (ips_count == 0 ||
 				 ip_find(ips, ips_count, &user_ip)) {
 				user = hash_table_lookup(users,
 						POINTER_CAST(user_hash));
@@ -327,6 +339,10 @@
 			}
 		} T_END;
 	}
+	if (line == NULL) {
+		i_error("Director disconnected unexpectedly");
+		doveadm_exit_code = EX_TEMPFAIL;
+	}
 	director_disconnect(ctx);
 	hash_table_destroy(&users);
 	pool_unref(&pool);
@@ -364,12 +380,11 @@
 		if (line == NULL || strcmp(line, "OK") != 0) {
 			fprintf(stderr, "%s: %s\n", net_ip2addr(&ips[i]),
 				line == NULL ? "failed" : line);
+			doveadm_exit_code = EX_TEMPFAIL;
 		} else if (doveadm_verbose) {
 			printf("%s: OK\n", net_ip2addr(&ips[i]));
 		}
 	}
-	if (i != ips_count)
-		i_fatal("director add failed");
 	director_disconnect(ctx);
 }
 
@@ -392,17 +407,19 @@
 	}
 	for (i = 0; i < ips_count; i++) {
 		line = i_stream_read_next_line(ctx->input);
-		if (line == NULL || strcmp(line, "OK") != 0) {
+		if (line != NULL && strcmp(line, "NOTFOUND") == 0) {
+			fprintf(stderr, "%s: doesn't exist\n",
+				net_ip2addr(&ips[i]));
+			if (doveadm_exit_code == 0)
+				doveadm_exit_code = DOVEADM_EX_NOTFOUND;
+		} else if (line == NULL || strcmp(line, "OK") != 0) {
 			fprintf(stderr, "%s: %s\n", net_ip2addr(&ips[i]),
-				line == NULL ? "failed" :
-				(strcmp(line, "NOTFOUND") == 0 ?
-				 "doesn't exist" : line));
+				line == NULL ? "failed" : line);
+			doveadm_exit_code = EX_TEMPFAIL;
 		} else if (doveadm_verbose) {
 			printf("%s: removed\n", net_ip2addr(&ips[i]));
 		}
 	}
-	if (i != ips_count)
-		i_fatal("director remove failed");
 	director_disconnect(ctx);
 }
 
@@ -426,18 +443,22 @@
 	director_send(ctx, t_strdup_printf(
 		"USER-MOVE\t%u\t%s\n", user_hash, ip_str));
 	line = i_stream_read_next_line(ctx->input);
-	if (line == NULL)
-		fprintf(stderr, "failed\n");
-	else if (strcmp(line, "OK") == 0) {
+	if (line == NULL) {
+		i_error("failed");
+		doveadm_exit_code = EX_TEMPFAIL;
+	} else if (strcmp(line, "OK") == 0) {
 		if (doveadm_verbose)
 			printf("User hash %u moved to %s\n", user_hash, ip_str);
 	} else if (strcmp(line, "NOTFOUND") == 0) {
-		fprintf(stderr, "Host '%s' doesn't exist\n", ip_str);
+		i_error("Host '%s' doesn't exist", ip_str);
+		doveadm_exit_code = DOVEADM_EX_NOTFOUND;
 	} else if (strcmp(line, "TRYAGAIN") == 0) {
-		fprintf(stderr, "User is already being moved, "
-			"wait a while for it to be finished\n");
+		i_error("User is already being moved, "
+			"wait a while for it to be finished");
+		doveadm_exit_code = EX_TEMPFAIL;
 	} else {
-		fprintf(stderr, "failed: %s\n", line);
+		i_error("failed: %s", line);
+		doveadm_exit_code = EX_TEMPFAIL;
 	}
 	director_disconnect(ctx);
 }
@@ -449,11 +470,13 @@
 	director_send(ctx, "HOST-FLUSH\n");
 
 	line = i_stream_read_next_line(ctx->input);
-	if (line == NULL)
-		fprintf(stderr, "failed\n");
-	else if (strcmp(line, "OK") != 0)
-		fprintf(stderr, "%s\n", line);
-	else if (doveadm_verbose)
+	if (line == NULL) {
+		i_error("failed");
+		doveadm_exit_code = EX_TEMPFAIL;
+	} else if (strcmp(line, "OK") != 0) {
+		i_error("failed: %s", line);


More information about the dovecot-cvs mailing list