doveadm-mail-fetch.c revision 23878bd03d1de531e3261a25598beec621351910
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
7d75b95c260e58ee5039fa3afd79e9fda3bc8002Timo Sirainen ARRAY_DEFINE(fields, const struct fetch_field);
7d75b95c260e58ee5039fa3afd79e9fda3bc8002Timo Sirainenstatic int fetch_mailbox(struct fetch_cmd_context *ctx)
7d75b95c260e58ee5039fa3afd79e9fda3bc8002Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, &value) < 0)
6b85bc4b03e552cfaeeae872d63c2d8ac5fcb7c4Timo Sirainenstatic int fetch_mailbox_guid(struct fetch_cmd_context *ctx)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (mailbox_get_guid(ctx->mail->box, guid) < 0)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen str_append(ctx->hdr, mail_guid_128_to_string(guid));
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainenstatic int fetch_seq(struct fetch_cmd_context *ctx)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic int fetch_uid(struct fetch_cmd_context *ctx)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic int fetch_guid(struct fetch_cmd_context *ctx)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &value) < 0)
1171f0abf442638bac1827bb24a0b6b8eb682a82Timo Sirainenstatic int fetch_flags(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_write_flags(ctx->hdr, mail_get_flags(ctx->mail),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void flush_hdr(struct fetch_cmd_context *ctx)
7d75b95c260e58ee5039fa3afd79e9fda3bc8002Timo Sirainen o_stream_send(ctx->output, str_data(ctx->hdr), str_len(ctx->hdr));
7d75b95c260e58ee5039fa3afd79e9fda3bc8002Timo Sirainenstatic int fetch_hdr(struct fetch_cmd_context *ctx)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen input = i_stream_create_limit(input, hdr_size.physical_size);
6237f743bbaf74de5a2d2051672baed87023657bTimo Sirainen if (o_stream_send_istream(ctx->output, input) <= 0)
fd44baee6e92f13d42ff711895d6510067f70955Timo Sirainenstatic int fetch_body(struct fetch_cmd_context *ctx)
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainen if (o_stream_send_istream(ctx->output, input) <= 0)
fd44baee6e92f13d42ff711895d6510067f70955Timo Sirainenstatic int fetch_text(struct fetch_cmd_context *ctx)
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainen if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
c740209eb3db031022c6fd436fa2ef1aa0ec46b8Timo Sirainen if (o_stream_send_istream(ctx->output, input) <= 0)
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainenstatic int fetch_size_physical(struct fetch_cmd_context *ctx)
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen if (mail_get_physical_size(ctx->mail, &size) < 0)
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainenstatic int fetch_size_virtual(struct fetch_cmd_context *ctx)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (mail_get_virtual_size(ctx->mail, &size) < 0)
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainenstatic int fetch_date_received(struct fetch_cmd_context *ctx)
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainen if (mail_get_received_date(ctx->mail, &t) < 0)
fe6cf42464c36ab281c0e0740f0255be77453670Timo Sirainenstatic int fetch_date_sent(struct fetch_cmd_context *ctx)
cc3ccdab8a510d88fecedf95187465bf84833711Timo Sirainen str_printfa(ctx->hdr, "%s (%c%02u%02u)", unixdate2str(t),
b8d232d88018c5cafd2f3be5a181d318137a45f2Timo Sirainenstatic int fetch_date_saved(struct fetch_cmd_context *ctx)
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainenstatic const struct fetch_field fetch_fields[] = {
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen { "hdr", MAIL_FETCH_STREAM_HEADER, fetch_hdr },
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen { "body", MAIL_FETCH_STREAM_BODY, fetch_body },
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen { "size.physical", MAIL_FETCH_PHYSICAL_SIZE, fetch_size_physical },
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen { "size.virtual", MAIL_FETCH_VIRTUAL_SIZE, fetch_size_virtual },
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen { "date.received", MAIL_FETCH_RECEIVED_DATE, fetch_date_received },
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen { "date.sent", MAIL_FETCH_DATE, fetch_date_sent },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "date.saved", MAIL_FETCH_SAVE_DATE, fetch_date_saved }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic const struct fetch_field *fetch_field_find(const char *name)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen unsigned int i;
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen for (i = 0; i < N_ELEMENTS(fetch_fields); i++) {
aff7542e1d2f48b030560a4f01096a2cc3f671ceTimo Sirainenstatic void print_fetch_fields(void)
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen unsigned int i;
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen fprintf(stderr, "Available fetch fields: %s", fetch_fields[0].name);
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen for (i = 1; i < N_ELEMENTS(fetch_fields); i++)
aff7542e1d2f48b030560a4f01096a2cc3f671ceTimo Sirainenstatic void parse_fetch_fields(struct fetch_cmd_context *ctx, const char *str)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen ctx->print_field_prefix = array_count(&ctx->fields) > 1;
3140537477eecdc5ea0a99f77df233c297dae58dTimo Sirainenstatic void cmd_fetch_mail(struct fetch_cmd_context *ctx)
369a1084c500a9df7448ffa9409ce32e42060bc2Timo Sirainen i_error("fetch(%s) failed for box=%s uid=%u: %s",
3140537477eecdc5ea0a99f77df233c297dae58dTimo Sirainen mail->uid, mail_storage_get_last_error(storage, NULL));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainencmd_fetch_box(struct fetch_cmd_context *ctx, const struct mailbox_info *info)
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen if (doveadm_mail_iter_init(info, ctx->search_args, &trans, &iter) < 0)
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen mail = mail_alloc(trans, ctx->wanted_fields, NULL);
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainenstatic bool search_args_have_unique_fetch(struct mail_search_args *args)
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen unsigned int count;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen for (arg = args->args; arg != NULL; arg = arg->next) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seqset = array_get(&arg->value.seqset, &count);
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen if (count == 1 && seqset->seq1 == seqset->seq2 &&
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainencmd_fetch_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
d0bbbc7057aa33b52ee378196dee7d773437468fTimo Sirainen const enum mailbox_list_iter_flags iter_flags =
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen iter = doveadm_mail_list_iter_init(user, ctx->search_args, iter_flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while ((info = doveadm_mail_list_iter_next(iter)) != NULL) T_BEGIN {
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainenstatic void cmd_fetch_deinit(struct doveadm_mail_cmd_context *_ctx)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainenstatic void cmd_fetch_init(struct doveadm_mail_cmd_context *_ctx,
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen const char *const args[])
d22390f33eedbd2413debabc0662dde5241b1aa6Timo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen ctx->search_args = doveadm_mail_build_search_args(args + 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
f1700e6d755306a2b137fad88ea5bf8b9fc6ec4fTimo Sirainen if (search_args_have_unique_fetch(ctx->search_args))
f1700e6d755306a2b137fad88ea5bf8b9fc6ec4fTimo Sirainen random_fill_weak(prefix_buf, sizeof(prefix_buf));
f1700e6d755306a2b137fad88ea5bf8b9fc6ec4fTimo Sirainen base64_encode(prefix_buf, sizeof(prefix_buf), ctx->hdr);
6fdf8b5e4e71a69f5974f59eec2b8c19bc421fe2Timo Sirainenstatic struct doveadm_mail_cmd_context *cmd_fetch_alloc(void)
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen ctx = doveadm_mail_cmd_alloc(struct fetch_cmd_context);
7ca9da144f79317f9a0d3b0b5cc1fe21e44a5bf4Timo Sirainen cmd_fetch_alloc, "fetch", "<fields> <search query>"