"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/imap/cmd-getmetadata.c" between
dovecot-2.3.7.2.tar.gz and dovecot-2.3.8.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

cmd-getmetadata.c  (dovecot-2.3.7.2):cmd-getmetadata.c  (dovecot-2.3.8)
skipping to change at line 31 skipping to change at line 31
uint32_t maxsize; uint32_t maxsize;
uoff_t largest_seen_size; uoff_t largest_seen_size;
unsigned int depth; unsigned int depth;
struct istream *cur_stream; struct istream *cur_stream;
struct imap_metadata_iter *iter; struct imap_metadata_iter *iter;
string_t *iter_entry_prefix; string_t *iter_entry_prefix;
string_t *delayed_errors; string_t *delayed_errors;
string_t *last_error_str;
enum mail_error last_error;
unsigned int entry_idx; unsigned int entry_idx;
bool first_entry_sent; bool first_entry_sent;
bool failed;
}; };
static bool static bool
cmd_getmetadata_mailbox_iter_next(struct imap_getmetadata_context *ctx); cmd_getmetadata_mailbox_iter_next(struct imap_getmetadata_context *ctx);
static bool static bool
cmd_getmetadata_parse_options(struct imap_getmetadata_context *ctx, cmd_getmetadata_parse_options(struct imap_getmetadata_context *ctx,
const struct imap_arg *options) const struct imap_arg *options)
{ {
const char *value; const char *value;
skipping to change at line 149 skipping to change at line 150
{ {
string_t *str; string_t *str;
/* client requested a specific entry that didn't exist. /* client requested a specific entry that didn't exist.
we must return it as NIL. */ we must return it as NIL. */
str = metadata_add_entry(ctx, entry); str = metadata_add_entry(ctx, entry);
str_append(str, " NIL"); str_append(str, " NIL");
o_stream_nsend(ctx->cmd->client->output, str_data(str), str_len(str)); o_stream_nsend(ctx->cmd->client->output, str_data(str), str_len(str));
} }
static void
cmd_getmetadata_handle_error_str(struct imap_getmetadata_context *ctx,
const char *error_string,
enum mail_error error)
{
if (str_len(ctx->last_error_str) > 0) {
str_append(ctx->delayed_errors, "* NO ");
str_append_str(ctx->delayed_errors, ctx->last_error_str);
str_append(ctx->delayed_errors, "\r\n");
str_truncate(ctx->last_error_str, 0);
}
str_append(ctx->last_error_str, error_string);
ctx->last_error = error;
}
static bool
cmd_getmetadata_handle_error(struct imap_getmetadata_context *ctx,
bool entry_error)
{
const char *error_string;
enum mail_error error;
error_string = imap_metadata_transaction_get_last_error(ctx->trans, &erro
r);
if ((error == MAIL_ERROR_NOTFOUND || error == MAIL_ERROR_PERM) &&
entry_error) {
/* don't treat this as an error */
return FALSE;
}
if (error == MAIL_ERROR_NOTPOSSIBLE && ctx->depth > 0) {
/* Using DEPTH to iterate children with imap_metadata=no.
Don't return an error, since some of the entries could be
returned successfully. */
return FALSE;
}
cmd_getmetadata_handle_error_str(ctx, error_string, error);
return TRUE;
}
static void cmd_getmetadata_send_entry(struct imap_getmetadata_context *ctx, static void cmd_getmetadata_send_entry(struct imap_getmetadata_context *ctx,
const char *entry, bool require_reply) const char *entry, bool require_reply)
{ {
struct client *client = ctx->cmd->client; struct client *client = ctx->cmd->client;
struct mail_attribute_value value; struct mail_attribute_value value;
const char *error_string;
enum mail_error error;
uoff_t value_len; uoff_t value_len;
string_t *str; string_t *str;
if (imap_metadata_get_stream(ctx->trans, entry, &value) < 0) { if (imap_metadata_get_stream(ctx->trans, entry, &value) < 0) {
error_string = imap_metadata_transaction_get_last_error( if (cmd_getmetadata_handle_error(ctx, TRUE))
ctx->trans, &error);
if (error != MAIL_ERROR_NOTFOUND && error != MAIL_ERROR_PERM) {
str_printfa(ctx->delayed_errors, "* NO %s\r\n",
error_string);
ctx->failed = TRUE;
return; return;
}
} }
if (value.value != NULL) if (value.value != NULL)
value_len = strlen(value.value); value_len = strlen(value.value);
else if (value.value_stream != NULL) { else if (value.value_stream != NULL) {
if (i_stream_get_size(value.value_stream, TRUE, &value_len) < 0) { if (i_stream_get_size(value.value_stream, TRUE, &value_len) < 0) {
i_error("GETMETADATA %s: i_stream_get_size(%s) failed: %s ", entry, i_error("GETMETADATA %s: i_stream_get_size(%s) failed: %s ", entry,
i_stream_get_name(value.value_stream), i_stream_get_name(value.value_stream),
i_stream_get_error(value.value_stream)); i_stream_get_error(value.value_stream));
i_stream_unref(&value.value_stream); i_stream_unref(&value.value_stream);
ctx->failed = TRUE; cmd_getmetadata_handle_error_str(ctx,
MAIL_ERRSTR_CRITICAL_MSG, MAIL_ERROR_TEMP);
return; return;
} }
} else { } else {
/* skip nonexistent entries */ /* skip nonexistent entries */
if (require_reply) if (require_reply)
cmd_getmetadata_send_nil_reply(ctx, entry); cmd_getmetadata_send_nil_reply(ctx, entry);
return; return;
} }
if (value_len > ctx->maxsize) { if (value_len > ctx->maxsize) {
skipping to change at line 263 skipping to change at line 296
if (ctx->iter != NULL) { if (ctx->iter != NULL) {
const char *subentry; const char *subentry;
/* DEPTH iteration */ /* DEPTH iteration */
do { do {
subentry = imap_metadata_iter_next(ctx->iter); subentry = imap_metadata_iter_next(ctx->iter);
if (subentry == NULL) { if (subentry == NULL) {
/* iteration finished, get to the next entry */ /* iteration finished, get to the next entry */
if (imap_metadata_iter_deinit(&ctx->iter) < 0) { if (imap_metadata_iter_deinit(&ctx->iter) < 0) {
enum mail_error error; if (!cmd_getmetadata_handle_error(ctx, FA
LSE))
str_printfa(ctx->delayed_errors, "* NO %s i_unreached();
\r\n",
imap_metadata_transaction_get_las
t_error(ctx->trans, &error));
ctx->failed = TRUE;
} }
return -1; return -1;
} }
} while (ctx->depth == 1 && strchr(subentry, '/') != NULL); } while (ctx->depth == 1 && strchr(subentry, '/') != NULL);
entry = t_strconcat(str_c(ctx->iter_entry_prefix), subentry, NULL ); entry = t_strconcat(str_c(ctx->iter_entry_prefix), subentry, NULL );
} }
cmd_getmetadata_send_entry(ctx, entry, ctx->iter == NULL); /* send NIL only on depth 0 query */
cmd_getmetadata_send_entry(ctx, entry, ctx->depth == 0);
if (ctx->cur_stream != NULL) { if (ctx->cur_stream != NULL) {
if (!cmd_getmetadata_stream_continue(ctx)) if (!cmd_getmetadata_stream_continue(ctx))
return 0; return 0;
i_stream_unref(&ctx->cur_stream); i_stream_unref(&ctx->cur_stream);
} }
if (ctx->iter != NULL) { if (ctx->iter != NULL) {
/* already iterating the entry */ /* already iterating the entry */
return 1; return 1;
skipping to change at line 321 skipping to change at line 352
static void cmd_getmetadata_deinit(struct imap_getmetadata_context *ctx) static void cmd_getmetadata_deinit(struct imap_getmetadata_context *ctx)
{ {
struct client_command_context *cmd = ctx->cmd; struct client_command_context *cmd = ctx->cmd;
cmd_getmetadata_iter_deinit(ctx); cmd_getmetadata_iter_deinit(ctx);
cmd->client->output_cmd_lock = NULL; cmd->client->output_cmd_lock = NULL;
if (ctx->list_iter != NULL && if (ctx->list_iter != NULL &&
mailbox_list_iter_deinit(&ctx->list_iter) < 0) mailbox_list_iter_deinit(&ctx->list_iter) < 0)
client_send_list_error(cmd, cmd->client->user->namespaces->list); client_send_list_error(cmd, cmd->client->user->namespaces->list);
else if (ctx->failed) { else if (ctx->last_error != 0) {
client_send_tagline(cmd, "NO Getmetadata failed to send some entr i_assert(str_len(ctx->last_error_str) > 0);
ies"); const char *tagline =
imap_get_error_string(cmd, str_c(ctx->last_error_str),
ctx->last_error);
client_send_tagline(cmd, tagline);
} else if (ctx->largest_seen_size != 0) { } else if (ctx->largest_seen_size != 0) {
client_send_tagline(cmd, t_strdup_printf( client_send_tagline(cmd, t_strdup_printf(
"OK [METADATA LONGENTRIES %"PRIuUOFF_T"] " "OK [METADATA LONGENTRIES %"PRIuUOFF_T"] "
"Getmetadata completed.", ctx->largest_seen_size)); "Getmetadata completed.", ctx->largest_seen_size));
} else { } else {
client_send_tagline(cmd, "OK Getmetadata completed."); client_send_tagline(cmd, "OK Getmetadata completed.");
} }
} }
static bool cmd_getmetadata_continue(struct client_command_context *cmd) static bool cmd_getmetadata_continue(struct client_command_context *cmd)
skipping to change at line 384 skipping to change at line 419
return TRUE; return TRUE;
} }
static bool static bool
cmd_getmetadata_start(struct imap_getmetadata_context *ctx) cmd_getmetadata_start(struct imap_getmetadata_context *ctx)
{ {
struct client_command_context *cmd = ctx->cmd; struct client_command_context *cmd = ctx->cmd;
if (ctx->depth > 0) if (ctx->depth > 0)
ctx->iter_entry_prefix = str_new(cmd->pool, 128); ctx->iter_entry_prefix = str_new(cmd->pool, 128);
imap_metadata_transaction_validated_only(ctx->trans,
!cmd->client->set->imap_metadata);
if (!cmd_getmetadata_continue(cmd)) { if (!cmd_getmetadata_continue(cmd)) {
cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT; cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
cmd->func = cmd_getmetadata_continue; cmd->func = cmd_getmetadata_continue;
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static bool static bool
skipping to change at line 467 skipping to change at line 504
bool cmd_getmetadata(struct client_command_context *cmd) bool cmd_getmetadata(struct client_command_context *cmd)
{ {
struct imap_getmetadata_context *ctx; struct imap_getmetadata_context *ctx;
struct mail_namespace *ns; struct mail_namespace *ns;
const struct imap_arg *args, *options, *entries; const struct imap_arg *args, *options, *entries;
const char *mailbox, *entry_name; const char *mailbox, *entry_name;
if (!client_read_args(cmd, 0, 0, &args)) if (!client_read_args(cmd, 0, 0, &args))
return FALSE; return FALSE;
if (!cmd->client->imap_metadata_enabled) {
client_send_command_error(cmd, "METADATA disabled.");
return TRUE;
}
ctx = p_new(cmd->pool, struct imap_getmetadata_context, 1); ctx = p_new(cmd->pool, struct imap_getmetadata_context, 1);
ctx->cmd = cmd; ctx->cmd = cmd;
ctx->maxsize = (uint32_t)-1; ctx->maxsize = (uint32_t)-1;
ctx->cmd->context = ctx; ctx->cmd->context = ctx;
ctx->delayed_errors = str_new(cmd->pool, 128); ctx->delayed_errors = str_new(cmd->pool, 128);
ctx->last_error_str = str_new(cmd->pool, 128);
if (imap_arg_get_list(&args[0], &options)) { if (imap_arg_get_list(&args[0], &options)) {
if (!cmd_getmetadata_parse_options(ctx, options)) if (!cmd_getmetadata_parse_options(ctx, options))
return TRUE; return TRUE;
args++; args++;
} }
if (!imap_arg_get_astring(&args[0], &mailbox)) { if (!imap_arg_get_astring(&args[0], &mailbox)) {
client_send_command_error(cmd, "Invalid arguments."); client_send_command_error(cmd, "Invalid arguments.");
return TRUE; return TRUE;
} }
 End of changes. 13 change blocks. 
27 lines changed or deleted 59 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)