Example #1
0
int imap_metadata_get_stream(struct imap_metadata_transaction *imtrans,
		      const char *entry, struct mail_attribute_value *value_r)
{
	enum mail_attribute_type type;
	const char *key;

	i_zero(value_r);
	if (!imap_metadata_entry2key(imtrans, entry, &type, &key))
		return 0;
	return mailbox_attribute_get_stream(imtrans->box, type, key, value_r);
}
Example #2
0
int imap_metadata_get_stream(struct imap_metadata_transaction *imtrans,
		      const char *entry, struct mail_attribute_value *value_r)
{
	enum mail_attribute_type type;
	const char *key;

	memset(value_r, 0, sizeof(*value_r));
	if (!imap_metadata_entry2key(imtrans, entry, &type, &key))
		return 0;
	if (imap_metadata_get_mailbox_transaction(imtrans) < 0)
		return -1;
	return mailbox_attribute_get_stream(imtrans->trans, type, key, value_r);
}
Example #3
0
int imap_metadata_set(struct imap_metadata_transaction *imtrans,
	const char *entry, const struct mail_attribute_value *value)
{
	enum mail_attribute_type type;
	const char *key;

	if (!imap_metadata_entry2key(imtrans, entry, &type, &key)) {
		imap_metadata_transaction_set_error(imtrans, MAIL_ERROR_PARAMS,
			"Internal mailbox attributes cannot be accessed");
		return -1;
	}

	if (imap_metadata_get_mailbox_transaction(imtrans) < 0)
		return -1;
	return (value->value == NULL ?
		mailbox_attribute_unset(imtrans->trans, type, key) :
		mailbox_attribute_set(imtrans->trans, type, key, value));
}
static int
cmd_setmetadata_entry_read_stream(struct imap_setmetadata_context *ctx)
{
	const unsigned char *data;
	size_t size;
	enum mail_attribute_type type;
	const char *key;
	struct mail_attribute_value value;
	int ret;

	while ((ret = i_stream_read_data(ctx->input, &data, &size, 0)) > 0)
		i_stream_skip(ctx->input, size);
	if (ctx->input->v_offset == ctx->entry_value_len) {
		/* finished reading the value */
		i_stream_seek(ctx->input, 0);

		if (ctx->failed) {
			i_stream_unref(&ctx->input);
			return 1;
		}

		imap_metadata_entry2key(ctx->entry_name, ctx->key_prefix,
					&type, &key);
		memset(&value, 0, sizeof(value));
		value.value_stream = ctx->input;
		if (mailbox_attribute_set(ctx->trans, type, key, &value) < 0) {
			/* delay reporting the failure so we'll finish
			   reading the command input */
			ctx->storage_failure = TRUE;
			ctx->failed = TRUE;
		}
		i_stream_unref(&ctx->input);
		return 1;
	}
	if (ctx->input->eof) {
		/* client disconnected */
		return -1;
	}
	return 0;
}
static int
cmd_setmetadata_entry(struct imap_setmetadata_context *ctx,
		      const char *entry_name,
		      const struct imap_arg *entry_value)
{
	struct istream *inputs[2];
	enum mail_attribute_type type;
	const char *key;
	struct mail_attribute_value value;
	string_t *path;
	int ret;

	switch (entry_value->type) {
	case IMAP_ARG_NIL:
	case IMAP_ARG_ATOM:
	case IMAP_ARG_STRING:
		/* we have the value already */
		imap_metadata_entry2key(entry_name, ctx->key_prefix,
					&type, &key);
		if (ctx->failed)
			return 1;
		memset(&value, 0, sizeof(value));
		value.value = imap_arg_as_nstring(entry_value);
		ret = value.value == NULL ?
			mailbox_attribute_unset(ctx->trans, type, key) :
			mailbox_attribute_set(ctx->trans, type, key, &value);
		if (ret < 0) {
			/* delay reporting the failure so we'll finish
			   reading the command input */
			ctx->storage_failure = TRUE;
			ctx->failed = TRUE;
		}
		return 1;
	case IMAP_ARG_LITERAL_SIZE:
		o_stream_nsend(ctx->cmd->client->output, "+ OK\r\n", 6);
		o_stream_nflush(ctx->cmd->client->output);
		o_stream_uncork(ctx->cmd->client->output);
		o_stream_cork(ctx->cmd->client->output);
		/* fall through */
	case IMAP_ARG_LITERAL_SIZE_NONSYNC:
		i_free(ctx->entry_name);
		ctx->entry_name = i_strdup(entry_name);
		ctx->entry_value_len = imap_arg_as_literal_size(entry_value);

		inputs[0] = i_stream_create_limit(ctx->cmd->client->input,
						  ctx->entry_value_len);
		inputs[1] = NULL;

		path = t_str_new(128);
		mail_user_set_get_temp_prefix(path, ctx->cmd->client->user->set);
		ctx->input = i_stream_create_seekable_path(inputs,
					METADATA_MAX_INMEM_SIZE, str_c(path));
		i_stream_set_name(ctx->input, i_stream_get_name(inputs[0]));
		i_stream_unref(&inputs[0]);
		return cmd_setmetadata_entry_read_stream(ctx);
	case IMAP_ARG_LITERAL:
	case IMAP_ARG_LIST:
	case IMAP_ARG_EOL:
		break;
	}
	i_unreached();
}