コード例 #1
0
ファイル: mbox-lock.c プロジェクト: bdraco/core
static int mbox_file_open_latest(struct mbox_lock_context *ctx, int lock_type)
{
	struct mbox_mailbox *mbox = ctx->mbox;
	struct stat st;

	if (ctx->checked_file || lock_type == F_UNLCK)
		return 0;

	if (mbox->mbox_fd != -1) {
		/* we could flush NFS file handle cache here if we wanted to
		   be sure that the file is latest, but mbox files get rarely
		   deleted and the flushing might cause errors (e.g. EBUSY for
		   trying to flush a /var/mail mountpoint) */
		if (nfs_safe_stat(mailbox_get_path(&mbox->box), &st) < 0) {
			if (errno == ENOENT)
				mailbox_set_deleted(&mbox->box);
			else
				mbox_set_syscall_error(mbox, "stat()");
			return -1;
		}

		if (st.st_ino != mbox->mbox_ino ||
		    !CMP_DEV_T(st.st_dev, mbox->mbox_dev))
			mbox_file_close(mbox);
	}

	if (mbox->mbox_fd == -1) {
		if (mbox_file_open(mbox) < 0)
			return -1;
	}

	ctx->checked_file = TRUE;
	return 0;
}
コード例 #2
0
ファイル: mbox-file.c プロジェクト: bechtoldt/dovecot-core
int mbox_file_open_stream(struct mbox_mailbox *mbox)
{
	if (mbox->mbox_stream != NULL)
		return 0;

	if (mbox->mbox_file_stream != NULL) {
		/* read-only mbox stream */
		i_assert(mbox->mbox_fd == -1 && mbox_is_backend_readonly(mbox));
	} else {
		if (mbox->mbox_fd == -1) {
			if (mbox_file_open(mbox) < 0)
				return -1;
		}

		if (mbox->mbox_writeonly) {
			mbox->mbox_file_stream =
				i_stream_create_from_data("", 0);
		} else {
			mbox->mbox_file_stream =
				i_stream_create_fd(mbox->mbox_fd,
						   MBOX_READ_BLOCK_SIZE);
			i_stream_set_init_buffer_size(mbox->mbox_file_stream,
						      MBOX_READ_BLOCK_SIZE);
		}
		i_stream_set_name(mbox->mbox_file_stream,
				  mailbox_get_path(&mbox->box));
	}

	mbox->mbox_stream = i_stream_create_raw_mbox(mbox->mbox_file_stream);
	if (mbox->mbox_lock_type != F_UNLCK)
		istream_raw_mbox_set_locked(mbox->mbox_stream);
	return 0;
}
コード例 #3
0
ファイル: mbox-storage.c プロジェクト: IvanKharpalev/core
static int
mbox_mailbox_get_guid(struct mbox_mailbox *mbox, guid_128_t guid_r)
{
	const char *errstr;

	if (mail_index_is_in_memory(mbox->box.index)) {
		errstr = "Mailbox GUIDs are not permanent without index files";
		if (mbox->storage->set->mbox_min_index_size != 0) {
			errstr = t_strconcat(errstr,
				" (mbox_min_index_size is non-zero)", NULL);
		}
		mail_storage_set_error(mbox->box.storage,
				       MAIL_ERROR_NOTPOSSIBLE, errstr);
		return -1;
	}
	if (mbox_sync_header_refresh(mbox) < 0)
		return -1;

	if (!guid_128_is_empty(mbox->mbox_hdr.mailbox_guid)) {
		/* we have the GUID */
	} else if (mbox_file_open(mbox) < 0)
		return -1;
	else if (mbox->backend_readonly) {
		mail_storage_set_error(mbox->box.storage, MAIL_ERROR_PERM,
			"Can't set mailbox GUID to a read-only mailbox");
		return -1;
	} else {
		/* create another mailbox and sync  */
		struct mailbox *box2;
		struct mbox_mailbox *mbox2;
		int ret;

		i_assert(mbox->mbox_lock_type == F_UNLCK);
		box2 = mailbox_alloc(mbox->box.list, mbox->box.vname, 0);
		ret = mailbox_sync(box2, 0);
		mbox2 = (struct mbox_mailbox *)box2;
		memcpy(guid_r, mbox2->mbox_hdr.mailbox_guid, GUID_128_SIZE);
		mailbox_free(&box2);
		return ret;
	}
	memcpy(guid_r, mbox->mbox_hdr.mailbox_guid, GUID_128_SIZE);
	return 0;
}
コード例 #4
0
ファイル: mbox-save.c プロジェクト: via/dovecot-clouddb
static int
mbox_save_init_file(struct mbox_save_context *ctx,
		    struct mbox_transaction_context *t, bool want_mail)
{
	struct mailbox_transaction_context *_t = &t->ictx.mailbox_ctx;
	struct mbox_mailbox *mbox = ctx->mbox;
	struct mail_storage *storage = &mbox->storage->storage;
	bool empty = FALSE;
	int ret;

	if (ctx->mbox->box.backend_readonly) {
		mail_storage_set_error(storage, MAIL_ERROR_PERM,
				       "Read-only mbox");
		return -1;
	}

	if ((_t->flags & MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS) != 0 ||
	    ctx->ctx.uid != 0)
		want_mail = TRUE;

	if (ctx->append_offset == (uoff_t)-1) {
		/* first appended mail in this transaction */
		if (mbox->mbox_lock_type != F_WRLCK) {
			if (mbox->mbox_lock_type == F_RDLCK) {
				/* FIXME: we shouldn't fail here. it's just
				   a locking issue that should be possible to
				   fix.. */
				mail_storage_set_error(storage,
					MAIL_ERROR_NOTPOSSIBLE,
					"Can't copy mails inside same mailbox");
				return -1;
			}
			if (mbox_lock(mbox, F_WRLCK, &t->mbox_lock_id) <= 0)
				return -1;
		}

		if (mbox->mbox_fd == -1) {
			if (mbox_file_open(mbox) < 0)
				return -1;
		}

		/* update mbox_sync_dirty state */
		ret = mbox_sync_has_changed_full(mbox, TRUE, &empty);
		if (ret < 0)
			return -1;
		if (!want_mail && ret == 0) {
			/* we're not required to assign UIDs for the appended
			   mails immediately. do it only if it doesn't require
			   syncing. */
			mbox_save_init_sync(_t);
		}
	}

	if (!ctx->synced && (want_mail || empty)) {
		/* we'll need to assign UID for the mail immediately. */
		if (mbox_sync(mbox, 0) < 0)
			return -1;
		mbox_save_init_sync(_t);
	}

	/* the syncing above could have changed the append offset */
	if (ctx->append_offset == (uoff_t)-1) {
		if (mbox_seek_to_end(ctx, &ctx->append_offset) < 0)
			return -1;

		ctx->output = o_stream_create_fd_file(mbox->mbox_fd,
						      ctx->append_offset,
						      FALSE);
		o_stream_cork(ctx->output);
	}
	return 0;
}