Example #1
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];
    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 */
        if (ctx->failed)
            return 1;
        memset(&value, 0, sizeof(value));
        value.value = imap_arg_as_nstring(entry_value);
        ret = imap_metadata_set(ctx->trans, entry_name, &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();
}
Example #2
0
static bool cmd_setmetadata_continue(struct client_command_context *cmd)
{
    struct imap_setmetadata_context *ctx = cmd->context;
    const char *entry, *error_string;
    enum mail_error error;
    const struct imap_arg *value;
    int ret;

    if (cmd->cancel) {
        cmd_setmetadata_deinit(ctx);
        return TRUE;
    }

    if (ctx->input != NULL) {
        if ((ret = cmd_setmetadata_entry_read_stream(ctx)) == 0)
            return FALSE;
        if (ret < 0) {
            cmd_setmetadata_deinit(ctx);
            return TRUE;
        }
    }

    while ((ret = cmd_setmetadata_parse_entryvalue(ctx, &entry, &value)) > 0 &&
            entry != NULL) {
        ret = ctx->failed ? 1 :
              cmd_setmetadata_entry(ctx, entry, value);
        imap_parser_reset(ctx->parser);
        if (ret <= 0)
            break;
    }
    if (ret == 0)
        return 0;

    if (ret < 0 || ctx->cmd_error_sent) {
        /* already sent the error to client */ ;
    } else if (ctx->storage_failure) {
        if (ctx->box == NULL)
            client_disconnect_if_inconsistent(cmd->client);
        error_string = imap_metadata_transaction_get_last_error
                       (ctx->trans, &error);
        client_send_tagline(cmd,
                            imap_get_error_string(cmd, error_string, error));
    } else if (imap_metadata_transaction_commit(&ctx->trans,
               &error, &error_string) < 0) {
        if (ctx->box == NULL)
            client_disconnect_if_inconsistent(cmd->client);
        client_send_tagline(cmd,
                            imap_get_error_string(cmd, error_string, error));
    } else {
        client_send_tagline(cmd, "OK Setmetadata completed.");
    }
    cmd_setmetadata_deinit(ctx);
    return TRUE;
}
static bool cmd_setmetadata_continue(struct client_command_context *cmd)
{
	struct imap_setmetadata_context *ctx = cmd->context;
	const char *entry;
	const struct imap_arg *value;
	int ret;

	if (cmd->cancel) {
		cmd_setmetadata_deinit(ctx);
		return TRUE;
	}

	if (ctx->input != NULL) {
		if ((ret = cmd_setmetadata_entry_read_stream(ctx)) == 0)
			return FALSE;
		if (ret < 0) {
			cmd_setmetadata_deinit(ctx);
			return TRUE;
		}
	}

	while ((ret = cmd_setmetadata_parse_entryvalue(ctx, &entry, &value)) > 0 &&
	       entry != NULL) {
		ret = ctx->failed ? 1 :
			cmd_setmetadata_entry(ctx, entry, value);
		imap_parser_reset(ctx->parser);
		if (ret <= 0)
			break;
	}
	if (ret == 0)
		return 0;

	if (ret < 0 || ctx->cmd_error_sent)
		/* already sent the error to client */ ;
	else if (ctx->storage_failure)
		client_send_box_error(cmd, ctx->box);
	else if (mailbox_transaction_commit(&ctx->trans) < 0)
		client_send_box_error(cmd, ctx->box);
	else
		client_send_tagline(cmd, "OK Setmetadata completed.");
	cmd_setmetadata_deinit(ctx);
	return TRUE;
}