Mercurial > dovecot > original-hg > dovecot-1.2
changeset 472:2fa0bfb65268 HEAD
Added setting mail_save_crlf. Few other settings cleanups.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 21 Oct 2002 03:09:29 +0300 |
parents | 3448c77bb3d2 |
children | cb7f34709d2d |
files | doc/configuration.txt dovecot-example.conf src/lib-index/maildir/maildir-sync.c src/lib-index/mbox/mbox-index.c src/lib-storage/index/index-save.c src/lib-storage/index/index-storage.h src/lib-storage/index/maildir/maildir-copy.c src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/mbox/mbox-save.c src/master/imap-process.c src/master/settings.c src/master/settings.h |
diffstat | 12 files changed, 137 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/configuration.txt Mon Oct 21 03:08:03 2002 +0300 +++ b/doc/configuration.txt Mon Oct 21 03:09:29 2002 +0300 @@ -82,7 +82,7 @@ sending mails. With Linux and FreeBSD Dovecot can use sendfile() syscall to send such mails. However extra CRs do increase the mail size, meaning more I/O and potentially losing the gained performance. You can enable this for -mails saved by Dovecot by setting mail_save_crs = yes. For mails saved by +mails saved by Dovecot by setting mail_save_crlf = yes. For mails saved by your mailer you'll need to do something else, not yet covered by this documentation.
--- a/dovecot-example.conf Mon Oct 21 03:08:03 2002 +0300 +++ b/dovecot-example.conf Mon Oct 21 03:09:29 2002 +0300 @@ -121,6 +121,11 @@ # needed. #mail_never_cache_fields = +# Save mails with CR+LF instead of plain LF. This makes sending those mails +# take less CPU, especially with sendfile() syscall with Linux and FreeBSD. +# But it also creates a bit more disk I/O which may just make it slower. +#mail_save_crlf = no + # Copy mail to another folders using hard links. This is much faster than # actually copying the file. Only problem with it is that if either of the # mails are modified directly both will change. This isn't a problem with
--- a/src/lib-index/maildir/maildir-sync.c Mon Oct 21 03:08:03 2002 +0300 +++ b/src/lib-index/maildir/maildir-sync.c Mon Oct 21 03:09:29 2002 +0300 @@ -230,7 +230,7 @@ /* Do we want to check changes in file contents? This slows down things as we need to do extra stat() for all files. */ - check_content_changes = getenv("CHECK_CONTENT_CHANGES") != NULL; + check_content_changes = getenv("MAILDIR_CHECK_CONTENT_CHANGES") != NULL; /* now walk through the index syncing and expunging existing mails */ failed = !maildir_index_sync_files(index, dir, files,
--- a/src/lib-index/mbox/mbox-index.c Mon Oct 21 03:08:03 2002 +0300 +++ b/src/lib-index/mbox/mbox-index.c Mon Oct 21 03:09:29 2002 +0300 @@ -484,6 +484,11 @@ const unsigned char *data; size_t size; + if (end_offset > inbuf->v_size) { + /* missing data */ + return FALSE; + } + /* don't bother parsing the whole body, just make sure it ends properly */ i_buffer_seek(inbuf, end_offset);
--- a/src/lib-storage/index/index-save.c Mon Oct 21 03:08:03 2002 +0300 +++ b/src/lib-storage/index/index-save.c Mon Oct 21 03:09:29 2002 +0300 @@ -2,78 +2,117 @@ #include "lib.h" #include "ibuffer.h" +#include "obuffer.h" #include "write-full.h" #include "index-storage.h" #include <stdlib.h> #include <unistd.h> -static int write_with_crlf(int fd, const unsigned char *data, - size_t size, int *last_cr) +static int write_with_crlf(OBuffer *outbuf, const unsigned char *data, + size_t size) { - ssize_t i, cr; + size_t i, start; - i_assert(size <= SSIZE_T_MAX); + i_assert(size > 0 && size <= SSIZE_T_MAX); - cr = *last_cr ? -1 : -2; - for (i = 0; i < (ssize_t)size; i++) { - if (data[i] == '\r') - cr = i; - else if (data[i] == '\n' && cr != i-1) { + start = 0; + for (i = 0; i < size; i++) { + if (data[i] == '\n' && (i == 0 || data[i-1] != '\r')) { /* missing CR */ - if (write_full(fd, data, (size_t)i) < 0) - return FALSE; - if (write_full(fd, "\r", 1) < 0) - return FALSE; + if (o_buffer_send(outbuf, data + start, i - start) < 0) + return -1; + if (o_buffer_send(outbuf, "\r", 1) < 0) + return -1; - /* skip the data so far. \n is left into buffer and - we'll continue from the next character. */ - data += i; - size -= i; - i = 0; cr = -2; + /* \n is written next time */ + start = i; } } - return write_full(fd, data, size) >= 0; + /* if last char is \r, leave it to buffer */ + if (data[size-1] == '\r') + size--; + + if (o_buffer_send(outbuf, data + start, size - start) < 0) + return -1; + + return size; } -int index_storage_save_into_fd(MailStorage *storage, int fd, const char *path, - IBuffer *buf, uoff_t data_size) +static int write_with_lf(OBuffer *outbuf, const unsigned char *data, + size_t size) { + size_t i, start; + + i_assert(size > 0 && size <= SSIZE_T_MAX); + + start = 0; + for (i = 0; i < size; i++) { + if (data[i] == '\n' && i > 0 && data[i-1] == '\r') { + /* \r\n - skip \r */ + if (o_buffer_send(outbuf, data + start, + i - start - 1) < 0) + return -1; + + /* \n is written next time */ + start = i; + } + } + + /* if last char is \r, leave it to buffer */ + if (data[size-1] == '\r') + size--; + + if (o_buffer_send(outbuf, data + start, size - start) < 0) + return -1; + + return size; +} + +int index_storage_save(MailStorage *storage, const char *path, + IBuffer *inbuf, OBuffer *outbuf, uoff_t data_size) +{ + int (*write_func)(OBuffer *, const unsigned char *, size_t); const unsigned char *data; size_t size; ssize_t ret; - int last_cr, failed; + int failed; - last_cr = FALSE; + write_func = getenv("MAIL_SAVE_CRLF") ? write_with_crlf : write_with_lf; failed = FALSE; while (data_size > 0) { - ret = i_buffer_read(buf); + ret = i_buffer_read(inbuf); if (ret < 0) { mail_storage_set_critical(storage, "Error reading mail: %m"); return FALSE; } - data = i_buffer_get_data(buf, &size); + data = i_buffer_get_data(inbuf, &size); if (size > data_size) size = (size_t)data_size; - data_size -= size; - if (!failed && !write_with_crlf(fd, data, size, &last_cr)) { - if (errno == ENOSPC) { - mail_storage_set_error(storage, - "Not enough disk space"); + if (!failed) { + ret = write_func(outbuf, data, size); + if (ret < 0) { + if (errno == ENOSPC) { + mail_storage_set_error(storage, + "Not enough disk space"); + } else { + mail_storage_set_critical(storage, + "write_full() failed for file " + "%s: %m", path); + } + failed = TRUE; } else { - mail_storage_set_critical(storage, - "write() failed for " - "file %s: %m", path); + size = ret; } - failed = TRUE; } - i_buffer_skip(buf, size); + data_size -= size; + i_buffer_skip(inbuf, size); } return !failed;
--- a/src/lib-storage/index/index-storage.h Mon Oct 21 03:08:03 2002 +0300 +++ b/src/lib-storage/index/index-storage.h Mon Oct 21 03:09:29 2002 +0300 @@ -50,8 +50,8 @@ int index_expunge_mail(IndexMailbox *ibox, MailIndexRecord *rec, unsigned int seq, int notify); -int index_storage_save_into_fd(MailStorage *storage, int fd, const char *path, - IBuffer *buf, uoff_t data_size); +int index_storage_save(MailStorage *storage, const char *path, + IBuffer *inbuf, OBuffer *outbuf, uoff_t data_size); void *index_msgcache_get_context(MailIndex *index, MailIndexRecord *rec);
--- a/src/lib-storage/index/maildir/maildir-copy.c Mon Oct 21 03:08:03 2002 +0300 +++ b/src/lib-storage/index/maildir/maildir-copy.c Mon Oct 21 03:09:29 2002 +0300 @@ -95,7 +95,7 @@ return FALSE; } - if (getenv("COPY_WITH_HARDLINKS") != NULL && + if (getenv("MAILDIR_COPY_WITH_HARDLINKS") != NULL && destbox->storage == box->storage) { /* both source and destination mailbox are in maildirs and copy_with_hardlinks option is on, do it */
--- a/src/lib-storage/index/maildir/maildir-save.c Mon Oct 21 03:08:03 2002 +0300 +++ b/src/lib-storage/index/maildir/maildir-save.c Mon Oct 21 03:09:29 2002 +0300 @@ -3,6 +3,7 @@ #include "lib.h" #include "ioloop.h" #include "hostpid.h" +#include "obuffer.h" #include "maildir-index.h" #include "maildir-storage.h" @@ -44,20 +45,28 @@ IBuffer *buf, uoff_t data_size) { const char *fname, *path; + OBuffer *outbuf; int fd; fd = maildir_create_tmp(storage, dir, &fname); if (fd == -1) return NULL; + t_push(); + outbuf = o_buffer_create_file(fd, data_stack_pool, 4096, + IO_PRIORITY_DEFAULT, FALSE); + path = t_strconcat(dir, "/", fname, NULL); - if (!index_storage_save_into_fd(storage, fd, path, buf, data_size)) + if (!index_storage_save(storage, path, buf, outbuf, data_size)) fname = NULL; - (void)close(fd); + o_buffer_unref(outbuf); + if (close(fd) < 0) + fname = NULL; if (fname == NULL) (void)unlink(path); + t_pop(); return fname; }
--- a/src/lib-storage/index/mbox/mbox-save.c Mon Oct 21 03:08:03 2002 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Mon Oct 21 03:09:29 2002 +0300 @@ -3,6 +3,7 @@ #include "lib.h" #include "hostpid.h" #include "ibuffer.h" +#include "obuffer.h" #include "write-full.h" #include "mbox-index.h" #include "mbox-lock.h" @@ -53,16 +54,17 @@ return set_error(storage, mbox_path); } -static int mbox_append_lf(MailStorage *storage, int fd, const char *mbox_path) +static int mbox_append_lf(MailStorage *storage, OBuffer *outbuf, + const char *mbox_path) { - if (write_full(fd, "\n", 1) < 0) + if (o_buffer_send(outbuf, "\n", 1) < 0) return set_error(storage, mbox_path); return TRUE; } -static int write_from_line(MailStorage *storage, int fd, const char *mbox_path, - time_t internal_date) +static int write_from_line(MailStorage *storage, OBuffer *outbuf, + const char *mbox_path, time_t internal_date) { const char *sender, *line, *name; size_t len; @@ -88,13 +90,14 @@ line = mbox_from_create(sender, internal_date); len = strlen(line); - if (write_full(fd, line, len) < 0) + if (o_buffer_send(outbuf, line, len) < 0) return set_error(storage, mbox_path); return TRUE; } -static int write_flags(MailStorage *storage, int fd, const char *mbox_path, +static int write_flags(MailStorage *storage, OBuffer *outbuf, + const char *mbox_path, MailFlags flags, const char *custom_flags[]) { const char *str; @@ -105,7 +108,7 @@ return TRUE; if (flags & MAIL_SEEN) { - if (write_full(fd, "Status: R\n", 10) < 0) + if (o_buffer_send(outbuf, "Status: R\n", 10) < 0) return set_error(storage, mbox_path); } @@ -117,27 +120,27 @@ (flags & MAIL_DELETED) ? "T" : "", "\n", NULL); - if (write_full(fd, str, strlen(str)) < 0) + if (o_buffer_send(outbuf, str, strlen(str)) < 0) return set_error(storage, mbox_path); } if (flags & MAIL_CUSTOM_FLAGS_MASK) { - if (write_full(fd, "X-Keywords:", 11) < 0) + if (o_buffer_send(outbuf, "X-Keywords:", 11) < 0) return set_error(storage, mbox_path); field = 1 << MAIL_CUSTOM_FLAG_1_BIT; for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++, field <<= 1) { if ((flags & field) && custom_flags[i] != NULL) { - if (write_full(fd, " ", 1) < 0) + if (o_buffer_send(outbuf, " ", 1) < 0) return set_error(storage, mbox_path); - if (write_full(fd, custom_flags[i], - strlen(custom_flags[i])) < 0) + if (o_buffer_send(outbuf, custom_flags[i], + strlen(custom_flags[i])) < 0) return set_error(storage, mbox_path); } } - if (write_full(fd, "\n", 1) < 0) + if (o_buffer_send(outbuf, "\n", 1) < 0) return set_error(storage, mbox_path); } @@ -151,6 +154,7 @@ MailFlags real_flags; const char *mbox_path; IBuffer *inbuf; + OBuffer *outbuf; int fd, failed; off_t pos; @@ -180,27 +184,31 @@ failed = FALSE; + mbox_path = ibox->index->mbox_path; pos = lseek(fd, 0, SEEK_END); if (pos < 0) { mail_storage_set_critical(box->storage, "lseek() failed for mbox file %s: %m", - ibox->index->mbox_path); + mbox_path); failed = TRUE; - } else { - mbox_path = ibox->index->mbox_path; + } else if (mbox_check_ending_lf(box->storage, fd, pos, mbox_path)) { + t_push(); + outbuf = o_buffer_create_file(fd, data_stack_pool, 4096, + IO_PRIORITY_DEFAULT, FALSE); - if (!mbox_check_ending_lf(box->storage, fd, pos, mbox_path) || - !write_from_line(box->storage, fd, mbox_path, + if (!write_from_line(box->storage, outbuf, mbox_path, internal_date) || - !write_flags(box->storage, fd, mbox_path, flags, + !write_flags(box->storage, outbuf, mbox_path, flags, custom_flags) || - !index_storage_save_into_fd(box->storage, fd, mbox_path, - data, data_size) || - !mbox_append_lf(box->storage, fd, mbox_path)) { + !index_storage_save(box->storage, mbox_path, + data, outbuf, data_size) || + !mbox_append_lf(box->storage, outbuf, mbox_path)) { /* failed, truncate file back to original size */ (void)ftruncate(fd, pos); failed = TRUE; } + o_buffer_unref(outbuf); + t_pop(); } (void)mbox_unlock(ibox->index);
--- a/src/master/imap-process.c Mon Oct 21 03:08:03 2002 +0300 +++ b/src/master/imap-process.c Mon Oct 21 03:09:29 2002 +0300 @@ -119,10 +119,12 @@ putenv((char *) t_strconcat("MAIL_NEVER_CACHE_FIELDS=", set_mail_never_cache_fields, NULL)); + if (set_mail_save_crlf) + putenv("MAIL_SAVE_CRLF=1"); if (set_maildir_copy_with_hardlinks) - putenv("COPY_WITH_HARDLINKS=1"); + putenv("MAILDIR_COPY_WITH_HARDLINKS=1"); if (set_maildir_check_content_changes) - putenv("CHECK_CONTENT_CHANGES=1"); + putenv("MAILDIR_CHECK_CONTENT_CHANGES=1"); if (set_overwrite_incompatible_index) putenv("OVERWRITE_INCOMPATIBLE_INDEX=1"); if (umask(set_umask) != set_umask)
--- a/src/master/settings.c Mon Oct 21 03:08:03 2002 +0300 +++ b/src/master/settings.c Mon Oct 21 03:09:29 2002 +0300 @@ -52,6 +52,7 @@ { "mail_cache_fields", SET_STR, &set_mail_cache_fields }, { "mail_never_cache_fields", SET_STR, &set_mail_never_cache_fields }, + { "mail_save_crlf", SET_BOOL,&set_mail_save_crlf }, { "maildir_copy_with_hardlinks", SET_BOOL,&set_maildir_copy_with_hardlinks }, { "maildir_check_content_changes", @@ -99,6 +100,7 @@ char *set_mail_cache_fields = "MessagePart"; char *set_mail_never_cache_fields = NULL; +int set_mail_save_crlf = FALSE; int set_maildir_copy_with_hardlinks = FALSE; int set_maildir_check_content_changes = FALSE; int set_overwrite_incompatible_index = FALSE;
--- a/src/master/settings.h Mon Oct 21 03:08:03 2002 +0300 +++ b/src/master/settings.h Mon Oct 21 03:09:29 2002 +0300 @@ -36,6 +36,7 @@ extern char *set_mail_cache_fields; extern char *set_mail_never_cache_fields; +extern int set_mail_save_crlf; extern int set_maildir_copy_with_hardlinks; extern int set_maildir_check_content_changes; extern int set_overwrite_incompatible_index;