dovecot-2.2: lib-lda: More smtp-client.h API changes to support ...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Apr 28 21:50:37 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/605df40b0aef
changeset: 17285:605df40b0aef
user: Timo Sirainen <tss at iki.fi>
date: Tue Apr 29 00:50:08 2014 +0300
description:
lib-lda: More smtp-client.h API changes to support multiple destination addresses.
diffstat:
src/lib-lda/mail-send.c | 4 +-
src/lib-lda/smtp-client.c | 176 +++++++++++++++++++++------------------------
src/lib-lda/smtp-client.h | 8 +-
3 files changed, 93 insertions(+), 95 deletions(-)
diffs (truncated from 320 to 300 lines):
diff -r cd6079c61c2b -r 605df40b0aef src/lib-lda/mail-send.c
--- a/src/lib-lda/mail-send.c Tue Apr 29 00:48:54 2014 +0300
+++ b/src/lib-lda/mail-send.c Tue Apr 29 00:50:08 2014 +0300
@@ -86,7 +86,9 @@
str_sanitize(reason, 512));
}
- smtp_client = smtp_client_init(ctx->set, return_addr, NULL, &output);
+ smtp_client = smtp_client_init(ctx->set, NULL);
+ smtp_client_add_rcpt(smtp_client, return_addr);
+ output = smtp_client_send(smtp_client);
msgid = mail_deliver_get_new_message_id(ctx);
boundary = t_strdup_printf("%s/%s", my_pid, ctx->set->hostname);
diff -r cd6079c61c2b -r 605df40b0aef src/lib-lda/smtp-client.c
--- a/src/lib-lda/smtp-client.c Tue Apr 29 00:48:54 2014 +0300
+++ b/src/lib-lda/smtp-client.c Tue Apr 29 00:50:08 2014 +0300
@@ -21,8 +21,8 @@
#define DEFAULT_SUBMISSION_PORT 25
struct smtp_client {
+ pool_t pool;
struct ostream *output;
- buffer_t *buf;
int temp_fd;
pid_t pid;
@@ -31,49 +31,33 @@
bool finished;
const struct lda_settings *set;
- char *temp_path;
- char *destination;
- char *return_path;
- char *error;
+ const char *temp_path;
+ ARRAY_TYPE(const_string) destinations;
+ const char *return_path;
+ const char *error;
bool tempfail;
};
-static struct smtp_client *smtp_client_devnull(struct ostream **output_r)
-{
- struct smtp_client *client;
-
- client = i_new(struct smtp_client, 1);
- client->buf = buffer_create_dynamic(default_pool, 1);
- client->output = o_stream_create_buffer(client->buf);
- o_stream_close(client->output);
- client->pid = (pid_t)-1;
-
- *output_r = client->output;
- return client;
-}
-
static void ATTR_NORETURN
-smtp_client_run_sendmail(const struct lda_settings *set,
- const char *destination,
- const char *return_path, int fd)
+smtp_client_run_sendmail(struct smtp_client *client, int fd)
{
const char *const *sendmail_args, *const *argv, *str;
ARRAY_TYPE(const_string) args;
unsigned int i;
- sendmail_args = t_strsplit(set->sendmail_path, " ");
+ sendmail_args = t_strsplit(client->set->sendmail_path, " ");
t_array_init(&args, 16);
for (i = 0; sendmail_args[i] != NULL; i++)
array_append(&args, &sendmail_args[i], 1);
str = "-i"; array_append(&args, &str, 1); /* ignore dots */
str = "-f"; array_append(&args, &str, 1);
- str = return_path != NULL && *return_path != '\0' ?
- return_path : "<>";
+ str = client->return_path != NULL && *client->return_path != '\0' ?
+ client->return_path : "<>";
array_append(&args, &str, 1);
str = "--"; array_append(&args, &str, 1);
- array_append(&args, &destination, 1);
+ array_append_array(&args, &client->destinations);
array_append_zero(&args);
argv = array_idx(&args, 0);
@@ -85,41 +69,6 @@
execv_const(argv[0], argv);
}
-static struct smtp_client *
-smtp_client_init_sendmail(const struct lda_settings *set,
- const char *destination, const char *return_path,
- struct ostream **output_r)
-{
- struct smtp_client *client;
- int fd[2];
- pid_t pid;
-
- if (pipe(fd) < 0) {
- i_error("pipe() failed: %m");
- return smtp_client_devnull(output_r);
- }
-
- if ((pid = fork()) == (pid_t)-1) {
- i_error("fork() failed: %m");
- i_close_fd(&fd[0]); i_close_fd(&fd[1]);
- return smtp_client_devnull(output_r);
- }
- if (pid == 0) {
- /* child */
- i_close_fd(&fd[1]);
- smtp_client_run_sendmail(set, destination, return_path, fd[0]);
- }
- i_close_fd(&fd[0]);
-
- client = i_new(struct smtp_client, 1);
- client->output = o_stream_create_fd(fd[1], IO_BLOCK_SIZE, TRUE);
- o_stream_set_no_error_handling(client->output, TRUE);
- client->pid = pid;
-
- *output_r = client->output;
- return client;
-}
-
static int create_temp_file(const char **path_r)
{
string_t *path;
@@ -149,33 +98,75 @@
}
struct smtp_client *
-smtp_client_init(const struct lda_settings *set, const char *destination,
- const char *return_path, struct ostream **output_r)
+smtp_client_init(const struct lda_settings *set, const char *return_path)
{
struct smtp_client *client;
+ pool_t pool;
+
+ pool = pool_alloconly_create("smtp client", 256);
+ client = p_new(pool, struct smtp_client, 1);
+ client->pool = pool;
+ client->set = set;
+ client->return_path = p_strdup(pool, return_path);
+ client->use_smtp = *set->submission_host != '\0';
+ p_array_init(&client->destinations, pool, 2);
+ client->pid = (pid_t)-1;
+ return client;
+}
+
+void smtp_client_add_rcpt(struct smtp_client *client, const char *address)
+{
+ i_assert(client->output == NULL);
+
+ address = p_strdup(client->pool, address);
+ array_append(&client->destinations, &address, 1);
+}
+
+static struct ostream *smtp_client_send_sendmail(struct smtp_client *client)
+{
+ int fd[2];
+ pid_t pid;
+
+ if (pipe(fd) < 0) {
+ i_error("pipe() failed: %m");
+ return o_stream_create_error(errno);
+ }
+
+ if ((pid = fork()) == (pid_t)-1) {
+ i_error("fork() failed: %m");
+ i_close_fd(&fd[0]); i_close_fd(&fd[1]);
+ return o_stream_create_error(errno);
+ }
+ if (pid == 0) {
+ /* child */
+ i_close_fd(&fd[1]);
+ smtp_client_run_sendmail(client, fd[0]);
+ }
+ i_close_fd(&fd[0]);
+
+ client->output = o_stream_create_fd(fd[1], IO_BLOCK_SIZE, TRUE);
+ o_stream_set_no_error_handling(client->output, TRUE);
+ client->pid = pid;
+ return client->output;
+}
+
+struct ostream *smtp_client_send(struct smtp_client *client)
+{
const char *path;
int fd;
- if (*set->submission_host == '\0') {
- return smtp_client_init_sendmail(set, destination,
- return_path, output_r);
- }
+ i_assert(array_count(&client->destinations) > 0);
+
+ if (!client->use_smtp)
+ return smtp_client_send_sendmail(client);
if ((fd = create_temp_file(&path)) == -1)
- return smtp_client_devnull(output_r);
-
- client = i_new(struct smtp_client, 1);
- client->set = set;
+ return o_stream_create_error(errno);
client->temp_path = i_strdup(path);
- client->destination = i_strdup(destination);
- client->return_path = i_strdup(return_path);
client->temp_fd = fd;
client->output = o_stream_create_fd(fd, IO_BLOCK_SIZE, TRUE);
o_stream_set_no_error_handling(client->output, TRUE);
- client->use_smtp = TRUE;
-
- *output_r = client->output;
- return client;
+ return client->output;
}
static int smtp_client_deinit_sendmail(struct smtp_client *client)
@@ -185,7 +176,7 @@
o_stream_destroy(&client->output);
if (client->pid == (pid_t)-1) {
- /* smtp_client_init() failed already */
+ /* smtp_client_send() failed already */
} else if (waitpid(client->pid, &status, 0) < 0)
i_error("waitpid() failed: %m");
else if (WIFEXITED(status)) {
@@ -204,9 +195,7 @@
i_error("Sendmail process terminated abnormally, "
"return status %d", status);
}
- if (client->buf != NULL)
- buffer_free(&client->buf);
- i_free(client);
+ pool_unref(&client->pool);
return ret;
}
@@ -257,13 +246,13 @@
}
}
-static int smtp_client_send(struct smtp_client *smtp_client)
+static int smtp_client_send_flush(struct smtp_client *smtp_client)
{
struct lmtp_client_settings client_set;
struct lmtp_client *client;
struct ioloop *ioloop;
struct istream *input;
- const char *host, *p;
+ const char *host, *p, *const *destp;
unsigned int port = DEFAULT_SUBMISSION_PORT;
host = smtp_client->set->submission_host;
@@ -303,8 +292,10 @@
return -1;
}
- lmtp_client_add_rcpt(client, smtp_client->destination,
- rcpt_to_callback, data_callback, smtp_client);
+ array_foreach(&smtp_client->destinations, destp) {
+ lmtp_client_add_rcpt(client, *destp, rcpt_to_callback,
+ data_callback, smtp_client);
+ }
input = i_stream_create_fd(smtp_client->temp_fd, (size_t)-1, FALSE);
lmtp_client_send(client, input);
@@ -335,16 +326,12 @@
}
/* the mail has been written to a file. now actually send it. */
- ret = smtp_client_send(client);
+ ret = smtp_client_send_flush(client);
o_stream_destroy(&client->output);
- i_free(client->return_path);
- i_free(client->destination);
- i_free(client->temp_path);
*error_r = t_strdup(client->error);
- i_free(client->error);
- i_free(client);
+ pool_unref(&client->pool);
return ret;
}
@@ -352,7 +339,12 @@
smtp_client_open(const struct lda_settings *set, const char *destination,
const char *return_path, struct ostream **output_r)
{
- return smtp_client_init(set, destination, return_path, output_r);
+ struct smtp_client *client;
+
+ client = smtp_client_init(set, return_path);
+ smtp_client_add_rcpt(client, destination);
+ *output_r = smtp_client_send(client);
+ return client;
}
More information about the dovecot-cvs
mailing list