doveadm-mail-fetch.c revision c154a05c76d4d83de1cdf9746ce4e2da0869705d
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ARRAY_DEFINE(fields, const struct fetch_field);
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenstatic int fetch_user(struct fetch_cmd_context *ctx)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen doveadm_print(ctx->ctx.cur_mail_user->username);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int fetch_mailbox(struct fetch_cmd_context *ctx)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, &value) < 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* not a valid mUTF-7 name, fallback to showing it as-is */
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenstatic int fetch_mailbox_guid(struct fetch_cmd_context *ctx)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen if (mailbox_get_guid(ctx->mail->box, guid) < 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int fetch_seq(struct fetch_cmd_context *ctx)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int fetch_uid(struct fetch_cmd_context *ctx)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenstatic int fetch_guid(struct fetch_cmd_context *ctx)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &value) < 0)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenstatic int fetch_flags(struct fetch_cmd_context *ctx)
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen imap_write_flags(str, mail_get_flags(ctx->mail),
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int fetch_hdr(struct fetch_cmd_context *ctx)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const unsigned char *data;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen input = i_stream_create_limit(input, hdr_size.physical_size);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (i_stream_read_data(input, &data, &size, 0) == -1)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic int fetch_hdr_field(struct fetch_cmd_context *ctx)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const char *const *value;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (mail_get_headers(ctx->mail, ctx->cur_field->name, &value) < 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic int fetch_body(struct fetch_cmd_context *ctx)
5214b67a7dabab87da74e04bb8b227f94b95bce4Timo Sirainen const unsigned char *data;
27586e4785d56aeb76e1fd96af8db799688dc64aTimo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (i_stream_read_data(input, &data, &size, 0) == -1)
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volkstatic int fetch_text(struct fetch_cmd_context *ctx)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const unsigned char *data;
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen if (i_stream_read_data(input, &data, &size, 0) == -1)
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainenstatic int fetch_size_physical(struct fetch_cmd_context *ctx)
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen if (mail_get_physical_size(ctx->mail, &size) < 0)
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainenstatic int fetch_size_virtual(struct fetch_cmd_context *ctx)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen if (mail_get_virtual_size(ctx->mail, &size) < 0)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenstatic int fetch_date_received(struct fetch_cmd_context *ctx)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen if (mail_get_received_date(ctx->mail, &t) < 0)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenstatic int fetch_date_sent(struct fetch_cmd_context *ctx)
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen doveadm_print(t_strdup_printf("%s (%c%02u%02u)", unixdate2str(t),
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic int fetch_date_saved(struct fetch_cmd_context *ctx)
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainenstatic int fetch_imap_envelope(struct fetch_cmd_context *ctx)
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_ENVELOPE, &value) < 0)
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainenstatic int fetch_imap_body(struct fetch_cmd_context *ctx)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_BODY, &value) < 0)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenstatic int fetch_imap_bodystructure(struct fetch_cmd_context *ctx)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_BODYSTRUCTURE, &value) < 0)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenstatic const struct fetch_field fetch_fields[] = {
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen { "hdr", MAIL_FETCH_STREAM_HEADER, fetch_hdr },
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen { "body", MAIL_FETCH_STREAM_BODY, fetch_body },
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen { "size.physical", MAIL_FETCH_PHYSICAL_SIZE, fetch_size_physical },
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen { "size.virtual", MAIL_FETCH_VIRTUAL_SIZE, fetch_size_virtual },
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen { "date.received", MAIL_FETCH_RECEIVED_DATE, fetch_date_received },
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen { "date.sent", MAIL_FETCH_DATE, fetch_date_sent },
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen { "date.saved", MAIL_FETCH_SAVE_DATE, fetch_date_saved },
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen { "imap.envelope", MAIL_FETCH_IMAP_ENVELOPE, fetch_imap_envelope },
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen { "imap.body", MAIL_FETCH_IMAP_BODY, fetch_imap_body },
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen { "imap.bodystructure", MAIL_FETCH_IMAP_BODYSTRUCTURE, fetch_imap_bodystructure }
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenstatic const struct fetch_field *fetch_field_find(const char *name)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen unsigned int i;
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen for (i = 0; i < N_ELEMENTS(fetch_fields); i++) {
1433bf361ddb0bba8878c8ada5726d0284edad57Timo Sirainenstatic void print_fetch_fields(void)
1433bf361ddb0bba8878c8ada5726d0284edad57Timo Sirainen unsigned int i;
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen fprintf(stderr, "Available fetch fields: %s", fetch_fields[0].name);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen for (i = 1; i < N_ELEMENTS(fetch_fields); i++)
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenstatic void parse_fetch_fields(struct fetch_cmd_context *ctx, const char *str)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen (void)array_append_space(&ctx->header_fields);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen ctx->print_field_prefix = array_count(&ctx->fields) > 1;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainenstatic void cmd_fetch_mail(struct fetch_cmd_context *ctx)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen i_error("fetch(%s) failed for box=%s uid=%u: %s",
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen mail->uid, mail_storage_get_last_error(storage, NULL));
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainencmd_fetch_box(struct fetch_cmd_context *ctx, const struct mailbox_info *info)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct mailbox_header_lookup_ctx *headers = NULL;
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen if (doveadm_mail_iter_init(info, ctx->ctx.search_args,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail = mail_alloc(trans, ctx->wanted_fields, headers);
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainencmd_fetch_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen const enum mailbox_list_iter_flags iter_flags =
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen iter = doveadm_mail_list_iter_init(user, _ctx->search_args, iter_flags);
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen while ((info = doveadm_mail_list_iter_next(iter)) != NULL) T_BEGIN {
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenstatic void cmd_fetch_deinit(struct doveadm_mail_cmd_context *_ctx)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenstatic void cmd_fetch_init(struct doveadm_mail_cmd_context *_ctx,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen const char *const args[])
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen _ctx->search_args = doveadm_mail_build_search_args(args + 1);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen ctx->output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainenstatic struct doveadm_mail_cmd_context *cmd_fetch_alloc(void)
8f70c97f7ab7b7e1683ed5cfcd96721a899c2520Timo Sirainen ctx = doveadm_mail_cmd_alloc(struct fetch_cmd_context);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen cmd_fetch_alloc, "fetch", "<fields> <search query>"