doveadm-mail-fetch.c revision 7f03bac2ef9fae720ce96536b1e936066f093de4
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
ef5fb27361cc5e15766e85e28355750ff04b13c9Timo Sirainen ARRAY_DEFINE(fields, const struct fetch_field);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_user(struct fetch_cmd_context *ctx)
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen doveadm_print(ctx->ctx.cur_mail_user->username);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenstatic int fetch_mailbox(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, &value) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* not a valid mUTF-7 name, fallback to showing it as-is */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic int fetch_mailbox_guid(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mailbox_get_guid(ctx->mail->box, guid) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_seq(struct fetch_cmd_context *ctx)
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainenstatic int fetch_uid(struct fetch_cmd_context *ctx)
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainenstatic int fetch_guid(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &value) < 0)
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainenstatic int fetch_flags(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_write_flags(str, mail_get_flags(ctx->mail),
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic int fetch_hdr(struct fetch_cmd_context *ctx)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen const unsigned char *data;
b9c44feadade0481b957f2978640afb3317bd1dfTimo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen input = i_stream_create_limit(input, hdr_size.physical_size);
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen if (i_stream_read_data(input, &data, &size, 0) == -1)
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainenstatic int fetch_hdr_field(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *const *value;
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen if (mail_get_headers(ctx->mail, ctx->cur_field->name, &value) < 0)
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainenstatic int fetch_body(struct fetch_cmd_context *ctx)
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen const unsigned char *data;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (i_stream_read_data(input, &data, &size, 0) == -1)
1f43c8ac132c153c224c4fffe34b2c3075d87ef7Timo Sirainenstatic int fetch_text(struct fetch_cmd_context *ctx)
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen const unsigned char *data;
b9c44feadade0481b957f2978640afb3317bd1dfTimo Sirainen if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen if (i_stream_read_data(input, &data, &size, 0) == -1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_size_physical(struct fetch_cmd_context *ctx)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (mail_get_physical_size(ctx->mail, &size) < 0)
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainenstatic int fetch_size_virtual(struct fetch_cmd_context *ctx)
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen if (mail_get_virtual_size(ctx->mail, &size) < 0)
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainenstatic int fetch_date_received(struct fetch_cmd_context *ctx)
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen if (mail_get_received_date(ctx->mail, &t) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_date_sent(struct fetch_cmd_context *ctx)
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen doveadm_print(t_strdup_printf("%s (%c%02u%02u)", unixdate2str(t),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_date_saved(struct fetch_cmd_context *ctx)
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainenstatic int fetch_imap_envelope(struct fetch_cmd_context *ctx)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_ENVELOPE, &value) < 0)
9404a7b90dcb80d31bd37ee2493f03751acdb1bdTimo Sirainenstatic int fetch_imap_body(struct fetch_cmd_context *ctx)
eac3948d67eff8623d51aeaea9eca582f3aec677Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_BODY, &value) < 0)
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainenstatic int fetch_imap_bodystructure(struct fetch_cmd_context *ctx)
48136ae5a0eb49daa44e343553f3688a500307e2Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_BODYSTRUCTURE, &value) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_pop3_uidl(struct fetch_cmd_context *ctx)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_UIDL_BACKEND, &value) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic const struct fetch_field fetch_fields[] = {
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen { "hdr", MAIL_FETCH_STREAM_HEADER, fetch_hdr },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { "body", MAIL_FETCH_STREAM_BODY, fetch_body },
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainen { "size.physical", MAIL_FETCH_PHYSICAL_SIZE, fetch_size_physical },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { "size.virtual", MAIL_FETCH_VIRTUAL_SIZE, fetch_size_virtual },
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen { "date.received", MAIL_FETCH_RECEIVED_DATE, fetch_date_received },
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen { "date.sent", MAIL_FETCH_DATE, fetch_date_sent },
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen { "date.saved", MAIL_FETCH_SAVE_DATE, fetch_date_saved },
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen { "imap.envelope", MAIL_FETCH_IMAP_ENVELOPE, fetch_imap_envelope },
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen { "imap.body", MAIL_FETCH_IMAP_BODY, fetch_imap_body },
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen { "imap.bodystructure", MAIL_FETCH_IMAP_BODYSTRUCTURE, fetch_imap_bodystructure },
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen { "pop3.uidl", MAIL_FETCH_UIDL_BACKEND, fetch_pop3_uidl }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic const struct fetch_field *fetch_field_find(const char *name)
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen unsigned int i;
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen for (i = 0; i < N_ELEMENTS(fetch_fields); i++) {
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainenstatic void print_fetch_fields(void)
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen unsigned int i;
768b7f5783c8de119d7386321e5d0c72d5c2d9f6Timo Sirainen fprintf(stderr, "Available fetch fields: %s", fetch_fields[0].name);
768b7f5783c8de119d7386321e5d0c72d5c2d9f6Timo Sirainen for (i = 1; i < N_ELEMENTS(fetch_fields); i++)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void parse_fetch_fields(struct fetch_cmd_context *ctx, const char *str)
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen (void)array_append_space(&ctx->header_fields);
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainenstatic void cmd_fetch_mail(struct fetch_cmd_context *ctx)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen i_error("fetch(%s) failed for box=%s uid=%u: %s",
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen mail->uid, mail_storage_get_last_error(storage, NULL));
bb26f09873c18f342cd1ab2d0ee0b9018e6546d9Timo Sirainencmd_fetch_box(struct fetch_cmd_context *ctx, const struct mailbox_info *info)
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen struct mailbox_header_lookup_ctx *headers = NULL;
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen if (doveadm_mail_iter_init(info, ctx->ctx.search_args,
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen mail = mail_alloc(trans, ctx->wanted_fields, headers);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainencmd_fetch_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
8cf32443413f811d514123c5c74c95c87594b0e3Timo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
8cf32443413f811d514123c5c74c95c87594b0e3Timo 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 {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void cmd_fetch_deinit(struct doveadm_mail_cmd_context *_ctx)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainenstatic void cmd_fetch_init(struct doveadm_mail_cmd_context *_ctx,
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen const char *const args[])
4b89231f4ec9cc69f4aea715e1d34f405c7e317dTimo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen _ctx->search_args = doveadm_mail_build_search_args(args + 1);
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen ctx->output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainenstatic struct doveadm_mail_cmd_context *cmd_fetch_alloc(void)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx = doveadm_mail_cmd_alloc(struct fetch_cmd_context);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen cmd_fetch_alloc, "fetch", "<fields> <search query>"