Mercurial > dovecot > original-hg > dovecot-1.2
changeset 364:ea958a5b9de1 HEAD
Added io_buffer_set_start_offset() and io_buffer_ref() and replaced
io_buffer_destroy() with io_buffer_unref().
mbox file is now kept open all the time.
line wrap: on
line diff
--- a/src/auth/master.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/auth/master.c Sun Oct 06 08:44:27 2002 +0300 @@ -77,6 +77,6 @@ void master_deinit(void) { - io_buffer_destroy(outbuf); + io_buffer_unref(outbuf); io_remove(io_master); }
--- a/src/auth/userinfo-passwd-file.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/auth/userinfo-passwd-file.c Sun Oct 06 08:44:27 2002 +0300 @@ -318,7 +318,7 @@ } t_pop(); } - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); } static PasswdFile *passwd_file_parse(const char *path)
--- a/src/imap/client.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/imap/client.c Sun Oct 06 08:44:27 2002 +0300 @@ -95,8 +95,8 @@ imap_parser_destroy(client->parser); io_remove(client->io); - io_buffer_destroy(client->inbuf); - io_buffer_destroy(client->outbuf); + io_buffer_unref(client->inbuf); + io_buffer_unref(client->outbuf); i_free(client);
--- a/src/lib-imap/imap-message-cache.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-imap/imap-message-cache.c Sun Oct 06 08:44:27 2002 +0300 @@ -348,7 +348,7 @@ void imap_msgcache_close(ImapMessageCache *cache) { if (cache->open_inbuf != NULL) { - io_buffer_destroy(cache->open_inbuf); + io_buffer_unref(cache->open_inbuf); cache->open_inbuf = NULL; }
--- a/src/lib-index/mail-index-update-cache.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mail-index-update-cache.c Sun Oct 06 08:44:27 2002 +0300 @@ -23,8 +23,7 @@ mail_index_update_headers(update, inbuf, cache_fields, NULL, NULL); failed = !index->update_end(update); - io_buffer_destroy(inbuf); - + io_buffer_unref(inbuf); return !failed; }
--- a/src/lib-index/mail-index-util.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mail-index-util.c Sun Oct 06 08:44:27 2002 +0300 @@ -155,6 +155,6 @@ message_get_body_size(inbuf, &body_size, (uoff_t)-1); *virtual_size = body_size.virtual_size; - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); return TRUE; }
--- a/src/lib-index/mail-index.h Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mail-index.h Sun Oct 06 08:44:27 2002 +0300 @@ -319,6 +319,7 @@ char *mbox_path; /* mbox-specific path to the actual mbox file */ uoff_t mbox_size; /* last synced size of mbox file */ + int mbox_fd; int mbox_locks; int fd; /* opened index file */ @@ -354,7 +355,7 @@ #define MAIL_INDEX_PRIVATE_FILL \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* defaults - same as above but prefixed with mail_index_. */ int mail_index_open(MailIndex *index, int update_recent, int fast);
--- a/src/lib-index/maildir/maildir-update.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/maildir/maildir-update.c Sun Oct 06 08:44:27 2002 +0300 @@ -13,6 +13,6 @@ inbuf = io_buffer_create_mmap(fd, default_pool, MAIL_MMAP_BLOCK_SIZE, 0, FALSE); mail_index_update_headers(update, inbuf, 0, NULL, NULL); - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); return TRUE; }
--- a/src/lib-index/mbox/mbox-fsck.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mbox/mbox-fsck.c Sun Oct 06 08:44:27 2002 +0300 @@ -287,25 +287,19 @@ int mbox_index_fsck(MailIndex *index) { IOBuffer *inbuf; - int fd, failed; + int failed; - /* open the mbox file. we don't really need to open it read-write, - but fcntl() locking requires it. */ - fd = open(index->mbox_path, O_RDWR); - if (fd == -1) - return mbox_set_syscall_error(index, "open()"); + inbuf = mbox_file_open(index, 0, TRUE); + if (inbuf == NULL) + return FALSE; - inbuf = io_buffer_create_mmap(fd, default_pool, - MAIL_MMAP_BLOCK_SIZE, 0, TRUE); - - if (!mbox_lock(index, index->mbox_path, fd, FALSE)) + if (!mbox_lock(index, index->mbox_path, index->mbox_fd, FALSE)) failed = TRUE; else { failed = !mbox_index_fsck_buf(index, inbuf); - (void)mbox_unlock(index, index->mbox_path, fd); + (void)mbox_unlock(index, index->mbox_path, index->mbox_fd); } - - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); if (failed) return FALSE;
--- a/src/lib-index/mbox/mbox-index.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mbox/mbox-index.c Sun Oct 06 08:44:27 2002 +0300 @@ -8,6 +8,9 @@ #include "mail-index-data.h" #include "mail-custom-flags.h" +#include <fcntl.h> +#include <unistd.h> + extern MailIndex mbox_index; int mbox_set_syscall_error(MailIndex *index, const char *function) @@ -19,6 +22,38 @@ return FALSE; } +IOBuffer *mbox_file_open(MailIndex *index, uoff_t offset, int reopen) +{ + i_assert(offset < OFF_T_MAX); + + if (reopen) + mbox_file_close(index); + + if (index->mbox_fd == -1) { + index->mbox_fd = open(index->mbox_path, O_RDWR); + if (index->mbox_fd == -1) { + mbox_set_syscall_error(index, "open()"); + return NULL; + } + } + + if (lseek(index->mbox_fd, (off_t)offset, SEEK_SET) != (off_t)offset) { + mbox_set_syscall_error(index, "lseek()"); + return NULL; + } + + return io_buffer_create_mmap(index->mbox_fd, default_pool, + MAIL_MMAP_BLOCK_SIZE, 0, FALSE); +} + +void mbox_file_close(MailIndex *index) +{ + if (index->mbox_fd != -1) { + close(index->mbox_fd); + index->mbox_fd = -1; + } +} + void mbox_header_init_context(MboxHeaderContext *ctx, MailIndex *index) { memset(ctx, 0, sizeof(MboxHeaderContext)); @@ -425,6 +460,7 @@ memcpy(index, &mbox_index, sizeof(MailIndex)); index->fd = -1; + index->mbox_fd = -1; index->dir = i_strdup(dir); len = strlen(index->dir); @@ -437,6 +473,7 @@ static void mbox_index_free(MailIndex *index) { + mbox_file_close(index); mail_index_close(index); i_free(index->dir); i_free(index);
--- a/src/lib-index/mbox/mbox-index.h Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mbox/mbox-index.h Sun Oct 06 08:44:27 2002 +0300 @@ -14,6 +14,12 @@ int mbox_set_syscall_error(MailIndex *index, const char *function); +/* Make sure the mbox is opened. If reopen is TRUE, the file is closed first, + which is useful when you want to be sure you're not accessing a deleted + mbox file. */ +IOBuffer *mbox_file_open(MailIndex *index, uoff_t offset, int reopen); +void mbox_file_close(MailIndex *index); + void mbox_header_init_context(MboxHeaderContext *ctx, MailIndex *index); void mbox_header_free_context(MboxHeaderContext *ctx); void mbox_header_func(MessagePart *part __attr_unused__,
--- a/src/lib-index/mbox/mbox-open.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mbox/mbox-open.c Sun Oct 06 08:44:27 2002 +0300 @@ -11,10 +11,11 @@ IOBuffer *mbox_open_mail(MailIndex *index, MailIndexRecord *rec) { + IOBuffer *inbuf; uoff_t offset, stop_offset; - off_t pos; - char buf[7], *p; - int fd, ret, failed; + unsigned char *data; + size_t size; + int failed; i_assert(index->lock_type != MAIL_LOCK_UNLOCK); @@ -27,71 +28,54 @@ stop_offset = offset + rec->header_size + rec->body_size; - fd = open(index->mbox_path, O_RDONLY); - if (fd == -1) { - mbox_set_syscall_error(index, "open()"); + inbuf = mbox_file_open(index, offset, FALSE); + if (inbuf == NULL) return NULL; - } - pos = lseek(fd, (off_t)offset, SEEK_SET); - if (pos == -1) { - mbox_set_syscall_error(index, "lseek()"); - (void)close(fd); + /* make sure message size is valid - it must end with + either EOF or "\nFrom "*/ + if (!io_buffer_seek(inbuf, stop_offset - offset)) { + mbox_set_syscall_error(index, "io_buffer_seek()"); + io_buffer_unref(inbuf); return NULL; } - failed = TRUE; - if ((uoff_t)pos == offset) { - /* make sure message size is valid */ - if (lseek(fd, (off_t)stop_offset, SEEK_SET) == - (off_t)stop_offset) { - /* and check that we end with either EOF or to - beginning of next message */ - ret = read(fd, buf, 7); - if (ret >= 6) { - /* "[\r]\nFrom " expected */ - if (buf[0] != '\r') - p = buf; - else { - p = buf+1; - ret--; - } - if (ret >= 6 && strncmp(p, "\nFrom ", 6) == 0) - failed = FALSE; - } else { - p = buf; - if (ret > 0 && *p == '\r') { - p++; - ret--; - } - if (ret > 0 && *p == '\n') - ret--; + (void)io_buffer_read_data_blocking(inbuf, &data, &size, 6); + if (size >= 6) { + /* "[\r]\nFrom " expected */ + if (data[0] == '\r') { + data++; + size--; + } - if (ret == 0) - failed = FALSE; /* end of file */ - } + failed = size < 6 || strncmp((char *) data, "\nFrom ", 6) != 0; + } else { + if (size > 0 && data[0] == '\r') { + data++; + size--; } + if (size > 0 && data[0] == '\n') + size--; + + /* we should be at end of file now */ + failed = size != 0; } - if (!failed) { - if (lseek(fd, (off_t)offset, SEEK_SET) < 0) { - mbox_set_syscall_error(index, "lseek()"); - failed = TRUE; - } - } else { + if (!io_buffer_seek(inbuf, 0)) { + mbox_set_syscall_error(index, "io_buffer_seek()"); + failed = TRUE; + } + + if (failed) { /* file has been updated, rescan it */ index->set_flags |= MAIL_INDEX_FLAG_FSCK; index_set_error(index, "mbox file %s was modified " "unexpectedly, fscking", index->mbox_path); + io_buffer_unref(inbuf); + return NULL; } - if (failed) { - (void)close(fd); - return NULL; - } else { - return io_buffer_create_mmap(fd, default_pool, - MAIL_MMAP_BLOCK_SIZE, - stop_offset - offset, TRUE); - } + io_buffer_set_read_limit(inbuf, stop_offset - offset); + return inbuf; }
--- a/src/lib-index/mbox/mbox-rebuild.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mbox/mbox-rebuild.c Sun Oct 06 08:44:27 2002 +0300 @@ -16,7 +16,7 @@ { IOBuffer *inbuf; struct stat st; - int fd, failed; + int failed; i_assert(index->lock_type != MAIL_LOCK_SHARED); @@ -42,26 +42,21 @@ if (!mail_index_data_reset(index->data)) return FALSE; - /* open the mbox file. we don't really need to open it read-write, - but fcntl() locking requires it. */ - fd = open(index->mbox_path, O_RDWR); - if (fd == -1) - return mbox_set_syscall_error(index, "open()"); + inbuf = mbox_file_open(index, 0, TRUE); + if (inbuf == NULL) + return FALSE; /* lock the mailbox so we can be sure no-one interrupts us. */ - if (!mbox_lock(index, index->mbox_path, fd, FALSE)) { - if (close(fd) < 0) - mbox_set_syscall_error(index, "close()"); + if (!mbox_lock(index, index->mbox_path, index->mbox_fd, FALSE)) { + io_buffer_unref(inbuf); return FALSE; } - inbuf = io_buffer_create_mmap(fd, default_pool, - MAIL_MMAP_BLOCK_SIZE, 0, TRUE); mbox_skip_empty_lines(inbuf); failed = !mbox_index_append(index, inbuf); + (void)mbox_unlock(index, index->mbox_path, index->mbox_fd); - (void)mbox_unlock(index, index->mbox_path, fd); - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); if (failed) return FALSE;
--- a/src/lib-index/mbox/mbox-rewrite.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-index/mbox/mbox-rewrite.c Sun Oct 06 08:44:27 2002 +0300 @@ -355,8 +355,8 @@ ret = ftruncate(out_fd, (off_t) (out_offset + inbuf->size)); } - io_buffer_destroy(outbuf); - io_buffer_destroy(inbuf); + io_buffer_unref(outbuf); + io_buffer_unref(inbuf); return ret; } @@ -372,7 +372,7 @@ uoff_t offset, dirty_offset; const char *path; unsigned int seq; - int mbox_fd, tmp_fd, failed, dirty_found, locked, rewrite; + int tmp_fd, failed, dirty_found, locked, rewrite; i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE); @@ -381,18 +381,16 @@ return TRUE; } - mbox_fd = tmp_fd = -1; locked = FALSE; + tmp_fd = -1; locked = FALSE; failed = TRUE; rewrite = FALSE; do { /* lock before fscking to prevent race conditions between fsck's unlock and our lock. */ - mbox_fd = open(index->mbox_path, O_RDWR); - if (mbox_fd == -1) { - mbox_set_syscall_error(index, "open()"); + inbuf = mbox_file_open(index, 0, TRUE); + if (inbuf == NULL) break; - } - if (!mbox_lock(index, index->mbox_path, mbox_fd, TRUE)) + if (!mbox_lock(index, index->mbox_path, index->mbox_fd, TRUE)) break; locked = TRUE; @@ -415,10 +413,12 @@ } while (0); if (!rewrite) { - if (locked) - (void)mbox_unlock(index, index->mbox_path, mbox_fd); - if (mbox_fd != -1 && close(mbox_fd) < 0) - mbox_set_syscall_error(index, "close()"); + if (locked) { + (void)mbox_unlock(index, index->mbox_path, + index->mbox_fd); + } + if (inbuf != NULL) + io_buffer_unref(inbuf); return !failed; } @@ -430,8 +430,6 @@ } dirty_offset = 0; - inbuf = io_buffer_create_mmap(mbox_fd, default_pool, - MAIL_MMAP_BLOCK_SIZE, 0, FALSE); outbuf = io_buffer_create_file(tmp_fd, default_pool, 8192, FALSE); failed = FALSE; seq = 1; @@ -500,8 +498,8 @@ failed = TRUE; } - io_buffer_destroy(outbuf); - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); + io_buffer_unref(outbuf); if (!failed) { /* POSSIBLE DATA LOSS HERE. We're writing to the mbox file, @@ -519,7 +517,7 @@ Also, we might as well be shrinking the file, in which case we can't lose data. */ - if (fd_copy(tmp_fd, mbox_fd, dirty_offset) == 0) { + if (fd_copy(tmp_fd, index->mbox_fd, dirty_offset) == 0) { /* all ok, we need to fsck the index next time. use set_flags because set_lock() would remove it if we modified it directly */ @@ -531,11 +529,9 @@ } } - (void)mbox_unlock(index, index->mbox_path, mbox_fd); + (void)mbox_unlock(index, index->mbox_path, index->mbox_fd); (void)unlink(path); - if (close(mbox_fd) < 0) - mbox_set_syscall_error(index, "close()"); if (close(tmp_fd) < 0) index_file_set_syscall_error(index, path, "close()"); return failed;
--- a/src/lib-storage/index/index-copy.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-storage/index/index-copy.c Sun Oct 06 08:44:27 2002 +0300 @@ -30,7 +30,7 @@ ctx->custom_flags, rec->internal_date, inbuf, inbuf->size); - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); return !failed; }
--- a/src/lib-storage/index/index-fetch.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-storage/index/index-fetch.c Sun Oct 06 08:44:27 2002 +0300 @@ -249,6 +249,9 @@ unsigned int orig_len; int failed, data_written; + if ((rec->msg_flags & MAIL_SEEN) == 0) + ctx->found_unseen = TRUE; + ctx->str = t_string_new(2048); t_string_printfa(ctx->str, "* %u FETCH (", client_seq); @@ -352,13 +355,15 @@ ctx.fetch_data = fetch_data; ctx.outbuf = outbuf; - /* If we have any BODY[..] sections, \Seen flag is added for - all messages */ - sect = ctx.fetch_data->body_sections; - for (; sect != NULL; sect = sect->next) { - if (!sect->peek) { - ctx.update_seen = TRUE; - break; + if (!box->readonly) { + /* If we have any BODY[..] sections, \Seen flag is added for + all messages */ + sect = ctx.fetch_data->body_sections; + for (; sect != NULL; sect = sect->next) { + if (!sect->peek) { + ctx.update_seen = TRUE; + break; + } } } @@ -374,7 +379,7 @@ if (all_found != NULL) *all_found = ret == 1; - if (ret >= 1 && ctx.update_seen && !box->readonly) { + if (ret >= 1 && ctx.update_seen && ctx.found_unseen) { /* BODY[..] was fetched, set \Seen flag for all messages. This needs to be done separately because we need exclusive lock for it */
--- a/src/lib-storage/index/index-fetch.h Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-storage/index/index-fetch.h Sun Oct 06 08:44:27 2002 +0300 @@ -11,7 +11,7 @@ MailFetchData *fetch_data; IOBuffer *outbuf; TempString *str; - int update_seen; + int update_seen, found_unseen; int first; } FetchContext;
--- a/src/lib-storage/index/index-msgcache.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-storage/index/index-msgcache.c Sun Oct 06 08:44:27 2002 +0300 @@ -37,7 +37,7 @@ if (!io_buffer_seek(inbuf, 0)) { i_error("index_msgcache_inbuf_rewind: lseek() failed: %m"); - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); return NULL; }
--- a/src/lib-storage/index/index-search.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-storage/index/index-search.c Sun Oct 06 08:44:27 2002 +0300 @@ -551,7 +551,7 @@ search_text_body); } - io_buffer_destroy(inbuf); + io_buffer_unref(inbuf); return TRUE; }
--- a/src/lib-storage/index/mbox/mbox-expunge.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-storage/index/mbox/mbox-expunge.c Sun Oct 06 08:44:27 2002 +0300 @@ -107,7 +107,7 @@ MailIndexRecord *rec; IOBuffer *inbuf, *outbuf; unsigned int seq; - int fd, failed; + int failed; if (!index_expunge_seek_first(ibox, &seq, &rec)) return FALSE; @@ -117,22 +117,17 @@ return TRUE; } - fd = open(ibox->index->mbox_path, O_RDWR); - if (fd == -1) { - mail_storage_set_error(ibox->box.storage, - "Error opening mbox file %s: %m", - ibox->index->mbox_path); + inbuf = mbox_file_open(ibox->index, 0, TRUE); + if (inbuf == NULL) + return FALSE; + + if (!mbox_lock(ibox->index, ibox->index->mbox_path, + ibox->index->mbox_fd, TRUE)) { + io_buffer_unref(inbuf); return FALSE; } - if (!mbox_lock(ibox->index, ibox->index->mbox_path, fd, TRUE)) { - (void)close(fd); - return FALSE; - } - - inbuf = io_buffer_create_mmap(fd, default_pool, - MAIL_MMAP_BLOCK_SIZE, 0, FALSE); - outbuf = io_buffer_create_file(fd, default_pool, 4096, FALSE); + outbuf = io_buffer_create_file(inbuf->fd, default_pool, 4096, FALSE); failed = !expunge_real(ibox, rec, seq, inbuf, outbuf, expunge_func, context); @@ -152,10 +147,9 @@ failed = TRUE; } - (void)mbox_unlock(ibox->index, ibox->index->mbox_path, fd); - (void)close(fd); - io_buffer_destroy(inbuf); - io_buffer_destroy(outbuf); + (void)mbox_unlock(ibox->index, ibox->index->mbox_path, + ibox->index->mbox_fd); + io_buffer_unref(outbuf); return !failed; }
--- a/src/lib-storage/index/mbox/mbox-save.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Sun Oct 06 08:44:27 2002 +0300 @@ -150,6 +150,7 @@ IndexMailbox *ibox = (IndexMailbox *) box; MailFlags real_flags; const char *mbox_path; + IOBuffer *inbuf; int fd, failed; off_t pos; @@ -164,13 +165,13 @@ if (!index_mailbox_fix_custom_flags(ibox, &real_flags, custom_flags)) return FALSE; - /* append the data into mbox file */ - fd = open(ibox->index->mbox_path, O_RDWR | O_CREAT, 0660); - if (fd == -1) { - mail_storage_set_critical(box->storage, "Can't open mbox file " - "%s: %m", ibox->index->mbox_path); + /* just make sure the mbox is opened, we don't need the iobuffer */ + inbuf = mbox_file_open(ibox->index, 0, TRUE); + if (inbuf == NULL) return FALSE; - } + + io_buffer_unref(inbuf); + fd = ibox->index->mbox_fd; if (!mbox_lock(ibox->index, ibox->index->mbox_path, fd, TRUE)) { (void)close(fd); @@ -203,6 +204,5 @@ } (void)mbox_unlock(ibox->index, ibox->index->mbox_path, fd); - (void)close(fd); return !failed; }
--- a/src/lib/iobuffer.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib/iobuffer.c Sun Oct 06 08:44:27 2002 +0300 @@ -58,6 +58,7 @@ i_assert(pool != NULL); buf = p_new(pool, IOBuffer, 1); + buf->refcount = 1; buf->fd = fd; buf->pool = pool; buf->priority = priority; @@ -126,11 +127,20 @@ return buf; } -void io_buffer_destroy(IOBuffer *buf) +void io_buffer_ref(IOBuffer *buf) +{ + buf->refcount++; +} + +void io_buffer_unref(IOBuffer *buf) { if (buf == NULL) return; + i_assert(buf->refcount > 0); + if (--buf->refcount > 0) + return; + if (buf->io != NULL) io_remove(buf->io); if (buf->buffer != NULL) { @@ -645,9 +655,12 @@ static ssize_t io_buffer_set_mmaped_pos(IOBuffer *buf) { - buf->pos = buf->buffer_size; - if (buf->pos - buf->skip > buf->limit - buf->offset) - buf->pos = buf->limit - buf->offset + buf->skip; + i_assert((uoff_t)buf->mmap_offset <= buf->start_offset + buf->limit); + + buf->pos = buf->start_offset + buf->limit - buf->mmap_offset; + if (buf->pos > buf->buffer_size) + buf->pos = buf->buffer_size; + return buf->pos - buf->skip; } @@ -703,18 +716,37 @@ return io_buffer_set_mmaped_pos(buf); } -void io_buffer_set_read_limit(IOBuffer *inbuf, uoff_t offset) +void io_buffer_set_start_offset(IOBuffer *buf, uoff_t offset) { - i_assert(offset <= inbuf->size); + off_t diff; + + i_assert(offset <= buf->size); + + if (offset == buf->start_offset) + return; + + diff = (off_t)buf->start_offset - (off_t)offset; + buf->start_offset = offset; + buf->size += diff; + buf->limit += diff; + + io_buffer_reset(buf); + + buf->skip = buf->pos = buf->start_offset; +} + +void io_buffer_set_read_limit(IOBuffer *buf, uoff_t offset) +{ + i_assert(offset <= buf->size); if (offset == 0) - inbuf->limit = inbuf->size; + buf->limit = buf->size; else { - i_assert(offset >= inbuf->offset); + i_assert(offset >= buf->offset); - inbuf->limit = offset; - if (inbuf->offset + (inbuf->pos - inbuf->skip) > offset) - inbuf->pos = offset - inbuf->offset + inbuf->skip; + buf->limit = offset; + if (buf->offset + (buf->pos - buf->skip) > offset) + buf->pos = offset - buf->offset + buf->skip; } } @@ -867,9 +899,12 @@ int io_buffer_seek(IOBuffer *buf, uoff_t offset) { uoff_t real_offset; + off_t ret; - if (buf->closed) + if (buf->closed) { + errno = EBADF; return FALSE; + } real_offset = buf->start_offset + offset; if (real_offset > OFF_T_MAX) { @@ -885,9 +920,14 @@ pick up from there */ buf->pos = buf->skip = real_offset; } else { - if (lseek(buf->fd, (off_t)real_offset, SEEK_SET) != - (off_t)real_offset) + ret = lseek(buf->fd, (off_t)real_offset, SEEK_SET); + if (ret < 0) return FALSE; + + if (ret != (off_t)real_offset) { + errno = EINVAL; + return FALSE; + } } buf->offset = offset;
--- a/src/lib/iobuffer.h Sun Oct 06 06:09:36 2002 +0300 +++ b/src/lib/iobuffer.h Sun Oct 06 08:44:27 2002 +0300 @@ -17,6 +17,7 @@ /* private: */ Pool pool; IO io; + int refcount; int priority; int timeout_msecs; @@ -56,8 +57,12 @@ stop reading, or 0 to end of file. */ IOBuffer *io_buffer_create_mmap(int fd, Pool pool, size_t block_size, uoff_t size, int autoclose_fd); -/* Destroy a buffer. */ -void io_buffer_destroy(IOBuffer *buf); + +/* Reference counting. References start from 1, so calling io_buffer_unref() + destroys the buffer if io_buffer_ref() is never used. */ +void io_buffer_ref(IOBuffer *buf); +void io_buffer_unref(IOBuffer *buf); + /* Mark the buffer closed. Any sends/reads after this will return -1. The data already in buffer can be used, and the remaining output buffer will be sent. */ @@ -108,9 +113,13 @@ void io_buffer_send_flush_callback(IOBuffer *buf, IOBufferFlushFunc func, void *context); +/* Change the start_offset and call io_buffer_reset(). Doesn't do anything + if offset is the same as existing start_offset. */ +void io_buffer_set_start_offset(IOBuffer *buf, uoff_t offset); + /* IO buffer won't be read past specified offset. Giving 0 as offset removes the limit. */ -void io_buffer_set_read_limit(IOBuffer *inbuf, uoff_t offset); +void io_buffer_set_read_limit(IOBuffer *buf, uoff_t offset); /* Returns number of bytes read if read was ok, -1 if disconnected / EOF, -2 if the buffer is full */
--- a/src/login/auth-connection.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/login/auth-connection.c Sun Oct 06 08:44:27 2002 +0300 @@ -118,8 +118,8 @@ (void)close(conn->fd); io_remove(conn->io); - io_buffer_destroy(conn->inbuf); - io_buffer_destroy(conn->outbuf); + io_buffer_unref(conn->inbuf); + io_buffer_unref(conn->outbuf); i_free(conn->path); i_free(conn); }
--- a/src/login/client.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/login/client.c Sun Oct 06 08:44:27 2002 +0300 @@ -289,8 +289,8 @@ if (--client->refcount > 0) return TRUE; - io_buffer_destroy(client->inbuf); - io_buffer_destroy(client->outbuf); + io_buffer_unref(client->inbuf); + io_buffer_unref(client->outbuf); i_free(client->tag); i_free(client->plain_login);
--- a/src/master/auth-process.c Sun Oct 06 06:09:36 2002 +0300 +++ b/src/master/auth-process.c Sun Oct 06 08:44:27 2002 +0300 @@ -154,7 +154,7 @@ (void)unlink(t_strconcat(set_login_dir, "/", p->name, NULL)); - io_buffer_destroy(p->outbuf); + io_buffer_unref(p->outbuf); io_remove(p->io); (void)close(p->fd); i_free(p->name);