[dovecot-cvs]
dovecot/src/lib-storage/index index-expunge.c,1.17,1.18
index-mail.c,1.12,1.13 index-mail.h,1.4,1.5
index-storage.c,1.36,1.37 index-storage.h,1.44,1.45
index-update-flags.c,1.23,1.24
cras at procontrol.fi
cras at procontrol.fi
Sat Jul 26 20:33:24 EEST 2003
Update of /home/cvs/dovecot/src/lib-storage/index
In directory danu:/tmp/cvs-serv28560/lib-storage/index
Modified Files:
index-expunge.c index-mail.c index-mail.h index-storage.c
index-storage.h index-update-flags.c
Log Message:
API change for expunging messages. Not exactly what I wanted, but good
enough.
Index: index-expunge.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-expunge.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- index-expunge.c 21 Jul 2003 14:35:39 -0000 1.17
+++ index-expunge.c 26 Jul 2003 16:33:22 -0000 1.18
@@ -1,10 +1,12 @@
-/* Copyright (C) 2002 Timo Sirainen */
+/* Copyright (C) 2002-2003 Timo Sirainen */
#include "lib.h"
#include "index-storage.h"
+#include "index-expunge.h"
-int index_expunge_seek_first(struct index_mailbox *ibox, unsigned int *seq,
- struct mail_index_record **rec)
+static int index_expunge_seek_first(struct index_mailbox *ibox,
+ unsigned int *seq,
+ struct mail_index_record **rec)
{
struct mail_index_header *hdr;
@@ -43,70 +45,156 @@
return TRUE;
}
-int index_expunge_mails(struct index_mailbox *ibox,
- struct mail_index_record *first_rec,
- struct mail_index_record *last_rec,
- unsigned int first_seq, unsigned int last_seq,
- int notify)
+struct mail_expunge_context *
+index_storage_expunge_init(struct mailbox *box,
+ enum mail_fetch_field wanted_fields,
+ int expunge_all)
{
- unsigned int max;
+ struct index_mailbox *ibox = (struct index_mailbox *) box;
+ struct mail_expunge_context *ctx;
- if (!ibox->index->expunge(ibox->index, first_rec, last_rec,
- first_seq, last_seq, FALSE))
- return FALSE;
+ if (box->readonly) {
+ box->storage->callbacks->
+ notify_no(box, "Mailbox is read-only, ignoring expunge",
+ box->storage->callback_context);
+ return i_new(struct mail_expunge_context, 1);
+ }
- if (first_seq > ibox->synced_messages_count)
- return TRUE;
+ if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
+ return NULL;
- max = last_seq > ibox->synced_messages_count ?
- ibox->synced_messages_count : last_seq;
+ ctx = i_new(struct mail_expunge_context, 1);
+ ctx->ibox = ibox;
+ ctx->expunge_all = expunge_all;
+ index_mail_init(ibox, &ctx->mail, wanted_fields, NULL);
- ibox->synced_messages_count -= max - first_seq + 1;
- if (notify) {
- struct mail_storage_callbacks *cb;
- void *cb_ctx;
+ do {
+ if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
+ MAIL_LOCK_EXCLUSIVE))
+ break;
- cb = ibox->box.storage->callbacks;
- cb_ctx = ibox->box.storage->callback_context;
+ /* modifylog must be marked synced before expunging
+ anything new */
+ if (!index_storage_sync_modifylog(ibox, TRUE))
+ break;
- while (max >= first_seq) {
- cb->expunge(&ibox->box, first_seq, cb_ctx);
- max--;
+ if (expunge_all) {
+ ctx->seq = 1;
+ ctx->rec = ibox->index->lookup(ibox->index, 1);
+ } else {
+ if (!index_expunge_seek_first(ibox, &ctx->seq,
+ &ctx->rec))
+ break;
+
+ ctx->fetch_next = ctx->rec != NULL &&
+ (ctx->rec->msg_flags & MAIL_DELETED) == 0;
}
+
+ return ctx;
+ } while (0);
+
+ (void)index_storage_lock(ctx->ibox, MAIL_LOCK_UNLOCK);
+ i_free(ctx);
+ return NULL;
+}
+
+int index_storage_expunge_deinit(struct mail_expunge_context *ctx)
+{
+ int ret = !ctx->failed;
+
+ if (ctx->first_seq != 0) {
+ if (!ctx->ibox->index->expunge(ctx->ibox->index,
+ ctx->first_rec, ctx->last_rec,
+ ctx->first_seq, ctx->last_seq,
+ FALSE))
+ ret = FALSE;
}
- return TRUE;
+ if (ctx->ibox != NULL) {
+ ctx->ibox->fetch_mail.data.rec = NULL;
+
+ if (!index_storage_lock(ctx->ibox, MAIL_LOCK_UNLOCK))
+ ret = FALSE;
+ }
+
+ i_free(ctx);
+ return ret;
}
-int index_storage_expunge(struct mailbox *box, int notify)
+struct mail *index_storage_expunge_fetch_next(struct mail_expunge_context *ctx)
{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
- int failed;
+ struct mail_index *index = ctx->ibox->index;
- if (box->readonly) {
- box->storage->callbacks->
- notify_no(&ibox->box,
- "Mailbox is read-only, ignoring expunge",
- box->storage->callback_context);
- return TRUE;
+ if (ctx->rec == NULL)
+ return NULL;
+
+ if (ctx->fetch_next) {
+ do {
+ ctx->seq++;
+ ctx->rec = index->next(index, ctx->rec);
+ if (ctx->rec == NULL)
+ return NULL;
+ } while ((ctx->rec->msg_flags & MAIL_DELETED) == 0 &&
+ !ctx->expunge_all);
+ } else {
+ ctx->fetch_next = TRUE;
}
- if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
- return FALSE;
+ ctx->mail.expunge_counter = index->expunge_counter;
+ ctx->mail.mail.seq = ctx->seq;
+ ctx->mail.mail.uid = ctx->rec->uid;
- if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
- MAIL_LOCK_EXCLUSIVE))
- return FALSE;
+ if (!index_mail_next(&ctx->mail, ctx->rec, ctx->seq)) {
+ ctx->failed = TRUE;
+ return NULL;
+ }
- /* modifylog must be marked synced before expunging
- anything new */
- if (!index_storage_sync_modifylog(ibox, TRUE))
- failed = TRUE;
- else
- failed = !ibox->expunge_locked(ibox, notify);
+ return &ctx->mail.mail;
+}
- if (!index_storage_lock(ibox, MAIL_LOCK_UNLOCK))
- return FALSE;
+int index_storage_expunge(struct mail *mail, struct mail_expunge_context *ctx,
+ unsigned int *seq_r, int notify)
+{
+ struct index_mail *imail = (struct index_mail *) mail;
+ struct index_mailbox *ibox = imail->ibox;
+ unsigned int seq;
- return !failed;
+ /* currently we allow expunges only from beginning to end so we can
+ easily update sequence numbers */
+ i_assert(ctx->last_seq < ctx->seq);
+
+ seq = mail->seq;
+ if (ctx->first_seq != 0)
+ seq -= (ctx->last_seq - ctx->first_seq) + 1;
+ if (seq_r != NULL) *seq_r = seq;
+
+ if (ctx->first_seq != 0 && ctx->seq != ctx->last_seq+1) {
+ if (!ibox->index->expunge(ibox->index,
+ ctx->first_rec, ctx->last_rec,
+ ctx->first_seq, ctx->last_seq, FALSE))
+ return FALSE;
+
+ ctx->seq -= (ctx->last_seq - ctx->first_seq) + 1;
+ ctx->rec = ibox->index->lookup(ibox->index, ctx->seq);
+
+ ctx->first_seq = 0;
+ }
+
+ if (ctx->first_seq == 0) {
+ ctx->first_seq = ctx->seq;
+ ctx->first_rec = ctx->rec;
+ }
+ ctx->last_seq = ctx->seq;
+ ctx->last_rec = ctx->rec;
+
+ ibox->fetch_mail.data.rec = NULL;
+
+ ibox->synced_messages_count--;
+ if (notify && seq <= ibox->synced_messages_count+1) {
+ ibox->box.storage->callbacks->
+ expunge(&ibox->box, seq,
+ ibox->box.storage->callback_context);
+ }
+
+ return TRUE;
}
Index: index-mail.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- index-mail.c 23 Jul 2003 01:44:16 -0000 1.12
+++ index-mail.c 26 Jul 2003 16:33:22 -0000 1.13
@@ -12,6 +12,7 @@
#include "mail-index-util.h"
#include "mail-custom-flags.h"
#include "index-storage.h"
+#include "index-expunge.h"
#include "index-mail.h"
#include <ctype.h>
@@ -650,7 +651,8 @@
get_stream,
get_special,
index_storage_update_flags,
- index_storage_copy
+ index_storage_copy,
+ index_storage_expunge
};
void index_mail_init(struct index_mailbox *ibox, struct index_mail *mail,
@@ -664,6 +666,7 @@
mail->ibox = ibox;
mail->wanted_fields = wanted_fields;
mail->wanted_headers = wanted_headers;
+ mail->expunge_counter = ibox->index->expunge_counter;
if (ibox->mail_init != NULL)
ibox->mail_init(mail);
@@ -674,6 +677,8 @@
{
struct index_mail_data *data = &mail->data;
int ret, open_mail, parse_header, envelope_headers;
+
+ i_assert(mail->expunge_counter == mail->ibox->index->expunge_counter);
t_push();
Index: index-mail.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-mail.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- index-mail.h 23 Jul 2003 01:44:16 -0000 1.4
+++ index-mail.h 26 Jul 2003 16:33:22 -0000 1.5
@@ -1,6 +1,10 @@
#ifndef __INDEX_MAIL_H
#define __INDEX_MAIL_H
+#include "message-size.h"
+
+struct message_header_line;
+
struct cached_header {
struct cached_header *next;
@@ -40,6 +44,7 @@
pool_t pool;
struct index_mailbox *ibox;
+ unsigned int expunge_counter;
buffer_t *header_buf;
enum mail_fetch_field wanted_fields;
Index: index-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- index-storage.c 23 Jul 2003 02:55:12 -0000 1.36
+++ index-storage.c 26 Jul 2003 16:33:22 -0000 1.37
@@ -288,7 +288,7 @@
if (ibox->lock_type != MAILBOX_LOCK_UNLOCK)
return TRUE;
} else {
- if (ibox->index->lock_type == MAIL_LOCK_EXCLUSIVE)
+ if (ibox->lock_type == MAIL_LOCK_EXCLUSIVE)
return TRUE;
}
Index: index-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- index-storage.h 23 Jul 2003 02:55:12 -0000 1.44
+++ index-storage.h 26 Jul 2003 16:33:22 -0000 1.45
@@ -17,7 +17,6 @@
/* expunge messages marked as deleted, requires index to be
exclusively locked */
- int (*expunge_locked)(struct index_mailbox *ibox, int notify);
void (*mail_init)(struct index_mail *mail);
struct mail_index *index;
@@ -36,6 +35,7 @@
enum mail_lock_notify_type last_notify_type;
unsigned int sent_diskspace_warning:1;
+ unsigned int sent_readonly_flags_warning:1;
};
int mail_storage_set_index_error(struct index_mailbox *ibox);
@@ -69,14 +69,6 @@
unsigned int index_storage_get_recent_count(struct mail_index *index);
-int index_expunge_seek_first(struct index_mailbox *ibox, unsigned int *seq,
- struct mail_index_record **rec);
-int index_expunge_mails(struct index_mailbox *ibox,
- struct mail_index_record *first_rec,
- struct mail_index_record *last_rec,
- unsigned int first_seq, unsigned int last_seq,
- int notify);
-
void index_mailbox_check_add(struct index_mailbox *ibox, const char *path);
void index_mailbox_check_remove_all(struct index_mailbox *ibox);
@@ -84,7 +76,6 @@
void index_storage_set_callbacks(struct mail_storage *storage,
struct mail_storage_callbacks *callbacks,
void *context);
-int index_storage_expunge(struct mailbox *box, int notify);
int index_storage_get_status(struct mailbox *box,
enum mailbox_status_items items,
struct mailbox_status *status);
Index: index-update-flags.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-update-flags.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- index-update-flags.c 23 Jul 2003 01:44:16 -0000 1.23
+++ index-update-flags.c 26 Jul 2003 16:33:22 -0000 1.24
@@ -15,6 +15,10 @@
enum mail_flags modify_flags, new_flags;
if (mail->box->readonly) {
+ if (ibox->sent_readonly_flags_warning)
+ return TRUE;
+ ibox->sent_readonly_flags_warning = TRUE;
+
storage->callbacks->
notify_no(&ibox->box,
"Mailbox is read-only, ignoring flag changes",
More information about the dovecot-cvs
mailing list