changeset 4455:fce5140fbe0b HEAD

Added mail_get_save_date() and some cleanups.
author Timo Sirainen <timo.sirainen@movial.fi>
date Thu, 29 Jun 2006 14:08:50 +0300
parents a75da1185a18
children 9577a99b7fef
files src/lib-storage/index/dbox/dbox-mail.c src/lib-storage/index/index-mail.c src/lib-storage/index/index-mail.h src/lib-storage/index/maildir/maildir-mail.c src/lib-storage/index/mbox/mbox-mail.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.h src/lib-storage/mail.c
diffstat 8 files changed, 144 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/dbox/dbox-mail.c	Wed Jun 28 23:21:43 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-mail.c	Thu Jun 29 14:08:50 2006 +0300
@@ -1,6 +1,7 @@
 /* Copyright (C) 2005 Timo Sirainen */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "hex-dec.h"
 #include "read-full.h"
 #include "istream.h"
@@ -164,6 +165,29 @@
 	return data->received_date;
 }
 
+static time_t dbox_mail_get_save_date(struct mail *_mail)
+{
+	struct index_mail *mail = (struct index_mail *)_mail;
+	struct index_mail_data *data = &mail->data;
+	uoff_t offset;
+
+	(void)index_mail_get_save_date(_mail);
+	if (data->save_date != (time_t)-1)
+		return data->save_date;
+
+	if (dbox_mail_open(mail, &offset) <= 0)
+		return (time_t)-1;
+	if (data->save_date == (time_t)-1) {
+		/* it's broken and conflicts with our "not found"
+		   return value. change it. */
+		data->save_date = ioloop_time;
+	}
+
+	index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE,
+			     &data->save_date, sizeof(data->save_date));
+	return data->save_date;
+}
+
 static uoff_t dbox_mail_get_physical_size(struct mail *_mail)
 {
 	struct index_mail *mail = (struct index_mail *)_mail;
@@ -214,8 +238,9 @@
 	index_mail_get_flags,
 	index_mail_get_keywords,
 	index_mail_get_parts,
+	index_mail_get_date,
 	dbox_mail_get_received_date,
-	index_mail_get_date,
+	dbox_mail_get_save_date,
 	dbox_mail_get_physical_size, /* physical = virtual in our case */
 	dbox_mail_get_physical_size,
 	index_mail_get_first_header,
--- a/src/lib-storage/index/index-mail.c	Wed Jun 28 23:21:43 2006 +0300
+++ b/src/lib-storage/index/index-mail.c	Thu Jun 29 14:08:50 2006 +0300
@@ -119,16 +119,6 @@
 					    MAIL_CACHE_PHYSICAL_FULL_SIZE);
 }
 
-time_t index_mail_get_cached_received_date(struct index_mail *mail)
-{
-	time_t t;
-
-	if (!index_mail_get_fixed_field(mail, MAIL_CACHE_RECEIVED_DATE,
-					&t, sizeof(t)))
-		t = (time_t)-1;
-	return t;
-}
-
 enum mail_flags index_mail_get_flags(struct mail *_mail)
 {
 	struct index_mail *mail = (struct index_mail *) _mail;
@@ -215,14 +205,30 @@
 	struct index_mail_data *data = &mail->data;
 
 	if (data->received_date == (time_t)-1) {
-		data->received_date = index_mail_get_cached_received_date(mail);
-		if (data->received_date != (time_t)-1)
-			return data->received_date;
+		if (!index_mail_get_fixed_field(mail, MAIL_CACHE_RECEIVED_DATE,
+						&data->received_date,
+						sizeof(data->received_date)))
+			return (time_t)-1;
 	}
 
 	return data->received_date;
 }
 
+time_t index_mail_get_save_date(struct mail *_mail)
+{
+	struct index_mail *mail = (struct index_mail *) _mail;
+	struct index_mail_data *data = &mail->data;
+
+	if (data->save_date == (time_t)-1) {
+		if (!index_mail_get_fixed_field(mail, MAIL_CACHE_SAVE_DATE,
+						&data->save_date,
+						sizeof(data->save_date)))
+			return (time_t)-1;
+	}
+
+	return data->save_date;
+}
+
 time_t index_mail_get_date(struct mail *_mail, int *timezone)
 {
 	struct index_mail *mail = (struct index_mail *) _mail;
--- a/src/lib-storage/index/index-mail.h	Wed Jun 28 23:21:43 2006 +0300
+++ b/src/lib-storage/index/index-mail.h	Thu Jun 29 14:08:50 2006 +0300
@@ -10,6 +10,7 @@
 	MAIL_CACHE_FLAGS = 0,
 	MAIL_CACHE_SENT_DATE,
 	MAIL_CACHE_RECEIVED_DATE,
+	MAIL_CACHE_SAVE_DATE,
 	MAIL_CACHE_VIRTUAL_FULL_SIZE,
 	MAIL_CACHE_PHYSICAL_FULL_SIZE,
 
@@ -67,7 +68,7 @@
 
 struct index_mail_data {
 	enum mail_flags flags;
-	time_t date, received_date;
+	time_t date, received_date, save_date;
 	uoff_t virtual_size, physical_size;
 
 	struct mail_sent_date sent_date;
@@ -153,6 +154,7 @@
 const char *const *index_mail_get_keywords(struct mail *_mail);
 const struct message_part *index_mail_get_parts(struct mail *_mail);
 time_t index_mail_get_received_date(struct mail *_mail);
+time_t index_mail_get_save_date(struct mail *_mail);
 time_t index_mail_get_date(struct mail *_mail, int *timezone);
 uoff_t index_mail_get_virtual_size(struct mail *mail);
 uoff_t index_mail_get_physical_size(struct mail *mail);
@@ -171,7 +173,6 @@
 uoff_t index_mail_get_cached_uoff_t(struct index_mail *mail,
 				    enum index_cache_field field);
 uoff_t index_mail_get_cached_virtual_size(struct index_mail *mail);
-time_t index_mail_get_cached_received_date(struct index_mail *mail);
 
 void index_mail_cache_add(struct index_mail *mail, unsigned int field,
 			  const void *data, size_t data_size);
--- a/src/lib-storage/index/maildir/maildir-mail.c	Wed Jun 28 23:21:43 2006 +0300
+++ b/src/lib-storage/index/maildir/maildir-mail.c	Thu Jun 29 14:08:50 2006 +0300
@@ -73,42 +73,50 @@
 	}
 }
 
-static time_t maildir_mail_get_received_date(struct mail *_mail)
+static int maildir_mail_stat(struct mail *mail, struct stat *st)
 {
-	struct index_mail *mail = (struct index_mail *)_mail;
-	struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
-	struct index_mail_data *data = &mail->data;
-	struct stat st;
+	struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->box;
+	struct index_mail_data *data = &((struct index_mail *)mail)->data;
 	const char *path;
 	int fd;
 
-	(void)index_mail_get_received_date(_mail);
-	if (data->received_date != (time_t)-1)
-		return data->received_date;
-
 	if (data->access_part != 0 && data->stream == NULL) {
 		/* we're going to open the mail anyway */
-		(void)mail_get_stream(_mail, NULL, NULL);
+		(void)mail_get_stream(mail, NULL, NULL);
 	}
 
 	if (data->stream != NULL) {
 		fd = i_stream_get_fd(data->stream);
 		i_assert(fd != -1);
 
-		if (fstat(fd, &st) < 0) {
+		if (fstat(fd, st) < 0) {
 			mail_storage_set_critical(STORAGE(mbox->storage),
 						  "fstat(maildir) failed: %m");
-			return (time_t)-1;
+			return -1;
 		}
-	} else if (_mail->uid != 0) {
-		if (maildir_file_do(mbox, _mail->uid, do_stat, &st) <= 0)
-			return (time_t)-1;
+	} else if (mail->uid != 0) {
+		if (maildir_file_do(mbox, mail->uid, do_stat, st) <= 0)
+			return -1;
 	} else {
-		path = maildir_save_file_get_path(_mail->transaction,
-						  _mail->seq);
-		if (do_stat(mbox, path, &st) <= 0)
-			return (time_t)-1;
+		path = maildir_save_file_get_path(mail->transaction, mail->seq);
+		if (do_stat(mbox, path, st) <= 0)
+			return -1;
 	}
+	return 0;
+}
+
+static time_t maildir_mail_get_received_date(struct mail *_mail)
+{
+	struct index_mail *mail = (struct index_mail *)_mail;
+	struct index_mail_data *data = &mail->data;
+	struct stat st;
+
+	(void)index_mail_get_received_date(_mail);
+	if (data->received_date != (time_t)-1)
+		return data->received_date;
+
+	if (maildir_mail_stat(_mail, &st) < 0)
+		return (time_t)-1;
 
 	data->received_date = st.st_mtime;
 	index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE,
@@ -116,6 +124,25 @@
 	return data->received_date;
 }
 
+static time_t maildir_mail_get_save_date(struct mail *_mail)
+{
+	struct index_mail *mail = (struct index_mail *)_mail;
+	struct index_mail_data *data = &mail->data;
+	struct stat st;
+
+	(void)index_mail_get_save_date(_mail);
+	if (data->save_date != (time_t)-1)
+		return data->save_date;
+
+	if (maildir_mail_stat(_mail, &st) < 0)
+		return (time_t)-1;
+
+	data->save_date = st.st_ctime;
+	index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE,
+			     &data->save_date, sizeof(data->save_date));
+	return data->save_date;
+}
+
 static uoff_t maildir_mail_get_virtual_size(struct mail *_mail)
 {
 	struct index_mail *mail = (struct index_mail *)_mail;
@@ -264,8 +291,9 @@
 	index_mail_get_flags,
 	index_mail_get_keywords,
 	index_mail_get_parts,
+	index_mail_get_date,
 	maildir_mail_get_received_date,
-	index_mail_get_date,
+	maildir_mail_get_save_date,
 	maildir_mail_get_virtual_size,
 	maildir_mail_get_physical_size,
 	index_mail_get_first_header,
--- a/src/lib-storage/index/mbox/mbox-mail.c	Wed Jun 28 23:21:43 2006 +0300
+++ b/src/lib-storage/index/mbox/mbox-mail.c	Thu Jun 29 14:08:50 2006 +0300
@@ -1,6 +1,7 @@
-/* Copyright (C) 2003 Timo Sirainen */
+/* Copyright (C) 2003-2006 Timo Sirainen */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "istream.h"
 #include "index-mail.h"
 #include "mbox-storage.h"
@@ -111,6 +112,24 @@
 	return data->received_date;
 }
 
+static time_t mbox_mail_get_save_date(struct mail *_mail)
+{
+	struct index_mail *mail = (struct index_mail *)_mail;
+	struct index_mail_data *data = &mail->data;
+
+	(void)index_mail_get_save_date(_mail);
+	if (data->save_date != (time_t)-1)
+		return data->save_date;
+
+	/* no way to know this. save the current time into cache and use
+	   that from now on. this works only as long as the index files
+	   are permanent */
+	data->save_date = ioloop_time;
+	index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE,
+			     &data->save_date, sizeof(data->save_date));
+	return data->save_date;
+}
+
 static const char *
 mbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field)
 {
@@ -207,8 +226,9 @@
 	index_mail_get_flags,
 	index_mail_get_keywords,
 	index_mail_get_parts,
+	index_mail_get_date,
 	mbox_mail_get_received_date,
-	index_mail_get_date,
+	mbox_mail_get_save_date,
 	index_mail_get_virtual_size,
 	mbox_mail_get_physical_size,
 	index_mail_get_first_header,
--- a/src/lib-storage/mail-storage-private.h	Wed Jun 28 23:21:43 2006 +0300
+++ b/src/lib-storage/mail-storage-private.h	Thu Jun 29 14:08:50 2006 +0300
@@ -178,8 +178,9 @@
 	const char *const *(*get_keywords)(struct mail *mail);
 	const struct message_part *(*get_parts)(struct mail *mail);
 
+	time_t (*get_date)(struct mail *mail, int *timezone);
 	time_t (*get_received_date)(struct mail *mail);
-	time_t (*get_date)(struct mail *mail, int *timezone);
+	time_t (*get_save_date)(struct mail *mail);
 	uoff_t (*get_virtual_size)(struct mail *mail);
 	uoff_t (*get_physical_size)(struct mail *mail);
 
--- a/src/lib-storage/mail-storage.h	Wed Jun 28 23:21:43 2006 +0300
+++ b/src/lib-storage/mail-storage.h	Thu Jun 29 14:08:50 2006 +0300
@@ -107,13 +107,14 @@
 	MAIL_FETCH_FLAGS		= 0x00000001,
 	MAIL_FETCH_MESSAGE_PARTS	= 0x00000002,
 
-	MAIL_FETCH_RECEIVED_DATE	= 0x00000004,
-	MAIL_FETCH_DATE			= 0x00000008,
-	MAIL_FETCH_VIRTUAL_SIZE		= 0x00000010,
-	MAIL_FETCH_PHYSICAL_SIZE	= 0x00000020,
+	MAIL_FETCH_STREAM_HEADER	= 0x00000004,
+	MAIL_FETCH_STREAM_BODY		= 0x00000008,
 
-	MAIL_FETCH_STREAM_HEADER	= 0x00000040,
-	MAIL_FETCH_STREAM_BODY		= 0x00000080,
+	MAIL_FETCH_DATE			= 0x00000010,
+	MAIL_FETCH_RECEIVED_DATE	= 0x00000020,
+	MAIL_FETCH_SAVE_DATE		= 0x00000040,
+	MAIL_FETCH_PHYSICAL_SIZE	= 0x00000080,
+	MAIL_FETCH_VIRTUAL_SIZE		= 0x00000100,
 
 	/* specials: */
 	MAIL_FETCH_IMAP_BODY		= 0x00001000,
@@ -436,18 +437,21 @@
 int mail_set_seq(struct mail *mail, uint32_t seq);
 int mail_set_uid(struct mail *mail, uint32_t uid);
 
-/* Get the time message was received (IMAP INTERNALDATE).
-   Returns (time_t)-1 if error occurred. */
-time_t mail_get_received_date(struct mail *mail);
-/* Get the Date-header in mail. Timezone is in minutes.
+/* Get the Date-header of the mail. Timezone is in minutes.
    Returns (time_t)-1 if error occurred, 0 if field wasn't found or
    couldn't be parsed. */
 time_t mail_get_date(struct mail *mail, int *timezone);
+/* Get the time when the mail was received (IMAP INTERNALDATE).
+   Returns (time_t)-1 if error occurred. */
+time_t mail_get_received_date(struct mail *mail);
+/* Get the time when the mail was saved into this mailbox. This time may not
+   always be entirely reliable. Returns (time_t)-1 if error occurred. */
+time_t mail_get_save_date(struct mail *mail);
 
-/* Get the full virtual size of mail (IMAP RFC822.SIZE).
-   Returns (uoff_t)-1 if error occurred */
+/* Get the space used by the mail as seen by the reader. Linefeeds are always
+   counted as being CR+LF. Returns (uoff_t)-1 if error occurred */
 uoff_t mail_get_virtual_size(struct mail *mail);
-/* Get the full physical size of mail.
+/* Get the space used by the mail in disk.
    Returns (uoff_t)-1 if error occurred */
 uoff_t mail_get_physical_size(struct mail *mail);
 
--- a/src/lib-storage/mail.c	Wed Jun 28 23:21:43 2006 +0300
+++ b/src/lib-storage/mail.c	Thu Jun 29 14:08:50 2006 +0300
@@ -61,6 +61,13 @@
 	return p->v.get_received_date(mail);
 }
 
+time_t mail_get_save_date(struct mail *mail)
+{
+	struct mail_private *p = (struct mail_private *)mail;
+
+	return p->v.get_save_date(mail);
+}
+
 time_t mail_get_date(struct mail *mail, int *timezone)
 {
 	struct mail_private *p = (struct mail_private *)mail;