bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen#include "lib.h"
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen#include "array.h"
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen#include "istream.h"
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen#include "ostream.h"
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen#include "str.h"
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen#include "message-address.h"
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen#include "message-size.h"
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen#include "message-parser.h"
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen#include "message-header-decode.h"
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen#include "message-decoder.h"
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen#include "imap-util.h"
1631885636d15abaf0375304a17928c8c23782cdTimo Sirainen#include "mail-user.h"
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen#include "mail-storage.h"
f330fcc3307d48954b6f8909349546773368a041Timo Sirainen#include "mail-search.h"
d389c93ada174a8fc6edf995b4f829d38e8fe567Timo Sirainen#include "mail-namespace.h"
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen#include "imap-msgpart.h"
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen#include "doveadm-print.h"
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen#include "doveadm-mail.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen#include "doveadm-mailbox-list-iter.h"
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen#include "doveadm-mail-iter.h"
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen#include <stdio.h>
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstruct fetch_cmd_context {
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen struct doveadm_mail_cmd_context ctx;
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen struct mail *mail;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
71fbc9af425dc9afc2fb58f911bfe4c5b4edba9bTimo Sirainen ARRAY(struct fetch_field) fields;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen ARRAY_TYPE(const_string) header_fields;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen enum mail_fetch_field wanted_fields;
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen const struct fetch_field *cur_field;
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen /* if print() returns -1, log this error if non-NULL. otherwise log
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen the storage error. */
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen const char *print_error;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen};
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainenstruct fetch_field {
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen const char *name;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen enum mail_fetch_field wanted_fields;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen int (*print)(struct fetch_cmd_context *ctx);
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen};
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen
1631885636d15abaf0375304a17928c8c23782cdTimo Sirainenstatic int fetch_user(struct fetch_cmd_context *ctx)
1631885636d15abaf0375304a17928c8c23782cdTimo Sirainen{
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(ctx->ctx.cur_mail_user->username);
1631885636d15abaf0375304a17928c8c23782cdTimo Sirainen return 0;
1631885636d15abaf0375304a17928c8c23782cdTimo Sirainen}
1631885636d15abaf0375304a17928c8c23782cdTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_mailbox(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen const char *value;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME, &value) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
ea1ae54fcfbd8e911978c149f9e7265a45b6380aTimo Sirainen
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen doveadm_print(value);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_mailbox_guid(struct fetch_cmd_context *ctx)
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen{
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen struct mailbox_metadata metadata;
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if (mailbox_get_metadata(ctx->mail->box, MAILBOX_METADATA_GUID,
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen &metadata) < 0)
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen return -1;
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen doveadm_print(guid_128_to_string(metadata.guid));
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen return 0;
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen}
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_seq(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print_num(ctx->mail->seq);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_uid(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
1f792fb84e8fdfd2a9b65100ce1c31d0212fa3b0Timo Sirainen doveadm_print_num(ctx->mail->uid);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_guid(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen const char *value;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &value) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(value);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_flags(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen string_t *str = t_str_new(64);
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen imap_write_flags(str, mail_get_flags(ctx->mail),
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen mail_get_keywords(ctx->mail));
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(str_c(str));
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
5e46f82843a13cc590900352d34c899cd5967de0Timo Sirainenstatic int fetch_modseq(struct fetch_cmd_context *ctx)
5e46f82843a13cc590900352d34c899cd5967de0Timo Sirainen{
5e46f82843a13cc590900352d34c899cd5967de0Timo Sirainen doveadm_print_num(mail_get_modseq(ctx->mail));
5e46f82843a13cc590900352d34c899cd5967de0Timo Sirainen return 0;
5e46f82843a13cc590900352d34c899cd5967de0Timo Sirainen}
5e46f82843a13cc590900352d34c899cd5967de0Timo Sirainen
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainenstatic void
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainenfetch_set_istream_error(struct fetch_cmd_context *ctx, struct istream *input)
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen{
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen ctx->print_error = t_strdup_printf("read(%s) failed: %s",
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen i_stream_get_name(input), i_stream_get_error(input));
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen}
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_hdr(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen struct istream *input;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen struct message_size hdr_size;
7fbd5e7ceedb73996290c5358f5243d7d22b4d49Timo Sirainen int ret;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen if (mail_get_hdr_stream(ctx->mail, &hdr_size, &input) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen input = i_stream_create_limit(input, hdr_size.physical_size);
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen if ((ret = doveadm_print_istream(input)) < 0)
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen fetch_set_istream_error(ctx, input);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen i_stream_unref(&input);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return ret;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainenstatic int fetch_hdr_field(struct fetch_cmd_context *ctx)
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen{
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen const char *const *value, *filter, *name = ctx->cur_field->name;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen string_t *str = t_str_new(256);
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen bool add_lf = FALSE;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen filter = strchr(name, '.');
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen if (filter != NULL)
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen name = t_strdup_until(name, filter++);
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen
b5ad250aeacc094b84cce08eeab227d0ec14fb14Timo Sirainen if (filter != NULL && strcmp(filter, "utf8") == 0) {
b5ad250aeacc094b84cce08eeab227d0ec14fb14Timo Sirainen if (mail_get_headers_utf8(ctx->mail, name, &value) < 0)
b5ad250aeacc094b84cce08eeab227d0ec14fb14Timo Sirainen return -1;
b5ad250aeacc094b84cce08eeab227d0ec14fb14Timo Sirainen } else {
b5ad250aeacc094b84cce08eeab227d0ec14fb14Timo Sirainen if (mail_get_headers(ctx->mail, name, &value) < 0)
b5ad250aeacc094b84cce08eeab227d0ec14fb14Timo Sirainen return -1;
b5ad250aeacc094b84cce08eeab227d0ec14fb14Timo Sirainen }
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen for (; *value != NULL; value++) {
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen if (add_lf)
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen str_append_c(str, '\n');
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen str_append(str, *value);
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen add_lf = TRUE;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen }
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen
b5ad250aeacc094b84cce08eeab227d0ec14fb14Timo Sirainen if (filter == NULL || strcmp(filter, "utf8") == 0) {
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen /* print the header as-is */
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen } else if (strcmp(filter, "address") == 0 ||
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen strcmp(filter, "address_name") == 0 ||
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen strcmp(filter, "address_name.utf8") == 0) {
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen struct message_address *addr;
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen addr = message_address_parse(pool_datastack_create(),
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen str_data(str), str_len(str),
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen UINT_MAX, FALSE);
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen str_truncate(str, 0);
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen add_lf = FALSE;
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen for (; addr != NULL; addr = addr->next) {
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen if (add_lf)
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen str_append_c(str, '\n');
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen if (strcmp(filter, "address") == 0) {
f33d37b678b5a14c8fb058a8f723e9b65f0b2043Timo Sirainen if (addr->mailbox != NULL)
f33d37b678b5a14c8fb058a8f723e9b65f0b2043Timo Sirainen str_append(str, addr->mailbox);
f33d37b678b5a14c8fb058a8f723e9b65f0b2043Timo Sirainen if (addr->domain != NULL) {
f33d37b678b5a14c8fb058a8f723e9b65f0b2043Timo Sirainen str_append_c(str, '@');
f33d37b678b5a14c8fb058a8f723e9b65f0b2043Timo Sirainen str_append(str, addr->domain);
f33d37b678b5a14c8fb058a8f723e9b65f0b2043Timo Sirainen }
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen } else if (addr->name != NULL) {
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen if (strcmp(filter, "address_name") == 0)
f33d37b678b5a14c8fb058a8f723e9b65f0b2043Timo Sirainen str_append(str, addr->name);
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen else {
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen message_header_decode_utf8(
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen (const void *)addr->name,
edd3573b249c7cc824d55897b77a768be3a2e13eTimo Sirainen strlen(addr->name), str, NULL);
c4ac0f222613903b7f8c9e0825198396e6bf793eTimo Sirainen }
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen }
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen add_lf = TRUE;
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen }
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen } else {
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen i_fatal("Unknown header filter: %s", filter);
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen }
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(str_c(str));
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen return 0;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen}
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainenstatic int fetch_body_field(struct fetch_cmd_context *ctx)
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen{
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen const char *name = ctx->cur_field->name;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen struct imap_msgpart *msgpart;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen struct imap_msgpart_open_result result;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen bool binary;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen int ret;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen binary = strncmp(name, "binary.", 7) == 0;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen name += binary ? 7 : 5;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen if (imap_msgpart_parse(name, &msgpart) < 0)
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen i_unreached(); /* we already verified this was ok */
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen if (binary)
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen imap_msgpart_set_decode_to_binary(msgpart);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen if (imap_msgpart_open(ctx->mail, msgpart, &result) < 0) {
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen imap_msgpart_free(&msgpart);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen return -1;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen }
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen if ((ret = doveadm_print_istream(result.input)) < 0)
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen fetch_set_istream_error(ctx, result.input);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen i_stream_unref(&result.input);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen imap_msgpart_free(&msgpart);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen return ret;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen}
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_body(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen struct istream *input;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen struct message_size hdr_size;
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen int ret;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_stream(ctx->mail, &hdr_size, NULL, &input) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen i_stream_skip(input, hdr_size.physical_size);
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen if ((ret = doveadm_print_istream(input)) < 0)
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen fetch_set_istream_error(ctx, input);
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen return ret;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainenstatic int fetch_body_snippet(struct fetch_cmd_context *ctx)
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen{
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen const char *value;
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_BODY_SNIPPET, &value) < 0)
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen return -1;
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen /* [0] contains the snippet algorithm, skip over it */
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen i_assert(value[0] != '\0');
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen doveadm_print(value + 1);
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen return 0;
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen}
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_text(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen struct istream *input;
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen int ret;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen if ((ret = doveadm_print_istream(input)) < 0)
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen fetch_set_istream_error(ctx, input);
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen return ret;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainenstatic int fetch_text_utf8(struct fetch_cmd_context *ctx)
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen{
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen struct istream *input;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen struct message_parser_ctx *parser;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen struct message_decoder_context *decoder;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen struct message_block raw_block, block;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen struct message_part *parts;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen int ret = 0;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen return -1;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen parser = message_parser_init(pool_datastack_create(), input,
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen 0);
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen decoder = message_decoder_init(NULL, 0);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen while ((ret = message_parser_parse_next_block(parser, &raw_block)) > 0) {
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen if (!message_decoder_decode_next_block(decoder, &raw_block,
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen &block))
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen continue;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen if (block.hdr == NULL) {
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen if (block.size > 0)
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen doveadm_print_stream(block.data, block.size);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen } else if (block.hdr->eoh)
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen doveadm_print_stream("\n", 1);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen else {
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen i_assert(block.hdr->name_len > 0);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen doveadm_print_stream(block.hdr->name,
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen block.hdr->name_len);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen doveadm_print_stream(": ", 2);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen if (block.hdr->full_value_len > 0) {
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen doveadm_print_stream(block.hdr->full_value,
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen block.hdr->full_value_len);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen }
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen doveadm_print_stream("\n", 1);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen }
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen }
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen i_assert(ret != 0);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen message_decoder_deinit(&decoder);
12e5ac049bd74f8b98d9dc62adcb0bf3217beef6Martti Rannanjärvi message_parser_deinit(&parser, &parts);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen doveadm_print_stream("", 0);
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen if (input->stream_errno != 0) {
9f7a3d6bbc4601e293656295f2aa44dc67e1cb16Timo Sirainen i_error("read(%s) failed: %s", i_stream_get_name(input),
9f7a3d6bbc4601e293656295f2aa44dc67e1cb16Timo Sirainen i_stream_get_error(input));
9e952e5d80c17d2b47d2383dfc0c955292bb5c38Timo Sirainen return -1;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen }
9e952e5d80c17d2b47d2383dfc0c955292bb5c38Timo Sirainen return 0;
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen}
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_size_physical(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen uoff_t size;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_physical_size(ctx->mail, &size) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print_num(size);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_size_virtual(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen uoff_t size;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_virtual_size(ctx->mail, &size) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print_num(size);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_date_received(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen time_t t;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_received_date(ctx->mail, &t) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(unixdate2str(t));
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_date_sent(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen time_t t;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen int tz;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen char chr;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_date(ctx->mail, &t, &tz) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen chr = tz < 0 ? '-' : '+';
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (tz < 0) tz = -tz;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(t_strdup_printf("%s (%c%02u%02u)", unixdate2str(t),
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen chr, tz/60, tz%60));
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic int fetch_date_saved(struct fetch_cmd_context *ctx)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen time_t t;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (mail_get_save_date(ctx->mail, &t) < 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return -1;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(unixdate2str(t));
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return 0;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainenstatic int fetch_date_received_unixtime(struct fetch_cmd_context *ctx)
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen{
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen time_t t;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen if (mail_get_received_date(ctx->mail, &t) < 0)
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen return -1;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen doveadm_print(dec2str(t));
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen return 0;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen}
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainenstatic int fetch_date_sent_unixtime(struct fetch_cmd_context *ctx)
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen{
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen time_t t;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen int tz;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen if (mail_get_date(ctx->mail, &t, &tz) < 0)
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen return -1;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen doveadm_print(dec2str(t));
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen return 0;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen}
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainenstatic int fetch_date_saved_unixtime(struct fetch_cmd_context *ctx)
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen{
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen time_t t;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen if (mail_get_save_date(ctx->mail, &t) < 0)
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen return -1;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen doveadm_print(dec2str(t));
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen return 0;
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen}
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainenstatic int fetch_imap_envelope(struct fetch_cmd_context *ctx)
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen{
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen const char *value;
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_ENVELOPE, &value) < 0)
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen return -1;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(value);
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen return 0;
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen}
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainenstatic int fetch_imap_body(struct fetch_cmd_context *ctx)
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen{
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen const char *value;
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_BODY, &value) < 0)
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen return -1;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(value);
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen return 0;
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen}
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainenstatic int fetch_imap_bodystructure(struct fetch_cmd_context *ctx)
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen{
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen const char *value;
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_IMAP_BODYSTRUCTURE, &value) < 0)
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen return -1;
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print(value);
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen return 0;
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen}
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainenstatic int fetch_pop3_uidl(struct fetch_cmd_context *ctx)
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen{
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen const char *value;
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_UIDL_BACKEND, &value) < 0)
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen return -1;
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen doveadm_print(value);
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen return 0;
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen}
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainenstatic int fetch_pop3_order(struct fetch_cmd_context *ctx)
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen{
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen const char *value;
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_POP3_ORDER, &value) < 0)
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen return -1;
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen doveadm_print(value);
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen return 0;
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen}
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainenstatic int fetch_refcount(struct fetch_cmd_context *ctx)
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen{
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen const char *value;
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_REFCOUNT, &value) < 0)
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen return -1;
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen doveadm_print(value);
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen return 0;
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen}
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainenstatic int fetch_storageid(struct fetch_cmd_context *ctx)
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen{
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen const char *value;
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen if (mail_get_special(ctx->mail, MAIL_FETCH_STORAGE_ID, &value) < 0)
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen return -1;
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen doveadm_print(value);
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen return 0;
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen}
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainenstatic const struct fetch_field fetch_fields[] = {
1631885636d15abaf0375304a17928c8c23782cdTimo Sirainen { "user", 0, fetch_user },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "mailbox", 0, fetch_mailbox },
f77da594de6318312a7f31589c9e4c38e2b74c73Timo Sirainen { "mailbox-guid", 0, fetch_mailbox_guid },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "seq", 0, fetch_seq },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "uid", 0, fetch_uid },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "guid", 0, fetch_guid },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "flags", MAIL_FETCH_FLAGS, fetch_flags },
5e46f82843a13cc590900352d34c899cd5967de0Timo Sirainen { "modseq", 0, fetch_modseq },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "hdr", MAIL_FETCH_STREAM_HEADER, fetch_hdr },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "body", MAIL_FETCH_STREAM_BODY, fetch_body },
ed897f9e09ae8ad86a88955420bd275b46ee8231Timo Sirainen { "body.snippet", MAIL_FETCH_BODY_SNIPPET, fetch_body_snippet },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "text", MAIL_FETCH_STREAM_HEADER |
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen MAIL_FETCH_STREAM_BODY, fetch_text },
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen { "text.utf8", MAIL_FETCH_STREAM_HEADER |
46d283ef537885386ab3fc72d1831054ea5f986bTimo Sirainen MAIL_FETCH_STREAM_BODY, fetch_text_utf8 },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "size.physical", MAIL_FETCH_PHYSICAL_SIZE, fetch_size_physical },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "size.virtual", MAIL_FETCH_VIRTUAL_SIZE, fetch_size_virtual },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "date.received", MAIL_FETCH_RECEIVED_DATE, fetch_date_received },
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen { "date.sent", MAIL_FETCH_DATE, fetch_date_sent },
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen { "date.saved", MAIL_FETCH_SAVE_DATE, fetch_date_saved },
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen { "date.received.unixtime", MAIL_FETCH_RECEIVED_DATE, fetch_date_received_unixtime },
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen { "date.sent.unixtime", MAIL_FETCH_DATE, fetch_date_sent_unixtime },
7dd67cf142c243c735c00d640b7c85015b7da50aTimo Sirainen { "date.saved.unixtime", MAIL_FETCH_SAVE_DATE, fetch_date_saved_unixtime },
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen { "imap.envelope", MAIL_FETCH_IMAP_ENVELOPE, fetch_imap_envelope },
c8ff6ff3a9b76f12b0e8269ca7bdd62d895f476bTimo Sirainen { "imap.body", MAIL_FETCH_IMAP_BODY, fetch_imap_body },
7f03bac2ef9fae720ce96536b1e936066f093de4Timo Sirainen { "imap.bodystructure", MAIL_FETCH_IMAP_BODYSTRUCTURE, fetch_imap_bodystructure },
58f5b4641f4c0f91738ba4cb1246beb247f07da4Timo Sirainen { "pop3.uidl", MAIL_FETCH_UIDL_BACKEND, fetch_pop3_uidl },
e1ba963457988db73650fbf972398e1d0e2318b6Timo Sirainen { "pop3.order", MAIL_FETCH_POP3_ORDER, fetch_pop3_order },
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen { "refcount", MAIL_FETCH_REFCOUNT, fetch_refcount },
7d56dc75f70aaea4369f4bfcffb0cd1b5abe1ca9Timo Sirainen { "storageid", MAIL_FETCH_STORAGE_ID, fetch_storageid }
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen};
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainenstatic const struct fetch_field *fetch_field_find(const char *name)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen unsigned int i;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen for (i = 0; i < N_ELEMENTS(fetch_fields); i++) {
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (strcmp(fetch_fields[i].name, name) == 0)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return &fetch_fields[i];
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen }
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen return NULL;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainenstatic void print_fetch_fields(void)
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen{
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen unsigned int i;
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen fprintf(stderr, "Available fetch fields: hdr.<name> body.<section> binary.<section> %s", fetch_fields[0].name);
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen for (i = 1; i < N_ELEMENTS(fetch_fields); i++)
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen fprintf(stderr, " %s", fetch_fields[i].name);
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen fprintf(stderr, "\n");
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen}
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainenstatic void parse_fetch_fields(struct fetch_cmd_context *ctx, const char *str)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen const char *const *fields, *name;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen const struct fetch_field *field;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen struct fetch_field hdr_field, body_field;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen struct imap_msgpart *msgpart;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&hdr_field);
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen hdr_field.print = fetch_hdr_field;
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&body_field);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen body_field.print = fetch_body_field;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen t_array_init(&ctx->fields, 32);
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen t_array_init(&ctx->header_fields, 32);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen fields = t_strsplit_spaces(str, " ");
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen for (; *fields != NULL; fields++) {
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen name = t_str_lcase(*fields);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
c154a05c76d4d83de1cdf9746ce4e2da0869705dTimo Sirainen doveadm_print_header_simple(name);
0d16e4b4ba379b5d4c9b21e55173b291cac4d354Timo Sirainen if ((field = fetch_field_find(name)) != NULL) {
0d16e4b4ba379b5d4c9b21e55173b291cac4d354Timo Sirainen ctx->wanted_fields |= field->wanted_fields;
0d16e4b4ba379b5d4c9b21e55173b291cac4d354Timo Sirainen array_append(&ctx->fields, field, 1);
0d16e4b4ba379b5d4c9b21e55173b291cac4d354Timo Sirainen } else if (strncmp(name, "hdr.", 4) == 0) {
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen name += 4;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen hdr_field.name = name;
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen array_append(&ctx->fields, &hdr_field, 1);
cf1c3e6833fc5031d89db48dad46ed025beda4e7Timo Sirainen name = t_strcut(name, '.');
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen array_append(&ctx->header_fields, &name, 1);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen } else if (strncmp(name, "body.", 5) == 0 ||
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen strncmp(name, "binary.", 7) == 0) {
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen bool binary = strncmp(name, "binary.", 7) == 0;
c001f4b968deb006f4f753af19db7843a2209ec5Timo Sirainen body_field.name = t_strarray_join(t_strsplit(name, ","), " ");
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen name += binary ? 7 : 5;
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen if (imap_msgpart_parse(name, &msgpart) < 0) {
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen print_fetch_fields();
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen i_fatal("Unknown fetch section: %s", name);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen }
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen array_append(&ctx->fields, &body_field, 1);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen ctx->wanted_fields |= imap_msgpart_get_fetch_data(msgpart);
f24b245f49b030d7dba3bcb2463cbc05b98c9d1dTimo Sirainen imap_msgpart_free(&msgpart);
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen } else {
0d16e4b4ba379b5d4c9b21e55173b291cac4d354Timo Sirainen print_fetch_fields();
0d16e4b4ba379b5d4c9b21e55173b291cac4d354Timo Sirainen i_fatal("Unknown fetch field: %s", name);
7f098e28ddad259d9fbe76e18347c722bb005189Timo Sirainen }
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen }
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen array_append_zero(&ctx->header_fields);
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen}
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainenstatic int cmd_fetch_mail(struct fetch_cmd_context *ctx)
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen{
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen const struct fetch_field *field;
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen struct mail *mail = ctx->mail;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen int ret = 0;
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen array_foreach(&ctx->fields, field) {
d38ca817bdcec666a3b91efb917064ab844c36a2Timo Sirainen ctx->cur_field = field;
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen if (field->print(ctx) < 0) {
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen i_error("fetch(%s) failed for box=%s uid=%u: %s",
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen field->name, mailbox_get_vname(mail->box),
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen mail->uid,
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen ctx->print_error != NULL ? ctx->print_error :
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mailbox_get_last_internal_error(mail->box, NULL));
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen doveadm_mail_failed_mailbox(&ctx->ctx, mail->box);
2d7da70c0e6768afeb1200c95f3e1293f2e502c6Timo Sirainen ctx->print_error = NULL;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen }
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen }
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen return ret;
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen}
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainenstatic int
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainencmd_fetch_box(struct fetch_cmd_context *ctx, const struct mailbox_info *info)
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen{
f23baa3b53b1dd4eb19729e99a43937fa3c7f309Timo Sirainen struct doveadm_mail_iter *iter;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen int ret = 0;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (doveadm_mail_iter_init(&ctx->ctx, info, ctx->ctx.search_args,
2dbb7b30d9bf6d6b0cd104c6931c4b44a77c2383Aki Tuomi ctx->wanted_fields,
ec1fe002da484f4c06f0c072d673abac74b66b9eTimo Sirainen array_idx(&ctx->header_fields, 0),
2dbb7b30d9bf6d6b0cd104c6931c4b44a77c2383Aki Tuomi FALSE,
c57ba1788a6598993a9625bbf26a4fedca23815eTimo Sirainen &iter) < 0)
ec1fe002da484f4c06f0c072d673abac74b66b9eTimo Sirainen return -1;
ec1fe002da484f4c06f0c072d673abac74b66b9eTimo Sirainen
ec1fe002da484f4c06f0c072d673abac74b66b9eTimo Sirainen while (doveadm_mail_iter_next(iter, &ctx->mail)) {
ec1fe002da484f4c06f0c072d673abac74b66b9eTimo Sirainen T_BEGIN {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (cmd_fetch_mail(ctx) < 0)
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
ec1fe002da484f4c06f0c072d673abac74b66b9eTimo Sirainen } T_END;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen }
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (doveadm_mail_iter_deinit(&iter) < 0)
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen return ret;
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen}
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainenstatic int
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainencmd_fetch_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen{
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen const enum mailbox_list_iter_flags iter_flags =
b3126bef7460052415eea07b300d02c8eb07c1d7Timo Sirainen MAILBOX_LIST_ITER_NO_AUTO_BOXES |
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen struct doveadm_mailbox_list_iter *iter;
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen const struct mailbox_info *info;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen int ret = 0;
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen iter = doveadm_mailbox_list_iter_init(_ctx, user, _ctx->search_args,
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen iter_flags);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (cmd_fetch_box(ctx, info) < 0)
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen } T_END;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (doveadm_mailbox_list_iter_deinit(&iter) < 0)
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = -1;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen return ret;
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen}
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen
23878bd03d1de531e3261a25598beec621351910Timo Sirainenstatic void cmd_fetch_init(struct doveadm_mail_cmd_context *_ctx,
23878bd03d1de531e3261a25598beec621351910Timo Sirainen const char *const args[])
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen{
23878bd03d1de531e3261a25598beec621351910Timo Sirainen struct fetch_cmd_context *ctx = (struct fetch_cmd_context *)_ctx;
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen const char *fetch_fields = args[0];
8732bdd21579472feb40da8ffc99b8fd3b341417Timo Sirainen
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen if (fetch_fields == NULL || args[1] == NULL)
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen doveadm_mail_help_name("fetch");
cdf294e5cceee81d58c8477c7c28d9ad6b55c36aTimo Sirainen
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen parse_fetch_fields(ctx, fetch_fields);
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen _ctx->search_args = doveadm_mail_build_search_args(args + 1);
23878bd03d1de531e3261a25598beec621351910Timo Sirainen}
23878bd03d1de531e3261a25598beec621351910Timo Sirainen
23878bd03d1de531e3261a25598beec621351910Timo Sirainenstatic struct doveadm_mail_cmd_context *cmd_fetch_alloc(void)
23878bd03d1de531e3261a25598beec621351910Timo Sirainen{
23878bd03d1de531e3261a25598beec621351910Timo Sirainen struct fetch_cmd_context *ctx;
23878bd03d1de531e3261a25598beec621351910Timo Sirainen
23878bd03d1de531e3261a25598beec621351910Timo Sirainen ctx = doveadm_mail_cmd_alloc(struct fetch_cmd_context);
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen ctx->ctx.v.init = cmd_fetch_init;
1db62753d9e3b5d71018889c8ef0a3722a307455Timo Sirainen ctx->ctx.v.run = cmd_fetch_run;
a4a7440a1033203c48d5f0174b3d85514b79f3a0Timo Sirainen doveadm_print_init(DOVEADM_PRINT_TYPE_PAGER);
cf63dc8723b971cc80638fccbf494d961cbafc7fTimo Sirainen return &ctx->ctx;
94ba4820927b906b333e39445c1508a29387c3aaTimo Sirainen}
23878bd03d1de531e3261a25598beec621351910Timo Sirainen
89d31290dab6e4bde08b8a118121f008154772e9Aki Tuomistruct doveadm_cmd_ver2 doveadm_cmd_fetch_ver2 = {
89d31290dab6e4bde08b8a118121f008154772e9Aki Tuomi .name = "fetch",
89d31290dab6e4bde08b8a118121f008154772e9Aki Tuomi .mail_cmd = cmd_fetch_alloc,
c45a841bee3f42ec6524b8f62c3fd457115c3f97Timo Sirainen .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"<fields> <search query>",
89d31290dab6e4bde08b8a118121f008154772e9Aki TuomiDOVEADM_CMD_PARAMS_START
89d31290dab6e4bde08b8a118121f008154772e9Aki TuomiDOVEADM_CMD_MAIL_COMMON
89d31290dab6e4bde08b8a118121f008154772e9Aki TuomiDOVEADM_CMD_PARAM('\0', "field", CMD_PARAM_ARRAY, 0)
89d31290dab6e4bde08b8a118121f008154772e9Aki TuomiDOVEADM_CMD_PARAM('\0', "fieldstr", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL | CMD_PARAM_FLAG_DO_NOT_EXPOSE) /* FIXME: horrible hack, remove me when possible */
89d31290dab6e4bde08b8a118121f008154772e9Aki TuomiDOVEADM_CMD_PARAM('\0', "query", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
89d31290dab6e4bde08b8a118121f008154772e9Aki TuomiDOVEADM_CMD_PARAMS_END
23878bd03d1de531e3261a25598beec621351910Timo Sirainen};