dovecot-2.0: maildir: uidlist can now override message's GUID
dovecot at dovecot.org
dovecot at dovecot.org
Thu Sep 16 18:29:15 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/b93405cdd4e9
changeset: 12128:b93405cdd4e9
user: Timo Sirainen <tss at iki.fi>
date: Thu Sep 16 16:28:58 2010 +0100
description:
maildir: uidlist can now override message's GUID
diffstat:
src/lib-storage/index/maildir/maildir-mail.c | 13 ++-
src/lib-storage/index/maildir/maildir-save.c | 10 ++-
src/lib-storage/index/maildir/maildir-uidlist.c | 104 ++++++++++++++++---------
src/lib-storage/index/maildir/maildir-uidlist.h | 12 ++-
4 files changed, 95 insertions(+), 44 deletions(-)
diffs (298 lines):
diff -r 6a99212b636d -r b93405cdd4e9 src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c Thu Sep 16 16:26:48 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-mail.c Thu Sep 16 16:28:58 2010 +0100
@@ -469,11 +469,20 @@
{
struct index_mail *mail = (struct index_mail *)_mail;
struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
- const char *path, *fname, *end, *uidl;
+ const char *path, *fname, *end, *guid, *uidl;
switch (field) {
+ case MAIL_FETCH_GUID:
+ /* use GUID from uidlist if it exists */
+ guid = maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
+ MAILDIR_UIDLIST_REC_EXT_GUID);
+ if (guid != NULL) {
+ *value_r = guid;
+ return 0;
+ }
+
+ /* default to base filename: */
case MAIL_FETCH_UIDL_FILE_NAME:
- case MAIL_FETCH_GUID:
if (mail->data.guid != NULL) {
*value_r = mail->data.guid;
return 0;
diff -r 6a99212b636d -r b93405cdd4e9 src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c Thu Sep 16 16:26:48 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-save.c Thu Sep 16 16:28:58 2010 +0100
@@ -33,6 +33,7 @@
uoff_t size, vsize;
enum mail_flags flags;
unsigned int preserve_filename:1;
+ unsigned int save_guid:1; /* tmp_name contains the GUID */
unsigned int keywords_count;
/* unsigned int keywords[]; */
};
@@ -786,6 +787,7 @@
mf->dest_basename = p_strdup(ctx->pool,
maildir_filename_generate());
mf->preserve_filename = FALSE;
+ mf->save_guid = TRUE;
}
}
@@ -828,6 +830,7 @@
struct maildir_filename *mf;
struct seq_range_iter iter;
enum maildir_uidlist_rec_flag flags;
+ struct maildir_uidlist_rec *rec;
unsigned int n = 0;
uint32_t uid;
bool newdir, bret;
@@ -845,8 +848,13 @@
if (newdir)
flags |= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR;
ret = maildir_uidlist_sync_next_uid(ctx->uidlist_sync_ctx,
- dest, uid, flags);
+ dest, uid, flags, &rec);
i_assert(ret > 0);
+ i_assert(rec != NULL);
+ if (mf->save_guid) {
+ maildir_uidlist_sync_set_ext(ctx->uidlist_sync_ctx, rec,
+ MAILDIR_UIDLIST_REC_EXT_GUID, mf->tmp_name);
+ }
} T_END;
i_assert(!seq_range_array_iter_nth(&iter, n, &uid));
}
diff -r 6a99212b636d -r b93405cdd4e9 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Thu Sep 16 16:26:48 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c Thu Sep 16 16:28:58 2010 +0100
@@ -1141,14 +1141,41 @@
}
static void
-maildir_uidlist_set_ext_real(struct maildir_uidlist *uidlist, uint32_t uid,
+maildir_uidlist_rec_set_ext(struct maildir_uidlist_rec *rec, pool_t pool,
+ enum maildir_uidlist_rec_ext_key key,
+ const char *value)
+{
+ const unsigned char *p;
+ buffer_t *buf;
+ unsigned int len;
+
+ /* copy existing extensions, except for the one we're updating */
+ buf = buffer_create_dynamic(pool_datastack_create(), 128);
+ if (rec->extensions != NULL) {
+ p = rec->extensions;
+ while (*p != '\0') {
+ /* <key><value>\0 */
+ len = strlen((const char *)p) + 1;
+ if (*p != (unsigned char)key)
+ buffer_append(buf, p, len);
+ p += len;
+ }
+ }
+ if (value != NULL) {
+ buffer_append_c(buf, key);
+ buffer_append(buf, value, strlen(value) + 1);
+ }
+ buffer_append_c(buf, '\0');
+
+ rec->extensions = p_malloc(pool, buf->used);
+ memcpy(rec->extensions, buf->data, buf->used);
+}
+
+void maildir_uidlist_set_ext(struct maildir_uidlist *uidlist, uint32_t uid,
enum maildir_uidlist_rec_ext_key key,
const char *value)
{
struct maildir_uidlist_rec *rec;
- const unsigned char *p;
- buffer_t *buf;
- unsigned int len;
int ret;
ret = maildir_uidlist_lookup_rec(uidlist, uid, &rec);
@@ -1165,27 +1192,10 @@
}
}
- buf = buffer_create_dynamic(pool_datastack_create(), 128);
-
- /* copy existing extensions, except for the one we're updating */
- if (rec->extensions != NULL) {
- p = rec->extensions;
- while (*p != '\0') {
- /* <key><value>\0 */
- len = strlen((const char *)p) + 1;
- if (*p != (unsigned char)key)
- buffer_append(buf, p, len);
- p += len;
- }
- }
- if (value != NULL) {
- buffer_append_c(buf, key);
- buffer_append(buf, value, strlen(value) + 1);
- }
- buffer_append_c(buf, '\0');
-
- rec->extensions = p_malloc(uidlist->record_pool, buf->used);
- memcpy(rec->extensions, buf->data, buf->used);
+ T_BEGIN {
+ maildir_uidlist_rec_set_ext(rec, uidlist->record_pool,
+ key, value);
+ } T_END;
if (rec->uid != (uint32_t)-1) {
/* message already exists in uidlist, need to recreate it */
@@ -1193,15 +1203,6 @@
}
}
-void maildir_uidlist_set_ext(struct maildir_uidlist *uidlist, uint32_t uid,
- enum maildir_uidlist_rec_ext_key key,
- const char *value)
-{
- T_BEGIN {
- maildir_uidlist_set_ext_real(uidlist, uid, key, value);
- } T_END;
-}
-
static void
maildir_uidlist_generate_uid_validity(struct maildir_uidlist *uidlist)
{
@@ -1645,10 +1646,12 @@
static int
maildir_uidlist_sync_next_partial(struct maildir_uidlist_sync_ctx *ctx,
const char *filename, uint32_t uid,
- enum maildir_uidlist_rec_flag flags)
+ enum maildir_uidlist_rec_flag flags,
+ struct maildir_uidlist_rec **rec_r)
{
struct maildir_uidlist *uidlist = ctx->uidlist;
- struct maildir_uidlist_rec *rec;
+ struct maildir_uidlist_rec *rec, *const *recs;
+ unsigned int count;
/* we'll update uidlist directly */
rec = hash_table_lookup(uidlist->files, filename);
@@ -1686,6 +1689,11 @@
rec->uid = uid;
if (uidlist->next_uid <= uid)
uidlist->next_uid = uid + 1;
+ else {
+ recs = array_get(&uidlist->records, &count);
+ if (count > 1 && uid < recs[count-1]->uid)
+ uidlist->unsorted = TRUE;
+ }
}
rec->flags = (rec->flags | flags) & ~MAILDIR_UIDLIST_REC_FLAG_NONSYNCED;
@@ -1693,6 +1701,7 @@
hash_table_insert(uidlist->files, rec->filename, rec);
ctx->finished = FALSE;
+ *rec_r = rec;
return 1;
}
@@ -1719,17 +1728,22 @@
const char *filename,
enum maildir_uidlist_rec_flag flags)
{
- return maildir_uidlist_sync_next_uid(ctx, filename, 0, flags);
+ struct maildir_uidlist_rec *rec;
+
+ return maildir_uidlist_sync_next_uid(ctx, filename, 0, flags, &rec);
}
int maildir_uidlist_sync_next_uid(struct maildir_uidlist_sync_ctx *ctx,
const char *filename, uint32_t uid,
- enum maildir_uidlist_rec_flag flags)
+ enum maildir_uidlist_rec_flag flags,
+ struct maildir_uidlist_rec **rec_r)
{
struct maildir_uidlist *uidlist = ctx->uidlist;
struct maildir_uidlist_rec *rec, *old_rec;
const char *p, *dir;
+ *rec_r = NULL;
+
if (ctx->failed)
return -1;
for (p = filename; *p != '\0'; p++) {
@@ -1746,7 +1760,7 @@
if (ctx->partial) {
return maildir_uidlist_sync_next_partial(ctx, filename,
- uid, flags);
+ uid, flags, rec_r);
}
rec = hash_table_lookup(ctx->files, filename);
@@ -1791,6 +1805,7 @@
rec->flags = (rec->flags | flags) & ~MAILDIR_UIDLIST_REC_FLAG_NONSYNCED;
rec->filename = p_strdup(ctx->record_pool, filename);
hash_table_insert(ctx->files, rec->filename, rec);
+ *rec_r = rec;
return 1;
}
@@ -1823,6 +1838,17 @@
ctx->uidlist->recreate = TRUE;
}
+void maildir_uidlist_sync_set_ext(struct maildir_uidlist_sync_ctx *ctx,
+ struct maildir_uidlist_rec *rec,
+ enum maildir_uidlist_rec_ext_key key,
+ const char *value)
+{
+ pool_t pool = ctx->partial ?
+ ctx->uidlist->record_pool : ctx->record_pool;
+
+ maildir_uidlist_rec_set_ext(rec, pool, key, value);
+}
+
const char *
maildir_uidlist_sync_get_full_filename(struct maildir_uidlist_sync_ctx *ctx,
const char *filename)
diff -r 6a99212b636d -r b93405cdd4e9 src/lib-storage/index/maildir/maildir-uidlist.h
--- a/src/lib-storage/index/maildir/maildir-uidlist.h Thu Sep 16 16:26:48 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h Thu Sep 16 16:28:58 2010 +0100
@@ -10,6 +10,7 @@
struct maildir_mailbox;
struct maildir_uidlist;
struct maildir_uidlist_sync_ctx;
+struct maildir_uidlist_rec;
enum maildir_uidlist_sync_flags {
MAILDIR_UIDLIST_SYNC_PARTIAL = 0x01,
@@ -44,7 +45,9 @@
isn't written to uidlist. */
MAILDIR_UIDLIST_REC_EXT_VSIZE = 'W',
/* POP3 UIDL overriding the default format */
- MAILDIR_UIDLIST_REC_EXT_POP3_UIDL = 'P'
+ MAILDIR_UIDLIST_REC_EXT_POP3_UIDL = 'P',
+ /* Message GUID (default is the base filename) */
+ MAILDIR_UIDLIST_REC_EXT_GUID = 'G'
};
int maildir_uidlist_lock(struct maildir_uidlist *uidlist);
@@ -109,9 +112,14 @@
enum maildir_uidlist_rec_flag flags);
int maildir_uidlist_sync_next_uid(struct maildir_uidlist_sync_ctx *ctx,
const char *filename, uint32_t uid,
- enum maildir_uidlist_rec_flag flags);
+ enum maildir_uidlist_rec_flag flags,
+ struct maildir_uidlist_rec **rec_r);
void maildir_uidlist_sync_remove(struct maildir_uidlist_sync_ctx *ctx,
const char *filename);
+void maildir_uidlist_sync_set_ext(struct maildir_uidlist_sync_ctx *ctx,
+ struct maildir_uidlist_rec *rec,
+ enum maildir_uidlist_rec_ext_key key,
+ const char *value);
const char *
maildir_uidlist_sync_get_full_filename(struct maildir_uidlist_sync_ctx *ctx,
const char *filename);
More information about the dovecot-cvs
mailing list