示例#1
0
static int
cmd_import_box_contents(struct doveadm_mail_iter *iter, struct mail *src_mail,
			struct mailbox *dest_box)
{
	struct mail_storage *dest_storage = mailbox_get_storage(dest_box);
	struct mail_save_context *save_ctx;
	struct mailbox_transaction_context *dest_trans;
	const char *mailbox = mailbox_get_vname(dest_box);
	int ret = 0;

	dest_trans = mailbox_transaction_begin(dest_box,
				MAILBOX_TRANSACTION_FLAG_EXTERNAL);
	do {
		if (doveadm_debug) {
			i_debug("import: box=%s uid=%u",
				mailbox, src_mail->uid);
		}
		save_ctx = mailbox_save_alloc(dest_trans);
		if (mailbox_copy(&save_ctx, src_mail) < 0) {
			i_error("Copying box=%s uid=%u failed: %s",
				mailbox, src_mail->uid,
				mail_storage_get_last_error(dest_storage, NULL));
			ret = -1;
		}
	} while (doveadm_mail_iter_next(iter, src_mail));

	if (mailbox_transaction_commit(&dest_trans) < 0) {
		i_error("Committing copied mails to %s failed: %s", mailbox,
			mail_storage_get_last_error(dest_storage, NULL));
		ret = -1;
	}
	return ret;
}
示例#2
0
static int
dest_mailbox_open_or_create(struct import_cmd_context *ctx,
			    struct mail_user *user, const char *name,
			    struct mailbox **box_r)
{
	struct mail_namespace *ns;
	struct mailbox *box;
	enum mail_error error;
	const char *errstr, *storage_name;

	if (*ctx->dest_parent != '\0') {
		/* prefix destination mailbox name with given parent mailbox */
		storage_name = ctx->dest_parent;
		ns = mail_namespace_find(user->namespaces, &storage_name);
		if (ns == NULL) {
			i_error("Can't find namespace for parent mailbox %s",
				ctx->dest_parent);
			return -1;
		}
		name = t_strdup_printf("%s%c%s", ctx->dest_parent,
				       ns->sep, name);
	}

	storage_name = name;
	ns = mail_namespace_find(user->namespaces, &storage_name);
	if (ns == NULL) {
		i_error("Can't find namespace for mailbox %s", name);
		return -1;
	}

	box = mailbox_alloc(ns->list, storage_name, MAILBOX_FLAG_SAVEONLY |
			    MAILBOX_FLAG_KEEP_RECENT);
	if (mailbox_create(box, NULL, FALSE) < 0) {
		errstr = mail_storage_get_last_error(mailbox_get_storage(box),
						     &error);
		if (error != MAIL_ERROR_EXISTS) {
			i_error("Couldn't create mailbox %s: %s", name, errstr);
			mailbox_free(&box);
			return -1;
		}
	}
	if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
		i_error("Syncing mailbox %s failed: %s", name,
			mail_storage_get_last_error(mailbox_get_storage(box),
						    NULL));
		mailbox_free(&box);
		return -1;
	}
	*box_r = box;
	return 0;
}
示例#3
0
static int
cmd_acl_mailbox_open(struct mail_user *user, const char *mailbox,
		     struct mailbox **box_r)
{
	struct acl_user *auser = ACL_USER_CONTEXT(user);
	struct mail_namespace *ns;
	struct mailbox *box;
	const char *storage_name;

	if (auser == NULL) {
		i_error("ACL not enabled for %s", user->username);
		return -1;
	}

	storage_name = mailbox;
	ns = mail_namespace_find(user->namespaces, &storage_name);
	if (ns == NULL) {
		i_error("No namespace found for mailbox %s", mailbox);
		return -1;
	}
	box = mailbox_alloc(ns->list, storage_name,
			    MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT |
			    MAILBOX_FLAG_IGNORE_ACLS);
	if (mailbox_open(box) < 0) {
		i_error("Can't open mailbox %s: %s", mailbox,
			mail_storage_get_last_error(box->storage, NULL));
		mailbox_free(&box);
		return -1;
	}
	*box_r = box;
	return 0;
}
示例#4
0
void virtual_box_copy_error(struct mailbox *dest, struct mailbox *src)
{
	const char *name, *str;
	enum mail_error error;

	name = get_user_visible_mailbox_name(src);
	str = mail_storage_get_last_error(src->storage, &error);

	str = t_strdup_printf("%s (for backend mailbox %s)", str, name);
	mail_storage_set_error(dest->storage, error, str);
}
示例#5
0
static int
ns_purge(struct doveadm_mail_cmd_context *ctx, struct mail_namespace *ns,
	 struct mail_storage *storage)
{
	if (mail_storage_purge(storage) < 0) {
		i_error("Purging namespace '%s' failed: %s", ns->prefix,
			mail_storage_get_last_error(storage, NULL));
		doveadm_mail_failed_storage(ctx, storage);
		return -1;
	}
	return 0;
}
示例#6
0
文件: mail-copy.c 项目: Raffprta/core
static void
mail_copy_set_failed(struct mail_save_context *ctx, struct mail *mail,
		     const char *func)
{
	const char *errstr;
	enum mail_error error;

	if (ctx->transaction->box->storage == mail->box->storage)
		return;

	errstr = mail_storage_get_last_error(mail->box->storage, &error);
	mail_storage_set_error(ctx->transaction->box->storage, error,
			       t_strdup_printf("%s (%s)", errstr, func));
}
示例#7
0
void client_send_untagged_storage_error(struct client *client,
					struct mail_storage *storage)
{
	const char *error_string;
	enum mail_error error;

	error_string = mail_storage_get_last_error(storage, &error);
	client_send_line(client, t_strconcat("* NO ", error_string, NULL));

	if (client->mailbox != NULL &&
	    mailbox_is_inconsistent(client->mailbox)) {
		/* we can't do forced CLOSE, so have to disconnect */
		client_disconnect_with_error(client,
			"IMAP session state is inconsistent, please relogin.");
	}
}
示例#8
0
int imap_msgpart_url_open_mailbox(struct imap_msgpart_url *mpurl,
				  struct mailbox **box_r, enum mail_error *error_code_r,
				  const char **error_r)
{
	struct mailbox_status box_status;
	enum mailbox_flags flags = MAILBOX_FLAG_READONLY;
	struct mail_namespace *ns;
	struct mailbox *box;

	if (mpurl->box != NULL) {
		*box_r = mpurl->box;
		*error_code_r = MAIL_ERROR_NONE;
		return 1;
	}

	/* find mailbox namespace */
	ns = mail_namespace_find(mpurl->user->namespaces, mpurl->mailbox);

	/* open mailbox */
	if (mpurl->selected_box != NULL &&
	    mailbox_equals(mpurl->selected_box, ns, mpurl->mailbox))
		box = mpurl->selected_box;
	else
		box = mailbox_alloc(ns->list, mpurl->mailbox, flags);
	if (mailbox_open(box) < 0) {
		*error_r = mail_storage_get_last_error(mailbox_get_storage(box),
						       error_code_r);
		if (box != mpurl->selected_box)
			mailbox_free(&box);
		return *error_code_r == MAIL_ERROR_TEMP ? -1 : 0;
	}

	/* verify UIDVALIDITY */
	mailbox_get_open_status(box, STATUS_UIDVALIDITY, &box_status);
	if (mpurl->uidvalidity > 0 &&
	    box_status.uidvalidity != mpurl->uidvalidity) {
		*error_r = "Invalid UIDVALIDITY";
		*error_code_r = MAIL_ERROR_EXPUNGED;
		if (box != mpurl->selected_box)
			mailbox_free(&box);
		return 0;
	}
	mpurl->box = box;
	*box_r = box;
	return 1;
}
示例#9
0
void client_send_storage_error(struct client_command_context *cmd,
			       struct mail_storage *storage)
{
	const char *error_string;
	enum mail_error error;

	error_string = mail_storage_get_last_error(storage, &error);
	client_send_tagline(cmd, imap_get_error_string(cmd, error_string,
						       error));

	if (cmd->client->mailbox != NULL &&
	    mailbox_is_inconsistent(cmd->client->mailbox)) {
		/* we can't do forced CLOSE, so have to disconnect */
		client_disconnect_with_error(cmd->client,
			"IMAP session state is inconsistent, please relogin.");
	}
}
示例#10
0
static int snarf(struct mailbox *srcbox, struct mailbox *destbox)
{
	struct mail_search_args *search_args;
	struct mail_search_context *search_ctx;
        struct mailbox_transaction_context *src_trans, *dest_trans;
	struct mail_save_context *save_ctx;
	struct mail *mail;
	enum mail_error error;
	int ret;

	/* make sure the destination mailbox has been opened */
	if (mailbox_open(destbox) < 0)
		return -1;

	if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
		return -1;

	src_trans = mailbox_transaction_begin(srcbox, 0);
	dest_trans = mailbox_transaction_begin(destbox,
					MAILBOX_TRANSACTION_FLAG_EXTERNAL);

	search_args = mail_search_build_init();
	mail_search_build_add_all(search_args);
	search_ctx = mailbox_search_init(src_trans, search_args, NULL);
	mail_search_args_unref(&search_args);

	ret = 0;
	mail = mail_alloc(src_trans, MAIL_FETCH_STREAM_HEADER |
			  MAIL_FETCH_STREAM_BODY, NULL);
	while (mailbox_search_next(search_ctx, mail)) {
		if (mail->expunged)
			continue;

		save_ctx = mailbox_save_alloc(dest_trans);
		if (mailbox_copy(&save_ctx, mail) < 0 && !mail->expunged) {
			(void)mail_storage_get_last_error(destbox->storage,
							  &error);
			/* if we failed because of out of disk space, just
			   move those messages we managed to move so far. */
			if (error != MAIL_ERROR_NOSPACE)
				ret = -1;
			break;
		}
		mail_expunge(mail);
	}
	mail_free(&mail);

	if (mailbox_search_deinit(&search_ctx) < 0)
		ret = -1;

	/* commit the copied messages to the destination mailbox. if we crash
	   between that and between expunging the messages from the source
	   mailbox, we're left with duplicates. */
	if (ret < 0)
		mailbox_transaction_rollback(&dest_trans);
	else if (mailbox_transaction_commit(&dest_trans) < 0)
		ret = -1;

	if (ret < 0)
		mailbox_transaction_rollback(&src_trans);
	else {
		if (mailbox_transaction_commit(&src_trans) < 0)
			ret = -1;
	}
	if (ret == 0) {
		if (mailbox_sync(srcbox, 0) < 0)
			ret = -1;
	}
	return ret;
}