bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#include "lib.h"
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#include "ioloop.h"
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen#include "buffer.h"
6c1a5346febccc35b8d5eb4f26e62748ca640529Timo Sirainen#include "hash.h"
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen#include "hex-binary.h"
d172c364637944d667aa98eb5de0d4a3a97ab92aTimo Sirainen#include "crc32.h"
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen#include "sha1.h"
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen#include "hostpid.h"
7370fb9ff75b674f99059adf24502ee9ae7a47bcTimo Sirainen#include "mail-cache.h"
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#include "mail-storage-private.h"
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi#include "message-part-data.h"
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen#include <time.h>
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct mail *mail_alloc(struct mailbox_transaction_context *t,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen enum mail_fetch_field wanted_fields,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen struct mail *mail;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
045d5940e885be4d5d3ce96f2fde31ae799fa556Timo Sirainen i_assert(wanted_headers == NULL || wanted_headers->box == t->box);
045d5940e885be4d5d3ce96f2fde31ae799fa556Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen T_BEGIN {
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen mail = t->box->v.mail_alloc(t, wanted_fields, wanted_headers);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen hook_mail_allocated(mail);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen } T_END;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_free(struct mail **mail)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct mail_private *p = (struct mail_private *)*mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen p->v.free(*mail);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *mail = NULL;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_set_seq(struct mail *mail, uint32_t seq)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen p->v.set_seq(mail, seq, FALSE);
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen}
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainenvoid mail_set_seq_saving(struct mail *mail, uint32_t seq)
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen{
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen p->v.set_seq(mail, seq, TRUE);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenbool mail_set_uid(struct mail *mail, uint32_t uid)
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen{
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen return p->v.set_uid(mail, uid);
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen}
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainenbool mail_prefetch(struct mail *mail)
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen{
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen bool ret;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.prefetch(mail);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen}
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainenvoid mail_add_temp_wanted_fields(struct mail *mail,
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen enum mail_fetch_field fields,
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen struct mailbox_header_lookup_ctx *headers)
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen{
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen
045d5940e885be4d5d3ce96f2fde31ae799fa556Timo Sirainen i_assert(headers == NULL || headers->box == mail->box);
045d5940e885be4d5d3ce96f2fde31ae799fa556Timo Sirainen
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen p->v.add_temp_wanted_fields(mail, fields, headers);
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen}
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenenum mail_flags mail_get_flags(struct mail *mail)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return p->v.get_flags(mail);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainenuint64_t mail_get_modseq(struct mail *mail)
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen{
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen return p->v.get_modseq(mail);
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen}
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainenuint64_t mail_get_pvt_modseq(struct mail *mail)
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen{
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen return p->v.get_pvt_modseq(mail);
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen}
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenconst char *const *mail_get_keywords(struct mail *mail)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return p->v.get_keywords(mail);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainenconst ARRAY_TYPE(keyword_indexes) *mail_get_keyword_indexes(struct mail *mail)
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen{
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen return p->v.get_keyword_indexes(mail);
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen}
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen
c0225f7f6b43d34dc58c17d3304f0fd60ab89894Timo Sirainenint mail_get_parts(struct mail *mail, struct message_part **parts_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_parts(mail, parts_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_date(mail, date_r, timezone_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_received_date(struct mail *mail, time_t *date_r)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen{
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_received_date(mail, date_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen}
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_save_date(struct mail *mail, time_t *date_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_save_date(mail, date_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_virtual_size(struct mail *mail, uoff_t *size_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_virtual_size(mail, size_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_physical_size(struct mail *mail, uoff_t *size_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_physical_size(mail, size_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_first_header(struct mail *mail, const char *field,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char **value_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_first_header(mail, field, FALSE, value_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen}
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_first_header_utf8(struct mail *mail, const char *field,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char **value_r)
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen{
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_first_header(mail, field, TRUE, value_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_headers(struct mail *mail, const char *field,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char *const **value_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_headers(mail, field, FALSE, value_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen}
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_headers_utf8(struct mail *mail, const char *field,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char *const **value_r)
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen{
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_headers(mail, field, TRUE, value_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_header_stream(struct mail *mail,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct mailbox_header_lookup_ctx *headers,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct istream **stream_r)
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen{
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen int ret;
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen
045d5940e885be4d5d3ce96f2fde31ae799fa556Timo Sirainen i_assert(headers->count > 0);
045d5940e885be4d5d3ce96f2fde31ae799fa556Timo Sirainen i_assert(headers->box == mail->box);
045d5940e885be4d5d3ce96f2fde31ae799fa556Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen ret = p->v.get_header_stream(mail, headers, stream_r);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_set_aborted(struct mail *mail)
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen{
a0cd302bcb827678f9c9c2ca1d0a3f0d3c0b3563Timo Sirainen mail_storage_set_error(mail->box->storage, MAIL_ERROR_LOOKUP_ABORTED,
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen "Mail field not cached");
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen}
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_stream(struct mail *mail, struct message_size *hdr_size,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct message_size *body_size, struct istream **stream_r)
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen{
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen return mail_get_stream_because(mail, hdr_size, body_size,
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen "mail stream", stream_r);
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen}
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainenint mail_get_stream_because(struct mail *mail, struct message_size *hdr_size,
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen struct message_size *body_size,
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen const char *reason, struct istream **stream_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen int ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen if (mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_set_aborted(mail);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return -1;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen }
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen T_BEGIN {
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen p->get_stream_reason = reason;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen ret = p->v.get_stream(mail, TRUE, hdr_size, body_size, stream_r);
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen p->get_stream_reason = "";
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen } T_END;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen return ret;
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen}
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainenint mail_get_hdr_stream(struct mail *mail, struct message_size *hdr_size,
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen struct istream **stream_r)
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen{
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen return mail_get_hdr_stream_because(mail, hdr_size, "header stream", stream_r);
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen}
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainenint mail_get_hdr_stream_because(struct mail *mail,
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen struct message_size *hdr_size,
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen const char *reason, struct istream **stream_r)
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen{
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen int ret;
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen if (mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_set_aborted(mail);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return -1;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen }
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen T_BEGIN {
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen p->get_stream_reason = reason;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen ret = p->v.get_stream(mail, FALSE, hdr_size, NULL, stream_r);
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen p->get_stream_reason = "";
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen } T_END;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainenint mail_get_binary_stream(struct mail *mail, const struct message_part *part,
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen bool include_hdr, uoff_t *size_r,
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen bool *binary_r, struct istream **stream_r)
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen{
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen int ret;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen if (mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen mail_set_aborted(mail);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen return -1;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen }
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen T_BEGIN {
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen ret = p->v.get_binary_stream(mail, part, include_hdr,
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen size_r, NULL, binary_r, stream_r);
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen } T_END;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen return ret;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen}
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainenint mail_get_binary_size(struct mail *mail, const struct message_part *part,
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen bool include_hdr, uoff_t *size_r,
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen unsigned int *lines_r)
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen{
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen bool binary;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen int ret;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen T_BEGIN {
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen ret = p->v.get_binary_stream(mail, part, include_hdr,
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen size_r, lines_r, &binary, NULL);
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen } T_END;
6e8f0036cad59d1d6bcd9ef69bfe712d01656ca3Timo Sirainen return ret;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen}
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenint mail_get_special(struct mail *mail, enum mail_fetch_field field,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char **value_r)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
c161661e74ed29504a461110670f816ffa408b42Timo Sirainen if (p->v.get_special(mail, field, value_r) < 0)
c161661e74ed29504a461110670f816ffa408b42Timo Sirainen return -1;
c161661e74ed29504a461110670f816ffa408b42Timo Sirainen i_assert(*value_r != NULL);
c161661e74ed29504a461110670f816ffa408b42Timo Sirainen return 0;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
541b251a99a55cb0fa2eaf02645a7c39ad997092Timo Sirainenint mail_get_backend_mail(struct mail *mail, struct mail **real_mail_r)
9af6cc9ebc9986c1275ebdfa29c39e152af1557eTimo Sirainen{
9af6cc9ebc9986c1275ebdfa29c39e152af1557eTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
21aaa6affb9f134112b75b5db737309fc35ef1cfMartti Rannanjärvi return p->v.get_backend_mail(mail, real_mail_r);
9af6cc9ebc9986c1275ebdfa29c39e152af1557eTimo Sirainen}
9af6cc9ebc9986c1275ebdfa29c39e152af1557eTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_update_flags(struct mail *mail, enum modify_type modify_type,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen enum mail_flags flags)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
efb373fd7e30df171452c9f40881a8bd06b81780Timo Sirainen p->v.update_flags(mail, modify_type, flags);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_update_keywords(struct mail *mail, enum modify_type modify_type,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen struct mail_keywords *keywords)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen p->v.update_keywords(mail, modify_type, keywords);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainenvoid mail_update_modseq(struct mail *mail, uint64_t min_modseq)
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen{
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen p->v.update_modseq(mail, min_modseq);
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen}
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainenvoid mail_update_pvt_modseq(struct mail *mail, uint64_t min_pvt_modseq)
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen{
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen p->v.update_pvt_modseq(mail, min_pvt_modseq);
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen}
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainenvoid mail_update_pop3_uidl(struct mail *mail, const char *uidl)
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen{
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen if (p->v.update_pop3_uidl != NULL)
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen p->v.update_pop3_uidl(mail, uidl);
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen}
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_expunge(struct mail *mail)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen T_BEGIN {
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen p->v.expunge(mail);
8dccbdbe38f0e9342caf752d9d980a64125fa4d1Timo Sirainen } T_END;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomivoid mail_autoexpunge(struct mail *mail)
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi{
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi struct mail_private *p = (struct mail_private *)mail;
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi p->autoexpunged = TRUE;
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi mail_expunge(mail);
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi p->autoexpunged = FALSE;
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi}
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainenvoid mail_set_expunged(struct mail *mail)
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen{
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen mail_storage_set_error(mail->box->storage, MAIL_ERROR_EXPUNGED,
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen "Message was expunged");
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen mail->expunged = TRUE;
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen}
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenvoid mail_precache(struct mail *mail)
c7e14824e4e1ca9dc5d48d1eddc4a38d3041218fTimo Sirainen{
c7e14824e4e1ca9dc5d48d1eddc4a38d3041218fTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
c7e14824e4e1ca9dc5d48d1eddc4a38d3041218fTimo Sirainen
b6c6c4f6483b8340eec4c16c50ea078fe8297da2Timo Sirainen T_BEGIN {
b6c6c4f6483b8340eec4c16c50ea078fe8297da2Timo Sirainen p->v.precache(mail);
b6c6c4f6483b8340eec4c16c50ea078fe8297da2Timo Sirainen } T_END;
c7e14824e4e1ca9dc5d48d1eddc4a38d3041218fTimo Sirainen}
c7e14824e4e1ca9dc5d48d1eddc4a38d3041218fTimo Sirainen
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvivoid mail_set_cache_corrupted(struct mail *mail,
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvi enum mail_fetch_field field,
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvi const char *reason)
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen{
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvi p->v.set_cache_corrupted(mail, field, reason);
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen}
b19a1420da0618a10edf67c2cfd13c8c8633057aTimo Sirainen
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainenvoid mail_generate_guid_128_hash(const char *guid, guid_128_t guid_128_r)
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen{
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen unsigned char sha1_sum[SHA1_RESULTLEN];
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen buffer_t buf;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen if (guid_128_from_string(guid, guid_128_r) < 0) {
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen /* not 128bit hex. use a hash of it instead. */
3281669db44d09a087a203201248abbc81b3cc1aTimo Sirainen buffer_create_from_data(&buf, guid_128_r, GUID_128_SIZE);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen buffer_set_used_size(&buf, 0);
0f83592ccc280a29bdf01c4475805f6a4bad9abdTimo Sirainen sha1_get_digest(guid, strlen(guid), sha1_sum);
111673ed6ef01d9395eb5bfc59e4ac707ba8f5d9Martti Rannanjärvi#if SHA1_RESULTLEN < GUID_128_SIZE
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen# error not possible
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen#endif
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen buffer_append(&buf,
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen sha1_sum + SHA1_RESULTLEN - GUID_128_SIZE,
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen GUID_128_SIZE);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen }
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen}
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomistatic bool
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomimail_message_has_attachment(struct message_part *part,
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi const struct message_part_attachment_settings *set)
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi{
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi for (; part != NULL; part = part->next) {
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi if (message_part_is_attachment(part, set) ||
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_message_has_attachment(part->children, set))
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi return TRUE;
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi }
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi return FALSE;
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi}
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomibool mail_has_attachment_keywords(struct mail *mail)
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi{
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi const char *const *kw = mail_get_keywords(mail);
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi return (str_array_icase_find(kw, MAIL_KEYWORD_HAS_ATTACHMENT) !=
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi str_array_icase_find(kw, MAIL_KEYWORD_HAS_NO_ATTACHMENT));
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi}
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomivoid mail_set_attachment_keywords(struct mail *mail)
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi{
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi const struct mail_storage_settings *mail_set =
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_storage_get_settings(mailbox_get_storage(mail->box));
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi const char *const keyword_has_attachment[] = {
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi MAIL_KEYWORD_HAS_ATTACHMENT,
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi NULL,
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi };
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi const char *const keyword_has_no_attachment[] = {
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi MAIL_KEYWORD_HAS_NO_ATTACHMENT,
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi NULL
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi };
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi struct message_part_attachment_settings set = {
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi .content_type_filter =
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_set->parsed_mail_attachment_content_type_filter,
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi .exclude_inlined =
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_set->parsed_mail_attachment_exclude_inlined,
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi };
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi struct mail_keywords *kw_has = NULL, *kw_has_not = NULL;
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi /* walk all parts and see if there is an attachment */
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi struct message_part *parts;
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi if (mail_get_parts(mail, &parts) < 0) {
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_set_critical(mail, "Failed to add attachment keywords: "
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi "mail_get_parts() failed: %s",
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_storage_get_last_internal_error(mail->box->storage, NULL));
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi return;
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi } else if (mailbox_keywords_create(mail->box, keyword_has_attachment, &kw_has) < 0 ||
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mailbox_keywords_create(mail->box, keyword_has_no_attachment, &kw_has_not) < 0) {
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi if (mail_set->mail_debug) {
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi i_debug("Failed to add attachment keywords: mailbox_keyword_create(%s) failed: %s",
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mailbox_get_vname(mail->box),
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_storage_get_last_error(mail->box->storage, NULL));
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi }
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi } else {
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi bool has_attachment = mail_message_has_attachment(parts, &set);
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi /* make sure only one of the keywords gets set */
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_update_keywords(mail, MODIFY_REMOVE, has_attachment ? kw_has_not : kw_has);
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mail_update_keywords(mail, MODIFY_ADD, has_attachment ? kw_has : kw_has_not);
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi }
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi if (kw_has != NULL)
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mailbox_keywords_unref(&kw_has);
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi if (kw_has_not != NULL)
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi mailbox_keywords_unref(&kw_has_not);
722c012ccadcf1f63d70439a2564e77510b6dd86Aki Tuomi}