doveadm-mail-fetch.c revision e4ac89c5e7bb96598a47011993718f0e654912b4
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ARRAY_DEFINE(fields, const struct fetch_field);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_mailbox(struct fetch_context *ctx)
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, &value) < 0)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenstatic int fetch_mailbox_guid(struct fetch_context *ctx)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen if (mailbox_get_guid(ctx->mail->box, guid) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(ctx->hdr, mail_guid_128_to_string(guid));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_seq(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_uid(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_guid(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &value) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_flags(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen imap_write_flags(ctx->hdr, mail_get_flags(ctx->mail),
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void flush_hdr(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen o_stream_send(ctx->output, str_data(ctx->hdr), str_len(ctx->hdr));
ca843e046e98b12f4730f4b87ee2e1a659c26e78Timo Sirainenstatic int fetch_hdr(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen input = i_stream_create_limit(input, hdr_size.physical_size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (o_stream_send_istream(ctx->output, input) <= 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_body(struct fetch_context *ctx)
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (o_stream_send_istream(ctx->output, input) <= 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_text(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen if (o_stream_send_istream(ctx->output, input) <= 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_size_physical(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mail_get_physical_size(ctx->mail, &size) < 0)
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainenstatic int fetch_size_virtual(struct fetch_context *ctx)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen if (mail_get_virtual_size(ctx->mail, &size) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_date_received(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mail_get_received_date(ctx->mail, &t) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int fetch_date_sent(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(ctx->hdr, "%s (%c%02u%02u)", unixdate2str(t),
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainenstatic int fetch_date_saved(struct fetch_context *ctx)
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainenstatic const struct fetch_field fetch_fields[] = {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { "hdr", MAIL_FETCH_STREAM_HEADER, fetch_hdr },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { "body", MAIL_FETCH_STREAM_BODY, fetch_body },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { "size.physical", MAIL_FETCH_PHYSICAL_SIZE, fetch_size_physical },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { "size.virtual", MAIL_FETCH_VIRTUAL_SIZE, fetch_size_virtual },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { "date.received", MAIL_FETCH_RECEIVED_DATE, fetch_date_received },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { "date.sent", MAIL_FETCH_DATE, fetch_date_sent },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { "date.saved", MAIL_FETCH_SAVE_DATE, fetch_date_saved }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic const struct fetch_field *fetch_field_find(const char *name)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int i;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (i = 0; i < N_ELEMENTS(fetch_fields); i++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void print_fetch_fields(void)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int i;
18f1bbf05980d3c53ecae81b62574212f0891522Timo Sirainen fprintf(stderr, "Available fetch fields: %s", fetch_fields[0].name);
77f1da4b5e2b800197d8db548235497d5e9d6a4fTimo Sirainen for (i = 1; i < N_ELEMENTS(fetch_fields); i++)
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainenstatic void parse_fetch_fields(struct fetch_context *ctx, const char *str)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ctx->print_field_prefix = array_count(&ctx->fields) > 1;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void cmd_fetch_mail(struct fetch_context *ctx)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_error("fetch(%s) failed for box=%s uid=%u: %s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail->uid, mail_storage_get_last_error(storage, NULL));
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainencmd_fetch_box(struct fetch_context *ctx, const struct mailbox_info *info)
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen if (doveadm_mail_iter_init(info, ctx->search_args, &trans, &iter) < 0)
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen mail = mail_alloc(trans, ctx->wanted_fields, NULL);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic bool search_args_have_unique_fetch(struct mail_search_args *args)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int count;
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen for (arg = args->args; arg != NULL; arg = arg->next) {
c51644e9e04effbbc9c415cadcfbcb4d9465855cTimo Sirainen seqset = array_get(&arg->value.seqset, &count);
c51644e9e04effbbc9c415cadcfbcb4d9465855cTimo Sirainen if (count == 1 && seqset->seq1 == seqset->seq2)
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainenvoid cmd_fetch(struct mail_user *user, const char *const args[])
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen const enum mailbox_list_iter_flags iter_flags =
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ctx.search_args = doveadm_mail_build_search_args(args + 1);
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen ctx.output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen if (search_args_have_unique_fetch(ctx.search_args))
280503e88a6b2f72a32a8fbe363794abaaa845d6Timo Sirainen random_fill_weak(prefix_buf, sizeof(prefix_buf));
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen base64_encode(prefix_buf, sizeof(prefix_buf), ctx.hdr);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen iter = doveadm_mail_list_iter_init(user, ctx.search_args, iter_flags);