struct doveadm_mail_cmd_context ctx;
struct mail *mail;
+ pool_t temp_pool;
ARRAY(struct fetch_field) fields;
ARRAY_TYPE(const_string) header_fields;
static int fetch_hdr_field(struct fetch_cmd_context *ctx)
{
const char *const *value, *filter, *name = ctx->cur_field->name;
- string_t *str = t_str_new(256);
+ string_t *str;
bool add_lf = FALSE;
+ p_clear(ctx->temp_pool);
filter = strchr(name, '.');
if (filter != NULL)
name = t_strdup_until(name, filter++);
return -1;
}
+ str = str_new(ctx->temp_pool, 256);
for (; *value != NULL; value++) {
if (add_lf)
str_append_c(str, '\n');
strcmp(filter, "address_name.utf8") == 0) {
struct message_address *addr;
- addr = message_address_parse(pool_datastack_create(),
+ addr = message_address_parse(ctx->temp_pool,
str_data(str), str_len(str),
UINT_MAX, 0);
str_truncate(str, 0);
if (!doveadm_cmd_param_array(cctx, "query", &query))
doveadm_mail_help_name("fetch");
+ ctx->temp_pool = pool_alloconly_create("doveadm fetch", 1024);
parse_fetch_fields(ctx, fields);
_ctx->search_args = doveadm_mail_build_search_args(query);
}
+static void cmd_fetch_deinit(struct doveadm_mail_cmd_context *_ctx)
+{
+ struct fetch_cmd_context *ctx =
+ container_of(_ctx, struct fetch_cmd_context, ctx);
+
+ pool_unref(&ctx->temp_pool);
+}
+
static struct doveadm_mail_cmd_context *cmd_fetch_alloc(void)
{
struct fetch_cmd_context *ctx;
ctx = doveadm_mail_cmd_alloc(struct fetch_cmd_context);
ctx->ctx.v.init = cmd_fetch_init;
+ ctx->ctx.v.deinit = cmd_fetch_deinit;
ctx->ctx.v.run = cmd_fetch_run;
doveadm_print_init(DOVEADM_PRINT_TYPE_PAGER);
return &ctx->ctx;
NULL, 0, NULL);
mail_search_args_unref(&search_args);
- t_array_init(&src_uids, 64);
+ i_array_init(&src_uids, 64);
ret = 1;
while (mailbox_search_next(search_ctx, &mail) && ret > 0) {
if (mail->expunged) {
copy_update_trashed(client, copy_ctx->destbox, copy_ctx->copy_count);
pool_unref(&changes.pool);
}
+ array_free(&src_uids);
if (!copy_ctx->move ||
copy_ctx->srcbox == copy_ctx->destbox) {
rfc822_parser_init(&ctx.parser, data, size, t_str_new(128));
ctx.parser.nul_replacement_str = RFC822_NUL_REPLACEMENT_STR;
ctx.pool = pool;
- ctx.str = t_str_new(128);
+ ctx.str = str_new(default_pool, 128);
ctx.fill_missing = (flags & MESSAGE_ADDRESS_PARSE_FLAG_FILL_MISSING) != 0;
ctx.non_strict_dots = (flags & MESSAGE_ADDRESS_PARSE_FLAG_STRICT_DOTS) == 0;
(void)parse_address_list(&ctx, max_addresses);
}
rfc822_parser_deinit(&ctx.parser);
+ str_free(&ctx.str);
return ctx.first_addr;
}
rfc822_parser_init(&ctx.parser, data, size, NULL);
ctx.pool = pool;
- ctx.str = t_str_new(128);
+ ctx.str = str_new(default_pool, 128);
ret = parse_path(&ctx);
rfc822_parser_deinit(&ctx.parser);
+ str_free(&ctx.str);
*addr_r = ctx.first_addr;
return (ret < 0 ? -1 : 0);
}
message_decoder_decode_reset(ctx->decoder);
}
-static int
-message_search_msg_real(struct message_search_context *ctx,
- struct istream *input, struct message_part *parts,
- const char **error_r)
+int message_search_msg(struct message_search_context *ctx,
+ struct istream *input, struct message_part *parts,
+ const char **error_r)
{
const struct message_parser_settings parser_set = {
.hdr_flags = MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
struct message_parser_ctx *parser_ctx;
struct message_block raw_block;
struct message_part *new_parts;
+ pool_t pool = NULL;
int ret;
message_search_reset(ctx);
parser_ctx = message_parser_init_from_parts(parts,
input, &parser_set);
} else {
- parser_ctx = message_parser_init(pool_datastack_create(),
- input, &parser_set);
+ pool = pool_alloconly_create("message search parts", 1024);
+ parser_ctx = message_parser_init(pool, input, &parser_set);
}
while ((ret = message_parser_parse_next_block(parser_ctx,
/* broken parts */
ret = -1;
}
- return ret;
-}
-
-int message_search_msg(struct message_search_context *ctx,
- struct istream *input, struct message_part *parts,
- const char **error_r)
-{
- int ret;
-
- T_BEGIN {
- ret = message_search_msg_real(ctx, input, parts, error_r);
- } T_END_PASS_STR_IF(ret < 0, error_r);
+ pool_unref(&pool);
return ret;
}
lines = array_get(&mail->header_lines, &count);
match = array_get(&mail->header_match, &match_count);
header = mail->header_data->data;
- buf = t_buffer_create(256);
+ pool_t pool = pool_alloconly_create("index mail header", 512);
+ buf = buffer_create_dynamic(pool, 256);
/* go through all the header lines we found */
for (i = match_idx = 0; i < count; i = j) {
mail->data.dont_cache_field_idx = UINT_MAX;
index_mail_parse_header_deinit(mail);
+ pool_unref(&pool);
}
static unsigned int
count = max_count;
decoded_list = p_new(mail->mail.data_pool, const char *, count + 1);
- str = t_str_new(512);
+ str = str_new(default_pool, 512);
for (i = 0; i < count; i++) {
str_truncate(str, 0);
input = list[i];
/* unfold all lines into a single line */
- if (unfold_header(mail->mail.data_pool, &input) < 0)
+ if (unfold_header(mail->mail.data_pool, &input) < 0) {
+ str_free(&str);
return -1;
+ }
/* decode MIME encoded-words. decoding may also add new LFs. */
message_header_decode_utf8((const unsigned char *)input,
}
decoded_list[i] = input;
}
+ str_free(&str);
*_list = decoded_list;
return 0;
}
return;
}
- T_BEGIN {
- buffer = t_buffer_create(1024);
- message_part_serialize(mail->data.parts, buffer);
- index_mail_cache_add_idx(mail, cache_field,
- buffer->data, buffer->used);
- } T_END;
+ pool_t pool = pool_alloconly_create("mail parts", 2048);
+ buffer = buffer_create_dynamic(pool, 1024);
+ message_part_serialize(mail->data.parts, buffer);
+ index_mail_cache_add_idx(mail, cache_field,
+ buffer->data, buffer->used);
+ pool_unref(&pool);
data->messageparts_saved_to_cache = TRUE;
}
struct mail *cur_mail;
struct index_mail *cur_imail;
struct mail_thread_context *thread_ctx;
+ pool_t temp_pool;
struct timeval search_start_time, last_notify;
struct timeval last_nonblock_timeval;
}
}
+static pool_t
+search_context_temp_pool(struct index_search_context *ctx, size_t size)
+{
+ if (ctx->temp_pool != NULL) {
+ p_clear(ctx->temp_pool);
+ return ctx->temp_pool;
+ }
+
+ if (size <= 1024)
+ return pool_datastack_create();
+ /* This could just as well be allocated from data stack, but it
+ makes it more difficult to track bad data_stack_grow events.
+ Use a temporary memory pool instead. */
+ ctx->temp_pool = pool_alloconly_create("search context temp", size);
+ return ctx->temp_pool;
+}
+
static void search_header_arg(struct mail_search_arg *arg,
struct search_header_context *ctx)
{
case SEARCH_HEADER:
/* simple match */
break;
- case SEARCH_HEADER_ADDRESS:
+ case SEARCH_HEADER_ADDRESS: {
/* we have to match against normalized address */
- addr = message_address_parse(pool_datastack_create(),
+ pool_t pool = search_context_temp_pool(ctx->index_ctx,
+ ctx->hdr->full_value_len);
+ addr = message_address_parse(pool,
ctx->hdr->full_value,
ctx->hdr->full_value_len,
UINT_MAX,
MESSAGE_ADDRESS_PARSE_FLAG_FILL_MISSING);
- str = t_str_new(ctx->hdr->value_len);
+ str = str_new(pool, ctx->hdr->value_len);
message_address_write(str, addr);
hdr.value = hdr.full_value = str_data(str);
hdr.value_len = hdr.full_value_len = str_len(str);
break;
- case SEARCH_HEADER_COMPRESS_LWSP:
+ }
+ case SEARCH_HEADER_COMPRESS_LWSP: {
/* convert LWSP to single spaces */
- str = t_str_new(hdr.full_value_len);
+ pool_t pool = search_context_temp_pool(ctx->index_ctx,
+ hdr.full_value_len);
+ str = str_new(pool, hdr.full_value_len);
compress_lwsp(str, hdr.full_value, hdr.full_value_len);
hdr.value = hdr.full_value = str_data(str);
hdr.value_len = hdr.full_value_len = str_len(str);
break;
+ }
default:
i_unreached();
}
if (ctx->failed)
mail_storage_last_error_pop(ctx->box->storage);
array_free(&ctx->mail_ctx.mails);
+ pool_unref(&ctx->temp_pool);
i_free(ctx);
return ret;
}
&dest_metadata) < 0)
i_unreached();
- buf = t_buffer_create(1024);
+ buf = buffer_create_dynamic(default_pool, 1024);
array_foreach(src_metadata.cache_fields, field) {
mail_copy_cache_field(ctx, src_mail, dest_seq,
field->name, buf);
}
index_copy_vsize_extension(ctx, src_mail, dest_seq);
+ buffer_free(&buf);
} T_END;
}
/* put files into an array sorted by the destination filename.
this way we can easily check if there are duplicate destination
filenames within this transaction. */
- t_array_init(&files, ctx->files_count);
+ p_array_init(&files, ctx->pool, ctx->files_count);
for (mf = ctx->files; mf != NULL; mf = mf->next)
array_push_back(&files, &mf);
array_sort(&files, maildir_filename_dest_basename_cmp);
ctx.pending_input = buffer_create_dynamic(default_pool, 128);
prev_part = NULL;
- parser = message_parser_init(pool_datastack_create(), input, &parser_set);
+ pool_t parts_pool = pool_alloconly_create("fts message parts", 512);
+ parser = message_parser_init(parts_pool, input, &parser_set);
decoder = message_decoder_init(update_ctx->normalizer, 0);
for (;;) {
i_free(ctx.content_disposition);
buffer_free(&ctx.word_buf);
buffer_free(&ctx.pending_input);
+ pool_unref(&parts_pool);
return ret < 0 ? -1 : 1;
}