cmd-setmetadata.c revision 8855b8b57050fe3b6dc3f19283488512fae98648
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "ioloop.h"
#include "istream.h"
#include "istream-seekable.h"
#include "ostream.h"
#include "str.h"
#include "imap-metadata.h"
struct imap_setmetadata_context {
struct client_command_context *cmd;
struct imap_parser *parser;
const char *key_prefix;
struct mailbox_transaction_context *trans;
char *entry_name;
bool failed;
bool cmd_error_sent;
bool storage_failure;
};
{
}
static int
const char **entry_r,
{
int ret;
bool fatal;
/* parse the entry name */
if (ret >= 0) {
if (ret == 0) {
/* ')' found */
return 1;
}
"Entry name isn't astring");
return -1;
}
}
if (ret < 0) {
if (ret == -2)
return 0;
if (fatal) {
return -1;
}
return -1;
}
return -1;
}
if (ctx->cmd_error_sent ||
/* client won't see "+ OK", so we can abort
immediately */
return -1;
}
}
/* entry names are case-insensitive. handle this by using only
lowercase names. */
return 1;
}
static int
{
const unsigned char *data;
enum mail_attribute_type type;
const char *key;
struct mail_attribute_value value;
int ret;
/* finished reading the value */
return 1;
}
/* delay reporting the failure so we'll finish
reading the command input */
}
return 1;
}
/* client disconnected */
return -1;
}
return 0;
}
static int
const char *entry_name,
const struct imap_arg *entry_value)
{
enum mail_attribute_type type;
const char *key;
struct mail_attribute_value value;
int ret;
switch (entry_value->type) {
case IMAP_ARG_NIL:
case IMAP_ARG_ATOM:
case IMAP_ARG_STRING:
/* we have the value already */
return 1;
if (ret < 0) {
/* delay reporting the failure so we'll finish
reading the command input */
}
return 1;
case IMAP_ARG_LITERAL_SIZE:
/* fall through */
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();
}
{
const char *entry;
int ret;
return TRUE;
}
return FALSE;
if (ret < 0) {
return TRUE;
}
}
if (ret <= 0)
break;
}
if (ret == 0)
return 0;
/* already sent the error to client */ ;
else if (ctx->storage_failure)
else
return TRUE;
}
{
struct imap_setmetadata_context *ctx;
const char *mailbox;
struct mail_namespace *ns;
int ret;
if (ret == -1) {
return TRUE;
}
if (ret == -2)
return FALSE;
return TRUE;
}
return TRUE;
}
if (mailbox[0] == '\0') {
/* server attribute */
mailbox = "INBOX";
} else {
return TRUE;
}
else {
return TRUE;
}
}
/* we support large literals, so read the values from client
asynchronously the same way as APPEND does. */
return cmd_setmetadata_continue(cmd);
}