コード例 #1
0
int client_enable(struct client *client, enum mailbox_feature features)
{
	struct mailbox_status status;
	int ret;

	if ((client->enabled_features & features) == features)
		return 0;

	client->enabled_features |= features;
	if (client->mailbox == NULL)
		return 0;

	ret = mailbox_enable(client->mailbox, features);
	if ((features & MAILBOX_FEATURE_CONDSTORE) != 0 && ret == 0) {
		/* CONDSTORE being enabled while mailbox is selected.
		   Notify client of the latest HIGHESTMODSEQ. */
		ret = mailbox_get_status(client->mailbox,
					 STATUS_HIGHESTMODSEQ, &status);
		if (ret == 0) {
			client_send_line(client, t_strdup_printf(
				"* OK [HIGHESTMODSEQ %llu] Highest",
				(unsigned long long)status.highest_modseq));
		}
	}
	if (ret < 0) {
		client_send_untagged_storage_error(client,
			mailbox_get_storage(client->mailbox));
	}
	return ret;
}
コード例 #2
0
ファイル: imap-status.c プロジェクト: bdraco/core
int imap_status_get(struct client_command_context *cmd,
		    struct mail_namespace *ns, const char *mailbox,
		    const struct imap_status_items *items,
		    struct imap_status_result *result_r)
{
	struct client *client = cmd->client;
	struct mailbox *box;
	const char *errstr;
	int ret = 0;

	if (client->mailbox != NULL &&
	    mailbox_equals(client->mailbox, ns, mailbox)) {
		/* this mailbox is selected */
		box = client->mailbox;
	} else {
		/* open the mailbox */
		box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_READONLY);
		mailbox_set_reason(box, "STATUS");
		if (client->enabled_features != 0)
			(void)mailbox_enable(box, client->enabled_features);
	}

	if ((items->status & STATUS_HIGHESTMODSEQ) != 0)
		(void)client_enable(client, MAILBOX_FEATURE_CONDSTORE);

	ret = mailbox_get_status(box, items->status, &result_r->status);
	if (items->metadata != 0 && ret == 0) {
		ret = mailbox_get_metadata(box, items->metadata,
					   &result_r->metadata);
	}

	if (ret < 0) {
		errstr = mailbox_get_last_error(box, &result_r->error);
		result_r->errstr = imap_get_error_string(cmd, errstr,
							 result_r->error);
	}
	if (box != client->mailbox)
		mailbox_free(&box);
	return ret;
}
コード例 #3
0
int client_open_save_dest_box(struct client_command_context *cmd,
			      const char *name, struct mailbox **destbox_r)
{
	struct mail_namespace *ns;
	struct mailbox *box;
	const char *error_string;
	enum mail_error error;

	ns = client_find_namespace(cmd, &name);
	if (ns == NULL)
		return -1;

	if (cmd->client->mailbox != NULL &&
	    mailbox_equals(cmd->client->mailbox, ns, name)) {
		*destbox_r = cmd->client->mailbox;
		return 0;
	}
	box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_SAVEONLY);
	if (mailbox_open(box) < 0) {
		error_string = mailbox_get_last_error(box, &error);
		if (error == MAIL_ERROR_NOTFOUND) {
			client_send_tagline(cmd,  t_strdup_printf(
				"NO [TRYCREATE] %s", error_string));
		} else {
			client_send_box_error(cmd, box);
		}
		mailbox_free(&box);
		return -1;
	}
	if (cmd->client->enabled_features != 0) {
		if (mailbox_enable(box, cmd->client->enabled_features) < 0) {
			client_send_box_error(cmd, box);
			mailbox_free(&box);
			return -1;
		}
	}
	*destbox_r = box;
	return 0;
}
コード例 #4
0
ファイル: cmd-copy.c プロジェクト: aosm/dovecot
bool cmd_copy(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct mail_namespace *dest_ns;
	struct mail_storage *dest_storage;
	struct mailbox *destbox;
	struct mailbox_transaction_context *t;
        struct mail_search_args *search_args;
	const char *messageset, *mailbox, *storage_name, *src_uidset;
	enum mailbox_name_status status;
	enum mailbox_sync_flags sync_flags = 0;
	enum imap_sync_flags imap_flags = 0;
	struct mail_transaction_commit_changes changes;
	unsigned int copy_count;
	string_t *msg;
	int ret;

	/* <message set> <mailbox> */
	if (!client_read_string_args(cmd, 2, &messageset, &mailbox))
		return FALSE;

	if (!client_verify_open_mailbox(cmd))
		return TRUE;

	ret = imap_search_get_seqset(cmd, messageset, cmd->uid, &search_args);
	if (ret <= 0)
		return ret < 0;

	/* open the destination mailbox */
	dest_ns = client_find_namespace(cmd, mailbox, &storage_name, &status);
	if (dest_ns == NULL) {
		mail_search_args_unref(&search_args);
		return TRUE;
	}

	switch (status) {
	case MAILBOX_NAME_EXISTS_MAILBOX:
		break;
	case MAILBOX_NAME_EXISTS_DIR:
		status = MAILBOX_NAME_VALID;
		/* fall through */
	case MAILBOX_NAME_VALID:
	case MAILBOX_NAME_INVALID:
	case MAILBOX_NAME_NOINFERIORS:
		client_fail_mailbox_name_status(cmd, mailbox,
						"TRYCREATE", status);
		mail_search_args_unref(&search_args);
		return TRUE;
	}

	if (mailbox_equals(client->mailbox, dest_ns, storage_name))
		destbox = client->mailbox;
	else {
		destbox = mailbox_alloc(dest_ns->list, storage_name,
					MAILBOX_FLAG_SAVEONLY |
					MAILBOX_FLAG_KEEP_RECENT);
		if (mailbox_open(destbox) < 0) {
			client_send_storage_error(cmd,
				mailbox_get_storage(destbox));
			mailbox_free(&destbox);
			mail_search_args_unref(&search_args);
			return TRUE;
		}
		if (client->enabled_features != 0)
			mailbox_enable(destbox, client->enabled_features);
	}

	t = mailbox_transaction_begin(destbox,
				      MAILBOX_TRANSACTION_FLAG_EXTERNAL |
				      MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS);
	ret = fetch_and_copy(client, t, search_args, &src_uidset, &copy_count);
	mail_search_args_unref(&search_args);

	msg = t_str_new(256);
	if (ret <= 0)
		mailbox_transaction_rollback(&t);
	else if (mailbox_transaction_commit_get_changes(&t, &changes) < 0)
		ret = -1;
	else if (copy_count == 0) {
		str_append(msg, "OK No messages copied.");
		pool_unref(&changes.pool);
	} else if (seq_range_count(&changes.saved_uids) == 0) {
		/* not supported by backend (virtual) */
		str_append(msg, "OK Copy completed.");
		pool_unref(&changes.pool);
	} else {
		i_assert(copy_count == seq_range_count(&changes.saved_uids));

		str_printfa(msg, "OK [COPYUID %u %s ", changes.uid_validity,
			    src_uidset);
		imap_write_seq_range(msg, &changes.saved_uids);
		str_append(msg, "] Copy completed.");
		pool_unref(&changes.pool);
	}

	dest_storage = mailbox_get_storage(destbox);
	if (destbox != client->mailbox) {
		sync_flags |= MAILBOX_SYNC_FLAG_FAST;
		imap_flags |= IMAP_SYNC_FLAG_SAFE;
		mailbox_free(&destbox);
	}

	if (ret > 0)
		return cmd_sync(cmd, sync_flags, imap_flags, str_c(msg));
	else if (ret == 0) {
		/* some messages were expunged, sync them */
		return cmd_sync(cmd, 0, 0,
			"NO ["IMAP_RESP_CODE_EXPUNGEISSUED"] "
			"Some of the requested messages no longer exist.");
	} else {
		client_send_storage_error(cmd, dest_storage);
		return TRUE;
	}
}