Michael Monnerie wrote:
> On Montag, 18. Juni 2007 Paul J Stevens wrote:
>> This is a todo for 2.3.0, together with what we've started calling
>> single-instance-storage. With SiS, mime-parts such as attachments
>> will never be stored more than once.
>
> And while doing this, would it be possible to do the "cyrus way" of
> checking for duplicate message id's? This would be nice also, and
> saving some space. We've had the problem with an Apple mail client,
> where the user copied some mailbox 5 times into the same folder, having
> 5 duplicates of each e-mail. It would be nice if the server just
> dropped a duplicate message right on the floor.
Does cyrus do this by default? I have a patch to avoid duplicate message-ids
which I can apply to the 2.2 branch right away. I'll attach it for good measure.
Or is it necessary to add a config/compile-time option?
--
________________________________________________________________
Paul Stevens paul at nfg.nl
NET FACILITIES GROUP GPG/PGP: 1024D/11F8CD31
The Netherlands________________________________http://www.nfg.nl
>From f294a5444771ff4c9f5962c92b7b55294ee36bce Mon Sep 17 00:00:00 2001
From: Paul J Stevens <[EMAIL PROTECTED]>
Date: Mon, 18 Jun 2007 13:40:36 +0200
Subject: avoid duplicate message-ids in a mailbox
---
db.c | 31 +++++++++++++++++++++++++++++++
db.h | 11 +++++++++++
sort.c | 8 ++++++++
3 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/db.c b/db.c
index af08d32..63f55a6 100644
--- a/db.c
+++ b/db.c
@@ -3636,6 +3636,37 @@ int db_movemsg(u64_t mailbox_to, u64_t mailbox_from)
return DM_SUCCESS; /* success */
}
+int db_mailbox_has_message_id(u64_t mailbox_idnr, const char *messageid)
+{
+ int rows;
+ char *safe_messageid;
+ char query[DEF_QUERYSIZE];
+ memset(query,0,DEF_QUERYSIZE);
+
+ g_return_val_if_fail(messageid!=NULL,0);
+
+ safe_messageid = dm_stresc(messageid);
+ snprintf(query, DEF_QUERYSIZE,
+ "SELECT message_idnr FROM %smessages m "
+ "JOIN %sphysmessage p ON m.physmessage_id=p.id "
+ "JOIN %sheadervalue v ON v.physmessage_id=p.id "
+ "JOIN %sheadername n ON v.headername_id=n.id "
+ "WHERE m.mailbox_idnr=%llu "
+ "AND n.headername='message-id' "
+ "AND v.headervalue='%s'", DBPFX, DBPFX,
+ DBPFX, DBPFX, mailbox_idnr, safe_messageid);
+ g_free(safe_messageid);
+
+ if (db_query(query) == DM_EQUERY)
+ return DM_EQUERY;
+
+ rows = db_num_rows();
+ db_free_result();
+
+ return rows;
+}
+
+
static u64_t message_get_size(u64_t message_idnr)
{
u64_t size = 0;
diff --git a/db.h b/db.h
index b7563e3..649fe32 100644
--- a/db.h
+++ b/db.h
@@ -1102,6 +1102,15 @@ int db_movemsg(u64_t mailbox_to, u64_t mailbox_from);
*/
int db_copymsg(u64_t msg_idnr, u64_t mailbox_to,
u64_t user_idnr, u64_t * newmsg_idnr);
+
+/**
+ * \brief check if mailbox already holds message with message-id
+ * \param mailbox_idnr
+ * \param messageid Message-ID header to check for
+ * \return number of matching messages or -1 on failure
+ */
+int db_mailbox_has_message_id(u64_t mailbox_idnr, const char *messageid);
+
/**
* \brief get name of mailbox
* \param mailbox_idnr
@@ -1112,6 +1121,8 @@ int db_copymsg(u64_t msg_idnr, u64_t mailbox_to,
* \attention name should be large enough to hold the name
* (preferably of size IMAP_MAX_MAILBOX_NAMELEN + 1)
*/
+
+
int db_getmailboxname(u64_t mailbox_idnr, u64_t user_idnr, char *name);
/**
* \brief set name of mailbox
diff --git a/sort.c b/sort.c
index 62a820c..6674b9e 100644
--- a/sort.c
+++ b/sort.c
@@ -131,6 +131,7 @@ dsn_class_t sort_deliver_to_mailbox(struct DbmailMessage *message,
int *msgflags)
{
u64_t mboxidnr, newmsgidnr;
+ char *messageid;
size_t msgsize = (u64_t)dbmail_message_get_size(message, FALSE);
TRACE(TRACE_INFO,"useridnr [%llu] mailbox [%s]", useridnr, mailbox);
@@ -180,6 +181,13 @@ dsn_class_t sort_deliver_to_mailbox(struct DbmailMessage *message,
}
}
+ // if the mailbox already holds this message we're done
+ messageid = dbmail_message_get_header(message, "message-id");
+ if ( messageid && ((db_mailbox_has_message_id(mboxidnr, messageid)) > 0) ) {
+ TRACE(TRACE_DEBUG, "mailbox already contains this message.");
+ return DSN_CLASS_OK;
+ }
+
// Ok, we have the ACL right, time to deliver the message.
switch (db_copymsg(message->id, mboxidnr, useridnr, &newmsgidnr)) {
case -2:
--
1.5.1
_______________________________________________
DBmail mailing list
[email protected]
https://mailman.fastxs.nl/mailman/listinfo/dbmail