changeset 13269:8aeeaf770612

dbox: Create symlink to alt root dir, and warn whenever it changes.
author Timo Sirainen <tss@iki.fi>
date Tue, 16 Aug 2011 22:53:01 +0300
parents da8da4a11039
children 4dff29fbc78d
files src/lib-storage/index/dbox-common/dbox-storage.c src/lib-storage/index/dbox-common/dbox-storage.h
diffstat 2 files changed, 56 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-common/dbox-storage.c	Tue Aug 16 22:52:19 2011 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-storage.c	Tue Aug 16 22:53:01 2011 +0300
@@ -27,6 +27,59 @@
 		set->mailbox_dir_name = DBOX_MAILBOX_DIR_NAME;
 }
 
+static bool
+dbox_alt_path_has_changed(const char *root_dir,
+			  const char *alt_path, const char *alt_symlink_path)
+{
+	char buf[PATH_MAX];
+	ssize_t ret;
+
+	ret = readlink(alt_symlink_path, buf, sizeof(buf)-1);
+	if (ret < 0) {
+		if (errno == ENOENT)
+			return alt_path != NULL;
+		i_error("readlink(%s) failed: %m", alt_symlink_path);
+		return FALSE;
+	}
+	buf[ret] = '\0';
+
+	if (alt_path == NULL) {
+		i_warning("dbox %s: Original ALT=%s, "
+			  "but currently no ALT path set", root_dir, buf);
+		return TRUE;
+	} else if (strcmp(buf, alt_path) != 0) {
+		i_warning("dbox %s: Original ALT=%s, "
+			  "but currently ALT=%s", root_dir, buf, alt_path);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static void dbox_verify_alt_path(struct mailbox_list *list)
+{
+	const char *root_dir, *alt_symlink_path, *alt_path;
+
+	root_dir = mailbox_list_get_path(list, NULL,
+					 MAILBOX_LIST_PATH_TYPE_DIR);
+	alt_symlink_path =
+		t_strconcat(root_dir, "/"DBOX_ALT_SYMLINK_NAME, NULL);
+	alt_path = mailbox_list_get_path(list, NULL,
+					 MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX);
+	if (!dbox_alt_path_has_changed(root_dir, alt_path, alt_symlink_path))
+		return;
+
+	/* unlink/create the current alt path symlink */
+	if (unlink(alt_symlink_path) < 0 && errno != ENOENT)
+		i_error("unlink(%s) failed: %m", alt_symlink_path);
+	if (alt_path != NULL) {
+		if (symlink(alt_path, alt_symlink_path) < 0 &&
+		    errno != EEXIST) {
+			i_error("symlink(%s, %s) failed: %m",
+				alt_path, alt_symlink_path);
+		}
+	}
+}
+
 int dbox_storage_create(struct mail_storage *_storage,
 			struct mail_namespace *ns,
 			const char **error_r ATTR_UNUSED)
@@ -53,6 +106,8 @@
 		storage->attachment_dir = p_strdup(_storage->pool, dir);
 		storage->attachment_fs = fs_init(name, args, &fs_set);
 	} T_END;
+
+	dbox_verify_alt_path(ns->list);
 	return 0;
 }
 
--- a/src/lib-storage/index/dbox-common/dbox-storage.h	Tue Aug 16 22:52:19 2011 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-storage.h	Tue Aug 16 22:53:01 2011 +0300
@@ -12,6 +12,7 @@
 #define DBOX_UIDVALIDITY_FILE_NAME "dovecot-uidvalidity"
 #define DBOX_INDEX_PREFIX "dovecot.index"
 #define DBOX_TEMP_FILE_PREFIX ".temp."
+#define DBOX_ALT_SYMLINK_NAME "dbox-alt-root"
 
 #define DBOX_MAILBOX_DIR_NAME "mailboxes"
 #define DBOX_TRASH_DIR_NAME "trash"