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); }
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); }
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(); }