changeset 13150:3b4612e2a25a

Merged changes from v2.0 tree.
author Timo Sirainen <tss@iki.fi>
date Wed, 03 Aug 2011 19:06:37 +0300
parents 4ed44f06c54c (current diff) d7f76c266657 (diff)
children 8aeff3210f8d
files src/imap/cmd-select.c src/imap/imap-fetch-body.c src/lib-lda/mail-deliver.c src/lib-storage/index/dbox-multi/mdbox-mail.c src/lib-storage/index/dbox-multi/mdbox-sync.c src/lib-storage/index/index-search.c src/lib-storage/index/index-storage.c src/lib-storage/list/mailbox-list-fs.c src/lib-storage/mail-namespace.c src/lmtp/client.c src/lmtp/commands.c src/plugins/acl/doveadm-acl.c src/plugins/imap-quota/imap-quota-plugin.c
diffstat 21 files changed, 93 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/doveadm-mail-server.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/doveadm/doveadm-mail-server.c	Wed Aug 03 19:06:37 2011 +0300
@@ -214,10 +214,6 @@
 	i_assert(cmd_ctx == ctx || cmd_ctx == NULL);
 	cmd_ctx = ctx;
 
-	/* server sends the sticky headers for each row as well,
-	   so undo any sticks we might have added already */
-	doveadm_print_unstick_headers();
-
 	ret = doveadm_mail_server_user_get_host(ctx, input, &host, error_r);
 	if (ret < 0)
 		return -1;
@@ -227,6 +223,10 @@
 		return 0;
 	}
 
+	/* server sends the sticky headers for each row as well,
+	   so undo any sticks we might have added already */
+	doveadm_print_unstick_headers();
+
 	server = doveadm_server_get(ctx, host);
 	conn = doveadm_server_find_unused_conn(server);
 	if (conn != NULL)
--- a/src/imap/cmd-select.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/imap/cmd-select.c	Wed Aug 03 19:06:37 2011 +0300
@@ -340,7 +340,8 @@
 		client->sync_last_full_modseq = status.highest_modseq;
 	}
 
-	if (ctx->qresync_uid_validity == status.uidvalidity) {
+	if (ctx->qresync_uid_validity == status.uidvalidity &&
+	    status.uidvalidity != 0) {
 		if ((ret = select_qresync(ctx)) < 0) {
 			client_send_storage_error(ctx->cmd,
 				mailbox_get_storage(ctx->box));
--- a/src/imap/imap-fetch-body.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/imap/imap-fetch-body.c	Wed Aug 03 19:06:37 2011 +0300
@@ -773,7 +773,7 @@
 
 		if (i != 0)
 			str_append_c(str, ' ');
-		arr[i] = t_str_ucase(value);
+		arr[i] = p_strdup(ctx->cmd->pool, t_str_ucase(value));
 
 		if (args[i].type == IMAP_ARG_ATOM)
 			str_append(str, arr[i]);
--- a/src/lib-lda/lmtp-client.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-lda/lmtp-client.c	Wed Aug 03 19:06:37 2011 +0300
@@ -592,8 +592,11 @@
 
 void lmtp_client_send_more(struct lmtp_client *client)
 {
-	if (client->input_state == LMTP_INPUT_STATE_DATA)
+	if (client->input_state == LMTP_INPUT_STATE_DATA) {
+		o_stream_cork(client->output);
 		lmtp_client_send_data(client);
+		o_stream_uncork(client->output);
+	}
 }
 
 void lmtp_client_set_data_output_callback(struct lmtp_client *client,
--- a/src/lib-lda/mail-deliver.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-lda/mail-deliver.c	Wed Aug 03 19:06:37 2011 +0300
@@ -208,20 +208,25 @@
 }
 
 static bool mail_deliver_check_duplicate(struct mail_deliver_session *session,
-					 struct mail_user *user)
+					 struct mailbox *box)
 {
-	const char *const *usernamep, *username;
+	struct mailbox_metadata metadata;
+	const mail_guid_128_t *guid;
+
+	if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) {
+		/* just play it safe and assume a duplicate */
+		return TRUE;
+	}
 
 	/* there shouldn't be all that many recipients,
 	   so just do a linear search */
-	if (!array_is_created(&session->inbox_users))
-		p_array_init(&session->inbox_users, session->pool, 8);
-	array_foreach(&session->inbox_users, usernamep) {
-		if (strcmp(*usernamep, user->username) == 0)
+	if (!array_is_created(&session->inbox_guids))
+		p_array_init(&session->inbox_guids, session->pool, 8);
+	array_foreach(&session->inbox_guids, guid) {
+		if (memcmp(metadata.guid, guid, sizeof(metadata.guid)) == 0)
 			return TRUE;
 	}
-	username = p_strdup(session->pool, user->username);
-	array_append(&session->inbox_users, &username, 1);
+	array_append(&session->inbox_guids, &metadata.guid, 1);
 	return FALSE;
 }
 
@@ -231,8 +236,6 @@
 	struct mailbox_transaction_context *trans =
 		mailbox_save_get_transaction(save_ctx);
 	struct mailbox *box = mailbox_transaction_get_mailbox(trans);
-	struct mail_storage *storage = mailbox_get_storage(box);
-	struct mail_user *user = mail_storage_get_user(storage);
 	uint8_t guid[MAIL_GUID_128_SIZE];
 
 	if (strcmp(mailbox_get_name(box), "INBOX") != 0)
@@ -242,7 +245,7 @@
 	   happens if mail is delivered to same user multiple times within a
 	   session. the problem with this is that if GUIDs are used as POP3
 	   UIDLs, some clients can't handle the duplicates well. */
-	if (mail_deliver_check_duplicate(session, user)) {
+	if (mail_deliver_check_duplicate(session, box)) {
 		mail_generate_guid_128(guid);
 		mailbox_save_set_guid(save_ctx, mail_guid_128_to_string(guid));
 	}
--- a/src/lib-lda/mail-deliver.h	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-lda/mail-deliver.h	Wed Aug 03 19:06:37 2011 +0300
@@ -1,6 +1,8 @@
 #ifndef MAIL_DELIVER_H
 #define MAIL_DELIVER_H
 
+#include "mail-types.h"
+
 enum mail_flags;
 enum mail_error;
 struct mail_storage;
@@ -10,8 +12,8 @@
 struct mail_deliver_session {
 	pool_t pool;
 
-	/* List of users who have already saved this mail to their INBOX */
-	ARRAY_TYPE(const_string) inbox_users;
+	/* List of INBOX GUIDs where this mail has already been saved to */
+	ARRAY_DEFINE(inbox_guids, mail_guid_128_t);
 };
 
 struct mail_deliver_context {
--- a/src/lib-lda/smtp-client.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-lda/smtp-client.c	Wed Aug 03 19:06:37 2011 +0300
@@ -101,6 +101,7 @@
 
 	client = i_new(struct smtp_client, 1);
 	client->f = *file_r = fdopen(fd[1], "w");
+	client->pid = pid;
 	if (client->f == NULL)
 		i_fatal("fdopen() failed: %m");
 	return client;
--- a/src/lib-mail/mail-types.h	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-mail/mail-types.h	Wed Aug 03 19:06:37 2011 +0300
@@ -2,6 +2,7 @@
 #define MAIL_TYPES_H
 
 #define MAIL_GUID_128_SIZE 16
+typedef uint8_t mail_guid_128_t[MAIL_GUID_128_SIZE];
 
 enum mail_flags {
 	MAIL_ANSWERED	= 0x01,
--- a/src/lib-storage/index/dbox-multi/mdbox-mail.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-mail.c	Wed Aug 03 19:06:37 2011 +0300
@@ -35,10 +35,8 @@
 	}
 
 	if (mbox->map_uid_validity == 0) {
-		if (mdbox_read_header(mbox, &hdr) < 0) {
-			mdbox_storage_set_corrupted(mbox->storage);
+		if (mdbox_read_header(mbox, &hdr) < 0)
 			return -1;
-		}
 		mbox->map_uid_validity = hdr.map_uid_validity;
 	}
 	if (mdbox_map_open_or_create(mbox->storage->map) < 0)
--- a/src/lib-storage/index/dbox-multi/mdbox-sync.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-sync.c	Wed Aug 03 19:06:37 2011 +0300
@@ -137,6 +137,9 @@
 	hdr = mail_index_get_header(ctx->sync_view);
 	if (hdr->uid_validity == 0) {
 		/* newly created index file */
+		mail_storage_set_critical(box->storage,
+			"Mailbox %s: Corrupted index, uidvalidity=0",
+			box->vname);
 		return 0;
 	}
 
--- a/src/lib-storage/index/index-search.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-storage/index/index-search.c	Wed Aug 03 19:06:37 2011 +0300
@@ -715,7 +715,7 @@
 	else {
 		/* if all messages are in the range, it can't match */
 		range = array_get_modifiable(seqset, &count);
-		return range[0].seq1 != 1 ||
+		return count == 0 || range[0].seq1 != 1 ||
 			range[count-1].seq2 != messages_count;
 	}
 }
@@ -739,6 +739,10 @@
 	if (!match_not) {
 		min_seq = range[0].seq1;
 		max_seq = range[count-1].seq2;
+	} else if (count == 0) {
+		/* matches all messages */
+		min_seq = 1;
+		max_seq = messages_count;
 	} else {
 		min_seq = range[0].seq1 > 1 ? 1 : range[0].seq2 + 1;
 		max_seq = range[count-1].seq2 < messages_count ?
--- a/src/lib-storage/index/index-storage.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-storage/index/index-storage.c	Wed Aug 03 19:06:37 2011 +0300
@@ -282,8 +282,7 @@
 	box->opened = TRUE;
 
 	index_thread_mailbox_opened(box);
-	if (hook_mailbox_opened != NULL)
-		hook_mailbox_opened(box);
+	hook_mailbox_opened(box);
 	return 0;
 }
 
--- a/src/lib-storage/list/mailbox-list-fs.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-storage/list/mailbox-list-fs.c	Wed Aug 03 19:06:37 2011 +0300
@@ -413,7 +413,8 @@
 		      struct mailbox_list *newlist, const char *newname,
 		      enum mailbox_list_path_type type, bool rmdir_parent)
 {
-	const char *oldpath, *newpath, *p;
+	struct stat st;
+	const char *oldpath, *newpath, *p, *oldparent, *newparent;
 
 	oldpath = mailbox_list_get_path(oldlist, oldname, type);
 	newpath = mailbox_list_get_path(newlist, newname, type);
@@ -421,6 +422,30 @@
 	if (strcmp(oldpath, newpath) == 0)
 		return 0;
 
+	p = strrchr(oldpath, '/');
+	oldparent = p == NULL ? "/" : t_strdup_until(oldpath, p);
+	p = strrchr(newpath, '/');
+	newparent = p == NULL ? "/" : t_strdup_until(newpath, p);
+
+	if (strcmp(oldparent, newparent) != 0 && stat(oldpath, &st) == 0) {
+		/* make sure the newparent exists */
+		mode_t file_mode, dir_mode;
+		gid_t gid;
+		const char *origin;
+
+		mailbox_list_get_permissions(newlist, NULL, &file_mode,
+					     &dir_mode, &gid, &origin);
+		if (mkdir_parents_chgrp(newparent, dir_mode, gid, origin) < 0 &&
+		    errno != EEXIST) {
+			if (mailbox_list_set_error_from_errno(oldlist))
+				return -1;
+
+			mailbox_list_set_critical(oldlist,
+				"mkdir_parents(%s) failed: %m", newparent);
+			return -1;
+		}
+	}
+
 	if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
 		mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m",
 					  oldpath, newpath);
--- a/src/lib-storage/mail-namespace.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-storage/mail-namespace.c	Wed Aug 03 19:06:37 2011 +0300
@@ -386,11 +386,9 @@
 	}
 	user->namespaces = ns;
 
-	if (hook_mail_namespaces_created != NULL) {
-		T_BEGIN {
-			hook_mail_namespaces_created(ns);
-		} T_END;
-	}
+	T_BEGIN {
+		hook_mail_namespaces_created(ns);
+	} T_END;
 	return 0;
 }
 
--- a/src/lib-storage/mail-storage-service.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib-storage/mail-storage-service.c	Wed Aug 03 19:06:37 2011 +0300
@@ -108,6 +108,7 @@
 	struct setting_parser_context *set_parser = user->set_parser;
 	bool mail_debug;
 	const char *key, *orig_key, *append_value = NULL;
+	unsigned int len;
 	int ret;
 
 	mail_debug = mail_user_set_get_mail_debug(user->user_info,
@@ -116,9 +117,11 @@
 		line = t_strconcat(line, "=yes", NULL);
 	orig_key = key = t_strcut(line, '=');
 
-	if (*key == '+') {
-		append_value = line + strlen(key) + 1;
-		key++;
+	len = strlen(key);
+	if (len > 0 && key[len-1] == '+') {
+		/* key+=value */
+		append_value = line + len + 1;
+		key = t_strndup(key, len-1);
 		line++;
 	}
 
@@ -218,7 +221,7 @@
 	}
 
 	if (home != NULL)
-		set_keyval(ctx, user, "mail_home", reply->home);
+		set_keyval(ctx, user, "mail_home", home);
 
 	if (chroot != NULL) {
 		if (!validate_chroot(user->user_set, chroot)) {
--- a/src/lib/failures.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib/failures.c	Wed Aug 03 19:06:37 2011 +0300
@@ -565,7 +565,7 @@
 		string_t *str;
 		unsigned int prefix_len;
 
-		if (!log_prefix_sent) {
+		if (!log_prefix_sent && log_prefix != NULL) {
 			log_prefix_sent = TRUE;
 			i_failure_send_option("prefix", log_prefix);
 		}
--- a/src/lib/ipwd.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lib/ipwd.c	Wed Aug 03 19:06:37 2011 +0300
@@ -31,9 +31,8 @@
 	long size;
 
 	if (grbuf == NULL) {
-		/* OpenBSD (up to 4.8 at least) reports too low value in
-		   sysconf() */
-#ifndef __OpenBSD__
+		/* OpenBSD up to 4.9 reports too low value in sysconf() */
+#if !defined(__OpenBSD__) || OpenBSD >= 201111
 		size = sysconf(_SC_GETGR_R_SIZE_MAX);
 		if (size < 0)
 #endif
--- a/src/lmtp/client.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lmtp/client.c	Wed Aug 03 19:06:37 2011 +0300
@@ -32,7 +32,7 @@
 {
 	client_destroy(client,
 		       t_strdup_printf("421 4.4.2 %s", client->my_domain),
-		       "Disconnected for inactivity");
+		       "Disconnected client for inactivity");
 }
 
 static int client_input_line(struct client *client, const char *line)
@@ -228,6 +228,7 @@
 	client_io_reset(client);
 	client->state_pool = pool_alloconly_create("client state", 4096);
 	client->state.mail_data_fd = -1;
+	client->state.name = "banner";
 	client_read_settings(client);
 	client_raw_user_create(client);
 	client_generate_session_id(client);
@@ -292,7 +293,8 @@
 		client_send_line(client, "%s %s", prefix, reason);
 	else
 		reason = client_get_disconnect_reason(client);
-	i_info("Disconnect from %s: %s", client_remote_id(client), reason);
+	i_info("Disconnect from %s: %s (in %s)", client_remote_id(client),
+	       reason, client->state.name);
 
 	client->disconnected = TRUE;
 }
@@ -327,6 +329,7 @@
 	client->state.mail_data_fd = -1;
 
 	client_generate_session_id(client);
+	client->state.name = "reset";
 }
 
 void client_send_line(struct client *client, const char *fmt, ...)
--- a/src/lmtp/client.h	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lmtp/client.h	Wed Aug 03 19:06:37 2011 +0300
@@ -12,6 +12,7 @@
 };
 
 struct client_state {
+	const char *name;
 	const char *session_id;
 	const char *mail_from;
 	ARRAY_DEFINE(rcpt_to, struct mail_recipient);
--- a/src/lmtp/commands.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/lmtp/commands.c	Wed Aug 03 19:06:37 2011 +0300
@@ -73,6 +73,7 @@
 
 	i_free(client->lhlo);
 	client->lhlo = i_strdup(str_c(domain));
+	client->state.name = "LHLO";
 	return 0;
 }
 
@@ -141,6 +142,7 @@
 	client->state.mail_from = p_strdup(client->state_pool, addr);
 	p_array_init(&client->state.rcpt_to, client->state_pool, 64);
 	client_send_line(client, "250 2.1.0 OK");
+	client->state.name = "MAIL FROM";
 	return 0;
 }
 
@@ -385,6 +387,8 @@
 	const char *error = NULL;
 	int ret = 0;
 
+	client->state.name = "RCPT TO";
+
 	if (client->state.mail_from == NULL) {
 		client_send_line(client, "503 5.5.1 MAIL needed first");
 		return 0;
@@ -897,12 +901,14 @@
 
 	io_remove(&client->io);
 	if (array_count(&client->state.rcpt_to) == 0) {
+		client->state.name = "DATA (proxy)";
 		timeout_remove(&client->to_idle);
 		lmtp_proxy_start(client->proxy, client->dot_input,
 				 client->state.added_headers,
 				 client_proxy_finish, client);
 		i_stream_unref(&client->dot_input);
 	} else {
+		client->state.name = "DATA";
 		client->io = io_add(client->fd_in, IO_READ,
 				    client_input_data, client);
 		client_input_data_handle(client);
--- a/src/plugins/acl/doveadm-acl.c	Wed Aug 03 18:59:07 2011 +0300
+++ b/src/plugins/acl/doveadm-acl.c	Wed Aug 03 19:06:37 2011 +0300
@@ -536,7 +536,7 @@
 static struct doveadm_mail_cmd acl_commands[] = {
 	{ cmd_acl_get_alloc, "acl get", "[-m] <mailbox>" },
 	{ cmd_acl_rights_alloc, "acl rights", "<mailbox>" },
-	{ cmd_acl_set_alloc, "acl set", "<mailbox> <id> <rights>" },
+	{ cmd_acl_set_alloc, "acl set", "<mailbox> <id> <right> [<right> ...]" },
 	{ cmd_acl_delete_alloc, "acl delete", "<mailbox> <id>" },
 	{ cmd_acl_debug_alloc, "acl debug", "<mailbox>" }
 };