changeset 175:73bf05a1d862 HEAD

Moved custom flags handling into lib-index.
author Timo Sirainen <tss@iki.fi>
date Sun, 08 Sep 2002 02:31:56 +0300
parents 61b0bb62b42e
children 782a0d4baa71
files configure.in src/lib-index/Makefile.am src/lib-index/mail-custom-flags.c src/lib-index/mail-custom-flags.h src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-storage/Makefile.am src/lib-storage/flags-file/.cvsignore src/lib-storage/flags-file/Makefile.am src/lib-storage/flags-file/flags-file.c src/lib-storage/flags-file/flags-file.h src/lib-storage/index/index-copy.c src/lib-storage/index/index-fetch.c src/lib-storage/index/index-status.c src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h src/lib-storage/index/index-sync.c src/lib-storage/index/index-update-flags.c src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/mbox/mbox-save.c src/lib-storage/index/mbox/mbox-storage.c
diffstat 21 files changed, 619 insertions(+), 625 deletions(-) [+]
line wrap: on
line diff
--- a/configure.in	Sat Sep 07 22:01:14 2002 +0300
+++ b/configure.in	Sun Sep 08 02:31:56 2002 +0300
@@ -335,7 +335,6 @@
 src/lib-storage/index/maildir/Makefile
 src/lib-storage/index/mbox/Makefile
 src/lib-storage/subscription-file/Makefile
-src/lib-storage/flags-file/Makefile
 src/auth/Makefile
 src/imap/Makefile
 src/login/Makefile
--- a/src/lib-index/Makefile.am	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-index/Makefile.am	Sun Sep 08 02:31:56 2002 +0300
@@ -8,6 +8,7 @@
 	-I$(top_srcdir)/src/lib-imap
 
 libstorage_index_a_SOURCES = \
+	mail-custom-flags.c \
 	mail-hash.c \
         mail-index.c \
         mail-index-compress.c \
@@ -20,6 +21,7 @@
 	mail-modifylog.c
 
 noinst_HEADERS = \
+	mail-custom-flags.h \
 	mail-hash.h \
 	mail-index.h \
         mail-index-data.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-index/mail-custom-flags.c	Sun Sep 08 02:31:56 2002 +0300
@@ -0,0 +1,534 @@
+/* Copyright (C) 2002 Timo Sirainen */
+
+#include "lib.h"
+#include "mmap-util.h"
+#include "write-full.h"
+#include "imap-util.h"
+#include "mail-index.h"
+#include "mail-index-util.h"
+#include "mail-custom-flags.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+/* Header is simply a counter which is increased every time the file is
+   updated. This allows other processes to easily notice if there's been
+   any changes. */
+
+#define COUNTER_SIZE 4
+#define HEADER_SIZE (COUNTER_SIZE + 1) /* 0000\n */
+
+struct _MailCustomFlags {
+	MailIndex *index;
+	char *path;
+	int fd;
+	int lock_type;
+
+	char sync_counter[COUNTER_SIZE];
+	char *custom_flags[MAIL_CUSTOM_FLAGS_COUNT];
+	int custom_flags_refcount;
+
+	void *mmap_base;
+	size_t mmap_length;
+
+	unsigned int syncing:1;
+};
+
+static int lock_file(MailCustomFlags *mcf, int type);
+
+static int update_mmap(MailCustomFlags *mcf)
+{
+	mcf->mmap_base = mmap_rw_file(mcf->fd, &mcf->mmap_length);
+	if (mcf->mmap_base == MAP_FAILED) {
+		mcf->mmap_base = NULL;
+		index_set_error(mcf->index, "mmap() failed for "
+				"custom flags file %s: %m", mcf->path);
+		return FALSE;
+	}
+
+	(void)madvise(mcf->mmap_base, mcf->mmap_length, MADV_SEQUENTIAL);
+	return TRUE;
+}
+
+static int custom_flags_init(MailCustomFlags *mcf)
+{
+	static char buf[HEADER_SIZE] = "0000\n";
+	off_t pos;
+
+	if (!lock_file(mcf, F_WRLCK))
+		return FALSE;
+
+	/* make sure it's still empty after locking */
+	pos = lseek(mcf->fd, 0, SEEK_END);
+	if (pos != -1 && pos < HEADER_SIZE)
+		pos = lseek(mcf->fd, 0, SEEK_SET);
+
+	if (pos == -1) {
+		index_set_error(mcf->index, "lseek() failed for "
+				"custom flags file %s: %m", mcf->path);
+		return FALSE;
+	}
+
+	/* write the header - it's a 4 byte counter as hex */
+	if (write_full(mcf->fd, buf, HEADER_SIZE) < 0) {
+		index_set_error(mcf->index, "write() failed for "
+				"custom flags file %s: %m", mcf->path);
+		return FALSE;
+	}
+
+	if (!lock_file(mcf, F_UNLCK))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void custom_flags_sync(MailCustomFlags *mcf)
+{
+	char *data, *data_end, *line;
+	unsigned int num;
+	int i;
+
+	memcpy(mcf->sync_counter, mcf->mmap_base, COUNTER_SIZE);
+
+	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
+		if (mcf->custom_flags[i] != NULL) {
+			i_free(mcf->custom_flags[i]);
+                        mcf->custom_flags[i] = NULL;
+		}
+	}
+
+	data = mcf->mmap_base;
+	data_end = data + mcf->mmap_length;
+
+	/* this loop skips the first line, which is the header */
+	while (data != data_end) {
+		if (*data != '\n') {
+			data++;
+			continue;
+		}
+
+		/* beginning of line, get the index */
+		if (data+1 == data_end)
+			break;
+		data++;
+
+		if (!i_isdigit(*data))
+			continue;
+
+		num = 0;
+		while (data != data_end && *data >= '0' && *data <= '9') {
+			num = num*10 + (*data-'0');
+			data++;
+		}
+
+		if (num < MAIL_CUSTOM_FLAGS_COUNT) {
+			/* get the name */
+			if (data == data_end || *data != ' ')
+				continue;
+
+			line = ++data;
+			while (data != data_end && *data != '\n')
+				data++;
+
+			if (mcf->custom_flags[num] != NULL) {
+				i_warning("Error in custom flags file %s: "
+					  "Duplicated ID %u", mcf->path, num);
+				i_free(mcf->custom_flags[num]);
+			}
+
+			mcf->custom_flags[num] = i_strdup_until(line, data);
+		}
+	}
+}
+
+static int custom_flags_check_sync(MailCustomFlags *mcf)
+{
+	if (mcf->custom_flags_refcount > 0) {
+		/* we've been locked from updates for now.. */
+		return TRUE;
+	}
+
+	if (mcf->mmap_length != 0 &&
+	    memcmp(mcf->sync_counter, mcf->mmap_base, COUNTER_SIZE) == 0)
+		return TRUE;
+
+	/* file modified, resync */
+	if (!update_mmap(mcf))
+		return FALSE;
+
+	if (mcf->mmap_length < HEADER_SIZE) {
+		/* it's broken, rewrite header */
+		if (mcf->lock_type == F_RDLCK)
+			(void)lock_file(mcf, F_UNLCK);
+
+		if (!custom_flags_init(mcf))
+			return FALSE;
+
+		if (!update_mmap(mcf))
+			return FALSE;
+	}
+
+	custom_flags_sync(mcf);
+	return TRUE;
+}
+
+static int lock_file(MailCustomFlags *mcf, int type)
+{
+	struct flock fl;
+
+	if (mcf->lock_type == type)
+		return TRUE;
+
+	/* lock whole file */
+	fl.l_type = type;
+	fl.l_whence = SEEK_SET;
+	fl.l_start = 0;
+	fl.l_len = 0;
+
+	while (fcntl(mcf->fd, F_SETLKW, &fl) == -1) {
+		if (errno != EINTR) {
+			index_set_error(mcf->index, "fcntl() failed for "
+					"custom flags file %s: %m", mcf->path);
+			return FALSE;
+		}
+	}
+
+	mcf->lock_type = type;
+
+	if (type != F_UNLCK && !mcf->syncing) {
+		mcf->syncing = TRUE;
+		if (!custom_flags_check_sync(mcf)) {
+			mcf->syncing = FALSE;
+			return FALSE;
+		}
+
+		/* syncing may have changed locking, do it again */
+		if (!lock_file(mcf, type)) {
+			mcf->syncing = FALSE;
+			return FALSE;
+		}
+
+		mcf->syncing = FALSE;
+	}
+	return TRUE;
+}
+
+int mail_custom_flags_open_or_create(MailIndex *index)
+{
+	MailCustomFlags *mcf;
+	const char *path;
+	int fd;
+
+	path = t_strconcat(index->dir, CUSTOM_FLAGS_FILE_NAME, NULL);
+	fd = open(path, O_RDWR | O_CREAT, 0660);
+	if (fd == -1) {
+		index_set_error(index, "Can't open custom flags file %s: %m",
+				path);
+		return FALSE;
+	}
+
+	mcf = i_new(MailCustomFlags, 1);
+	mcf->index = index;
+	mcf->path = i_strdup(path);
+	mcf->fd = fd;
+
+	if (!update_mmap(mcf)) {
+		mail_custom_flags_free(mcf);
+		return FALSE;
+	}
+
+	if (mcf->mmap_length < HEADER_SIZE) {
+		/* we just created it, write the header */
+		mcf->syncing = TRUE;
+		if (!custom_flags_init(mcf) || !update_mmap(mcf)) {
+			mail_custom_flags_free(mcf);
+			return FALSE;
+		}
+		mcf->syncing = FALSE;
+	}
+
+	custom_flags_sync(mcf);
+
+	index->custom_flags = mcf;
+	return TRUE;
+}
+
+void mail_custom_flags_free(MailCustomFlags *mcf)
+{
+	int i;
+
+	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++)
+		i_free(mcf->custom_flags[i]);
+
+	(void)munmap(mcf->mmap_base, mcf->mmap_length);
+	(void)close(mcf->fd);
+
+	i_free(mcf->path);
+	i_free(mcf);
+}
+
+static int custom_flags_update_counter(MailCustomFlags *mcf)
+{
+	int i;
+
+	if (lseek(mcf->fd, 0, SEEK_SET) == -1) {
+		index_set_error(mcf->index, "lseek() failed for "
+				"custom flags file %s: %m", mcf->path);
+		return FALSE;
+	}
+
+	for (i = COUNTER_SIZE-1; i >= 0; i--) {
+		if (mcf->sync_counter[i] == '9') {
+			mcf->sync_counter[i] = 'A';
+			break;
+		}
+
+		if (mcf->sync_counter[i] == 'F') {
+			/* digit wrapped, update next one */
+			mcf->sync_counter[i] = '0';
+		} else {
+			mcf->sync_counter[i]++;
+			break;
+		}
+	}
+
+	if (write_full(mcf->fd, mcf->sync_counter, COUNTER_SIZE) < 0) {
+		index_set_error(mcf->index, "write() failed for "
+				"custom flags file %s: %m", mcf->path);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static int custom_flags_add(MailCustomFlags *mcf, int idx, const char *name)
+{
+	const char *buf;
+	unsigned int len;
+	off_t pos;
+
+	i_assert(idx < MAIL_CUSTOM_FLAGS_COUNT);
+
+	/* first update the sync counter */
+	if (!custom_flags_update_counter(mcf))
+		return FALSE;
+
+	/* add the flag */
+	pos = lseek(mcf->fd, 0, SEEK_END);
+	if (pos == -1) {
+		index_set_error(mcf->index, "lseek() failed for "
+				"custom flags file %s: %m", mcf->path);
+		return FALSE;
+	}
+
+	if (pos != (off_t)mcf->mmap_length) {
+		index_set_error(mcf->index, "custom flags file %s was "
+				"changed by someone while we were"
+				"trying to modify it", mcf->path);
+		return FALSE;
+	}
+
+	buf = t_strdup_printf("\n%d %s\n", idx, name);
+	len = strlen(buf);
+
+	if (((char *) mcf->mmap_base)[mcf->mmap_length-1] == '\n') {
+		/* don't add the \n prefix */
+		buf++;
+		len--;
+	}
+
+	if (write_full(mcf->fd, buf, len) < 0) {
+		index_set_error(mcf->index, "write() failed for "
+				"custom flags file %s: %m", mcf->path);
+		return FALSE;
+	}
+
+	if (!update_mmap(mcf))
+		return FALSE;
+
+	return TRUE;
+}
+
+static int custom_flags_remove(MailCustomFlags *mcf, unsigned int idx)
+{
+	char *data, *data_end, *line;
+	unsigned int num;
+	int pos, linelen;
+
+	data = mcf->mmap_base;
+	data_end = data + mcf->mmap_length;
+
+	while (data != data_end) {
+		if (*data != '\n') {
+			data++;
+			continue;
+		}
+
+		/* beginning of line, get the index */
+		if (data+1 == data_end)
+			break;
+		line = ++data;
+
+		num = 0;
+		while (data != data_end && *data >= '0' && *data <= '9') {
+			num = num*10 + (*data-'0');
+			data++;
+		}
+
+		if (num == idx) {
+			/* remove this line */
+			while (data != data_end && data[-1] != '\n')
+				data++;
+
+			linelen = (int) (data - line);
+			pos = (int) (data - (char *) mcf->mmap_base);
+			memmove(line, data, mcf->mmap_length - pos);
+
+			mcf->mmap_length -= linelen;
+			if (ftruncate(mcf->fd, (off_t) mcf->mmap_length) == -1) {
+				index_set_error(mcf->index,
+						"ftruncate() failed for "
+						"custom flags file %s: %m",
+						mcf->path);
+				return FALSE;
+			}
+
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static int find_first_unused_flag(MailCustomFlags *mcf)
+{
+	int i;
+
+	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
+		if (mcf->custom_flags[i] == NULL)
+			return i;
+	}
+
+	return -1;
+}
+
+static void remove_unused_custom_flags(MailCustomFlags *mcf,
+				       MailFlags used_flags)
+{
+	unsigned int i;
+
+	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
+		if ((used_flags & (1 << (i + MAIL_CUSTOM_FLAG_1_BIT))) == 0) {
+			i_free(mcf->custom_flags[i]);
+			mcf->custom_flags[i] = NULL;
+
+			custom_flags_remove(mcf, i);
+		}
+	}
+}
+
+static MailFlags get_used_flags(MailCustomFlags *mcf)
+{
+	MailIndexRecord *rec;
+	MailFlags used_flags;
+
+	used_flags = 0;
+
+	rec = mcf->index->lookup(mcf->index, 1);
+	while (rec != NULL) {
+		used_flags |= rec->msg_flags;
+		rec = mcf->index->next(mcf->index, rec);
+	}
+
+	return used_flags;
+}
+
+static int get_flag_index(MailCustomFlags *mcf, const char *flag)
+{
+	int i, first_empty;
+
+	/* check existing flags */
+	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
+		if (mcf->custom_flags[i] == NULL)
+			continue;
+
+		i_assert(mcf->custom_flags[i] != '\0');
+		if (strcasecmp(mcf->custom_flags[i], flag) == 0)
+			return i;
+	}
+
+	/* unlock + write lock, don't directly change from read -> write lock
+	   to prevent deadlocking */
+	if (!lock_file(mcf, F_UNLCK) || !lock_file(mcf, F_WRLCK))
+		return -1;
+
+	/* new flag, add it. first find the first free flag, note that
+	   unlock+lock might have just changed it. */
+	first_empty = find_first_unused_flag(mcf);
+	if (first_empty == -1) {
+		/* all custom flags are used, see if some of them are unused */
+		remove_unused_custom_flags(mcf, get_used_flags(mcf));
+
+		first_empty = find_first_unused_flag(mcf);
+		if (first_empty == -1) {
+			/* everything is in use */
+			return -1;
+		}
+	}
+
+	if (!custom_flags_add(mcf, first_empty, flag))
+		return -1;
+
+	mcf->custom_flags[first_empty] = i_strdup(flag);
+	return first_empty;
+}
+
+int mail_custom_flags_fix_list(MailCustomFlags *mcf, MailFlags *flags,
+			       const char *custom_flags[])
+{
+	MailFlags oldflags, flag;
+	int i, idx;
+
+	if ((*flags & MAIL_CUSTOM_FLAGS_MASK) == 0)
+		return 1;
+
+	if (!lock_file(mcf, F_RDLCK))
+		return -1;
+
+	oldflags = *flags;
+	*flags &= MAIL_SYSTEM_FLAGS_MASK;
+
+	flag = MAIL_CUSTOM_FLAG_1;
+	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++, flag <<= 1) {
+		if (oldflags & flag) {
+			i_assert(custom_flags[i] != NULL &&
+				 *custom_flags[i] != '\0');
+
+			idx = get_flag_index(mcf, custom_flags[i]);
+			if (idx == -1) {
+				(void)lock_file(mcf, F_UNLCK);
+				return 0;
+			}
+			*flags |= 1 << (idx + MAIL_CUSTOM_FLAG_1_BIT);
+		}
+	}
+
+	if (!lock_file(mcf, F_UNLCK))
+		return -1;
+
+	return 1;
+}
+
+const char **mail_custom_flags_list_get(MailCustomFlags *mcf)
+{
+	mcf->custom_flags_refcount++;
+	return (const char **) mcf->custom_flags;
+}
+
+void mail_custom_flags_list_unref(MailCustomFlags *mcf)
+{
+	i_assert(mcf->custom_flags_refcount > 0);
+
+	mcf->custom_flags_refcount--;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-index/mail-custom-flags.h	Sun Sep 08 02:31:56 2002 +0300
@@ -0,0 +1,23 @@
+#ifndef __MAIL_CUSTOM_FLAGS_H
+#define __MAIL_CUSTOM_FLAGS_H
+
+#include "mail-index.h"
+
+#define CUSTOM_FLAGS_FILE_NAME ".customflags"
+
+int mail_custom_flags_open_or_create(MailIndex *index);
+void mail_custom_flags_free(MailCustomFlags *mcf);
+
+/* Change custom flags so that they reflect the real flag numbers in
+   the file. Returns 1 if ok, 0 if number of custom flags exceeded or
+   -1 if error */
+int mail_custom_flags_fix_list(MailCustomFlags *mcf, MailFlags *flags,
+			       const char *custom_flags[]);
+
+/* Returns a pointer to list of flags. */
+const char **mail_custom_flags_list_get(MailCustomFlags *mcf);
+
+/* Call this after you've done with the flags list above */
+void mail_custom_flags_list_unref(MailCustomFlags *mcf);
+
+#endif
--- a/src/lib-index/mail-index.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-index/mail-index.c	Sun Sep 08 02:31:56 2002 +0300
@@ -11,6 +11,7 @@
 #include "mail-hash.h"
 #include "mail-lockdir.h"
 #include "mail-modifylog.h"
+#include "mail-custom-flags.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -113,6 +114,11 @@
 		index->modifylog = NULL;
 	}
 
+	if (index->custom_flags != NULL) {
+		mail_custom_flags_free(index->custom_flags);
+                index->custom_flags = NULL;
+	}
+
 	if (index->error != NULL) {
 		i_free(index->error);
 		index->error = NULL;
@@ -553,6 +559,8 @@
 			break;
 		if (!mail_modifylog_open_or_create(index))
 			break;
+		if (!mail_custom_flags_open_or_create(index))
+			break;
 
 		if (hdr.flags & MAIL_INDEX_FLAG_FSCK) {
 			/* index needs fscking */
--- a/src/lib-index/mail-index.h	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-index/mail-index.h	Sun Sep 08 02:31:56 2002 +0300
@@ -80,6 +80,7 @@
 typedef struct _MailIndexData MailIndexData;
 typedef struct _MailHash MailHash;
 typedef struct _MailModifyLog MailModifyLog;
+typedef struct _MailCustomFlags MailCustomFlags;
 
 typedef struct _MailIndexHeader MailIndexHeader;
 typedef struct _MailIndexDataHeader MailIndexDataHeader;
@@ -296,6 +297,7 @@
 	MailIndexData *data;
 	MailHash *hash;
 	MailModifyLog *modifylog;
+	MailCustomFlags *custom_flags;
 
 	char *dir; /* directory where to place the index files */
 	char *filepath; /* index file path */
@@ -338,7 +340,7 @@
 #define MAIL_INDEX_PRIVATE_FILL \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0
 
 /* defaults - same as above but prefixed with mail_index_. */
 int mail_index_open(MailIndex *index, int update_recent);
--- a/src/lib-storage/Makefile.am	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/Makefile.am	Sun Sep 08 02:31:56 2002 +0300
@@ -1,4 +1,4 @@
-SUBDIRS = index subscription-file flags-file
+SUBDIRS = index subscription-file
 
 noinst_LIBRARIES = libstorage.a
 
--- a/src/lib-storage/flags-file/.cvsignore	Sat Sep 07 22:01:14 2002 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-*.la
-*.lo
-*.o
-.deps
-.libs
-Makefile
-Makefile.in
-so_locations
--- a/src/lib-storage/flags-file/Makefile.am	Sat Sep 07 22:01:14 2002 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-noinst_LIBRARIES = libstorage_flags_file.a
-
-INCLUDES = \
-	-I$(top_srcdir)/src/lib \
-	-I$(top_srcdir)/src/lib-storage \
-	-I$(top_srcdir)/src/lib-imap
-
-libstorage_flags_file_a_SOURCES = \
-	flags-file.c
-
-noinst_HEADERS = \
-	flags-file.h
-
--- a/src/lib-storage/flags-file/flags-file.c	Sat Sep 07 22:01:14 2002 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,519 +0,0 @@
-/* Copyright (C) 2002 Timo Sirainen */
-
-#include "lib.h"
-#include "mmap-util.h"
-#include "write-full.h"
-#include "imap-util.h"
-#include "flags-file.h"
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-/* Header is simply a counter which is increased every time the file is
-   updated. This allows other processes to easily notice if there's been
-   any changes. */
-
-#define COUNTER_SIZE 4
-#define HEADER_SIZE (COUNTER_SIZE + 1) /* 0000\n */
-
-struct _FlagsFile {
-	MailStorage *storage;
-	char *path;
-	int fd;
-	int lock_type;
-
-	char sync_counter[COUNTER_SIZE];
-	char *custom_flags[MAIL_CUSTOM_FLAGS_COUNT];
-	int custom_flags_refcount;
-
-	void *mmap_base;
-	size_t mmap_length;
-
-	unsigned int syncing:1;
-};
-
-static int lock_file(FlagsFile *ff, int type);
-
-static int update_mmap(FlagsFile *ff)
-{
-	ff->mmap_base = mmap_rw_file(ff->fd, &ff->mmap_length);
-	if (ff->mmap_base == MAP_FAILED) {
-		ff->mmap_base = NULL;
-		mail_storage_set_critical(ff->storage, "mmap() failed for "
-					  "flags file %s: %m", ff->path);
-		return FALSE;
-	}
-
-	(void)madvise(ff->mmap_base, ff->mmap_length, MADV_SEQUENTIAL);
-	return TRUE;
-}
-
-static int flags_file_init(FlagsFile *ff)
-{
-	static char buf[HEADER_SIZE] = "0000\n";
-	off_t pos;
-
-	if (!lock_file(ff, F_WRLCK))
-		return FALSE;
-
-	/* make sure it's still empty after locking */
-	pos = lseek(ff->fd, 0, SEEK_END);
-	if (pos != -1 && pos < HEADER_SIZE)
-		pos = lseek(ff->fd, 0, SEEK_SET);
-
-	if (pos == -1) {
-		mail_storage_set_critical(ff->storage, "lseek() failed for "
-					  "flags file %s: %m", ff->path);
-		return FALSE;
-	}
-
-	/* write the header - it's a 4 byte counter as hex */
-	if (write_full(ff->fd, buf, HEADER_SIZE) < 0) {
-		mail_storage_set_critical(ff->storage, "write() failed for "
-					  "flags file %s: %m", ff->path);
-		return FALSE;
-	}
-
-	if (!lock_file(ff, F_UNLCK))
-		return FALSE;
-
-	return TRUE;
-}
-
-static void flags_file_sync(FlagsFile *ff)
-{
-	char *data, *data_end, *line;
-	unsigned int num;
-	int i;
-
-	memcpy(ff->sync_counter, ff->mmap_base, COUNTER_SIZE);
-
-	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
-		if (ff->custom_flags[i] != NULL) {
-			i_free(ff->custom_flags[i]);
-                        ff->custom_flags[i] = NULL;
-		}
-	}
-
-	data = ff->mmap_base;
-	data_end = data + ff->mmap_length;
-
-	/* this loop skips the first line, which is the header */
-	while (data != data_end) {
-		if (*data != '\n') {
-			data++;
-			continue;
-		}
-
-		/* beginning of line, get the index */
-		if (data+1 == data_end)
-			break;
-		data++;
-
-		if (!i_isdigit(*data))
-			continue;
-
-		num = 0;
-		while (data != data_end && *data >= '0' && *data <= '9') {
-			num = num*10 + (*data-'0');
-			data++;
-		}
-
-		if (num < MAIL_CUSTOM_FLAGS_COUNT) {
-			/* get the name */
-			if (data == data_end || *data != ' ')
-				continue;
-
-			line = ++data;
-			while (data != data_end && *data != '\n')
-				data++;
-
-			if (ff->custom_flags[num] != NULL) {
-				i_warning("Error in custom flags file %s: "
-					  "Duplicated ID %u", ff->path, num);
-				i_free(ff->custom_flags[num]);
-			}
-
-			ff->custom_flags[num] = i_strdup_until(line, data);
-		}
-	}
-}
-
-static int flags_file_check_sync(FlagsFile *ff)
-{
-	if (ff->custom_flags_refcount > 0) {
-		/* we've been locked from updates for now.. */
-		return TRUE;
-	}
-
-	if (ff->mmap_length != 0 &&
-	    memcmp(ff->sync_counter, ff->mmap_base, COUNTER_SIZE) == 0)
-		return TRUE;
-
-	/* file modified, resync */
-	if (!update_mmap(ff))
-		return FALSE;
-
-	if (ff->mmap_length < HEADER_SIZE) {
-		/* it's broken, rewrite header */
-		if (ff->lock_type == F_RDLCK)
-			(void)lock_file(ff, F_UNLCK);
-
-		if (!flags_file_init(ff))
-			return FALSE;
-
-		if (!update_mmap(ff))
-			return FALSE;
-	}
-
-	flags_file_sync(ff);
-	return TRUE;
-}
-
-static int lock_file(FlagsFile *ff, int type)
-{
-	struct flock fl;
-
-	if (ff->lock_type == type)
-		return TRUE;
-
-	/* lock whole file */
-	fl.l_type = type;
-	fl.l_whence = SEEK_SET;
-	fl.l_start = 0;
-	fl.l_len = 0;
-
-	while (fcntl(ff->fd, F_SETLKW, &fl) == -1) {
-		if (errno != EINTR) {
-			mail_storage_set_critical(ff->storage, "fcntl() failed "
-						  "for flags file %s: %m",
-						  ff->path);
-			return FALSE;
-		}
-	}
-
-	ff->lock_type = type;
-
-	if (type != F_UNLCK && !ff->syncing) {
-		ff->syncing = TRUE;
-		if (!flags_file_check_sync(ff)) {
-			ff->syncing = FALSE;
-			return FALSE;
-		}
-
-		/* syncing may have changed locking, do it again */
-		if (!lock_file(ff, type)) {
-			ff->syncing = FALSE;
-			return FALSE;
-		}
-
-		ff->syncing = FALSE;
-	}
-	return TRUE;
-}
-
-FlagsFile *flags_file_open_or_create(MailStorage *storage, const char *path)
-{
-	FlagsFile *ff;
-	int fd;
-
-	fd = open(path, O_RDWR | O_CREAT, 0660);
-	if (fd == -1) {
-		mail_storage_set_critical(storage, "Can't open flags file "
-					  "%s: %m", path);
-		return NULL;
-	}
-
-	ff = i_new(FlagsFile, 1);
-	ff->storage = storage;
-	ff->path = i_strdup(path);
-	ff->fd = fd;
-
-	if (!update_mmap(ff)) {
-		flags_file_destroy(ff);
-		return NULL;
-	}
-
-	if (ff->mmap_length < HEADER_SIZE) {
-		/* we just created it, write the header */
-		ff->syncing = TRUE;
-		if (!flags_file_init(ff) || !update_mmap(ff)) {
-			flags_file_destroy(ff);
-			return NULL;
-		}
-		ff->syncing = FALSE;
-	}
-
-        flags_file_sync(ff);
-	return ff;
-}
-
-void flags_file_destroy(FlagsFile *ff)
-{
-	int i;
-
-	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++)
-		i_free(ff->custom_flags[i]);
-
-	(void)munmap(ff->mmap_base, ff->mmap_length);
-	(void)close(ff->fd);
-
-	i_free(ff->path);
-	i_free(ff);
-}
-
-static int flags_file_update_counter(FlagsFile *ff)
-{
-	int i;
-
-	if (lseek(ff->fd, 0, SEEK_SET) == -1) {
-		mail_storage_set_critical(ff->storage, "lseek() failed for "
-					  "flags file %s: %m", ff->path);
-		return FALSE;
-	}
-
-	for (i = COUNTER_SIZE-1; i >= 0; i--) {
-		if (ff->sync_counter[i] == '9') {
-			ff->sync_counter[i] = 'A';
-			break;
-		}
-
-		if (ff->sync_counter[i] == 'F') {
-			/* digit wrapped, update next one */
-			ff->sync_counter[i] = '0';
-		} else {
-			ff->sync_counter[i]++;
-			break;
-		}
-	}
-
-	if (write_full(ff->fd, ff->sync_counter, COUNTER_SIZE) < 0) {
-		mail_storage_set_critical(ff->storage, "write() failed for "
-					  "flags file %s: %m", ff->path);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static int flags_file_add(FlagsFile *ff, int idx, const char *name)
-{
-	const char *buf;
-	unsigned int len;
-	off_t pos;
-
-	i_assert(idx < MAIL_CUSTOM_FLAGS_COUNT);
-
-	/* first update the sync counter */
-	if (!flags_file_update_counter(ff))
-		return FALSE;
-
-	/* add the flag */
-	pos = lseek(ff->fd, 0, SEEK_END);
-	if (pos == -1) {
-		mail_storage_set_critical(ff->storage, "lseek() failed for "
-					  "flags file %s: %m", ff->path);
-		return FALSE;
-	}
-
-	if (pos != (off_t)ff->mmap_length) {
-		mail_storage_set_critical(ff->storage, "flags file %s was "
-					  "changed by someone while we were"
-					  "trying to modify it", ff->path);
-		return FALSE;
-	}
-
-	buf = t_strdup_printf("\n%d %s\n", idx, name);
-	len = strlen(buf);
-
-	if (((char *) ff->mmap_base)[ff->mmap_length-1] == '\n') {
-		/* don't add the \n prefix */
-		buf++;
-		len--;
-	}
-
-	if (write_full(ff->fd, buf, len) < 0) {
-		mail_storage_set_critical(ff->storage, "write() failed for "
-					  "flags file %s: %m", ff->path);
-		return FALSE;
-	}
-
-	if (!update_mmap(ff))
-		return FALSE;
-
-	return TRUE;
-}
-
-static int flags_file_remove(FlagsFile *ff, unsigned int idx)
-{
-	char *data, *data_end, *line;
-	unsigned int num;
-	int pos, linelen;
-
-	data = ff->mmap_base;
-	data_end = data + ff->mmap_length;
-
-	while (data != data_end) {
-		if (*data != '\n') {
-			data++;
-			continue;
-		}
-
-		/* beginning of line, get the index */
-		if (data+1 == data_end)
-			break;
-		line = ++data;
-
-		num = 0;
-		while (data != data_end && *data >= '0' && *data <= '9') {
-			num = num*10 + (*data-'0');
-			data++;
-		}
-
-		if (num == idx) {
-			/* remove this line */
-			while (data != data_end && data[-1] != '\n')
-				data++;
-
-			linelen = (int) (data - line);
-			pos = (int) (data - (char *) ff->mmap_base);
-			memmove(line, data, ff->mmap_length - pos);
-
-			ff->mmap_length -= linelen;
-			if (ftruncate(ff->fd, (off_t) ff->mmap_length) == -1) {
-				mail_storage_set_critical(ff->storage,
-					"ftruncate() failed for flags file "
-					"%s: %m", ff->path);
-				return FALSE;
-			}
-
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-static int find_first_unused_flag(FlagsFile *ff)
-{
-	int i;
-
-	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
-		if (ff->custom_flags[i] == NULL)
-			return i;
-	}
-
-	return -1;
-}
-
-static void remove_unused_custom_flags(FlagsFile *ff, MailFlags used_flags)
-{
-	unsigned int i;
-
-	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
-		if ((used_flags & (1 << (i + MAIL_CUSTOM_FLAG_1_BIT))) == 0) {
-			i_free(ff->custom_flags[i]);
-			ff->custom_flags[i] = NULL;
-
-			flags_file_remove(ff, i);
-		}
-	}
-}
-
-static int get_flag_index(FlagsFile *ff, const char *flag,
-			  MailFlags (*get_used_flags)(void *context),
-			  void *context)
-{
-	int i, first_empty;
-
-	/* check existing flags */
-	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
-		if (ff->custom_flags[i] == NULL)
-			continue;
-
-		i_assert(ff->custom_flags[i] != '\0');
-		if (strcasecmp(ff->custom_flags[i], flag) == 0)
-			return i;
-	}
-
-	/* unlock + write lock, don't directly change from read -> write lock
-	   to prevent deadlocking */
-	if (!lock_file(ff, F_UNLCK) || !lock_file(ff, F_WRLCK))
-		return -1;
-
-	/* new flag, add it. first find the first free flag, note that
-	   unlock+lock might have just changed it. */
-	first_empty = find_first_unused_flag(ff);
-	if (first_empty == -1) {
-		/* all custom flags are used, see if some of them are unused */
-		remove_unused_custom_flags(ff, get_used_flags(context));
-
-		first_empty = find_first_unused_flag(ff);
-		if (first_empty == -1) {
-			/* everything is in use */
-			return -1;
-		}
-	}
-
-	if (!flags_file_add(ff, first_empty, flag))
-		return -1;
-
-	ff->custom_flags[first_empty] = i_strdup(flag);
-	return first_empty;
-}
-
-int flags_file_fix_custom_flags(FlagsFile *ff, MailFlags *flags,
-				const char *custom_flags[],
-				MailFlags (*get_used_flags)(void *context),
-				void *context)
-{
-	MailFlags oldflags, flag;
-	int i, idx;
-
-	if ((*flags & MAIL_CUSTOM_FLAGS_MASK) == 0)
-		return TRUE;
-
-	if (!lock_file(ff, F_RDLCK))
-		return FALSE;
-
-	oldflags = *flags;
-	*flags &= MAIL_SYSTEM_FLAGS_MASK;
-
-	flag = MAIL_CUSTOM_FLAG_1;
-	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++, flag <<= 1) {
-		if (oldflags & flag) {
-			i_assert(custom_flags[i] != NULL &&
-				 *custom_flags[i] != '\0');
-
-			idx = get_flag_index(ff, custom_flags[i],
-					     get_used_flags, context);
-			if (idx == -1) {
-				mail_storage_set_error(ff->storage,
-					"Maximum number of different custom "
-					"flags exceeded");
-				(void)lock_file(ff, F_UNLCK);
-				return FALSE;
-			}
-			*flags |= 1 << (idx + MAIL_CUSTOM_FLAG_1_BIT);
-		}
-	}
-
-	if (!lock_file(ff, F_UNLCK))
-		return FALSE;
-
-	return TRUE;
-}
-
-const char **flags_file_list_get(FlagsFile *ff)
-{
-	ff->custom_flags_refcount++;
-	return (const char **) ff->custom_flags;
-}
-
-void flags_file_list_unref(FlagsFile *ff)
-{
-	i_assert(ff->custom_flags_refcount > 0);
-
-	ff->custom_flags_refcount--;
-}
--- a/src/lib-storage/flags-file/flags-file.h	Sat Sep 07 22:01:14 2002 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef __FLAGS_FILE_H
-#define __FLAGS_FILE_H
-
-#include "mail-storage.h"
-
-#define FLAGS_FILE_NAME ".customflags"
-
-typedef struct _FlagsFile FlagsFile;
-
-FlagsFile *flags_file_open_or_create(MailStorage *storage, const char *path);
-void flags_file_destroy(FlagsFile *ff);
-
-/* Change custom flags so that they reflect the real flag numbers in
-   the file. get_used_flags is called when all flags are in use to figure
-   out which of them could be removed. */
-int flags_file_fix_custom_flags(FlagsFile *ff, MailFlags *flags,
-				const char *custom_flags[],
-				MailFlags (*get_used_flags)(void *context),
-				void *context);
-
-/* Returns a pointer to list of flags. */
-const char **flags_file_list_get(FlagsFile *ff);
-
-/* Call this after you've done with the flags list above */
-void flags_file_list_unref(FlagsFile *ff);
-
-#endif
--- a/src/lib-storage/index/index-copy.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/index-copy.c	Sun Sep 08 02:31:56 2002 +0300
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "iobuffer.h"
+#include "mail-custom-flags.h"
 #include "index-storage.h"
 #include "index-messageset.h"
 
@@ -48,13 +49,13 @@
 	if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_SHARED))
 		return mail_storage_set_index_error(ibox);
 
-	cd.custom_flags = flags_file_list_get(ibox->flagsfile);
+	cd.custom_flags = mail_custom_flags_list_get(ibox->index->custom_flags);
 	cd.dest = destbox;
 
 	failed = index_messageset_foreach(ibox, messageset, uidset,
 					  copy_func, &cd) <= 0;
 
-	flags_file_list_unref(ibox->flagsfile);
+	mail_custom_flags_list_unref(ibox->index->custom_flags);
 
 	if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK))
 		return mail_storage_set_index_error(ibox);
--- a/src/lib-storage/index/index-fetch.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/index-fetch.c	Sun Sep 08 02:31:56 2002 +0300
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "iobuffer.h"
 #include "temp-string.h"
+#include "mail-custom-flags.h"
 #include "index-storage.h"
 #include "index-fetch.h"
 #include "index-messageset.h"
@@ -285,7 +286,8 @@
 	ctx.box = box;
 	ctx.cache = ibox->cache;
 	ctx.index = ibox->index;
-	ctx.custom_flags = flags_file_list_get(ibox->flagsfile);
+	ctx.custom_flags =
+		mail_custom_flags_list_get(ibox->index->custom_flags);
 
 	ctx.fetch_data = fetch_data;
 	ctx.outbuf = outbuf;
@@ -304,7 +306,7 @@
 				       fetch_data->uidset,
 				       index_fetch_mail, &ctx);
 
-        flags_file_list_unref(ibox->flagsfile);
+        mail_custom_flags_list_unref(ibox->index->custom_flags);
 
 	if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK))
 		return mail_storage_set_index_error(ibox);
--- a/src/lib-storage/index/index-status.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/index-status.c	Sun Sep 08 02:31:56 2002 +0300
@@ -1,6 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
+#include "mail-custom-flags.h"
 #include "index-storage.h"
 
 static unsigned int get_recent_count(MailIndex *index)
@@ -80,15 +81,16 @@
 }
 
 static void
-get_custom_flags(FlagsFile *ff, const char *result[MAIL_CUSTOM_FLAGS_COUNT])
+get_custom_flags(MailCustomFlags *mcf,
+		 const char *result[MAIL_CUSTOM_FLAGS_COUNT])
 {
 	const char **flags;
 	int i;
 
-	flags = flags_file_list_get(ff);
+	flags = mail_custom_flags_list_get(mcf);
 	for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++)
 		result[i] = t_strdup(flags[i]);
-	flags_file_list_unref(ff);
+	mail_custom_flags_list_unref(mcf);
 }
 
 int index_storage_get_status(Mailbox *box, MailboxStatusItems items,
@@ -117,8 +119,10 @@
 	if (items & STATUS_RECENT)
 		status->recent = get_recent_count(ibox->index);
 
-	if (items & STATUS_CUSTOM_FLAGS)
-		get_custom_flags(ibox->flagsfile, status->custom_flags);
+	if (items & STATUS_CUSTOM_FLAGS) {
+		get_custom_flags(ibox->index->custom_flags,
+				 status->custom_flags);
+	}
 
 	/* STATUS sends EXISTS, so we've synced it */
 	ibox->synced_messages_count = hdr->messages_count;
--- a/src/lib-storage/index/index-storage.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/index-storage.c	Sun Sep 08 02:31:56 2002 +0300
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "mail-index.h"
 #include "mail-index-util.h"
+#include "mail-custom-flags.h"
 #include "index-storage.h"
 
 IndexMailbox *index_storage_init(MailStorage *storage, Mailbox *box,
@@ -10,8 +11,6 @@
 				 int readonly)
 {
 	IndexMailbox *ibox;
-	FlagsFile *flagsfile;
-	const char *path;
 
 	i_assert(name != NULL);
 
@@ -22,14 +21,6 @@
 		return NULL;
 	}
 
-	/* then flags file */
-	path = t_strconcat(index->dir, "/", FLAGS_FILE_NAME, NULL);
-	flagsfile = flags_file_open_or_create(storage, path);
-	if (flagsfile == NULL) {
-		index->free(index);
-		return NULL;
-	}
-
 	ibox = i_new(IndexMailbox, 1);
 	ibox->box = *box;
 
@@ -38,7 +29,6 @@
 	ibox->box.readonly = readonly;
 
 	ibox->index = index;
-	ibox->flagsfile = flagsfile;
 	ibox->cache = imap_msgcache_alloc(&index_msgcache_iface);
 
 	return ibox;
@@ -48,7 +38,6 @@
 {
 	IndexMailbox *ibox = (IndexMailbox *) box;
 
-	flags_file_destroy(ibox->flagsfile);
 	imap_msgcache_free(ibox->cache);
 	ibox->index->free(ibox->index);
 	i_free(box->name);
@@ -64,26 +53,21 @@
 	return FALSE;
 }
 
-static MailFlags get_used_flags(void *context)
+int index_mailbox_fix_custom_flags(IndexMailbox *ibox, MailFlags *flags,
+                                   const char *custom_flags[])
 {
-        IndexMailbox *ibox = context;
-	MailIndexRecord *rec;
-	MailFlags used_flags;
-
-	used_flags = 0;
+	int ret;
 
-	rec = ibox->index->lookup(ibox->index, 1);
-	while (rec != NULL) {
-		used_flags |= rec->msg_flags;
-		rec = ibox->index->next(ibox->index, rec);
+	ret = mail_custom_flags_fix_list(ibox->index->custom_flags,
+					 flags, custom_flags);
+	switch (ret) {
+	case 1:
+		return TRUE;
+	case 0:
+		mail_storage_set_error(ibox->box.storage, "Maximum number of "
+				       "different custom flags exceeded");
+		return FALSE;
+	default:
+		return mail_storage_set_index_error(ibox);
 	}
-
-	return used_flags;
 }
-
-int index_mailbox_fix_custom_flags(IndexMailbox *ibox, MailFlags *flags,
-				   const char *custom_flags[])
-{
-	return flags_file_fix_custom_flags(ibox->flagsfile, flags,
-					   custom_flags, get_used_flags, ibox);
-}
--- a/src/lib-storage/index/index-storage.h	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/index-storage.h	Sun Sep 08 02:31:56 2002 +0300
@@ -4,7 +4,6 @@
 #include "mail-storage.h"
 #include "mail-index.h"
 #include "imap-message-cache.h"
-#include "flags-file/flags-file.h"
 
 typedef struct _IndexMailbox IndexMailbox;
 
@@ -17,7 +16,6 @@
 			      MailExpungeFunc expunge_func, void *context);
 
 	MailIndex *index;
-	FlagsFile *flagsfile;
 	ImapMessageCache *cache;
 	unsigned int synced_messages_count;
 };
@@ -32,7 +30,7 @@
 int mail_storage_set_index_error(IndexMailbox *ibox);
 
 int index_mailbox_fix_custom_flags(IndexMailbox *ibox, MailFlags *flags,
-				   const char *custom_flags[]);
+                                   const char *custom_flags[]);
 
 int index_expunge_seek_first(IndexMailbox *ibox, unsigned int *seq,
 			     MailIndexRecord **rec);
--- a/src/lib-storage/index/index-sync.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/index-sync.c	Sun Sep 08 02:31:56 2002 +0300
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "index-storage.h"
 #include "mail-modifylog.h"
+#include "mail-custom-flags.h"
 
 int index_storage_sync(Mailbox *box, unsigned int *messages, int expunge,
 		       MailExpungeFunc expunge_func,
@@ -33,7 +34,7 @@
 	if (log == NULL)
 		failed = TRUE;
 
-	custom_flags = flags_file_list_get(ibox->flagsfile);
+	custom_flags = mail_custom_flags_list_get(ibox->index->custom_flags);
 	for (; count > 0; count--, log++) {
 		switch (log->type) {
 		case RECORD_TYPE_EXPUNGE:
@@ -59,7 +60,7 @@
 			break;
 		}
 	}
-	flags_file_list_unref(ibox->flagsfile);
+	mail_custom_flags_list_unref(ibox->index->custom_flags);
 
 	/* mark synced */
 	failed = !mail_modifylog_mark_synced(ibox->index->modifylog);
--- a/src/lib-storage/index/index-update-flags.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/index-update-flags.c	Sun Sep 08 02:31:56 2002 +0300
@@ -3,11 +3,12 @@
 #include "lib.h"
 #include "index-storage.h"
 #include "index-messageset.h"
+#include "mail-custom-flags.h"
 
 typedef struct {
 	Mailbox *box;
+	MailCustomFlags *custom_flags;
 	MailFlags flags;
-	FlagsFile *flagsfile;
 	ModifyType modify_type;
 	MailFlagUpdateFunc func;
 	void *context;
@@ -42,9 +43,9 @@
 
 	if (ctx->func != NULL) {
 		ctx->func(ctx->box, seq, rec->uid, flags,
-			  flags_file_list_get(ctx->flagsfile),
+			  mail_custom_flags_list_get(ctx->custom_flags),
 			  ctx->context);
-		flags_file_list_unref(ctx->flagsfile);
+		mail_custom_flags_list_unref(ctx->custom_flags);
 	}
 	return TRUE;
 }
@@ -65,14 +66,14 @@
 	}
 
 	if (!index_mailbox_fix_custom_flags(ibox, &flags, custom_flags))
-		return mail_storage_set_index_error((IndexMailbox *) box);
+		return FALSE;
 
 	if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_EXCLUSIVE))
 		return mail_storage_set_index_error(ibox);
 
 	ctx.box = box;
 	ctx.flags = flags & ~MAIL_RECENT; /* \Recent can't be changed */
-	ctx.flagsfile = ibox->flagsfile;
+	ctx.custom_flags = ibox->index->custom_flags;
 	ctx.modify_type = modify_type;
 	ctx.func = func;
 	ctx.context = context;
--- a/src/lib-storage/index/maildir/maildir-save.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/maildir/maildir-save.c	Sun Sep 08 02:31:56 2002 +0300
@@ -71,7 +71,7 @@
 	}
 
 	if (!index_mailbox_fix_custom_flags(ibox, &flags, custom_flags))
-		return mail_storage_set_index_error(ibox);
+		return FALSE;
 
 	t_push();
 
--- a/src/lib-storage/index/mbox/mbox-save.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/mbox/mbox-save.c	Sun Sep 08 02:31:56 2002 +0300
@@ -57,7 +57,7 @@
 	}
 
 	if (!index_mailbox_fix_custom_flags(ibox, &flags, custom_flags))
-		return mail_storage_set_index_error(ibox);
+		return FALSE;
 
 	/* append the data into mbox file */
 	fd = open(ibox->index->mbox_path, O_RDWR | O_CREAT);
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sat Sep 07 22:01:14 2002 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Sun Sep 08 02:31:56 2002 +0300
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "unlink-directory.h"
 #include "subscription-file/subscription-file.h"
+#include "mail-custom-flags.h"
 #include "mbox-index.h"
 #include "mbox-storage.h"
 
@@ -365,14 +366,15 @@
 static void mbox_storage_close(Mailbox *box)
 {
 	IndexMailbox *ibox = (IndexMailbox *) box;
+	const char **list;
 
 	if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_EXCLUSIVE))
 		mail_storage_set_index_error(ibox);
 	else {
 		/* update flags by rewrite mbox file */
-		mbox_index_rewrite(ibox->index,
-				   flags_file_list_get(ibox->flagsfile));
-		flags_file_list_unref(ibox->flagsfile);
+                list = mail_custom_flags_list_get(ibox->index->custom_flags);
+		mbox_index_rewrite(ibox->index, list);
+		mail_custom_flags_list_unref(ibox->index->custom_flags);
 
 		(void)ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK);
 	}