This is a preparation for plugins overriding the default backend for a recipient.
#include "submission-common.h"
#include "llist.h"
+#include "istream.h"
+#include "istream-sized.h"
#include "submission-client.h"
#include "submission-commands.h"
{
struct client *client = backend->client;
+ i_stream_unref(&backend->data_input);
+
DLLIST_REMOVE(&client->backends, backend);
backend->v.destroy(backend);
}
{
while (client->backends != NULL)
submission_backend_destroy(client->backends);
+ array_clear(&client->rcpt_backends);
client->state.backend = NULL;
}
return UOFF_T_MAX;
}
+void submission_backends_trans_free(struct client *client)
+{
+ struct submission_backend *const *bkp;
+
+ i_assert(client->state.backend != NULL ||
+ array_count(&client->rcpt_backends) == 0);
+
+ array_foreach(&client->rcpt_backends, bkp) {
+ struct submission_backend *backend = *bkp;
+
+ i_stream_unref(&backend->data_input);
+ }
+ array_clear(&client->rcpt_backends);
+ client->state.backend = NULL;
+}
+
int submission_backend_cmd_helo(struct submission_backend *backend,
struct smtp_server_cmd_ctx *cmd,
struct smtp_server_cmd_helo *data)
return backend->v.cmd_rset(backend, cmd);
}
-int submission_backend_cmd_data(struct submission_backend *backend,
- struct smtp_server_cmd_ctx *cmd,
- struct smtp_server_transaction *trans,
- struct istream *data_input, uoff_t data_size)
+static int
+submission_backend_cmd_data(struct submission_backend *backend,
+ struct smtp_server_cmd_ctx *cmd,
+ struct smtp_server_transaction *trans)
{
- return backend->v.cmd_data(backend, cmd, trans, data_input, data_size);
+ return backend->v.cmd_data(backend, cmd, trans,
+ backend->data_input, backend->data_size);
+}
+
+int submission_backends_cmd_data(struct client *client,
+ struct smtp_server_cmd_ctx *cmd,
+ struct smtp_server_transaction *trans,
+ struct istream *data_input, uoff_t data_size)
+{
+ struct submission_backend *const *bkp;
+ int ret = 0;
+
+ i_assert(array_count(&client->rcpt_backends) > 0);
+
+ /* create the data_input streams first */
+ array_foreach_modifiable(&client->rcpt_backends, bkp) {
+ struct submission_backend *backend = *bkp;
+
+ backend->data_input =
+ i_stream_create_sized(data_input, data_size);
+ backend->data_size = data_size;
+ }
+
+ /* now that all the streams are created, start reading them
+ (reading them earlier could have caused the data_input parent's
+ offset to change) */
+ array_foreach_modifiable(&client->rcpt_backends, bkp) {
+ struct submission_backend *backend = *bkp;
+
+ ret = submission_backend_cmd_data(backend, cmd, trans);
+ if (ret < 0)
+ break;
+ }
+
+ return ret;
}
int submission_backend_cmd_vrfy(struct submission_backend *backend,
struct submission_backend_vfuncs v;
+ struct istream *data_input;
+ uoff_t data_size;
+
bool started:1;
};
uoff_t submission_backend_get_max_mail_size(struct submission_backend *backend);
+void submission_backends_trans_free(struct client *client);
+
void submission_backend_helo_reply_submit(struct submission_backend *backend,
struct smtp_server_cmd_ctx *cmd,
struct smtp_server_cmd_helo *data);
struct smtp_server_cmd_rcpt *data);
int submission_backend_cmd_rset(struct submission_backend *backend,
struct smtp_server_cmd_ctx *cmd);
-int submission_backend_cmd_data(struct submission_backend *backend,
- struct smtp_server_cmd_ctx *cmd,
- struct smtp_server_transaction *trans,
- struct istream *data_input, uoff_t data_size);
+int submission_backends_cmd_data(struct client *client,
+ struct smtp_server_cmd_ctx *cmd,
+ struct smtp_server_transaction *trans,
+ struct istream *data_input, uoff_t data_size);
int submission_backend_cmd_vrfy(struct submission_backend *backend,
struct smtp_server_cmd_ctx *cmd,
client->session_id = i_strdup(session_id);
i_array_init(&client->rcpt_to, 8);
+ i_array_init(&client->rcpt_backends, 8);
i_zero(&smtp_set);
smtp_set.hostname = set->hostname;
submission_backends_destroy_all(client);
array_free(&client->rcpt_to);
+ array_free(&client->rcpt_backends);
submission_client_count--;
DLLIST_REMOVE(&submission_clients, client);
submission_recipient_destroy(rcptp);
array_clear(&client->rcpt_to);
+ submission_backends_trans_free(client);
client_state_reset(client);
}
enum smtp_server_state last_state;
struct client_state state;
ARRAY(struct submission_recipient *) rcpt_to;
+ ARRAY(struct submission_backend *) rcpt_backends;
struct mail_storage_service_user *service_user;
struct mail_user *user;
data->trans_context = rcpt;
data->hook_finished = submission_rcpt_finished;
- return submission_backend_cmd_rcpt(client->state.backend, cmd, data);
+ return submission_backend_cmd_rcpt(rcpt->backend, cmd, data);
}
/*
i_stream_unref(&inputs[0]);
i_stream_unref(&inputs[1]);
- ret = submission_backend_cmd_data(client->state.backend, cmd,
- trans, data_input, data_size);
+ ret = submission_backends_cmd_data(client, cmd, trans,
+ data_input, data_size);
i_stream_unref(&data_input);
return ret;
#include "submission-common.h"
+#include "submission-backend.h"
#include "submission-recipient.h"
struct submission_recipient *
struct submission_recipient *rcpt;
rcpt = i_new(struct submission_recipient, 1);
- rcpt->client = client;
+ rcpt->backend = client->state.backend;
rcpt->path = path;
return rcpt;
struct smtp_server_recipient *trcpt,
unsigned int index)
{
- struct client *client = rcpt->client;
+ struct submission_backend *backend = rcpt->backend;
+ struct client *client = backend->client;
+ struct submission_backend *const *bknd_idx;
+ bool backend_found = FALSE;
rcpt->path = trcpt->path;
rcpt->index = index;
array_append(&client->rcpt_to, &rcpt, 1);
+
+ array_foreach(&client->rcpt_backends, bknd_idx) {
+ if (*bknd_idx == backend) {
+ backend_found = TRUE;
+ break;
+ }
+ }
+ if (!backend_found)
+ array_append(&client->rcpt_backends, &backend, 1);
}
#ifndef SUBMISSION_RECIPIENT_H
#define SUBMISSION_RECIPIENT_H
+struct submission_backend;
struct client;
struct submission_recipient {
- struct client *client;
+ struct submission_backend *backend;
struct smtp_address *path;
unsigned int index;