/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "str.h"
#include "str-sanitize.h"
#include "time-util.h"
#include "unichar.h"
#include "var-expand.h"
#include "message-address.h"
#include "smtp-address.h"
#include "lda-settings.h"
#include "mail-storage.h"
#include "mail-namespace.h"
#include "mail-storage-private.h"
#include "mail-duplicate.h"
#include "mail-deliver.h"
struct mail_deliver_user {
bool want_storage_id;
};
struct mail_deliver_cache {
bool filled;
const char *message_id;
const char *subject;
const char *from;
const char *from_envelope;
const char *storage_id;
};
struct mail_deliver_mailbox {
};
struct mail_deliver_transaction {
};
static const char *lda_log_wanted_headers[] = {
"From", "Message-ID", "Subject",
};
const struct smtp_address *
{
const char *str;
return NULL;
(const unsigned char *)str,
}
{
}
static void
{
const char *from;
return;
}
const struct var_expand_table *
const char *message)
{
unsigned int delivery_time_msecs;
following call is ignored. Otherwise, only the source mail exists. */
/* This call finishes a mail delivery. With Sieve there may be multiple
mail deliveries. */
};
}
{
return;
i_error("Failed to expand deliver_log_format=%s: %s",
}
}
{
return session;
}
{
}
{
*error_str_r = NULL;
if (!uni_utf8_str_is_valid(name)) {
*error_str_r = "Mailbox name not valid UTF-8";
return -1;
}
if (ctx->lda_mailbox_autocreate)
if (ctx->lda_mailbox_autosubscribe)
if (mailbox_open(box) == 0)
return 0;
return -1;
}
{
/* just play it safe and assume a duplicate */
return TRUE;
}
/* there shouldn't be all that many recipients,
so just do a linear search */
return TRUE;
}
return FALSE;
}
struct mail_save_context *save_ctx)
{
return;
/* avoid storing duplicate GUIDs to delivered mails to INBOX. this
happens if mail is delivered to same user multiple times within a
session. the problem with this is that if GUIDs are used as POP3
UIDLs, some clients can't handle the duplicates well. */
}
}
static struct mail *
struct mailbox_transaction_context **trans_r)
{
struct mailbox_transaction_context *t;
return NULL;
}
*trans_r = t;
return mail;
}
struct mail_storage **storage_r)
{
struct mailbox_transaction_context *t;
bool default_save;
int ret = 0;
if (default_save)
mailbox_free(&box);
}
return -1;
}
if (ctx->save_dest_mail)
save_ctx = mailbox_save_alloc(t);
}
ret = -1;
if (ret < 0)
else
if (ret == 0) {
if (ctx->save_dest_mail) {
/* copying needs the message body. with maildir we also
need to get the GUID in case the message gets
expunged. get these early so the copying won't fail
later on. */
}
}
} else {
}
mailbox_free(&box);
return ret;
}
const struct smtp_address *
{
const char *path;
int ret;
"Return-Path", &path)) <= 0) {
if (ret < 0) {
i_warning("Failed read return-path header: %s",
}
return NULL;
}
(const unsigned char *)path,
i_warning("Failed to parse return-path header");
return NULL;
}
}
{
static int count = 0;
return t_strdup_printf("<dovecot-%s-%s-%d@%s>",
}
struct mail_storage *storage)
{
return TRUE;
return error == MAIL_ERROR_TEMP;
}
return FALSE;
}
struct mail_storage **storage_r)
{
int ret;
if (deliver_mail == NULL)
ret = -1;
else {
/* if message was saved, don't bounce it even though
the script failed later. */
} else {
/* success. message may or may not have been saved. */
ret = 0;
}
return -1;
}
}
/* plugins didn't handle this. save into the default mailbox. */
return -1;
}
}
/* still didn't work. try once more to save it
to INBOX. */
}
return ret;
}
{
return old_hook;
}
{
return -1;
/* initialize most of the fields from dest_mail */
return 0;
}
{
return -1;
/* initialize most of the fields from dest_mail */
return 0;
}
static void
{
struct mailbox_transaction_context *t;
const char *storage_id;
if (!muser->want_storage_id)
return;
/* getting storage_id requires a whole new mailbox view that is
synced, so it'll contain the newly written mail. this is racy, so
it's possible another process has already deleted the mail. */
storage_id[0] == '\0')
storage_id = NULL;
(void)mailbox_transaction_commit(&t);
} else {
}
mailbox_free(&box);
}
static struct mailbox_transaction_context *
const char *reason)
{
struct mailbox_transaction_context *t;
return t;
}
static int
struct mail_transaction_commit_changes *changes_r)
{
/* sieve creates multiple transactions, saves the mails and
then commits all of them at the end. we'll need to keep
switching the deliver_ctx->cache for each commit.
we also want to do this only for commits generated by sieve.
other plugins or storage backends may be creating transactions as
well, which we need to ignore. */
return -1;
}
return 0;
}
{
}
{
and should not be involved */
return;
v->copy = mail_deliver_copy;
}
};
void mail_deliver_hooks_init(void)
{
}