doveadm-mail-fetch.c revision 2dbb7b30d9bf6d6b0cd104c6931c4b44a77c2383
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2010-2016 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ostream.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "message-address.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "message-size.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "message-parser.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "message-header-decode.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "message-decoder.h"
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen#include "imap-util.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "mail-user.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "mail-storage.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "mail-search.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "mail-namespace.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "imap-msgpart.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "doveadm-print.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "doveadm-mail.h"
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen#include "doveadm-mailbox-list-iter.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "doveadm-mail-iter.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include <stdio.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct fetch_cmd_context {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct doveadm_mail_cmd_context ctx;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct mail *mail;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen ARRAY(struct fetch_field) fields;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen ARRAY_TYPE(const_string) header_fields;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_fetch_field wanted_fields;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen const struct fetch_field *cur_field;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* if print() returns -1, log this error if non-NULL. otherwise log
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen the storage error. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *print_error;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct fetch_field {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const char *name;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen enum mail_fetch_field wanted_fields;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen int (*print)(struct fetch_cmd_context *ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_user(struct fetch_cmd_context *ctx)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print(ctx->ctx.cur_mail_user->username);
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen return 0;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen}
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainenstatic int fetch_mailbox(struct fetch_cmd_context *ctx)
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *value;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, &value) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print(value);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainenstatic int fetch_mailbox_guid(struct fetch_cmd_context *ctx)
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen{
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen struct mailbox_metadata metadata;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (mailbox_get_metadata(ctx->mail->box, MAILBOX_METADATA_GUID,
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen &metadata) < 0)
5c1a8aee989af87bddefd71e2aa83aa2bd695155Timo Sirainen return -1;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen doveadm_print(guid_128_to_string(metadata.guid));
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen return 0;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen}
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainenstatic int fetch_seq(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print_num(ctx->mail->seq);
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen return 0;
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_uid(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen doveadm_print_num(ctx->mail->uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_guid(struct fetch_cmd_context *ctx)
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *value;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &value) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print(value);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_flags(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen string_t *str = t_str_new(64);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen imap_write_flags(str, mail_get_flags(ctx->mail),
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen mail_get_keywords(ctx->mail));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print(str_c(str));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_modseq(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print_num(mail_get_modseq(ctx->mail));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenfetch_set_istream_error(struct fetch_cmd_context *ctx, struct istream *input)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->print_error = t_strdup_printf("read(%s) failed: %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_get_name(input), i_stream_get_error(input));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_hdr(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct istream *input;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct message_size hdr_size;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen int ret;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (mail_get_hdr_stream(ctx->mail, &hdr_size, &input) < 0)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return -1;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen input = i_stream_create_limit(input, hdr_size.physical_size);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if ((ret = doveadm_print_istream(input)) < 0)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen fetch_set_istream_error(ctx, input);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen i_stream_unref(&input);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return ret;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenstatic int fetch_hdr_field(struct fetch_cmd_context *ctx)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen const char *const *value, *filter, *name = ctx->cur_field->name;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen string_t *str = t_str_new(256);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen bool add_lf = FALSE;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen filter = strchr(name, '.');
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (filter != NULL)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen name = t_strdup_until(name, filter++);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (filter != NULL && strcmp(filter, "utf8") == 0) {
bef8712387812fc5d9496b9958935c6d0c418777Timo Sirainen if (mail_get_headers_utf8(ctx->mail, name, &value) < 0)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return -1;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen } else {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (mail_get_headers(ctx->mail, name, &value) < 0)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return -1;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
bef8712387812fc5d9496b9958935c6d0c418777Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen for (; *value != NULL; value++) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (add_lf)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append_c(str, '\n');
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append(str, *value);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen add_lf = TRUE;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (filter == NULL || strcmp(filter, "utf8") == 0) {
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen /* print the header as-is */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen } else if (strcmp(filter, "address") == 0 ||
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen strcmp(filter, "address_name") == 0 ||
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen strcmp(filter, "address_name.utf8") == 0) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct message_address *addr;
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen addr = message_address_parse(pool_datastack_create(),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_data(str), str_len(str),
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen UINT_MAX, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_truncate(str, 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen add_lf = FALSE;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen for (; addr != NULL; addr = addr->next) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (add_lf)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen str_append_c(str, '\n');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (strcmp(filter, "address") == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (addr->mailbox != NULL)
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen str_append(str, addr->mailbox);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (addr->domain != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(str, '@');
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen str_append(str, addr->domain);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen } else if (addr->name != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (strcmp(filter, "address_name") == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, addr->name);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen message_header_decode_utf8(
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen (const void *)addr->name,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen strlen(addr->name), str, NULL);
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen add_lf = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_fatal("Unknown header filter: %s", filter);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen doveadm_print(str_c(str));
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_body_field(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen const char *name = ctx->cur_field->name;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct imap_msgpart *msgpart;
5529671faac3c5672a948be93091056736c7afffTimo Sirainen struct imap_msgpart_open_result result;
5529671faac3c5672a948be93091056736c7afffTimo Sirainen bool binary;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen int ret;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen binary = strncmp(name, "binary.", 7) == 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen name += binary ? 7 : 5;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (imap_msgpart_parse(name, &msgpart) < 0)
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen i_unreached(); /* we already verified this was ok */
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen if (binary)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_msgpart_set_decode_to_binary(msgpart);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (imap_msgpart_open(ctx->mail, msgpart, &result) < 0) {
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen imap_msgpart_free(&msgpart);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return -1;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen if ((ret = doveadm_print_istream(result.input)) < 0)
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen fetch_set_istream_error(ctx, result.input);
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen i_stream_unref(&result.input);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen imap_msgpart_free(&msgpart);
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen return ret;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen}
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_body(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct istream *input;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct message_size hdr_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_skip(input, hdr_size.physical_size);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if ((ret = doveadm_print_istream(input)) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fetch_set_istream_error(ctx, input);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_body_snippet(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *value;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_BODY_SNIPPET, &value) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen /* [0] contains the snippet algorithm, skip over it */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen i_assert(value[0] != '\0');
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen doveadm_print(value + 1);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainenstatic int fetch_text(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct istream *input;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((ret = doveadm_print_istream(input)) < 0)
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen fetch_set_istream_error(ctx, input);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_text_utf8(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen struct istream *input;
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen struct message_parser_ctx *parser;
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen struct message_decoder_context *decoder;
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen struct message_block raw_block, block;
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen struct message_part *parts;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret = 0;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen parser = message_parser_init(pool_datastack_create(), input,
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen decoder = message_decoder_init(NULL, 0);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while ((ret = message_parser_parse_next_block(parser, &raw_block)) > 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!message_decoder_decode_next_block(decoder, &raw_block,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen &block))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen continue;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (block.hdr == NULL) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (block.size > 0)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen doveadm_print_stream(block.data, block.size);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen } else if (block.hdr->eoh)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print_stream("\n", 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(block.hdr->name_len > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print_stream(block.hdr->name,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen block.hdr->name_len);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print_stream(": ", 2);
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen if (block.hdr->full_value_len > 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print_stream(block.hdr->full_value,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen block.hdr->full_value_len);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen doveadm_print_stream("\n", 1);
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen }
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen }
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen i_assert(ret != 0);
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen message_decoder_deinit(&decoder);
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen message_parser_deinit(&parser, &parts);
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen doveadm_print_stream("", 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (input->stream_errno != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("read(%s) failed: %s", i_stream_get_name(input),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_get_error(input));
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_size_physical(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_physical_size(ctx->mail, &size) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print_num(size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_size_virtual(struct fetch_cmd_context *ctx)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uoff_t size;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_virtual_size(ctx->mail, &size) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print_num(size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int fetch_date_received(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen time_t t;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_received_date(ctx->mail, &t) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen doveadm_print(unixdate2str(t));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenstatic int fetch_date_sent(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen time_t t;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int tz;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen char chr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_date(ctx->mail, &t, &tz) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen chr = tz < 0 ? '-' : '+';
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (tz < 0) tz = -tz;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print(t_strdup_printf("%s (%c%02u%02u)", unixdate2str(t),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen chr, tz/60, tz%60));
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen return 0;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen}
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainenstatic int fetch_date_saved(struct fetch_cmd_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen time_t t;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_get_save_date(ctx->mail, &t) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen doveadm_print(unixdate2str(t));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic int fetch_date_received_unixtime(struct fetch_cmd_context *ctx)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen time_t t;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (mail_get_received_date(ctx->mail, &t) < 0)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return -1;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen doveadm_print(dec2str(t));
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstatic int fetch_date_sent_unixtime(struct fetch_cmd_context *ctx)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen time_t t;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen int tz;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (mail_get_date(ctx->mail, &t, &tz) < 0)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return -1;
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen doveadm_print(dec2str(t));
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen return 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstatic int fetch_date_saved_unixtime(struct fetch_cmd_context *ctx)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen time_t t;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (mail_get_save_date(ctx->mail, &t) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen doveadm_print(dec2str(t));
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic int fetch_imap_envelope(struct fetch_cmd_context *ctx)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const char *value;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_ENVELOPE, &value) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen doveadm_print(value);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic int fetch_imap_body(struct fetch_cmd_context *ctx)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const char *value;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_BODY, &value) < 0)
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen return -1;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen doveadm_print(value);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic int fetch_imap_bodystructure(struct fetch_cmd_context *ctx)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const char *value;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_BODYSTRUCTURE, &value) < 0)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return -1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen doveadm_print(value);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return 0;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainenstatic int fetch_pop3_uidl(struct fetch_cmd_context *ctx)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen const char *value;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_UIDL_BACKEND, &value) < 0)
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen return -1;
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen doveadm_print(value);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return 0;
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic int fetch_pop3_order(struct fetch_cmd_context *ctx)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const char *value;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_POP3_ORDER, &value) < 0)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return -1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen doveadm_print(value);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return 0;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstatic int fetch_refcount(struct fetch_cmd_context *ctx)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const char *value;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_REFCOUNT, &value) < 0)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return -1;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen doveadm_print(value);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return 0;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic int fetch_storageid(struct fetch_cmd_context *ctx)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const char *value;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_STORAGE_ID, &value) < 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return -1;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen doveadm_print(value);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic const struct fetch_field fetch_fields[] = {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "user", 0, fetch_user },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "mailbox", 0, fetch_mailbox },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "mailbox-guid", 0, fetch_mailbox_guid },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "seq", 0, fetch_seq },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "uid", 0, fetch_uid },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "guid", 0, fetch_guid },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "flags", MAIL_FETCH_FLAGS, fetch_flags },
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen { "modseq", 0, fetch_modseq },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "hdr", MAIL_FETCH_STREAM_HEADER, fetch_hdr },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "body", MAIL_FETCH_STREAM_BODY, fetch_body },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "body.snippet", MAIL_FETCH_BODY_SNIPPET, fetch_body_snippet },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "text", MAIL_FETCH_STREAM_HEADER |
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen MAIL_FETCH_STREAM_BODY, fetch_text },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "text.utf8", MAIL_FETCH_STREAM_HEADER |
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen MAIL_FETCH_STREAM_BODY, fetch_text_utf8 },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "size.physical", MAIL_FETCH_PHYSICAL_SIZE, fetch_size_physical },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "size.virtual", MAIL_FETCH_VIRTUAL_SIZE, fetch_size_virtual },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "date.received", MAIL_FETCH_RECEIVED_DATE, fetch_date_received },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "date.sent", MAIL_FETCH_DATE, fetch_date_sent },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "date.saved", MAIL_FETCH_SAVE_DATE, fetch_date_saved },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "date.received.unixtime", MAIL_FETCH_RECEIVED_DATE, fetch_date_received_unixtime },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "date.sent.unixtime", MAIL_FETCH_DATE, fetch_date_sent_unixtime },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "date.saved.unixtime", MAIL_FETCH_SAVE_DATE, fetch_date_saved_unixtime },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "imap.envelope", MAIL_FETCH_IMAP_ENVELOPE, fetch_imap_envelope },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "imap.body", MAIL_FETCH_IMAP_BODY, fetch_imap_body },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "imap.bodystructure", MAIL_FETCH_IMAP_BODYSTRUCTURE, fetch_imap_bodystructure },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "pop3.uidl", MAIL_FETCH_UIDL_BACKEND, fetch_pop3_uidl },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "pop3.order", MAIL_FETCH_POP3_ORDER, fetch_pop3_order },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "refcount", MAIL_FETCH_REFCOUNT, fetch_refcount },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "storageid", MAIL_FETCH_STORAGE_ID, fetch_storageid }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen};
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic const struct fetch_field *fetch_field_find(const char *name)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen unsigned int i;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen for (i = 0; i < N_ELEMENTS(fetch_fields); i++) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (strcmp(fetch_fields[i].name, name) == 0)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return &fetch_fields[i];
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return NULL;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic void print_fetch_fields(void)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen unsigned int i;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen fprintf(stderr, "Available fetch fields: hdr.<name> body.<section> binary.<section> %s", fetch_fields[0].name);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen for (i = 1; i < N_ELEMENTS(fetch_fields); i++)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen fprintf(stderr, " %s", fetch_fields[i].name);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen fprintf(stderr, "\n");
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic void parse_fetch_fields(struct fetch_cmd_context *ctx, const char *str)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const char *const *fields, *name;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const struct fetch_field *field;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct fetch_field hdr_field, body_field;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct imap_msgpart *msgpart;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen memset(&hdr_field, 0, sizeof(hdr_field));
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen hdr_field.print = fetch_hdr_field;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen memset(&body_field, 0, sizeof(body_field));
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen body_field.print = fetch_body_field;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen t_array_init(&ctx->fields, 32);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen t_array_init(&ctx->header_fields, 32);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen fields = t_strsplit_spaces(str, " ");
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen for (; *fields != NULL; fields++) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen name = t_str_lcase(*fields);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen doveadm_print_header_simple(name);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if ((field = fetch_field_find(name)) != NULL) {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen ctx->wanted_fields |= field->wanted_fields;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen array_append(&ctx->fields, field, 1);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen } else if (strncmp(name, "hdr.", 4) == 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen name += 4;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen hdr_field.name = name;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen array_append(&ctx->fields, &hdr_field, 1);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen name = t_strcut(name, '.');
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen array_append(&ctx->header_fields, &name, 1);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen } else if (strncmp(name, "body.", 5) == 0 ||
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen strncmp(name, "binary.", 7) == 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen bool binary = strncmp(name, "binary.", 7) == 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen body_field.name = t_strarray_join(t_strsplit(name, ","), " ");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen name += binary ? 7 : 5;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (imap_msgpart_parse(name, &msgpart) < 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen print_fetch_fields();
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen i_fatal("Unknown fetch section: %s", name);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen array_append(&ctx->fields, &body_field, 1);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen ctx->wanted_fields |= imap_msgpart_get_fetch_data(msgpart);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen imap_msgpart_free(&msgpart);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen } else {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen print_fetch_fields();
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen i_fatal("Unknown fetch field: %s", name);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen array_append_zero(&ctx->header_fields);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic int cmd_fetch_mail(struct fetch_cmd_context *ctx)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const struct fetch_field *field;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen struct mail *mail = ctx->mail;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen int ret = 0;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen array_foreach(&ctx->fields, field) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen ctx->cur_field = field;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (field->print(ctx) < 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen i_error("fetch(%s) failed for box=%s uid=%u: %s",
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen field->name, mailbox_get_vname(mail->box),
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen mail->uid,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen ctx->print_error != NULL ? ctx->print_error :
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen mailbox_get_last_error(mail->box, NULL));
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, mail->box);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen ctx->print_error = NULL;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen ret = -1;
cdb3c8e1054f4ea382bb6c1557fd28d067f90e5eTimo Sirainen }
cdb3c8e1054f4ea382bb6c1557fd28d067f90e5eTimo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return ret;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic int
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainencmd_fetch_box(struct fetch_cmd_context *ctx, const struct mailbox_info *info)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct doveadm_mail_iter *iter;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen int ret = 0;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen ctx->wanted_fields,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen array_idx(&ctx->header_fields, 0),
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen FALSE,
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen &iter) < 0)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return -1;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen while (doveadm_mail_iter_next(iter, &ctx->mail)) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen T_BEGIN {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (cmd_fetch_mail(ctx) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen ret = -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen } T_END;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (doveadm_mail_iter_deinit(&iter) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen ret = -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return ret;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainenstatic int
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainencmd_fetch_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
{
struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
const enum mailbox_list_iter_flags iter_flags =
MAILBOX_LIST_ITER_NO_AUTO_BOXES |
MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
struct doveadm_mailbox_list_iter *iter;
const struct mailbox_info *info;
int ret = 0;
iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args,
iter_flags);
while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN {
if (cmd_fetch_box(ctx, info) < 0)
ret = -1;
} T_END;
if (doveadm_mailbox_list_iter_deinit(&iter) < 0)
ret = -1;
return ret;
}
static void cmd_fetch_init(struct doveadm_mail_cmd_context *_ctx,
const char *const args[])
{
struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
const char *fetch_fields = args[0];
if (fetch_fields == NULL || args[1] == NULL)
doveadm_mail_help_name("fetch");
parse_fetch_fields(ctx, fetch_fields);
_ctx->search_args = doveadm_mail_build_search_args(args + 1);
}
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.run = cmd_fetch_run;
doveadm_print_init(DOVEADM_PRINT_TYPE_PAGER);
return &ctx->ctx;
}
struct doveadm_cmd_ver2 doveadm_cmd_fetch_ver2 = {
.name = "fetch",
.mail_cmd = cmd_fetch_alloc,
.usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"<fields> <search query>",
DOVEADM_CMD_PARAMS_START
DOVEADM_CMD_MAIL_COMMON
DOVEADM_CMD_PARAM('\0', "field", CMD_PARAM_ARRAY, 0)
DOVEADM_CMD_PARAM('\0', "fieldstr", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL | CMD_PARAM_FLAG_DO_NOT_EXPOSE) /* FIXME: horrible hack, remove me when possible */
DOVEADM_CMD_PARAM('\0', "query", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
DOVEADM_CMD_PARAMS_END
};