[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-file.c, NONE,
1.1 mbox-file.h, NONE, 1.1 mbox-lock.c, NONE, 1.1 mbox-lock.h,
NONE, 1.1 mbox-mail.c, NONE, 1.1 mbox-transaction.c, NONE,
1.1 Makefile.am, 1.2, 1.3 istream-raw-mbox.c, 1.1,
1.2 istream-raw-mbox.h, 1.1, 1.2 mbox-from.c, 1.1,
1.2 mbox-from.h, 1.1, 1.2 mbox-list.c, 1.23, 1.24 mbox-save.c,
1.47, 1.48 mbox-storage.c, 1.73, 1.74 mbox-storage.h, 1.18,
1.19 mbox-sync-parse.c, 1.1, 1.2 mbox-sync-private.h, 1.2,
1.3 mbox-sync-rewrite.c, 1.1, 1.2 mbox-sync.c, 1.1,
1.2 mbox-expunge.c, 1.34, NONE
cras at procontrol.fi
cras at procontrol.fi
Thu May 6 04:22:28 EEST 2004
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-list.c,
1.27, 1.28 maildir-mail.c, 1.2, 1.3 maildir-storage.c, 1.70,
1.71 maildir-storage.h, 1.21, 1.22 maildir-sync.c, 1.11,
1.12 maildir-uidlist.c, 1.12, 1.13 maildir-uidlist.h, 1.3, 1.4
- Next message: [dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-mail.c, 1.1,
1.2 mbox-sync.c, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/lib-storage/index/mbox
In directory talvi:/tmp/cvs-serv13512/src/lib-storage/index/mbox
Modified Files:
Makefile.am istream-raw-mbox.c istream-raw-mbox.h mbox-from.c
mbox-from.h mbox-list.c mbox-save.c mbox-storage.c
mbox-storage.h mbox-sync-parse.c mbox-sync-private.h
mbox-sync-rewrite.c mbox-sync.c
Added Files:
mbox-file.c mbox-file.h mbox-lock.c mbox-lock.h mbox-mail.c
mbox-transaction.c
Removed Files:
mbox-expunge.c
Log Message:
mbox code compiles again, but syncing is only partially implemented so
accessing mboxes fails..
Also some cleanups to index-storage and maildir code.
--- NEW FILE: mbox-file.c ---
/* Copyright (C) 2002-2003 Timo Sirainen */
#include "lib.h"
#include "istream.h"
#include "mbox-storage.h"
#include "mbox-file.h"
#include "istream-raw-mbox.h"
#include <sys/stat.h>
int mbox_file_open(struct index_mailbox *ibox)
{
struct stat st;
int fd;
i_assert(ibox->mbox_fd == -1);
fd = open(ibox->path, ibox->readonly ? O_RDONLY : O_RDWR);
if (fd == -1) {
mbox_set_syscall_error(ibox, "open()");
return -1;
}
if (fstat(fd, &st) < 0) {
mbox_set_syscall_error(ibox, "fstat()");
(void)close(fd);
return -1;
}
ibox->mbox_fd = fd;
ibox->mbox_dev = st.st_dev;
ibox->mbox_ino = st.st_ino;
return 0;
}
void mbox_file_close(struct index_mailbox *ibox)
{
mbox_file_close_stream(ibox);
if (ibox->mbox_fd != -1) {
if (close(ibox->mbox_fd) < 0)
i_error("close(mbox) failed: %m");
ibox->mbox_fd = -1;
}
}
int mbox_file_open_stream(struct index_mailbox *ibox)
{
if (ibox->mbox_stream != NULL)
return 0;
i_assert(ibox->mbox_file_stream == NULL);
if (ibox->mbox_fd == -1) {
if (mbox_file_open(ibox) < 0)
return -1;
}
if (ibox->mail_read_mmaped) {
ibox->mbox_file_stream =
i_stream_create_mmap(ibox->mbox_fd, default_pool,
MAIL_MMAP_BLOCK_SIZE,
0, 0, FALSE);
} else {
ibox->mbox_file_stream =
i_stream_create_file(ibox->mbox_fd, default_pool,
MAIL_READ_BLOCK_SIZE, FALSE);
}
ibox->mbox_stream =
i_stream_create_raw_mbox(default_pool, ibox->mbox_file_stream);
return 0;
}
void mbox_file_close_stream(struct index_mailbox *ibox)
{
if (ibox->mbox_stream != NULL) {
i_stream_close(ibox->mbox_file_stream);
i_stream_unref(ibox->mbox_file_stream);
ibox->mbox_file_stream = NULL;
i_stream_unref(ibox->mbox_stream);
ibox->mbox_stream = NULL;
}
}
--- NEW FILE: mbox-file.h ---
#ifndef __MBOX_FILE_H
#define __MBOX_FILE_H
int mbox_file_open(struct index_mailbox *ibox);
void mbox_file_close(struct index_mailbox *ibox);
int mbox_file_open_stream(struct index_mailbox *ibox);
void mbox_file_close_stream(struct index_mailbox *ibox);
#endif
--- NEW FILE: mbox-lock.c ---
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
#include "mbox-storage.h"
#include "mbox-file.h"
#include "mbox-lock.h"
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef HAVE_FLOCK
# include <sys/file.h>
#endif
/* 0.1 .. 0.2msec */
#define LOCK_RANDOM_USLEEP_TIME (100000 + (unsigned int)rand() % 100000)
/* lock methods to use in wanted order */
#define DEFAULT_LOCK_METHODS "dotlock fcntl"
/* lock timeout */
#define DEFAULT_LOCK_TIMEOUT 300
/* assume stale dotlock if mbox file hasn't changed for n seconds */
#define DEFAULT_DOTLOCK_CHANGE_TIMEOUT 30
struct dotlock_context {
struct index_mailbox *ibox;
int lock_type;
int last_stale;
};
static int lock_settings_initialized = FALSE;
static int use_dotlock, use_fcntl_lock, use_flock, fcntl_before_flock;
static int use_read_dotlock, lock_timeout, dotlock_change_timeout;
static int mbox_unlock_files(struct index_mailbox *ibox);
static void mbox_init_lock_settings(void)
{
const char *str;
const char *const *lock;
use_dotlock = use_fcntl_lock = use_flock = fcntl_before_flock = FALSE;
str = getenv("MBOX_LOCKS");
if (str == NULL) str = DEFAULT_LOCK_METHODS;
for (lock = t_strsplit(str, " "); *lock != NULL; lock++) {
if (strcasecmp(*lock, "dotlock") == 0)
use_dotlock = TRUE;
else if (strcasecmp(*lock, "fcntl") == 0) {
use_fcntl_lock = TRUE;
fcntl_before_flock = use_flock == FALSE;
} else if (strcasecmp(*lock, "flock") == 0)
use_flock = TRUE;
else
i_fatal("MBOX_LOCKS: Invalid value %s", *lock);
}
use_read_dotlock = getenv("MBOX_READ_DOTLOCK") != NULL;
str = getenv("MBOX_LOCK_TIMEOUT");
lock_timeout = str == NULL ? DEFAULT_LOCK_TIMEOUT : atoi(str);
str = getenv("MBOX_DOTLOCK_CHANGE_TIMEOUT");
dotlock_change_timeout = str == NULL ?
DEFAULT_DOTLOCK_CHANGE_TIMEOUT : atoi(str);
lock_settings_initialized = TRUE;
}
#ifdef HAVE_FLOCK
static int mbox_lock_flock(struct index_mailbox *ibox, int lock_type,
time_t max_wait_time)
{
time_t now, last_notify;
if (lock_type == F_WRLCK)
lock_type = LOCK_EX;
else if (lock_type == F_RDLCK)
lock_type = LOCK_SH;
else
lock_type = LOCK_UN;
last_notify = 0;
while (flock(ibox->mbox_fd, lock_type | LOCK_NB) < 0) {
if (errno != EWOULDBLOCK) {
mbox_set_syscall_error(ibox, "flock()");
return -1;
}
if (max_wait_time == 0)
return 0;
now = time(NULL);
if (now >= max_wait_time)
return 0;
if (now != last_notify) {
index_storage_lock_notify(ibox,
MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
max_wait_time - now);
}
usleep(LOCK_RANDOM_USLEEP_TIME);
}
return 1;
}
#endif
static int mbox_lock_fcntl(struct index_mailbox *ibox, int lock_type,
time_t max_wait_time)
{
struct flock fl;
time_t now;
int wait_type;
fl.l_type = lock_type;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
wait_type = max_wait_time == 0 ? F_SETLK : F_SETLKW;
while (fcntl(ibox->mbox_fd, wait_type, &fl) < 0) {
if (errno != EINTR) {
if (errno != EAGAIN && errno != EACCES)
mbox_set_syscall_error(ibox, "fcntl()");
return -1;
}
now = time(NULL);
if (max_wait_time != 0 && now >= max_wait_time)
return 0;
index_storage_lock_notify(ibox,
MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
max_wait_time - now);
}
return 1;
}
static int mbox_file_locks(struct index_mailbox *ibox, int lock_type,
time_t max_wait_time)
{
struct stat st;
int ret;
/* now we need to have the file itself locked. open it if needed. */
if (stat(ibox->path, &st) < 0) {
mbox_set_syscall_error(ibox, "stat()");
return -1;
}
if (st.st_dev != ibox->mbox_dev || st.st_ino != ibox->mbox_ino)
mbox_file_close(ibox);
if (ibox->mbox_fd == -1) {
if (mbox_file_open(ibox) < 0) {
(void)mbox_unlock_files(ibox);
return -1;
}
}
if (use_fcntl_lock && fcntl_before_flock) {
ret = mbox_lock_fcntl(ibox, lock_type, max_wait_time);
if (ret <= 0)
return ret;
}
#ifdef HAVE_FLOCK
if (use_flock) {
ret = mbox_lock_flock(ibox, lock_type, max_wait_time);
if (ret <= 0)
return ret;
}
#endif
if (use_fcntl_lock && !fcntl_before_flock) {
ret = mbox_lock_fcntl(ibox, lock_type, max_wait_time);
if (ret <= 0)
return ret;
}
return 1;
}
static int mbox_file_unlock(struct index_mailbox *ibox)
{
int ret = 0;
#ifdef HAVE_FLOCK
if (use_flock && mbox_lock_flock(ibox, F_UNLCK, 0) < 0)
ret = -1;
#endif
if (use_fcntl_lock && mbox_lock_fcntl(ibox, F_UNLCK, 0) < 0)
ret = -1;
return ret;
}
static int dotlock_callback(unsigned int secs_left, int stale, void *context)
{
struct dotlock_context *ctx = context;
if (stale && !ctx->last_stale) {
if (mbox_file_locks(ctx->ibox, ctx->lock_type, 0) <= 0) {
/* we couldn't get fcntl/flock - it's really locked */
ctx->last_stale = TRUE;
return FALSE;
}
(void)mbox_file_unlock(ctx->ibox);
}
ctx->last_stale = stale;
index_storage_lock_notify(ctx->ibox, stale ?
MAILBOX_LOCK_NOTIFY_MAILBOX_OVERRIDE :
MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
secs_left);
return TRUE;
}
int mbox_lock(struct index_mailbox *ibox, int lock_type,
unsigned int *lock_id_r)
{
time_t max_wait_time;
int ret;
/* allow only unlock -> shared/exclusive or exclusive -> shared */
i_assert(lock_type == F_RDLCK || lock_type == F_WRLCK);
i_assert(lock_type == F_RDLCK || ibox->mbox_lock_type != F_RDLCK);
if (ibox->mbox_lock_type == lock_type) {
ibox->mbox_locks++;
return 1;
}
index_storage_lock_notify_reset(ibox);
if (!lock_settings_initialized)
mbox_init_lock_settings();
max_wait_time = time(NULL) + lock_timeout;
/* make .lock file first to protect overwriting the file */
if (use_dotlock && ibox->mbox_dotlock.ino == 0) {
struct dotlock_context ctx;
ctx.ibox = ibox;
ctx.lock_type = lock_type;
ctx.last_stale = -1;
ret = file_lock_dotlock(ibox->path, NULL,
lock_type == F_RDLCK &&
!use_read_dotlock, lock_timeout,
dotlock_change_timeout, 0,
dotlock_callback, &ctx,
&ibox->mbox_dotlock);
if (ret < 0) {
mbox_set_syscall_error(ibox, "file_lock_dotlock()");
return -1;
}
if (ret == 0) {
mail_storage_set_error(ibox->box.storage,
"Timeout while waiting for lock");
return 0;
}
}
ibox->mbox_lock_type = lock_type;
ret = mbox_file_locks(ibox, ibox->mbox_lock_type, max_wait_time);
if (ret <= 0) {
(void)mbox_unlock_files(ibox);
if (ret == 0) {
mail_storage_set_error(ibox->box.storage,
"Timeout while waiting for lock");
}
return ret;
}
*lock_id_r = ++ibox->mbox_lock_id;
return 1;
}
static int mbox_unlock_files(struct index_mailbox *ibox)
{
int ret = 0;
if (ibox->mbox_fd != -1) {
if (mbox_file_unlock(ibox) < 0)
ret = -1;
}
if (ibox->mbox_dotlock.ino != 0) {
if (file_unlock_dotlock(ibox->path, &ibox->mbox_dotlock) <= 0) {
mbox_set_syscall_error(ibox, "file_unlock_dotlock()");
ret = -1;
}
ibox->mbox_dotlock.ino = 0;
}
/* make sure we don't keep mmap() between locks */
mbox_file_close_stream(ibox);
ibox->mbox_lock_id++;
ibox->mbox_lock_type = F_UNLCK;
return ret;
}
int mbox_unlock(struct index_mailbox *ibox, unsigned int lock_id)
{
i_assert(ibox->mbox_lock_id == lock_id);
if (--ibox->mbox_locks > 0)
return 0;
return mbox_unlock_files(ibox);
}
--- NEW FILE: mbox-lock.h ---
#ifndef __MBOX_LOCK_H
#define __MBOX_LOCK_H
/* NOTE: if mbox file is not open, it's opened. if it is open but file has
been overwritten (ie. inode has changed), it's reopened. */
int mbox_lock(struct index_mailbox *ibox, int lock_type,
unsigned int *lock_id_r);
int mbox_unlock(struct index_mailbox *ibox, unsigned int lock_id);
#endif
--- NEW FILE: mbox-mail.c ---
/* Copyright (C) 2003 Timo Sirainen */
#include "lib.h"
#include "istream.h"
#include "index-mail.h"
#include "mbox-storage.h"
#include "mbox-file.h"
#include "istream-raw-mbox.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
static int mbox_mail_seek(struct index_mail *mail)
{
i_assert(mail->mail.seq <= mail->ibox->mbox_data_count);
// FIXME: lock the file
if (mbox_file_open_stream(mail->ibox) < 0)
return -1;
i_stream_seek(mail->ibox->mbox_stream,
mail->ibox->mbox_data[mail->mail.seq-1] >> 1);
return 0;
}
static const struct mail_full_flags *mbox_mail_get_flags(struct mail *_mail)
{
struct index_mail *mail = (struct index_mail *)_mail;
struct index_mail_data *data = &mail->data;
i_assert(_mail->seq <= mail->ibox->mbox_data_count);
(void)index_mail_get_flags(_mail);
if ((mail->ibox->mbox_data[_mail->seq-1] & 1) != 0)
data->flags.flags |= MAIL_RECENT;
return &data->flags;
}
static time_t mbox_mail_get_received_date(struct mail *_mail)
{
struct index_mail *mail = (struct index_mail *)_mail;
struct index_mail_data *data = &mail->data;
(void)index_mail_get_received_date(_mail);
if (data->received_date != (time_t)-1)
return data->received_date;
if (mbox_mail_seek(mail) < 0)
return (time_t)-1;
data->received_date =
istream_raw_mbox_get_received_time(mail->ibox->mbox_stream);
if (data->received_date != (time_t)-1) {
index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE,
&data->received_date,
sizeof(data->received_date));
}
return data->received_date;
}
static const char *
mbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field)
{
struct index_mail *mail = (struct index_mail *)_mail;
if (field == MAIL_FETCH_FROM_ENVELOPE) {
if (mbox_mail_seek(mail) < 0)
return NULL;
return istream_raw_mbox_get_sender(mail->ibox->mbox_stream);
}
return index_mail_get_special(_mail, field);
}
static struct istream *mbox_mail_get_stream(struct mail *_mail,
struct message_size *hdr_size,
struct message_size *body_size)
{
struct index_mail *mail = (struct index_mail *)_mail;
struct index_mail_data *data = &mail->data;
if (data->stream == NULL) {
if (mbox_mail_seek(mail) < 0)
return NULL;
data->stream = mail->ibox->mbox_stream;
}
return index_mail_init_stream(mail, hdr_size, body_size);
}
struct mail mbox_mail = {
0, 0, 0, 0, 0, 0,
mbox_mail_get_flags,
index_mail_get_parts,
mbox_mail_get_received_date,
index_mail_get_date,
index_mail_get_size,
index_mail_get_header,
index_mail_get_headers,
mbox_mail_get_stream,
mbox_mail_get_special,
index_mail_update_flags,
index_mail_expunge
};
--- NEW FILE: mbox-transaction.c ---
/* Copyright (C) 2004 Timo Sirainen */
#include "lib.h"
#include "mbox-storage.h"
#include "mbox-lock.h"
#include "mbox-sync-private.h"
struct mailbox_transaction_context *
mbox_transaction_begin(struct mailbox *box, int hide)
{
struct index_mailbox *ibox = (struct index_mailbox *)box;
struct mbox_transaction_context *t;
t = i_new(struct mbox_transaction_context, 1);
t->ictx.mailbox_ctx.box = box;
t->ictx.ibox = ibox;
t->ictx.trans = mail_index_transaction_begin(ibox->view, hide);
return &t->ictx.mailbox_ctx;
}
int mbox_transaction_commit(struct mailbox_transaction_context *_t)
{
struct mbox_transaction_context *t =
(struct mbox_transaction_context *)_t;
struct index_mailbox *ibox = t->ictx.ibox;
unsigned int lock_id = t->mbox_lock_id;
int ret = 0;
if (t->save_ctx != NULL)
ret = mbox_save_commit(t->save_ctx);
if (ret == 0) {
if (index_transaction_commit(_t) < 0)
ret = -1;
} else {
index_transaction_rollback(_t);
}
if (ret == 0) {
if (mbox_sync(ibox, TRUE) < 0)
ret = -1;
}
if (lock_id != 0) {
if (mbox_unlock(ibox, lock_id) < 0)
ret = -1;
}
return ret;
}
void mbox_transaction_rollback(struct mailbox_transaction_context *_t)
{
struct mbox_transaction_context *t =
(struct mbox_transaction_context *)_t;
struct index_mailbox *ibox = t->ictx.ibox;
if (t->save_ctx != NULL)
mbox_save_rollback(t->save_ctx);
if (t->mbox_lock_id != 0)
(void)mbox_unlock(ibox, t->mbox_lock_id);
index_transaction_rollback(_t);
}
Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/Makefile.am,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Makefile.am 27 Apr 2004 20:25:54 -0000 1.2
+++ Makefile.am 6 May 2004 01:22:25 -0000 1.3
@@ -11,18 +11,23 @@
libstorage_mbox_a_SOURCES = \
istream-raw-mbox.c \
- mbox-expunge.c \
+ mbox-file.c \
mbox-from.c \
mbox-list.c \
+ mbox-lock.c \
+ mbox-mail.c \
mbox-save.c \
mbox-sync-parse.c \
mbox-sync-rewrite.c \
mbox-sync-update.c \
- mbox-sync.c
- mbox-storage.c
+ mbox-sync.c \
+ mbox-storage.c \
+ mbox-transaction.c
noinst_HEADERS = \
istream-raw-mbox.h \
+ mbox-file.h \
mbox-from.h \
+ mbox-lock.h \
mbox-storage.h \
mbox-sync-private.h
Index: istream-raw-mbox.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/istream-raw-mbox.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- istream-raw-mbox.c 27 Apr 2004 20:25:54 -0000 1.1
+++ istream-raw-mbox.c 6 May 2004 01:22:25 -0000 1.2
@@ -10,7 +10,9 @@
struct _istream istream;
time_t received_time, next_received_time;
- uoff_t from_offset, body_size;
+ char *sender, *next_sender;
+
+ uoff_t from_offset, hdr_offset, next_from_offset, body_size;
struct istream *input;
};
@@ -42,12 +44,66 @@
timeout_cb, context);
}
+static int mbox_read_from_line(struct raw_mbox_istream *rstream)
+{
+ const unsigned char *buf, *p;
+ char *sender;
+ time_t received_time;
+ size_t pos, line_pos;
+ int skip;
+
+ buf = i_stream_get_data(rstream->input, &pos);
+ i_assert(pos > 0);
+
+ /* from_offset points to "\nFrom ", so unless we're at the beginning
+ of the file, skip the initial \n */
+ skip = rstream->from_offset != 0;
+
+ while ((p = memchr(buf+skip, '\n', pos-skip)) == NULL) {
+ if (i_stream_read(rstream->input) < 0) {
+ /* EOF - shouldn't happen */
+ return -1;
+ }
+ buf = i_stream_get_data(rstream->input, &pos);
+ }
+ line_pos = (size_t)(p - buf);
+
+ if (rstream->from_offset != 0) {
+ buf++;
+ pos--;
+ }
+
+ /* beginning of mbox */
+ if (memcmp(buf, "From ", 5) != 0 ||
+ mbox_from_parse(buf+5, pos-5, &received_time, &sender) < 0) {
+ /* broken From - should happen only at beginning of
+ file if this isn't a mbox.. */
+ return -1;
+ }
+
+ if (rstream->istream.istream.v_offset == rstream->from_offset) {
+ rstream->received_time = received_time;
+ i_free(rstream->sender);
+ rstream->sender = sender;
+ } else {
+ rstream->next_received_time = received_time;
+ i_free(rstream->next_sender);
+ rstream->next_sender = sender;
+ }
+
+ /* we'll skip over From-line */
+ rstream->istream.istream.v_offset += line_pos+1;
+ rstream->hdr_offset = rstream->istream.istream.v_offset;
+ return 0;
+}
+
static ssize_t _read(struct _istream *stream)
{
static const char *mbox_from = "\nFrom ";
struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream;
- const unsigned char *buf, *p;
+ const unsigned char *buf;
const char *fromp;
+ char *sender;
time_t received_time;
size_t i, pos;
ssize_t ret;
@@ -71,58 +127,24 @@
}
if (stream->istream.v_offset == rstream->from_offset) {
- /* read the full From-line */
- int skip = rstream->from_offset != 0;
- size_t line_pos;
-
- while ((p = memchr(buf+skip, '\n', pos-skip)) == NULL) {
- if (i_stream_read(rstream->input) < 0) {
- /* EOF - shouldn't happen */
- stream->pos = 0;
- stream->istream.eof = TRUE;
- return -1;
- }
- buf = i_stream_get_data(rstream->input, &pos);
- }
- line_pos = (size_t)(p - buf);
-
- if (rstream->from_offset != 0) {
- buf++;
- pos--;
- }
-
- /* beginning of mbox */
- if (memcmp(buf, "From ", 5) != 0)
- received_time = (time_t)-1;
- else
- received_time = mbox_from_parse_date(buf+5, pos-5);
-
- if (received_time == (time_t)-1) {
- /* broken From - should happen only at beginning of
- file if this isn't a mbox.. */
+ if (mbox_read_from_line(rstream) < 0) {
stream->pos = 0;
stream->istream.eof = TRUE;
return -1;
}
-
- if (rstream->from_offset == 0)
- rstream->received_time = received_time;
- else
- rstream->next_received_time = received_time;
-
- /* we'll skip over From-line and try again */
- stream->istream.v_offset += line_pos+1;
return _read(stream);
}
if (pos >= 31) {
- if (memcmp(buf, "\nFrom ", 6) == 0) {
- received_time = mbox_from_parse_date(buf+6, pos-6);
- if (received_time != (time_t)-1) {
- rstream->next_received_time = received_time;
- i_assert(stream->pos == 0);
- return -1;
- }
+ if (memcmp(buf, "\nFrom ", 6) == 0 &&
+ mbox_from_parse(buf+6, pos-6,
+ &received_time, &sender) == 0) {
+ rstream->next_received_time = received_time;
+
+ i_free(rstream->next_sender);
+ rstream->next_sender = sender;
+ i_assert(stream->pos == 0);
+ return -1;
}
} else if (ret == -1) {
/* last few bytes, can't contain From-line */
@@ -194,6 +216,7 @@
const unsigned char *data;
size_t size;
time_t received_time;
+ char *sender;
/* minimal: "From x Thu Nov 29 22:33:52 2001" = 31 chars */
if (i_stream_read_data(rstream->input, &data, &size, 30) == -1)
@@ -212,11 +235,12 @@
break;
}
- received_time = mbox_from_parse_date(data+6, size-6);
- if (received_time == (time_t)-1)
+ if (mbox_from_parse(data+6, size-6, &received_time, &sender) < 0)
return FALSE;
rstream->next_received_time = received_time;
+ i_free(rstream->next_sender);
+ rstream->next_sender = sender;
return TRUE;
}
@@ -250,6 +274,24 @@
return rstream->body_size;
}
+time_t istream_raw_mbox_get_received_time(struct istream *stream)
+{
+ struct raw_mbox_istream *rstream =
+ (struct raw_mbox_istream *)stream->real_stream;
+
+ (void)_read(&rstream->istream);
+ return rstream->received_time;
+}
+
+const char *istream_raw_mbox_get_sender(struct istream *stream)
+{
+ struct raw_mbox_istream *rstream =
+ (struct raw_mbox_istream *)stream->real_stream;
+
+ (void)_read(&rstream->istream);
+ return rstream->sender == NULL ? "" : rstream->sender;
+}
+
void istream_raw_mbox_next(struct istream *stream, uoff_t body_size)
{
struct raw_mbox_istream *rstream =
@@ -261,10 +303,48 @@
rstream->received_time = rstream->next_received_time;
rstream->next_received_time = (time_t)-1;
+ i_free(rstream->sender);
+ rstream->sender = rstream->next_sender;
+ rstream->next_sender = NULL;
+
rstream->from_offset = stream->v_offset + body_size;
+ rstream->hdr_offset = rstream->from_offset;
+
+ /* don't clear stream->eof if we don't have to */
+ if (stream->v_offset != rstream->from_offset)
+ i_stream_seek(stream, rstream->from_offset);
i_stream_seek(rstream->input, rstream->from_offset);
}
+void istream_raw_mbox_seek(struct istream *stream, uoff_t offset)
+{
+ struct raw_mbox_istream *rstream =
+ (struct raw_mbox_istream *)stream->real_stream;
+
+ if (offset == rstream->next_from_offset) {
+ istream_raw_mbox_next(stream, (uoff_t)-1);
+ return;
+ }
+
+ if (offset == rstream->from_offset) {
+ /* back to beginning of current message */
+ offset = rstream->hdr_offset;
+ } else {
+ rstream->body_size = (uoff_t)-1;
+ rstream->received_time = (time_t)-1;
+ rstream->next_received_time = (time_t)-1;
+
+ i_free(rstream->sender);
+ rstream->sender = NULL;
+ i_free(rstream->next_sender);
+ rstream->next_sender = NULL;
+ }
+
+ rstream->from_offset = rstream->hdr_offset = offset;
+ i_stream_seek(stream, offset);
+ i_stream_seek(rstream->input, offset);
+}
+
void istream_raw_mbox_flush(struct istream *stream)
{
struct raw_mbox_istream *rstream =
Index: istream-raw-mbox.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/istream-raw-mbox.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- istream-raw-mbox.h 27 Apr 2004 20:25:54 -0000 1.1
+++ istream-raw-mbox.h 6 May 2004 01:22:25 -0000 1.2
@@ -10,10 +10,21 @@
to avoid actually reading through the whole message. */
uoff_t istream_raw_mbox_get_size(struct istream *stream, uoff_t body_size);
+/* Return received time of current message, or (time_t)-1 if the timestamp is
+ broken. */
+time_t istream_raw_mbox_get_received_time(struct istream *stream);
+
+/* Return sender of current message. */
+const char *istream_raw_mbox_get_sender(struct istream *stream);
+
/* Jump to next message. If body_size isn't (uoff_t)-1, we'll use it as
potentially valid body size. */
void istream_raw_mbox_next(struct istream *stream, uoff_t body_size);
+/* Seek to message at given offset. offset must point to beginning of
+ "\nFrom ", or 0 for beginning of file. */
+void istream_raw_mbox_seek(struct istream *stream, uoff_t offset);
+
/* Flush all buffering. Call if you modify the mbox. */
void istream_raw_mbox_flush(struct istream *stream);
Index: mbox-from.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-from.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mbox-from.c 27 Apr 2004 20:25:54 -0000 1.1
+++ mbox-from.c 6 May 2004 01:22:25 -0000 1.2
@@ -17,22 +17,28 @@
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
-time_t mbox_from_parse_date(const unsigned char *msg, size_t size)
+int mbox_from_parse(const unsigned char *msg, size_t size,
+ time_t *time_r, char **sender_r)
{
- const unsigned char *msg_end;
+ const unsigned char *msg_start, *sender_end, *msg_end;
struct tm tm;
int i, timezone;
time_t t;
+ *time_r = (time_t)-1;
+ *sender_r = NULL;
+
/* <sender> <date> <moreinfo> */
+ msg_start = msg;
msg_end = msg + size;
- /* skip sender */
+ /* get sender */
while (msg < msg_end && *msg != ' ') {
if (*msg == '\r' || *msg == '\n')
- return (time_t)-1;
+ return -1;
msg++;
}
+ sender_end = msg;
while (msg < msg_end && *msg == ' ') msg++;
/* next 24 chars should be in the date in asctime() format, eg.
@@ -43,7 +49,7 @@
"Thu Nov 29 22:33:52 EEST 2001"
*/
if (msg+24 > msg_end)
- return (time_t)-1;
+ return -1;
memset(&tm, 0, sizeof(tm));
@@ -64,17 +70,17 @@
}
if (i == 12 || msg[3] != ' ')
- return (time_t)-1;
+ return -1;
msg += 4;
/* day */
if (msg[0] == ' ') {
if (!i_isdigit(msg[1]) || msg[2] != ' ')
- return (time_t)-1;
+ return -1;
tm.tm_mday = msg[1]-'0';
} else {
if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ' ')
- return (time_t)-1;
+ return -1;
tm.tm_mday = (msg[0]-'0') * 10 + (msg[1]-'0');
}
if (tm.tm_mday == 0)
@@ -83,19 +89,19 @@
/* hour */
if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ':')
- return (time_t)-1;
+ return -1;
tm.tm_hour = (msg[0]-'0') * 10 + (msg[1]-'0');
msg += 3;
/* minute */
if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ':')
- return (time_t)-1;
+ return -1;
tm.tm_min = (msg[0]-'0') * 10 + (msg[1]-'0');
msg += 3;
/* second */
if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) || msg[2] != ' ')
- return (time_t)-1;
+ return -1;
tm.tm_sec = (msg[0]-'0') * 10 + (msg[1]-'0');
msg += 3;
@@ -105,18 +111,18 @@
/* skip to next space */
while (msg < msg_end && *msg != ' ') {
if (*msg == '\r' || *msg == '\n')
- return (time_t)-1;
+ return -1;
msg++;
}
if (msg+5 > msg_end)
- return (time_t)-1;
+ return -1;
msg++;
}
/* year */
if (!i_isdigit(msg[0]) || !i_isdigit(msg[1]) ||
!i_isdigit(msg[2]) || !i_isdigit(msg[3]))
- return (time_t)-1;
+ return -1;
tm.tm_year = (msg[0]-'0') * 1000 + (msg[1]-'0') * 100 +
(msg[2]-'0') * 10 + (msg[3]-'0') - 1900;
@@ -132,14 +138,17 @@
t = utc_mktime(&tm);
if (t == (time_t)-1)
- return (time_t)-1;
+ return -1;
t -= timezone * 60;
- return t;
+ *time_r = t;
} else {
/* assume local timezone */
- return mktime(&tm);
+ *time_r = mktime(&tm);
}
+
+ *sender_r = i_strdup_until(msg_start, sender_end);
+ return 0;
}
const char *mbox_from_create(const char *sender, time_t time)
Index: mbox-from.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-from.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mbox-from.h 27 Apr 2004 20:25:54 -0000 1.1
+++ mbox-from.h 6 May 2004 01:22:25 -0000 1.2
@@ -1,7 +1,8 @@
#ifndef __MBOX_FROM_H
#define __MBOX_FROM_H
-time_t mbox_from_parse_date(const unsigned char *msg, size_t size);
+int mbox_from_parse(const unsigned char *msg, size_t size,
+ time_t *time_r, char **sender_r);
const char *mbox_from_create(const char *sender, time_t time);
#endif
Index: mbox-list.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-list.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mbox-list.c 27 Apr 2004 20:25:54 -0000 1.23
+++ mbox-list.c 6 May 2004 01:22:25 -0000 1.24
@@ -1,11 +1,9 @@
/* Copyright (C) 2002-2003 Timo Sirainen */
-#if 0
#include "lib.h"
#include "unlink-directory.h"
#include "imap-match.h"
#include "subscription-file/subscription-file.h"
-#include "mbox-index.h"
#include "mbox-storage.h"
#include "home-expand.h"
@@ -27,8 +25,10 @@
char *real_path, *virtual_path;
};
-struct mailbox_list_context {
- struct mail_storage *storage;
+struct mbox_list_context {
+ struct mailbox_list_context mailbox_ctx;
+ struct index_storage *istorage;
+
enum mailbox_list_flags flags;
const char *prefix;
@@ -37,18 +37,18 @@
int failed;
- struct mailbox_list *(*next)(struct mailbox_list_context *ctx);
+ struct mailbox_list *(*next)(struct mbox_list_context *ctx);
pool_t list_pool;
struct mailbox_list list;
struct list_dir_context *dir;
};
-static struct mailbox_list *mbox_list_subs(struct mailbox_list_context *ctx);
-static struct mailbox_list *mbox_list_inbox(struct mailbox_list_context *ctx);
-static struct mailbox_list *mbox_list_path(struct mailbox_list_context *ctx);
-static struct mailbox_list *mbox_list_next(struct mailbox_list_context *ctx);
-static struct mailbox_list *mbox_list_none(struct mailbox_list_context *ctx);
+static struct mailbox_list *mbox_list_subs(struct mbox_list_context *ctx);
+static struct mailbox_list *mbox_list_inbox(struct mbox_list_context *ctx);
+static struct mailbox_list *mbox_list_path(struct mbox_list_context *ctx);
+static struct mailbox_list *mbox_list_next(struct mbox_list_context *ctx);
+static struct mailbox_list *mbox_list_none(struct mbox_list_context *ctx);
static const char *mask_get_dir(struct mail_storage *storage, const char *mask)
{
@@ -72,7 +72,8 @@
return last_dir == NULL ? NULL : t_strdup_until(mask, last_dir);
}
-static const char *mbox_get_path(struct mail_storage *storage, const char *name)
+static const char *
+mbox_get_path(struct index_storage *storage, const char *name)
{
if (!full_filesystem_access || name == NULL ||
(*name != '/' && *name != '~' && *name != '\0'))
@@ -109,10 +110,11 @@
}
struct mailbox_list_context *
-mbox_list_mailbox_init(struct mail_storage *storage, const char *mask,
+mbox_mailbox_list_init(struct mail_storage *storage, const char *mask,
enum mailbox_list_flags flags)
{
- struct mailbox_list_context *ctx;
+ struct index_storage *istorage = (struct index_storage *)storage;
+ struct mbox_list_context *ctx;
const char *path, *virtual_path;
DIR *dirp;
@@ -120,13 +122,13 @@
if (storage->hierarchy_sep != '/' && strchr(mask, '/') != NULL) {
/* this will never match, return nothing */
- ctx = i_new(struct mailbox_list_context, 1);
- ctx->storage = storage;
+ ctx = i_new(struct mbox_list_context, 1);
+ ctx->mailbox_ctx.storage = storage;
ctx->next = mbox_list_none;
- return ctx;
+ return &ctx->mailbox_ctx;
}
- mask = mbox_fix_mailbox_name(storage, mask, FALSE);
+ mask = mbox_fix_mailbox_name(istorage, mask, FALSE);
/* check that we're not trying to do any "../../" lists */
if (!mbox_is_valid_mask(mask)) {
@@ -135,36 +137,39 @@
}
if ((flags & MAILBOX_LIST_SUBSCRIBED) != 0) {
- ctx = i_new(struct mailbox_list_context, 1);
- ctx->storage = storage;
+ ctx = i_new(struct mbox_list_context, 1);
+ ctx->mailbox_ctx.storage = storage;
+ ctx->istorage = istorage;
ctx->flags = flags;
ctx->next = mbox_list_subs;
- ctx->subsfile_ctx = subsfile_list_init(storage);
+ ctx->subsfile_ctx =
+ subsfile_list_init(storage, SUBSCRIPTION_FILE_NAME);
if (ctx->subsfile_ctx == NULL) {
i_free(ctx);
return NULL;
}
ctx->glob = imap_match_init(default_pool, mask, TRUE, '/');
ctx->list_pool = pool_alloconly_create("mbox_list", 1024);
- return ctx;
+ return &ctx->mailbox_ctx;
}
/* if we're matching only subdirectories, don't bother scanning the
parent directories */
virtual_path = mask_get_dir(storage, mask);
- path = mbox_get_path(storage, virtual_path);
+ path = mbox_get_path(istorage, virtual_path);
if (list_opendir(storage, path, TRUE, &dirp) < 0)
return NULL;
/* if user gave invalid directory, we just don't show any results. */
- ctx = i_new(struct mailbox_list_context, 1);
- ctx->storage = storage;
+ ctx = i_new(struct mbox_list_context, 1);
+ ctx->mailbox_ctx.storage = storage;
+ ctx->istorage = istorage;
ctx->flags = flags;
ctx->glob = imap_match_init(default_pool, mask, TRUE, '/');
ctx->list_pool = pool_alloconly_create("mbox_list", 1024);
ctx->prefix = storage->namespace == NULL ? "" :
- mbox_fix_mailbox_name(storage, storage->namespace, FALSE);
+ mbox_fix_mailbox_name(istorage, storage->namespace, FALSE);
if (virtual_path == NULL && imap_match(ctx->glob, "INBOX") > 0)
ctx->next = mbox_list_inbox;
@@ -180,7 +185,7 @@
ctx->dir->virtual_path = virtual_path == NULL ? NULL :
i_strconcat(ctx->prefix, virtual_path, NULL);
}
- return ctx;
+ return &ctx->mailbox_ctx;
}
static void list_dir_context_free(struct list_dir_context *dir)
@@ -191,13 +196,14 @@
i_free(dir);
}
-int mbox_list_mailbox_deinit(struct mailbox_list_context *ctx)
+int mbox_mailbox_list_deinit(struct mailbox_list_context *_ctx)
{
- int failed = ctx->failed;
+ struct mbox_list_context *ctx = (struct mbox_list_context *)_ctx;
+ int ret = ctx->failed ? -1 : 0;
if (ctx->subsfile_ctx != NULL) {
- if (!subsfile_list_deinit(ctx->subsfile_ctx))
- failed = TRUE;
+ if (subsfile_list_deinit(ctx->subsfile_ctx) < 0)
+ ret = -1;
}
while (ctx->dir != NULL) {
@@ -213,15 +219,17 @@
imap_match_deinit(ctx->glob);
i_free(ctx);
- return !failed;
+ return ret;
}
-struct mailbox_list *mbox_list_mailbox_next(struct mailbox_list_context *ctx)
+struct mailbox_list *mbox_mailbox_list_next(struct mailbox_list_context *_ctx)
{
+ struct mbox_list_context *ctx = (struct mbox_list_context *)_ctx;
+
return ctx->next(ctx);
}
-static int list_file(struct mailbox_list_context *ctx, const char *fname)
+static int list_file(struct mbox_list_context *ctx, const char *fname)
{
struct list_dir_context *dir;
const char *list_path, *real_path, *path;
@@ -260,8 +268,8 @@
else {
if (ENOTFOUND(errno))
return 0;
- mail_storage_set_critical(ctx->storage, "stat(%s) failed: %m",
- real_path);
+ mail_storage_set_critical(ctx->mailbox_ctx.storage,
+ "stat(%s) failed: %m", real_path);
return -1;
}
@@ -279,7 +287,8 @@
ctx->list.name = NULL;
ret = match2 < 0 ? 0 :
- list_opendir(ctx->storage, real_path, FALSE, &dirp);
+ list_opendir(ctx->mailbox_ctx.storage,
+ real_path, FALSE, &dirp);
if (ret > 0) {
dir = i_new(struct list_dir_context, 1);
dir->dirp = dirp;
@@ -292,7 +301,7 @@
return -1;
return match > 0 || match2 > 0;
} else if (match > 0 &&
- strcmp(real_path, ctx->storage->inbox_file) != 0 &&
+ strcmp(real_path, ctx->istorage->inbox_path) != 0 &&
strcasecmp(list_path, "INBOX") != 0) {
/* don't match any INBOX here, it's added separately.
we might also have ~/mail/inbox, ~/mail/Inbox etc.
@@ -306,7 +315,7 @@
return 0;
}
-static struct mailbox_list *list_fix_name(struct mailbox_list_context *ctx)
+static struct mailbox_list *list_fix_name(struct mbox_list_context *ctx)
{
char *p, *str, sep;
@@ -314,7 +323,7 @@
str = p_strdup(ctx->list_pool, ctx->list.name);
ctx->list.name = str;
- sep = ctx->storage->hierarchy_sep;
+ sep = ctx->mailbox_ctx.storage->hierarchy_sep;
for (p = str; *p != '\0'; p++) {
if (*p == '/')
*p = sep;
@@ -324,7 +333,7 @@
return &ctx->list;
}
-static struct mailbox_list *mbox_list_subs(struct mailbox_list_context *ctx)
+static struct mailbox_list *mbox_list_subs(struct mbox_list_context *ctx)
{
struct stat st;
const char *name, *path, *p;
@@ -361,8 +370,8 @@
return &ctx->list;
t_push();
- name = mbox_fix_mailbox_name(ctx->storage, ctx->list.name, TRUE);
- path = mbox_get_path(ctx->storage, name);
+ name = mbox_fix_mailbox_name(ctx->istorage, ctx->list.name, TRUE);
+ path = mbox_get_path(ctx->istorage, name);
if (stat(path, &st) == 0) {
if (S_ISDIR(st.st_mode))
ctx->list.flags = MAILBOX_NOSELECT | MAILBOX_CHILDREN;
@@ -380,7 +389,7 @@
return &ctx->list;
}
-static struct mailbox_list *mbox_list_inbox(struct mailbox_list_context *ctx)
+static struct mailbox_list *mbox_list_inbox(struct mbox_list_context *ctx)
{
struct stat st;
@@ -393,7 +402,7 @@
ctx->list.flags = strncmp(ctx->prefix, "INBOX/", 6) == 0 ?
MAILBOX_CHILDREN : MAILBOX_NOINFERIORS;
if ((ctx->flags & MAILBOX_LIST_FAST_FLAGS) == 0) {
- if (stat(ctx->storage->inbox_file, &st) < 0)
+ if (stat(ctx->istorage->inbox_path, &st) < 0)
ctx->list.flags |= MAILBOX_UNMARKED;
else
ctx->list.flags |= STAT_GET_MARKED(st);
@@ -403,7 +412,7 @@
return &ctx->list;
}
-static struct mailbox_list *mbox_list_path(struct mailbox_list_context *ctx)
+static struct mailbox_list *mbox_list_path(struct mbox_list_context *ctx)
{
ctx->next = mbox_list_next;
@@ -417,7 +426,7 @@
return ctx->next(ctx);
}
-static struct mailbox_list *mbox_list_next(struct mailbox_list_context *ctx)
+static struct mailbox_list *mbox_list_next(struct mbox_list_context *ctx)
{
struct list_dir_context *dir;
struct dirent *d;
@@ -450,8 +459,7 @@
}
static struct mailbox_list *
-mbox_list_none(struct mailbox_list_context *ctx __attr_unused__)
+mbox_list_none(struct mbox_list_context *ctx __attr_unused__)
{
return NULL;
}
-#endif
Index: mbox-save.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-save.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- mbox-save.c 2 May 2004 20:32:16 -0000 1.47
+++ mbox-save.c 6 May 2004 01:22:25 -0000 1.48
@@ -1,14 +1,14 @@
/* Copyright (C) 2002 Timo Sirainen */
-#if 0
#include "lib.h"
#include "hostpid.h"
#include "ostream.h"
#include "str.h"
#include "write-full.h"
-#include "mbox-index.h"
-#include "mbox-lock.h"
#include "mbox-storage.h"
+#include "mbox-file.h"
+#include "mbox-from.h"
+#include "mbox-lock.h"
#include "mail-save.h"
#include <stdlib.h>
@@ -17,9 +17,9 @@
#include <sys/stat.h>
#include <netdb.h>
-struct mail_save_context {
+struct mbox_save_context {
struct index_mailbox *ibox;
- int transaction;
+ uoff_t append_offset;
struct ostream *output;
uoff_t sync_offset, content_length_offset, eoh_offset;
@@ -29,45 +29,37 @@
static char my_hostdomain[256] = "";
-static int syscall_error(struct mail_save_context *ctx, const char *function)
-{
- mail_storage_set_critical(ctx->ibox->box.storage,
- "%s failed for mbox file %s: %m",
- function, ctx->ibox->index->mailbox_path);
- return FALSE;
-}
-
-static int write_error(struct mail_save_context *ctx)
+static int write_error(struct mbox_save_context *ctx)
{
if (ENOSPACE(errno)) {
mail_storage_set_error(ctx->ibox->box.storage,
"Not enough disk space");
} else {
- syscall_error(ctx, "write()");
+ mbox_set_syscall_error(ctx->ibox, "write()");
}
- return FALSE;
+ return -1;
}
-static int mbox_seek_to_end(struct mail_save_context *ctx, uoff_t *offset)
+static int mbox_seek_to_end(struct mbox_save_context *ctx, uoff_t *offset)
{
struct stat st;
char ch;
int fd;
- fd = ctx->ibox->index->mbox_fd;
+ fd = ctx->ibox->mbox_fd;
if (fstat(fd, &st) < 0)
- return syscall_error(ctx, "fstat()");
+ return mbox_set_syscall_error(ctx->ibox, "fstat()");
*offset = (uoff_t)st.st_size;
if (st.st_size == 0)
- return TRUE;
+ return 0;
if (lseek(fd, st.st_size-1, SEEK_SET) < 0)
- return syscall_error(ctx, "lseek()");
+ return mbox_set_syscall_error(ctx->ibox, "lseek()");
if (read(fd, &ch, 1) != 1)
- return syscall_error(ctx, "read()");
+ return mbox_set_syscall_error(ctx->ibox, "read()");
if (ch != '\n') {
if (write_full(fd, "\n", 1) < 0)
@@ -75,10 +67,10 @@
*offset += 1;
}
- return TRUE;
+ return 0;
}
-static int mbox_append_lf(struct mail_save_context *ctx)
+static int mbox_append_lf(struct mbox_save_context *ctx)
{
if (o_stream_send(ctx->output, "\n", 1) < 0)
return write_error(ctx);
@@ -86,9 +78,10 @@
return TRUE;
}
-static int write_from_line(struct mail_save_context *ctx, time_t received_date)
+static int write_from_line(struct mbox_save_context *ctx, time_t received_date,
+ const char *from_envelope)
{
- const char *sender, *line, *name;
+ const char *line, *name;
if (*my_hostdomain == '\0') {
struct hostent *hent;
@@ -104,16 +97,18 @@
strocpy(my_hostdomain, name, sizeof(my_hostdomain));
}
- sender = t_strconcat(ctx->ibox->box.storage->user, "@",
- my_hostdomain, NULL);
+ if (from_envelope == NULL) {
+ from_envelope = t_strconcat(ctx->ibox->storage->user, "@",
+ my_hostdomain, NULL);
+ }
/* save in local timezone, no matter what it was given with */
- line = mbox_from_create(sender, received_date);
+ line = mbox_from_create(from_envelope, received_date);
if (o_stream_send_str(ctx->output, line) < 0)
return write_error(ctx);
- return TRUE;
+ return 0;
}
static const char *get_system_flags(enum mail_flags flags)
@@ -147,25 +142,17 @@
static const char *get_keywords(const struct mail_full_flags *flags)
{
string_t *str;
- unsigned int field;
unsigned int i;
- if ((flags->flags & MAIL_KEYWORDS_MASK) == 0)
+ if (flags->keywords_count == 0)
return "";
str = t_str_new(256);
- field = 1 << MAIL_KEYWORD_1_BIT;
for (i = 0; i < flags->keywords_count; i++) {
- const char *keyword = flags->keywords[i];
-
- if ((flags->flags & field) && keyword != NULL) {
+ if (str_len(str) > 0)
str_append_c(str, ' ');
- str_append(str, keyword);
- }
-
- field <<= 1;
+ str_append(str, flags->keywords[i]);
}
-
return str_c(str);
}
@@ -173,7 +160,7 @@
void *context)
{
static const char *content_length = "Content-Length: ";
- struct mail_save_context *ctx = context;
+ struct mbox_save_context *ctx = context;
const char *str;
char *buf;
size_t space;
@@ -238,7 +225,7 @@
return 1;
}
-static int mbox_fix_header(struct mail_save_context *ctx)
+static int mbox_fix_header(struct mbox_save_context *ctx)
{
uoff_t old_offset;
const char *str;
@@ -246,7 +233,7 @@
old_offset = ctx->output->offset;
if (o_stream_seek(ctx->output, ctx->content_length_offset) < 0)
- return syscall_error(ctx, "o_stream_seek()");
+ return mbox_set_syscall_error(ctx->ibox, "o_stream_seek()");
/* write value for Content-Length */
str = dec2str(old_offset - (ctx->eoh_offset + 1 + crlf));
@@ -264,112 +251,102 @@
return write_error(ctx);
if (o_stream_seek(ctx->output, old_offset) < 0)
- return syscall_error(ctx, "o_stream_seek()");
- return TRUE;
+ return mbox_set_syscall_error(ctx->ibox, "o_stream_seek()");
+ return 0;
}
-int mbox_storage_save_next(struct mail_save_context *ctx,
- const struct mail_full_flags *flags,
- time_t received_date,
- int timezone_offset __attr_unused__,
- struct istream *data)
+int mbox_save(struct mailbox_transaction_context *_t,
+ const struct mail_full_flags *flags,
+ time_t received_date, int timezone_offset __attr_unused__,
+ const char *from_envelope, struct istream *data)
{
- enum mail_flags real_flags;
- int failed;
+ struct mbox_transaction_context *t =
+ (struct mbox_transaction_context *)_t;
+ struct index_mailbox *ibox = t->ictx.ibox;
+ struct mbox_save_context *ctx = t->save_ctx;
+ int ret;
- /* we don't need the real flag positions, easier to keep using our own.
- they need to be checked/added though. */
ctx->flags = flags;
- real_flags = flags->flags;
- if (!index_mailbox_fix_keywords(ctx->ibox, &real_flags,
- flags->keywords,
- flags->keywords_count))
- return FALSE;
- t_push();
- if (!write_from_line(ctx, received_date) ||
- !mail_storage_save(ctx->ibox->box.storage,
- ctx->ibox->index->mailbox_path,
- data, ctx->output,
- getenv("MAIL_SAVE_CRLF") != NULL,
- save_header_callback, ctx) ||
- !mbox_fix_header(ctx) ||
- !mbox_append_lf(ctx)) {
- /* failed, truncate file back to original size.
- output stream needs to be flushed before truncating
- so unref() won't write anything. */
- o_stream_flush(ctx->output);
- if (ctx->sync_offset != (uoff_t)-1) {
- (void)ftruncate(ctx->ibox->index->mbox_fd,
- ctx->sync_offset);
- ctx->sync_offset = (uoff_t)-1;
+ if (ctx == NULL) {
+ ctx = t->save_ctx = i_new(struct mbox_save_context, 1);
+ ctx->ibox = ibox;
+ ctx->append_offset = (uoff_t)-1;
+ }
+
+ if (ctx->append_offset == (uoff_t)-1) {
+ if (ibox->mbox_lock_type != F_WRLCK) {
+ if (mbox_lock(ibox, F_WRLCK, &t->mbox_lock_id) <= 0)
+ return -1;
}
- failed = TRUE;
+
+ if (ibox->mbox_fd == -1) {
+ if (mbox_file_open(ibox) < 0)
+ return -1;
+ }
+
+ if (mbox_seek_to_end(ctx, &ctx->append_offset) < 0)
+ return -1;
+
+ ctx->output = o_stream_create_file(ibox->mbox_fd, default_pool,
+ 4096, FALSE);
+ o_stream_set_blocking(ctx->output, 60000, NULL, NULL);
+ }
+
+ i_assert(ibox->mbox_lock_type == F_WRLCK);
+
+ t_push();
+ if (write_from_line(ctx, received_date, from_envelope) < 0 ||
+ mail_storage_save(ibox->box.storage, ibox->path, data, ctx->output,
+ getenv("MAIL_SAVE_CRLF") != NULL,
+ save_header_callback, ctx) < 0 ||
+ mbox_fix_header(ctx) < 0 ||
+ mbox_append_lf(ctx) < 0) {
+ ret = -1;
} else {
- if (!ctx->transaction)
- ctx->sync_offset = ctx->output->offset;
- failed = FALSE;
+ ret = 0;
}
t_pop();
-
- return !failed;
+ return ret;
}
-struct mail_save_context *
-mbox_storage_save_init(struct mailbox *box, int transaction)
+static void mbox_save_deinit(struct mbox_save_context *ctx)
{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
- struct mail_save_context *ctx;
-
- if (box->is_readonly(box)) {
- mail_storage_set_error(box->storage, "Mailbox is read-only");
- return NULL;
- }
-
- if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
- MAIL_LOCK_EXCLUSIVE))
- return NULL;
+ if (ctx->output != NULL)
+ o_stream_unref(ctx->output);
+ i_free(ctx);
+}
- ctx = i_new(struct mail_save_context, 1);
- ctx->ibox = ibox;
- ctx->transaction = transaction;
+int mbox_save_commit(struct mbox_save_context *ctx)
+{
+ int ret = 0;
- if (!mbox_seek_to_end(ctx, &ctx->sync_offset)) {
- i_free(ctx);
- return NULL;
+ if (ctx->ibox->mbox_fd != -1) {
+ if (fdatasync(ctx->ibox->mbox_fd) < 0) {
+ mbox_set_syscall_error(ctx->ibox, "fsync()");
+ ret = -1;
+ }
}
- ctx->output = o_stream_create_file(ibox->index->mbox_fd,
- default_pool, 4096, FALSE);
- o_stream_set_blocking(ctx->output, 60000, NULL, NULL);
- return ctx;
+ mbox_save_deinit(ctx);
+ return ret;
}
-int mbox_storage_save_deinit(struct mail_save_context *ctx, int rollback)
+void mbox_save_rollback(struct mbox_save_context *ctx)
{
- int failed = FALSE;
+ struct index_mailbox *ibox = ctx->ibox;
- if (!index_storage_lock(ctx->ibox, MAIL_LOCK_UNLOCK))
- failed = TRUE;
+ if (ctx->append_offset != (uoff_t)-1 && ibox->mbox_fd != -1) {
+ i_assert(ibox->mbox_lock_type == F_WRLCK);
- if (o_stream_flush(ctx->output) < 0)
- failed = TRUE;
- o_stream_unref(ctx->output);
+ /* failed, truncate file back to original size.
+ output stream needs to be flushed before truncating
+ so unref() won't write anything. */
+ o_stream_flush(ctx->output);
- if (rollback && ctx->sync_offset != (uoff_t)-1) {
- if (ftruncate(ctx->ibox->index->mbox_fd,
- ctx->sync_offset) < 0) {
- syscall_error(ctx, "ftruncate()");
- failed = TRUE;
- }
- } else {
- if (fdatasync(ctx->ibox->index->mbox_fd) < 0) {
- syscall_error(ctx, "fsync()");
- failed = TRUE;
- }
+ if (ftruncate(ibox->mbox_fd, (off_t)ctx->append_offset) < 0)
+ mbox_set_syscall_error(ibox, "ftruncate()");
}
- i_free(ctx);
- return !failed;
+ mbox_save_deinit(ctx);
}
-#endif
Index: mbox-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-storage.c,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- mbox-storage.c 2 May 2004 20:32:16 -0000 1.73
+++ mbox-storage.c 6 May 2004 01:22:25 -0000 1.74
@@ -1,14 +1,14 @@
/* Copyright (C) 2002-2003 Timo Sirainen */
#include "lib.h"
+#include "buffer.h"
#include "home-expand.h"
#include "mkdir-parents.h"
#include "unlink-directory.h"
#include "subscription-file/subscription-file.h"
-#include "mail-keywords.h"
-#include "mbox-index.h"
-#include "mbox-lock.h"
#include "mbox-storage.h"
+#include "mbox-lock.h"
+#include "mail-save.h"
#include <stdio.h>
#include <stdlib.h>
@@ -21,8 +21,19 @@
extern struct mail_storage mbox_storage;
extern struct mailbox mbox_mailbox;
-static int mbox_handle_errors(struct mail_storage *storage)
+int mbox_set_syscall_error(struct index_mailbox *ibox, const char *function)
+{
+ i_assert(function != NULL);
+
+ mail_storage_set_critical(ibox->box.storage,
+ "%s failed with mbox file %s: %m", function, ibox->path);
+ return -1;
+}
+
+static int mbox_handle_errors(struct index_storage *istorage)
{
+ struct mail_storage *storage = &istorage->storage;
+
if (ENOACCESS(errno))
mail_storage_set_error(storage, "Permission denied");
else if (ENOSPACE(errno))
@@ -130,7 +141,7 @@
mbox_create(const char *data, const char *user,
const char *namespace, char hierarchy_sep)
{
- struct mail_storage *storage;
+ struct index_storage *storage;
const char *root_dir, *inbox_file, *index_dir, *p;
struct stat st;
int autodetect;
@@ -191,39 +202,40 @@
else if (strcmp(index_dir, "MEMORY") == 0)
index_dir = NULL;
- storage = i_new(struct mail_storage, 1);
- memcpy(storage, &mbox_storage, sizeof(struct mail_storage));
+ storage = i_new(struct index_storage, 1);
+ storage->storage = mbox_storage;
if (hierarchy_sep != '\0')
- storage->hierarchy_sep = hierarchy_sep;
- storage->namespace = i_strdup(namespace);
+ storage->storage.hierarchy_sep = hierarchy_sep;
+ storage->storage.namespace = i_strdup(namespace);
storage->dir = i_strdup(home_expand(root_dir));
- storage->inbox_file = i_strdup(home_expand(inbox_file));
+ storage->inbox_path = i_strdup(home_expand(inbox_file));
storage->index_dir = i_strdup(home_expand(index_dir));
storage->user = i_strdup(user);
storage->callbacks = i_new(struct mail_storage_callbacks, 1);
index_storage_init(storage);
- return storage;
+ return &storage->storage;
}
-static void mbox_free(struct mail_storage *storage)
+static void mbox_free(struct mail_storage *_storage)
{
+ struct index_storage *storage = (struct index_storage *)_storage;
+
index_storage_deinit(storage);
- i_free(storage->namespace);
i_free(storage->dir);
- i_free(storage->inbox_file);
+ i_free(storage->inbox_path);
i_free(storage->index_dir);
i_free(storage->user);
- i_free(storage->error);
i_free(storage->callbacks);
i_free(storage);
}
-const char *mbox_fix_mailbox_name(struct mail_storage *storage,
+const char *mbox_fix_mailbox_name(struct index_storage *istorage,
const char *name, int remove_namespace)
{
+ struct mail_storage *storage = &istorage->storage;
char *dup, *p, sep;
size_t len;
@@ -304,7 +316,7 @@
return mbox_is_valid_mask(name);
}
-static const char *mbox_get_index_dir(struct mail_storage *storage,
+static const char *mbox_get_index_dir(struct index_storage *storage,
const char *name)
{
const char *p;
@@ -329,56 +341,58 @@
}
}
-static int create_mbox_index_dirs(struct mail_storage *storage,
+static int create_mbox_index_dirs(struct index_storage *storage,
const char *name)
{
const char *index_dir;
index_dir = mbox_get_index_dir(storage, name);
if (index_dir == NULL)
- return TRUE;
+ return 0;
if (mkdir_parents(index_dir, CREATE_MODE) < 0) {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(&storage->storage,
"mkdir_parents(%s) failed: %m", index_dir);
- return FALSE;
+ return -1;
}
- return TRUE;
+ return 0;
}
-static int verify_inbox(struct mail_storage *storage)
+static int verify_inbox(struct index_storage *storage)
{
int fd;
/* make sure inbox file itself exists */
- fd = open(storage->inbox_file, O_RDWR | O_CREAT | O_EXCL, 0660);
+ fd = open(storage->inbox_path, O_RDWR | O_CREAT | O_EXCL, 0660);
if (fd != -1)
(void)close(fd);
/* make sure the index directories exist */
- if (!create_mbox_index_dirs(storage, "INBOX"))
- return FALSE;
+ if (create_mbox_index_dirs(storage, "INBOX") < 0)
+ return -1;
- return TRUE;
+ return 0;
}
-static const char *mbox_get_path(struct mail_storage *storage, const char *name)
+static const char *
+mbox_get_path(struct index_storage *storage, const char *name)
{
if (strcasecmp(name, "INBOX") == 0)
- return storage->inbox_file;
+ return storage->inbox_path;
if (full_filesystem_access && (*name == '/' || *name == '~'))
return home_expand(name);
return t_strconcat(storage->dir, "/", name, NULL);
}
-static void mbox_mail_init(struct index_mail *mail)
+static uint32_t mbox_get_recent_count(struct index_mailbox *ibox)
{
- mail->mail.expunge = mbox_storage_expunge;
+ return 0; // FIXME
}
-static struct mailbox *mbox_open(struct mail_storage *storage, const char *name,
- enum mailbox_open_flags flags)
+static struct mailbox *
+mbox_open(struct index_storage *storage, const char *name,
+ enum mailbox_open_flags flags)
{
struct index_mailbox *ibox;
struct mail_index *index;
@@ -388,7 +402,7 @@
/* name = "INBOX"
path = "<inbox_file>/INBOX"
index_dir = "/mail/.imap/INBOX" */
- path = storage->inbox_file;
+ path = storage->inbox_path;
index_dir = mbox_get_index_dir(storage, "INBOX");
} else {
/* name = "foo/bar"
@@ -398,99 +412,105 @@
index_dir = mbox_get_index_dir(storage, name);
}
- index = index_storage_lookup_ref(index_dir, path);
- if (index == NULL) {
- index = mbox_index_alloc(path, index_dir, index_dir);
- index_storage_add(index);
- }
+ index = index_storage_alloc(index_dir, path, MBOX_INDEX_PREFIX);
+ ibox = index_storage_mailbox_init(storage, &mbox_mailbox,
+ index, name, flags);
+ if (ibox == NULL)
+ return NULL;
- ibox = index_storage_mailbox_init(storage, &mbox_mailbox, index,
- name, flags);
- if (ibox != NULL)
- ibox->mail_init = mbox_mail_init;
- return (struct mailbox *) ibox;
+ ibox->path = i_strdup(path);
+ ibox->mbox_fd = -1;
+
+ ibox->get_recent_count = mbox_get_recent_count;
+ ibox->mail_interface = &mbox_mail;
+
+ return &ibox->box;
}
static struct mailbox *
-mbox_open_mailbox(struct mail_storage *storage,
+mbox_mailbox_open(struct mail_storage *_storage,
const char *name, enum mailbox_open_flags flags)
{
+ struct index_storage *storage = (struct index_storage *)_storage;
const char *path;
struct stat st;
- mail_storage_clear_error(storage);
+ mail_storage_clear_error(_storage);
name = mbox_fix_mailbox_name(storage, name, TRUE);
/* INBOX is always case-insensitive */
if (strcasecmp(name, "INBOX") == 0) {
/* make sure inbox exists */
- if (!verify_inbox(storage))
- return FALSE;
+ if (verify_inbox(storage) < 0)
+ return NULL;
return mbox_open(storage, "INBOX", flags);
}
if (!mbox_is_valid_existing_name(name)) {
- mail_storage_set_error(storage, "Invalid mailbox name");
- return FALSE;
+ mail_storage_set_error(_storage, "Invalid mailbox name");
+ return NULL;
}
path = mbox_get_path(storage, name);
if (stat(path, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
- mail_storage_set_error(storage,
+ mail_storage_set_error(_storage,
"Mailbox isn't selectable: %s", name);
return NULL;
}
/* exists - make sure the required directories are also there */
- if (!create_mbox_index_dirs(storage, name))
+ if (create_mbox_index_dirs(storage, name) < 0)
return NULL;
return mbox_open(storage, name, flags);
}
if (ENOTFOUND(errno)) {
- mail_storage_set_error(storage, "Mailbox doesn't exist: %s",
+ mail_storage_set_error(_storage, "Mailbox doesn't exist: %s",
name);
- } else if (!mbox_handle_errors(storage))
- mail_storage_set_critical(storage, "stat(%s) failed: %m", path);
+ } else if (!mbox_handle_errors(storage)) {
+ mail_storage_set_critical(_storage, "stat(%s) failed: %m",
+ path);
+ }
return NULL;
}
-static int mbox_create_mailbox(struct mail_storage *storage, const char *name,
+static int mbox_mailbox_create(struct mail_storage *_storage, const char *name,
int directory)
{
+ struct index_storage *storage = (struct index_storage *)_storage;
const char *path, *p;
struct stat st;
int fd;
- mail_storage_clear_error(storage);
+ mail_storage_clear_error(_storage);
name = mbox_fix_mailbox_name(storage, name, TRUE);
if (!mbox_is_valid_create_name(name)) {
- mail_storage_set_error(storage, "Invalid mailbox name");
- return FALSE;
+ mail_storage_set_error(_storage, "Invalid mailbox name");
+ return -1;
}
/* make sure it doesn't exist already */
path = mbox_get_path(storage, name);
if (stat(path, &st) == 0) {
- mail_storage_set_error(storage, "Mailbox already exists");
- return FALSE;
+ mail_storage_set_error(_storage, "Mailbox already exists");
+ return -1;
}
if (errno != ENOENT && errno != ELOOP && errno != EACCES) {
if (errno == ENOTDIR) {
- mail_storage_set_error(storage,
+ mail_storage_set_error(_storage,
"Mailbox doesn't allow inferior mailboxes");
} else {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"stat() failed for mbox file %s: %m", path);
}
- return FALSE;
+ return -1;
}
/* create the hierarchy if needed */
@@ -499,16 +519,16 @@
p = t_strdup_until(path, p);
if (mkdir_parents(p, CREATE_MODE) < 0) {
if (mbox_handle_errors(storage))
- return FALSE;
+ return -1;
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"mkdir_parents(%s) failed: %m", p);
- return FALSE;
+ return -1;
}
if (directory) {
/* wanted to create only the directory */
- return TRUE;
+ return 0;
}
}
@@ -516,48 +536,49 @@
fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0660);
if (fd != -1) {
(void)close(fd);
- return TRUE;
+ return 0;
}
if (errno == EEXIST) {
/* mailbox was just created between stat() and open() call.. */
- mail_storage_set_error(storage, "Mailbox already exists");
+ mail_storage_set_error(_storage, "Mailbox already exists");
} else if (!mbox_handle_errors(storage)) {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"Can't create mailbox %s: %m", name);
}
- return FALSE;
+ return -1;
}
-static int mbox_delete_mailbox(struct mail_storage *storage, const char *name)
+static int mbox_mailbox_delete(struct mail_storage *_storage, const char *name)
{
+ struct index_storage *storage = (struct index_storage *)_storage;
const char *index_dir, *path;
struct stat st;
- mail_storage_clear_error(storage);
+ mail_storage_clear_error(_storage);
name = mbox_fix_mailbox_name(storage, name, TRUE);
if (strcasecmp(name, "INBOX") == 0) {
- mail_storage_set_error(storage, "INBOX can't be deleted.");
- return FALSE;
+ mail_storage_set_error(_storage, "INBOX can't be deleted.");
+ return -1;
}
if (!mbox_is_valid_existing_name(name)) {
- mail_storage_set_error(storage, "Invalid mailbox name");
- return FALSE;
+ mail_storage_set_error(_storage, "Invalid mailbox name");
+ return -1;
}
path = mbox_get_path(storage, name);
if (lstat(path, &st) < 0) {
if (ENOTFOUND(errno)) {
- mail_storage_set_error(storage,
+ mail_storage_set_error(_storage,
"Mailbox doesn't exist: %s", name);
} else if (!mbox_handle_errors(storage)) {
- mail_storage_set_critical(storage, "lstat() failed for "
- "%s: %m", path);
+ mail_storage_set_critical(_storage,
+ "lstat() failed for %s: %m", path);
}
- return FALSE;
+ return -1;
}
if (S_ISDIR(st.st_mode)) {
@@ -568,40 +589,40 @@
if (index_dir != NULL && rmdir(index_dir) < 0 &&
!ENOTFOUND(errno) && errno != ENOTEMPTY) {
- if (!mbox_handle_errors(storage)) {
- mail_storage_set_critical(storage,
+ if (!mbox_handle_errors(storage) < 0) {
+ mail_storage_set_critical(_storage,
"rmdir() failed for %s: %m", index_dir);
- return FALSE;
+ return -1;
}
}
if (rmdir(path) == 0)
- return TRUE;
+ return 0;
if (ENOTFOUND(errno)) {
- mail_storage_set_error(storage,
+ mail_storage_set_error(_storage,
"Mailbox doesn't exist: %s", name);
} else if (errno == ENOTEMPTY) {
- mail_storage_set_error(storage,
+ mail_storage_set_error(_storage,
"Folder %s isn't empty, can't delete it.",
name);
} else if (!mbox_handle_errors(storage)) {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"rmdir() failed for %s: %m", path);
}
- return FALSE;
+ return -1;
}
/* first unlink the mbox file */
if (unlink(path) < 0) {
if (ENOTFOUND(errno)) {
- mail_storage_set_error(storage,
+ mail_storage_set_error(_storage,
"Mailbox doesn't exist: %s", name);
} else if (!mbox_handle_errors(storage)) {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"unlink() failed for %s: %m", path);
}
- return FALSE;
+ return -1;
}
/* next delete the index directory */
@@ -610,7 +631,7 @@
index_storage_destroy_unrefed();
if (unlink_directory(index_dir, TRUE) < 0 && errno != ENOENT) {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"unlink_directory(%s) failed: %m", index_dir);
/* mailbox itself is deleted, so return success
@@ -618,24 +639,25 @@
}
}
- return TRUE;
+ return 0;
}
-static int mbox_rename_mailbox(struct mail_storage *storage,
+static int mbox_mailbox_rename(struct mail_storage *_storage,
const char *oldname, const char *newname)
{
+ struct index_storage *storage = (struct index_storage *)_storage;
const char *oldpath, *newpath, *old_indexdir, *new_indexdir, *p;
struct stat st;
- mail_storage_clear_error(storage);
+ mail_storage_clear_error(_storage);
oldname = mbox_fix_mailbox_name(storage, oldname, TRUE);
newname = mbox_fix_mailbox_name(storage, newname, TRUE);
if (!mbox_is_valid_existing_name(oldname) ||
!mbox_is_valid_create_name(newname)) {
- mail_storage_set_error(storage, "Invalid mailbox name");
- return FALSE;
+ mail_storage_set_error(_storage, "Invalid mailbox name");
+ return -1;
}
oldpath = mbox_get_path(storage, oldname);
@@ -647,11 +669,11 @@
p = t_strdup_until(newpath, p);
if (mkdir_parents(p, CREATE_MODE) < 0) {
if (mbox_handle_errors(storage))
- return FALSE;
+ return -1;
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"mkdir_parents(%s) failed: %m", p);
- return FALSE;
+ return -1;
}
}
@@ -660,26 +682,26 @@
possibility that someone actually tries to rename two mailboxes
to same new one */
if (lstat(newpath, &st) == 0) {
- mail_storage_set_error(storage,
+ mail_storage_set_error(_storage,
"Target mailbox already exists");
- return FALSE;
+ return -1;
} else if (!ENOTFOUND(errno) && errno != EACCES) {
- mail_storage_set_critical(storage, "lstat(%s) failed: %m",
+ mail_storage_set_critical(_storage, "lstat(%s) failed: %m",
newpath);
- return FALSE;
+ return -1;
}
/* NOTE: renaming INBOX works just fine with us, it's simply recreated
the next time it's needed. */
if (rename(oldpath, newpath) < 0) {
if (ENOTFOUND(errno)) {
- mail_storage_set_error(storage,
+ mail_storage_set_error(_storage,
"Mailbox doesn't exist: %s", oldname);
} else if (!mbox_handle_errors(storage)) {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"rename(%s, %s) failed: %m", oldpath, newpath);
}
- return FALSE;
+ return -1;
}
/* we need to rename the index directory as well */
@@ -688,85 +710,82 @@
if (old_indexdir != NULL) {
if (rename(old_indexdir, new_indexdir) < 0 &&
errno != ENOENT) {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(_storage,
"rename(%s, %s) failed: %m",
old_indexdir, new_indexdir);
}
}
- return TRUE;
+ return 0;
}
-static int mbox_set_subscribed(struct mail_storage *storage,
+static int mbox_set_subscribed(struct mail_storage *_storage,
const char *name, int set)
{
+ struct index_storage *storage = (struct index_storage *)_storage;
+ const char *path;
+
+ path = t_strconcat(storage->dir, "/" SUBSCRIPTION_FILE_NAME, NULL);
name = mbox_fix_mailbox_name(storage, name, FALSE);
- return subsfile_set_subscribed(storage, name, set);
+ return subsfile_set_subscribed(_storage, path, name, set);
}
-static int mbox_get_mailbox_name_status(struct mail_storage *storage,
+static int mbox_get_mailbox_name_status(struct mail_storage *_storage,
const char *name,
enum mailbox_name_status *status)
{
+ struct index_storage *storage = (struct index_storage *)_storage;
struct stat st;
const char *path;
- mail_storage_clear_error(storage);
+ mail_storage_clear_error(_storage);
name = mbox_fix_mailbox_name(storage, name, TRUE);
if (!mbox_is_valid_existing_name(name)) {
*status = MAILBOX_NAME_INVALID;
- return TRUE;
+ return 0;
}
path = mbox_get_path(storage, name);
if (stat(path, &st) == 0) {
*status = MAILBOX_NAME_EXISTS;
- return TRUE;
+ return 0;
}
if (!mbox_is_valid_create_name(name)) {
*status = MAILBOX_NAME_INVALID;
- return TRUE;
+ return 0;
}
if (ENOTFOUND(errno) || errno == EACCES) {
*status = MAILBOX_NAME_VALID;
- return TRUE;
+ return 0;
} else if (errno == ENOTDIR) {
*status = MAILBOX_NAME_NOINFERIORS;
- return TRUE;
+ return 0;
} else {
- mail_storage_set_critical(storage, "mailbox name status: "
+ mail_storage_set_critical(_storage, "mailbox name status: "
"stat(%s) failed: %m", path);
- return FALSE;
+ return -1;
}
}
static int mbox_storage_close(struct mailbox *box)
{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
- int failed = FALSE;
-
- /* update flags by rewrite mbox file */
- index_storage_init_lock_notify(ibox);
- if (!ibox->index->mailbox_readonly) {
- if (!mbox_index_rewrite(ibox->index)) {
- mail_storage_set_index_error(ibox);
- failed = TRUE;
- }
- }
- ibox->index->set_lock_notify_callback(ibox->index, NULL, NULL);
+ struct index_mailbox *ibox = (struct index_mailbox *)box;
- return index_storage_mailbox_free(box) && !failed;
+ if (ibox->mbox_data_buf != NULL)
+ buffer_free(ibox->mbox_data_buf);
+ index_storage_mailbox_free(box);
+ return 0;
}
static void mbox_storage_auto_sync(struct mailbox *box,
enum mailbox_sync_flags flags,
unsigned int min_newmail_notify_interval)
{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
+ struct index_mailbox *ibox = (struct index_mailbox *)box;
ibox->min_newmail_notify_interval = min_newmail_notify_interval;
@@ -780,40 +799,7 @@
if (flags == 0)
index_mailbox_check_remove_all(ibox);
else
- index_mailbox_check_add(ibox, ibox->index->mailbox_path, FALSE);
-}
-
-static int mbox_storage_lock(struct mailbox *box,
- enum mailbox_lock_type lock_type)
-{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
-
- if (lock_type == MAIL_LOCK_UNLOCK) {
- ibox->lock_type = MAIL_LOCK_UNLOCK;
- if (!index_storage_lock(ibox, MAIL_LOCK_UNLOCK))
- return FALSE;
- return TRUE;
- }
-
- i_assert(ibox->lock_type == MAIL_LOCK_UNLOCK);
-
- if ((lock_type & (MAILBOX_LOCK_EXPUNGE | MAILBOX_LOCK_FLAGS)) != 0) {
- if (!index_storage_lock(ibox, MAIL_LOCK_EXCLUSIVE))
- return FALSE;
- } else if ((lock_type & MAILBOX_LOCK_READ) != 0) {
- if (!index_storage_lock(ibox, MAIL_LOCK_SHARED))
- return FALSE;
- }
-
- if ((lock_type & (MAILBOX_LOCK_EXPUNGE | MAILBOX_LOCK_SAVE)) != 0) {
- /* FIXME: saving doesn't have to sync it, just lock it */
- if (!index_storage_sync_and_lock(ibox, FALSE, TRUE,
- MAIL_LOCK_EXCLUSIVE))
- return FALSE;
- }
-
- ibox->lock_type = lock_type;
- return TRUE;
+ index_mailbox_check_add(ibox, ibox->path, FALSE);
}
struct mail_storage mbox_storage = {
@@ -826,24 +812,18 @@
mbox_free,
mbox_autodetect,
index_storage_set_callbacks,
- mbox_open_mailbox,
- mbox_create_mailbox,
- mbox_delete_mailbox,
- mbox_rename_mailbox,
- mbox_list_mailbox_init,
- mbox_list_mailbox_deinit,
- mbox_list_mailbox_next,
+ mbox_mailbox_open,
+ mbox_mailbox_create,
+ mbox_mailbox_delete,
+ mbox_mailbox_rename,
+ mbox_mailbox_list_init,
+ mbox_mailbox_list_next,
+ mbox_mailbox_list_deinit,
mbox_set_subscribed,
mbox_get_mailbox_name_status,
mail_storage_get_last_error,
NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, NULL, NULL,
-
0
};
@@ -854,24 +834,19 @@
index_storage_is_readonly,
index_storage_allow_new_keywords,
mbox_storage_close,
- mbox_storage_lock,
index_storage_get_status,
- index_storage_sync,
+ mbox_storage_sync,
mbox_storage_auto_sync,
- index_storage_fetch_uid,
- index_storage_fetch_seq,
+ mbox_transaction_begin,
+ mbox_transaction_commit,
+ mbox_transaction_rollback,
+ index_storage_fetch,
+ index_storage_get_uids,
index_storage_search_get_sorting,
index_storage_search_init,
index_storage_search_deinit,
index_storage_search_next,
- mbox_storage_save_init,
- mbox_storage_save_deinit,
- mbox_storage_save_next,
- index_storage_copy_init,
- index_storage_copy_deinit,
- index_storage_copy,
- mbox_storage_expunge_init,
- mbox_storage_expunge_deinit,
- mbox_storage_expunge_fetch_next,
- index_storage_is_inconsistency_error
+ mbox_save,
+ mail_storage_copy,
+ index_storage_is_inconsistent
};
Index: mbox-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-storage.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- mbox-storage.h 27 Jul 2003 03:12:13 -0000 1.18
+++ mbox-storage.h 6 May 2004 01:22:25 -0000 1.19
@@ -1,34 +1,46 @@
#ifndef __MBOX_STORAGE_H
#define __MBOX_STORAGE_H
+/* Extra space to leave in X-Keywords header when rewriting mbox */
+#define MBOX_HEADER_EXTRA_SPACE 100
+
+#define SUBSCRIPTION_FILE_NAME "subscriptions"
+#define MBOX_INDEX_PREFIX "dovecot.index"
+
#include "index-storage.h"
-int mbox_storage_copy(struct mailbox *box, struct mailbox *destbox,
- const char *messageset, int uidset);
+struct mbox_transaction_context {
+ struct index_transaction_context ictx;
-struct mail_save_context *
-mbox_storage_save_init(struct mailbox *box, int transaction);
-int mbox_storage_save_deinit(struct mail_save_context *ctx, int rollback);
-int mbox_storage_save_next(struct mail_save_context *ctx,
- const struct mail_full_flags *flags,
- time_t received_date, int timezone_offset,
- struct istream *data);
+ struct mbox_save_context *save_ctx;
+ unsigned int mbox_lock_id;
+};
+
+extern struct mail mbox_mail;
+
+int mbox_set_syscall_error(struct index_mailbox *ibox, const char *function);
struct mailbox_list_context *
-mbox_list_mailbox_init(struct mail_storage *storage, const char *mask,
+mbox_mailbox_list_init(struct mail_storage *storage, const char *mask,
enum mailbox_list_flags flags);
-int mbox_list_mailbox_deinit(struct mailbox_list_context *ctx);
-struct mailbox_list *mbox_list_mailbox_next(struct mailbox_list_context *ctx);
+int mbox_mailbox_list_deinit(struct mailbox_list_context *ctx);
+struct mailbox_list *mbox_mailbox_list_next(struct mailbox_list_context *ctx);
-struct mail_expunge_context *
-mbox_storage_expunge_init(struct mailbox *box,
- enum mail_fetch_field wanted_fields, int expunge_all);
-int mbox_storage_expunge_deinit(struct mail_expunge_context *ctx);
-struct mail *mbox_storage_expunge_fetch_next(struct mail_expunge_context *ctx);
-int mbox_storage_expunge(struct mail *mail, struct mail_expunge_context *ctx,
- unsigned int *seq_r, int notify);
+struct mailbox_transaction_context *
+mbox_transaction_begin(struct mailbox *box, int hide);
+int mbox_transaction_commit(struct mailbox_transaction_context *t);
+void mbox_transaction_rollback(struct mailbox_transaction_context *t);
-const char *mbox_fix_mailbox_name(struct mail_storage *storage,
+int mbox_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags);
+
+int mbox_save(struct mailbox_transaction_context *t,
+ const struct mail_full_flags *flags,
+ time_t received_date, int timezone_offset,
+ const char *from_envelope, struct istream *data);
+int mbox_save_commit(struct mbox_save_context *ctx);
+void mbox_save_rollback(struct mbox_save_context *ctx);
+
+const char *mbox_fix_mailbox_name(struct index_storage *istorage,
const char *name, int remove_namespace);
int mbox_is_valid_mask(const char *mask);
Index: mbox-sync-parse.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-parse.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mbox-sync-parse.c 27 Apr 2004 20:25:54 -0000 1.1
+++ mbox-sync-parse.c 6 May 2004 01:22:25 -0000 1.2
@@ -85,27 +85,24 @@
return FALSE;
}
- t_push();
-
/* <uid validity> <last uid> */
+ t_push();
str = t_strndup(hdr->full_value, hdr->full_value_len);
ctx->base_uid_validity = strtoul(str, &end, 10);
ctx->base_uid_last = strtoul(end, &end, 10);
pos = end - str;
+ t_pop();
while (pos < hdr->full_value_len && IS_LWSP_LF(hdr->full_value[pos]))
pos++;
if (ctx->base_uid_validity == 0) {
/* broken */
- t_pop();
return FALSE;
}
- if (pos == hdr->full_value_len) {
- t_pop();
+ if (pos == hdr->full_value_len)
return TRUE;
- }
// FIXME: save keywords
Index: mbox-sync-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-private.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mbox-sync-private.h 2 May 2004 20:32:16 -0000 1.2
+++ mbox-sync-private.h 6 May 2004 01:22:25 -0000 1.3
@@ -25,7 +25,7 @@
extern struct mbox_flag_type mbox_status_flags[];
extern struct mbox_flag_type mbox_xstatus_flags[];
-struct mbox_mail {
+struct mbox_sync_mail {
uint32_t uid;
uint8_t flags;
keywords_mask_t keywords;
@@ -37,7 +37,7 @@
struct mbox_sync_mail_context {
struct mbox_sync_context *sync_ctx;
- struct mbox_mail *mail;
+ struct mbox_sync_mail *mail;
uint32_t seq;
uoff_t hdr_offset, body_offset;
@@ -55,8 +55,8 @@
};
struct mbox_sync_context {
- struct istream *file_input;
- struct istream *input;
+ struct index_mailbox *ibox;
+ struct istream *input, *file_input;
int fd;
const struct mail_index_header *hdr;
@@ -64,6 +64,7 @@
uint32_t prev_msg_uid, next_uid;
};
+int mbox_sync(struct index_mailbox *ibox, int last_commit);
void mbox_sync_parse_next_mail(struct istream *input,
struct mbox_sync_mail_context *ctx);
void mbox_sync_update_header(struct mbox_sync_mail_context *ctx,
Index: mbox-sync-rewrite.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-rewrite.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mbox-sync-rewrite.c 27 Apr 2004 20:25:54 -0000 1.1
+++ mbox-sync-rewrite.c 6 May 2004 01:22:25 -0000 1.2
@@ -19,7 +19,7 @@
i_stream_seek(sync_ctx->file_input, source);
o_stream_seek(output, dest);
- istream_raw_mbox_flush(sync_ctx->input);
+ istream_raw_mbox_flush(sync_ctx->file_input);
if (size == (uoff_t)-1) {
input = sync_ctx->file_input;
@@ -157,7 +157,7 @@
int mbox_sync_rewrite(struct mbox_sync_context *sync_ctx, buffer_t *mails_buf,
uint32_t first_seq, uint32_t last_seq, off_t extra_space)
{
- struct mbox_mail *mails;
+ struct mbox_sync_mail *mails;
size_t size;
uint32_t first_idx, last_idx, extra_per_mail;
Index: mbox-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mbox-sync.c 27 Apr 2004 20:25:54 -0000 1.1
+++ mbox-sync.c 6 May 2004 01:22:25 -0000 1.2
@@ -45,16 +45,21 @@
*/
#include "lib.h"
+#include "ioloop.h"
#include "buffer.h"
#include "istream.h"
#include "file-set-size.h"
#include "str.h"
#include "write-full.h"
#include "istream-raw-mbox.h"
+#include "mbox-storage.h"
+#include "mbox-file.h"
#include "mbox-sync-private.h"
+#include <sys/stat.h>
+
static int mbox_sync_grow_file(struct mbox_sync_context *sync_ctx,
- struct mbox_mail *mail, uoff_t body_offset,
+ struct mbox_sync_mail *mail, uoff_t body_offset,
uoff_t grow_size)
{
char spaces[1024];
@@ -112,41 +117,94 @@
return 0;
}
-int mbox_sync(struct istream *input)
+int mbox_sync(struct index_mailbox *ibox, int last_commit)
{
struct mbox_sync_context sync_ctx;
struct mbox_sync_mail_context mail_ctx;
- struct mbox_mail mail;
+ struct mbox_sync_mail mail;
+ struct mail_index_sync_ctx *index_sync_ctx;
+ struct mail_index_view *sync_view;
+ const struct mail_index_header *hdr;
+ struct istream *input;
uint32_t seq, need_space_seq;
off_t space_diff;
+ uoff_t from_offset, offset;
buffer_t *mails;
- int ret = 0;
+ string_t *header;
+ struct stat st;
+ int readonly, ret = 0;
+
+ if (last_commit) {
+ seq = ibox->commit_log_file_seq;
+ offset = ibox->commit_log_file_offset;
+ } else {
+ seq = 0;
+ offset = 0;
+ }
+
+ ret = mail_index_sync_begin(ibox->index, &index_sync_ctx, &sync_view,
+ seq, offset);
+ if (ret <= 0)
+ return ret;
+
+ if (mbox_file_open_stream(ibox) < 0)
+ return -1;
+
+ if (mail_index_get_header(sync_view, &hdr) < 0)
+ return -1;
+
+ if (ibox->mbox_data_buf == NULL) {
+ ibox->mbox_data_buf =
+ buffer_create_dynamic(default_pool, 512, (size_t)-1);
+ } else {
+ buffer_set_used_size(ibox->mbox_data_buf, 0);
+ }
+
+ readonly = TRUE; // FIXME
+
+ // FIXME: lock the file
mails = buffer_create_dynamic(default_pool, 4096, (size_t)-1);
memset(&sync_ctx, 0, sizeof(sync_ctx));
- sync_ctx.file_input = input;
- sync_ctx.input = i_stream_create_raw_mbox(default_pool, input);
- sync_ctx.fd = i_stream_get_fd(input);
- //sync_ctx.hdr = ;
+ sync_ctx.file_input = ibox->mbox_file_stream;
+ sync_ctx.input = ibox->mbox_stream;
+ sync_ctx.fd = ibox->mbox_fd;
+ sync_ctx.hdr = hdr;
input = sync_ctx.input;
+ header = str_new(default_pool, 4096);
space_diff = 0; need_space_seq = 0; seq = 1;
for (seq = 1; !input->eof; seq++) {
+ from_offset = input->v_offset;
+
memset(&mail, 0, sizeof(mail));
memset(&mail_ctx, 0, sizeof(mail_ctx));
mail_ctx.sync_ctx = &sync_ctx;
mail_ctx.mail = &mail;
mail_ctx.seq = seq;
+ mail_ctx.header = header;
mbox_sync_parse_next_mail(input, &mail_ctx);
+ if (input->v_offset == from_offset) {
+ /* this was the last mail */
+ break;
+ }
+
mail.body_size =
istream_raw_mbox_get_size(input,
mail_ctx.content_length);
buffer_append(mails, &mail, sizeof(mail));
- if (mail_ctx.need_rewrite) {
+ /* save the offset permanently with recent flag state */
+ from_offset <<= 1;
+ if ((mail.flags & MBOX_NONRECENT) != 0)
+ from_offset |= 1;
+ buffer_append(ibox->mbox_data_buf,
+ &from_offset, sizeof(from_offset));
+
+ if (mail_ctx.need_rewrite && !readonly) {
mbox_sync_update_header(&mail_ctx, NULL);
if ((ret = mbox_sync_try_rewrite(&mail_ctx)) < 0)
break;
@@ -185,83 +243,34 @@
ret = -1;
}
- i_stream_unref(input);
- return ret < 0 ? -1 : 0;
-}
-
-#if 0
-int mbox_sync(void)
-{
- struct mail_index_view *sync_view;
- struct mail_index_sync_ctx *sync_ctx;
- struct mail_index_sync_rec sync_rec;
- struct mbox_sync_context ctx;
- struct mbox_sync_mail_context mail_ctx;
- struct mbox_mail mail;
- string_t *header;
- uint32_t seq;
- unsigned int need_space_seq;
- uoff_t missing_space;
- buffer_t *mails;
- int ret;
-
- memset(&ctx, 0, sizeof(ctx));
- /*ctx.index = storage->index;
- ctx.input = storage->input;*/
- ctx.fd = i_stream_get_fd(ctx.input);
-
- header = str_new(default_pool, 4096);
-
- if (mail_index_sync_begin(ctx.index, &sync_ctx, &sync_view, 0, 0) < 0)
- return -1;
-
- ctx.hdr = mail_index_get_header(sync_view);
- ctx.next_uid = ctx.hdr->next_uid;
-
- seq = 1;
- while ((ret = mail_index_sync_next(sync_ctx, &sync_rec)) > 0) {
- while (seq < sync_rec.seq1) {
- seq++;
- }
- switch (sync_rec.type) {
- case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
- break;
- case MAIL_INDEX_SYNC_TYPE_FLAGS:
- break;
- }
+ if (fstat(ibox->mbox_fd, &st) < 0) {
+ mbox_set_syscall_error(ibox, "fstat()");
+ ret = -1;
}
- while (!ctx.input->eof) {
- memset(&mail_ctx, 0, sizeof(mail_ctx));
- mail_ctx.parent = &ctx;
- mail_ctx.header = header;
- mail_ctx.seq = seq;
+ if (ret < 0) {
+ st.st_mtime = 0;
+ st.st_size = 0;
+ }
- mail_ctx.hdr_offset = ctx.input->v_offset;
- mbox_sync_mail_parse_headers(&mail_ctx);
- mail_ctx.body_offset = ctx.input->v_offset;
- mail_ctx.body_size =
- istream_raw_mbox_get_size(ctx.input,
- mail_ctx.content_length);
+ if (mail_index_sync_end(index_sync_ctx, st.st_mtime, st.st_size) < 0)
+ ret = -1;
- mbox_sync_mail_add_missing_headers(&mail_ctx);
+ str_free(header);
+ return ret < 0 ? -1 : 0;
+}
- ret = mbox_sync_try_rewrite_headers(&mail_ctx, &missing_space);
- if (ret < 0)
- break;
- if (missing_space != 0) {
- ctx.space_diff -= missing_space;
- } else {
- ctx.space_diff += mail_ctx.extra_space;
- }
+int mbox_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
+{
+ struct index_mailbox *ibox = (struct index_mailbox *)box;
- if (ctx.first_spacy_msg_offset == 0)
- ctx.first_spacy_msg_offset = mail_ctx.hdr_offset;
+ if ((flags & MAILBOX_SYNC_FLAG_FAST) == 0 ||
+ ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) {
+ ibox->sync_last_check = ioloop_time;
- ctx.prev_msg_uid = mail_ctx.uid;
- istream_raw_mbox_next(ctx.input, mail_ctx.content_length);
+ if (mbox_sync(ibox, FALSE) < 0)
+ return -1;
}
- str_free(header);
- return 0;
+
+ return index_storage_sync(box, flags);
}
-#endif
--- mbox-expunge.c DELETED ---
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-list.c,
1.27, 1.28 maildir-mail.c, 1.2, 1.3 maildir-storage.c, 1.70,
1.71 maildir-storage.h, 1.21, 1.22 maildir-sync.c, 1.11,
1.12 maildir-uidlist.c, 1.12, 1.13 maildir-uidlist.h, 1.3, 1.4
- Next message: [dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-mail.c, 1.1,
1.2 mbox-sync.c, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list