Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/deliver/smtp-client.c @ 7086:7ed926ed7aa4 HEAD
Updated copyright notices to include year 2008.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 01 Jan 2008 22:05:21 +0200 |
parents | 65c69a53a7be |
children | db0d0d7385fd |
rev | line source |
---|---|
7086
7ed926ed7aa4
Updated copyright notices to include year 2008.
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
1 /* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */ |
4347
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "deliver.h" |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "smtp-client.h" |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #include <unistd.h> |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include <sys/wait.h> |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 struct smtp_client { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 FILE *f; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 pid_t pid; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 }; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 static struct smtp_client *smtp_client_devnull(FILE **file_r) |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 struct smtp_client *client; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 client = i_new(struct smtp_client, 1); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 client->f = *file_r = fopen("/dev/null", "w"); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 if (client->f == NULL) |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 i_fatal("fopen() failed: %m"); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 client->pid = (pid_t)-1; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 return client; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 } |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5987
diff
changeset
|
27 static void ATTR_NORETURN |
4823
414c0c45040e
Added some noreturn attributes and fixed warnings caused by them.
Timo Sirainen <tss@iki.fi>
parents:
4347
diff
changeset
|
28 smtp_client_run_sendmail(const char *destination, |
414c0c45040e
Added some noreturn attributes and fixed warnings caused by them.
Timo Sirainen <tss@iki.fi>
parents:
4347
diff
changeset
|
29 const char *return_path, int fd) |
4347
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 { |
5602
117ec208d66b
If sendmail_path was set in config file, it was cleared just before trying
Timo Sirainen <tss@iki.fi>
parents:
5220
diff
changeset
|
31 const char *argv[7], *sendmail_path; |
4347
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 |
5602
117ec208d66b
If sendmail_path was set in config file, it was cleared just before trying
Timo Sirainen <tss@iki.fi>
parents:
5220
diff
changeset
|
33 /* deliver_set's contents may point to environment variables. |
117ec208d66b
If sendmail_path was set in config file, it was cleared just before trying
Timo Sirainen <tss@iki.fi>
parents:
5220
diff
changeset
|
34 deliver_env_clean() cleans them up, so they have to be copied. */ |
117ec208d66b
If sendmail_path was set in config file, it was cleared just before trying
Timo Sirainen <tss@iki.fi>
parents:
5220
diff
changeset
|
35 sendmail_path = t_strdup(deliver_set->sendmail_path); |
117ec208d66b
If sendmail_path was set in config file, it was cleared just before trying
Timo Sirainen <tss@iki.fi>
parents:
5220
diff
changeset
|
36 |
117ec208d66b
If sendmail_path was set in config file, it was cleared just before trying
Timo Sirainen <tss@iki.fi>
parents:
5220
diff
changeset
|
37 argv[0] = sendmail_path; |
4347
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 argv[1] = "-i"; /* ignore dots */ |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 argv[2] = "-f"; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 argv[3] = return_path != NULL && *return_path != '\0' ? |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 return_path : "<>"; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 argv[4] = "--"; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 argv[5] = destination; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 argv[6] = NULL; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 if (dup2(fd, STDIN_FILENO) < 0) |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 i_fatal("dup2() failed: %m"); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 |
5220
7fbdcce95982
Keep only TZ and HOME environments when calling sendmail.
Timo Sirainen <tss@iki.fi>
parents:
4823
diff
changeset
|
49 deliver_env_clean(); |
7fbdcce95982
Keep only TZ and HOME environments when calling sendmail.
Timo Sirainen <tss@iki.fi>
parents:
4823
diff
changeset
|
50 |
5987 | 51 (void)execv(sendmail_path, (void *)argv); |
5602
117ec208d66b
If sendmail_path was set in config file, it was cleared just before trying
Timo Sirainen <tss@iki.fi>
parents:
5220
diff
changeset
|
52 i_fatal("execv(%s) failed: %m", sendmail_path); |
4347
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 } |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 struct smtp_client *smtp_client_open(const char *destination, |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 const char *return_path, FILE **file_r) |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 struct smtp_client *client; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 int fd[2]; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 pid_t pid; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 if (pipe(fd) < 0) { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 i_error("pipe() failed: %m"); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 return smtp_client_devnull(file_r); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 } |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 if ((pid = fork()) == (pid_t)-1) { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 i_error("fork() failed: %m"); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 (void)close(fd[0]); (void)close(fd[1]); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 return smtp_client_devnull(file_r); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 } |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 if (pid == 0) { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 /* child */ |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 (void)close(fd[1]); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 smtp_client_run_sendmail(destination, return_path, fd[0]); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 } |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 (void)close(fd[0]); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 client = i_new(struct smtp_client, 1); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 client->f = *file_r = fdopen(fd[1], "w"); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 if (client->f == NULL) |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 i_fatal("fdopen() failed: %m"); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 return client; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 } |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 int smtp_client_close(struct smtp_client *client) |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 int ret = EX_TEMPFAIL, status; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 fclose(client->f); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 if (client->pid == (pid_t)-1) { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 /* smtp_client_open() failed already */ |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 } else if (waitpid(client->pid, &status, 0) < 0) |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 i_error("waitpid() failed: %m"); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 else if (WIFEXITED(status)) { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 ret = WEXITSTATUS(status); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 if (ret != 0) { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 i_error("Sendmail process terminated abnormally, " |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 "exit status %d", ret); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 } |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 } else if (WIFSIGNALED(status)) { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 i_error("Sendmail process terminated abnormally, " |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 "signal %d", WTERMSIG(status)); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 } else if (WIFSTOPPED(status)) { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 i_error("Sendmail process stopped, signal %d", |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 WSTOPSIG(status)); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 } else { |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 i_error("Sendmail process terminated abnormally, " |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 "return status %d", status); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 } |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 i_free(client); |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 return ret; |
a73d2867f6e1
Moved all the non-Sieve code from dovecot-lda in here and rewrote parts of
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 } |