view src/lib-index/mbox/mbox-open.c @ 160:ff05b320482c HEAD

Bigger changes.. full_virtual_size was removed from index record and MessagePart caching is now forced. Also added per-message flags, including binary flags which can be used to check if CRs need to be inserted into message data. Added mbox-rewrite support which can be used to write out mbox file with updated flags. This still has the problem of being able to read changed custom flags, that'll require another bigger change. There's also several other mostly mbox related fixes.
author Timo Sirainen <tss@iki.fi>
date Fri, 06 Sep 2002 16:43:58 +0300
parents a6d7ed739926
children 2a2ab4994b8a
line wrap: on
line source

/* Copyright (C) 2002 Timo Sirainen */

#include "lib.h"
#include "iobuffer.h"
#include "mbox-index.h"
#include "mail-index-util.h"

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

IOBuffer *mbox_open_mail(MailIndex *index, MailIndexRecord *rec)
{
	uoff_t offset, stop_offset;
	off_t pos;
	char buf[7], *p;
	int fd, ret, failed;

	i_assert(index->lock_type != MAIL_LOCK_UNLOCK);

	if (!mbox_mail_get_start_offset(index, rec, &offset))
		return NULL;

	stop_offset = offset + rec->header_size + rec->body_size;

	fd = open(index->mbox_path, O_RDONLY);
	if (fd == -1) {
		index_set_error(index, "Can't open mbox file %s: %m",
				index->mbox_path);
		return NULL;
	}

	pos = lseek(fd, (off_t)offset, SEEK_SET);
	if (pos == -1) {
		index_set_error(index, "lseek() failed with mbox file %s: %m",
				index->mbox_path);
		(void)close(fd);
		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--;

				if (ret == 0)
					failed = FALSE; /* end of file */
			}
		}
	}

	if (!failed) {
		if (lseek(fd, (off_t)offset, SEEK_SET) == (off_t)offset) {
			/* everything ok */
			return io_buffer_create_mmap(fd, default_pool,
						     MAIL_MMAP_BLOCK_SIZE,
						     stop_offset - offset);
		}


		index_set_error(index, "lseek() failed with mbox file %s: %m",
				index->mbox_path);
	} else {
		/* 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);
	}

	(void)close(fd);
	return NULL;
}