Blame


1 ba97b2d7 2024-03-20 stsp /*
2 ba97b2d7 2024-03-20 stsp * Copyright (c) 2024 Stefan Sperling <stsp@openbsd.org>
3 ba97b2d7 2024-03-20 stsp *
4 ba97b2d7 2024-03-20 stsp * Permission to use, copy, modify, and distribute this software for any
5 ba97b2d7 2024-03-20 stsp * purpose with or without fee is hereby granted, provided that the above
6 ba97b2d7 2024-03-20 stsp * copyright notice and this permission notice appear in all copies.
7 ba97b2d7 2024-03-20 stsp *
8 ba97b2d7 2024-03-20 stsp * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 ba97b2d7 2024-03-20 stsp * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 ba97b2d7 2024-03-20 stsp * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 ba97b2d7 2024-03-20 stsp * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 ba97b2d7 2024-03-20 stsp * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 ba97b2d7 2024-03-20 stsp * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 ba97b2d7 2024-03-20 stsp * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 ba97b2d7 2024-03-20 stsp */
16 ba97b2d7 2024-03-20 stsp
17 ba97b2d7 2024-03-20 stsp #include <sys/types.h>
18 ba97b2d7 2024-03-20 stsp #include <sys/socket.h>
19 ba97b2d7 2024-03-20 stsp
20 39910b63 2024-03-20 op #include <errno.h>
21 09486e84 2024-03-21 op #include <poll.h>
22 ba97b2d7 2024-03-20 stsp #include <stdio.h>
23 ba97b2d7 2024-03-20 stsp #include <stdlib.h>
24 ba97b2d7 2024-03-20 stsp #include <string.h>
25 ba97b2d7 2024-03-20 stsp #include <stdarg.h>
26 ba97b2d7 2024-03-20 stsp #include <getopt.h>
27 ba97b2d7 2024-03-20 stsp #include <err.h>
28 ba97b2d7 2024-03-20 stsp #include <pwd.h>
29 ba97b2d7 2024-03-20 stsp #include <netdb.h>
30 ba97b2d7 2024-03-20 stsp #include <time.h>
31 ba97b2d7 2024-03-20 stsp #include <unistd.h>
32 ba97b2d7 2024-03-20 stsp
33 ba97b2d7 2024-03-20 stsp #include "got_error.h"
34 ba97b2d7 2024-03-20 stsp
35 ba97b2d7 2024-03-20 stsp #include "got_lib_poll.h"
36 ba97b2d7 2024-03-20 stsp
37 09486e84 2024-03-21 op #define SMTP_LINE_MAX 65535
38 09486e84 2024-03-21 op
39 100d3e4b 2024-03-20 op static int smtp_timeout = 60; /* in seconds */
40 09486e84 2024-03-21 op static char smtp_buf[SMTP_LINE_MAX];
41 09486e84 2024-03-21 op static size_t smtp_buflen;
42 ba97b2d7 2024-03-20 stsp
43 ba97b2d7 2024-03-20 stsp __dead static void
44 ba97b2d7 2024-03-20 stsp usage(void)
45 ba97b2d7 2024-03-20 stsp {
46 dfa6ae4c 2024-03-20 op fprintf(stderr, "usage: %s [-f sender] [-r responder] "
47 ba97b2d7 2024-03-20 stsp "[-s subject] [-h hostname] [-p port] recipient\n", getprogname());
48 ba97b2d7 2024-03-20 stsp exit(1);
49 ba97b2d7 2024-03-20 stsp }
50 ba97b2d7 2024-03-20 stsp
51 39910b63 2024-03-20 op static int
52 39910b63 2024-03-20 op dial(const char *host, const char *port)
53 39910b63 2024-03-20 op {
54 39910b63 2024-03-20 op struct addrinfo hints, *res, *res0;
55 39910b63 2024-03-20 op const char *cause = NULL;
56 39910b63 2024-03-20 op int s, error, save_errno;
57 39910b63 2024-03-20 op
58 39910b63 2024-03-20 op memset(&hints, 0, sizeof(hints));
59 39910b63 2024-03-20 op hints.ai_family = AF_UNSPEC;
60 39910b63 2024-03-20 op hints.ai_socktype = SOCK_STREAM;
61 39910b63 2024-03-20 op error = getaddrinfo(host, port, &hints, &res0);
62 39910b63 2024-03-20 op if (error)
63 39910b63 2024-03-20 op errx(1, "failed to resolve %s:%s: %s", host, port,
64 39910b63 2024-03-20 op gai_strerror(error));
65 39910b63 2024-03-20 op
66 39910b63 2024-03-20 op s = -1;
67 39910b63 2024-03-20 op for (res = res0; res; res = res->ai_next) {
68 39910b63 2024-03-20 op s = socket(res->ai_family, res->ai_socktype,
69 39910b63 2024-03-20 op res->ai_protocol);
70 39910b63 2024-03-20 op if (s == -1) {
71 39910b63 2024-03-20 op cause = "socket";
72 39910b63 2024-03-20 op continue;
73 39910b63 2024-03-20 op }
74 39910b63 2024-03-20 op
75 39910b63 2024-03-20 op if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
76 39910b63 2024-03-20 op cause = "connect";
77 39910b63 2024-03-20 op save_errno = errno;
78 39910b63 2024-03-20 op close(s);
79 39910b63 2024-03-20 op errno = save_errno;
80 39910b63 2024-03-20 op s = -1;
81 39910b63 2024-03-20 op continue;
82 39910b63 2024-03-20 op }
83 39910b63 2024-03-20 op
84 39910b63 2024-03-20 op break;
85 39910b63 2024-03-20 op }
86 39910b63 2024-03-20 op
87 39910b63 2024-03-20 op freeaddrinfo(res0);
88 39910b63 2024-03-20 op if (s == -1)
89 39910b63 2024-03-20 op err(1, "%s", cause);
90 39910b63 2024-03-20 op return s;
91 39910b63 2024-03-20 op }
92 39910b63 2024-03-20 op
93 ba97b2d7 2024-03-20 stsp static char *
94 ba97b2d7 2024-03-20 stsp set_default_fromaddr(void)
95 ba97b2d7 2024-03-20 stsp {
96 ba97b2d7 2024-03-20 stsp struct passwd *pw = NULL;
97 ba97b2d7 2024-03-20 stsp char *s;
98 ba97b2d7 2024-03-20 stsp char hostname[255];
99 ba97b2d7 2024-03-20 stsp
100 ba97b2d7 2024-03-20 stsp pw = getpwuid(getuid());
101 ba97b2d7 2024-03-20 stsp if (pw == NULL) {
102 ba97b2d7 2024-03-20 stsp errx(1, "my UID %d was not found in password database",
103 ba97b2d7 2024-03-20 stsp getuid());
104 ba97b2d7 2024-03-20 stsp }
105 ba97b2d7 2024-03-20 stsp
106 ba97b2d7 2024-03-20 stsp if (gethostname(hostname, sizeof(hostname)) == -1)
107 ba97b2d7 2024-03-20 stsp err(1, "gethostname");
108 ba97b2d7 2024-03-20 stsp
109 ba97b2d7 2024-03-20 stsp if (asprintf(&s, "%s@%s", pw->pw_name, hostname) == -1)
110 ba97b2d7 2024-03-20 stsp err(1, "asprintf");
111 ba97b2d7 2024-03-20 stsp
112 ba97b2d7 2024-03-20 stsp return s;
113 ba97b2d7 2024-03-20 stsp }
114 ba97b2d7 2024-03-20 stsp
115 ba97b2d7 2024-03-20 stsp static int
116 ba97b2d7 2024-03-20 stsp read_smtp_code(int s, const char *code)
117 ba97b2d7 2024-03-20 stsp {
118 ba97b2d7 2024-03-20 stsp const struct got_error *error;
119 09486e84 2024-03-21 op char *endl;
120 09486e84 2024-03-21 op size_t linelen;
121 09486e84 2024-03-21 op ssize_t r;
122 ba97b2d7 2024-03-20 stsp
123 09486e84 2024-03-21 op for (;;) {
124 09486e84 2024-03-21 op endl = memmem(smtp_buf, smtp_buflen, "\r\n", 2);
125 09486e84 2024-03-21 op if (endl != NULL)
126 09486e84 2024-03-21 op break;
127 ba97b2d7 2024-03-20 stsp
128 09486e84 2024-03-21 op if (smtp_buflen == sizeof(smtp_buf))
129 09486e84 2024-03-21 op errx(1, "line too long");
130 ba97b2d7 2024-03-20 stsp
131 09486e84 2024-03-21 op error = got_poll_fd(s, POLLIN, smtp_timeout);
132 ba97b2d7 2024-03-20 stsp if (error)
133 09486e84 2024-03-21 op errx(1, "poll: %s", error->msg);
134 09486e84 2024-03-21 op
135 09486e84 2024-03-21 op r = read(s, smtp_buf + smtp_buflen,
136 09486e84 2024-03-21 op sizeof(smtp_buf) - smtp_buflen);
137 09486e84 2024-03-21 op if (r == -1)
138 09486e84 2024-03-21 op err(1, "read");
139 09486e84 2024-03-21 op if (r == 0)
140 09486e84 2024-03-21 op errx(1, "unexpected EOF");
141 09486e84 2024-03-21 op smtp_buflen += r;
142 ba97b2d7 2024-03-20 stsp }
143 ba97b2d7 2024-03-20 stsp
144 09486e84 2024-03-21 op linelen = endl - smtp_buf;
145 09486e84 2024-03-21 op if (linelen < 3)
146 09486e84 2024-03-21 op errx(1, "invalid SMTP response");
147 09486e84 2024-03-21 op
148 09486e84 2024-03-21 op if (strncmp(code, smtp_buf, 3) != 0) {
149 09486e84 2024-03-21 op smtp_buf[3] = '\0';
150 09486e84 2024-03-21 op warnx("unexpected SMTP message code: %s", smtp_buf);
151 09486e84 2024-03-21 op return -1;
152 09486e84 2024-03-21 op }
153 09486e84 2024-03-21 op
154 09486e84 2024-03-21 op /*
155 09486e84 2024-03-21 op * Normally we would get just one reply, but the regress doesn't
156 09486e84 2024-03-21 op * use a real SMTP server and queues all the replies upfront.
157 09486e84 2024-03-21 op */
158 09486e84 2024-03-21 op linelen += 2;
159 09486e84 2024-03-21 op memmove(smtp_buf, smtp_buf + linelen, smtp_buflen - linelen);
160 09486e84 2024-03-21 op smtp_buflen -= linelen;
161 09486e84 2024-03-21 op
162 09486e84 2024-03-21 op return 0;
163 ba97b2d7 2024-03-20 stsp }
164 ba97b2d7 2024-03-20 stsp
165 ba97b2d7 2024-03-20 stsp static int
166 ba97b2d7 2024-03-20 stsp send_smtp_msg(int s, const char *fmt, ...)
167 ba97b2d7 2024-03-20 stsp {
168 ba97b2d7 2024-03-20 stsp const struct got_error *error;
169 ba97b2d7 2024-03-20 stsp char buf[512];
170 ba97b2d7 2024-03-20 stsp int len;
171 ba97b2d7 2024-03-20 stsp va_list ap;
172 ba97b2d7 2024-03-20 stsp
173 ba97b2d7 2024-03-20 stsp va_start(ap, fmt);
174 ba97b2d7 2024-03-20 stsp len = vsnprintf(buf, sizeof(buf), fmt, ap);
175 ba97b2d7 2024-03-20 stsp va_end(ap);
176 ba97b2d7 2024-03-20 stsp if (len < 0) {
177 ba97b2d7 2024-03-20 stsp warn("vsnprintf");
178 ba97b2d7 2024-03-20 stsp return -1;
179 ba97b2d7 2024-03-20 stsp }
180 ba97b2d7 2024-03-20 stsp if (len >= sizeof(buf)) {
181 ba97b2d7 2024-03-20 stsp warnx("%s: buffer too small for message '%s...'",
182 ba97b2d7 2024-03-20 stsp __func__, buf);
183 ba97b2d7 2024-03-20 stsp return -1;
184 ba97b2d7 2024-03-20 stsp }
185 ba97b2d7 2024-03-20 stsp
186 ba97b2d7 2024-03-20 stsp error = got_poll_write_full(s, buf, len);
187 ba97b2d7 2024-03-20 stsp if (error) {
188 ba97b2d7 2024-03-20 stsp warnx("write: %s", error->msg);
189 ba97b2d7 2024-03-20 stsp return -1;
190 ba97b2d7 2024-03-20 stsp }
191 ba97b2d7 2024-03-20 stsp
192 ba97b2d7 2024-03-20 stsp return 0;
193 ba97b2d7 2024-03-20 stsp }
194 ba97b2d7 2024-03-20 stsp
195 ba97b2d7 2024-03-20 stsp static char *
196 ba97b2d7 2024-03-20 stsp get_datestr(time_t *time, char *datebuf)
197 ba97b2d7 2024-03-20 stsp {
198 ba97b2d7 2024-03-20 stsp struct tm mytm, *tm;
199 ba97b2d7 2024-03-20 stsp char *p, *s;
200 ba97b2d7 2024-03-20 stsp
201 ba97b2d7 2024-03-20 stsp tm = gmtime_r(time, &mytm);
202 ba97b2d7 2024-03-20 stsp if (tm == NULL)
203 ba97b2d7 2024-03-20 stsp return NULL;
204 ba97b2d7 2024-03-20 stsp s = asctime_r(tm, datebuf);
205 ba97b2d7 2024-03-20 stsp if (s == NULL)
206 ba97b2d7 2024-03-20 stsp return NULL;
207 ba97b2d7 2024-03-20 stsp p = strchr(s, '\n');
208 ba97b2d7 2024-03-20 stsp if (p)
209 ba97b2d7 2024-03-20 stsp *p = '\0';
210 ba97b2d7 2024-03-20 stsp return s;
211 ba97b2d7 2024-03-20 stsp }
212 ba97b2d7 2024-03-20 stsp
213 ba97b2d7 2024-03-20 stsp static void
214 39910b63 2024-03-20 op send_email(int s, const char *myfromaddr, const char *fromaddr,
215 ba97b2d7 2024-03-20 stsp const char *recipient, const char *replytoaddr,
216 39910b63 2024-03-20 op const char *subject)
217 ba97b2d7 2024-03-20 stsp {
218 ba97b2d7 2024-03-20 stsp const struct got_error *error;
219 ba97b2d7 2024-03-20 stsp char *line = NULL;
220 ba97b2d7 2024-03-20 stsp size_t linesize = 0;
221 ba97b2d7 2024-03-20 stsp ssize_t linelen;
222 ba97b2d7 2024-03-20 stsp time_t now;
223 ba97b2d7 2024-03-20 stsp char datebuf[26];
224 ba97b2d7 2024-03-20 stsp char *datestr;
225 ba97b2d7 2024-03-20 stsp
226 ba97b2d7 2024-03-20 stsp now = time(NULL);
227 ba97b2d7 2024-03-20 stsp datestr = get_datestr(&now, datebuf);
228 ba97b2d7 2024-03-20 stsp
229 ba97b2d7 2024-03-20 stsp if (read_smtp_code(s, "220"))
230 ba97b2d7 2024-03-20 stsp errx(1, "unexpected SMTP greeting received");
231 ba97b2d7 2024-03-20 stsp
232 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "HELO localhost\r\n"))
233 ba97b2d7 2024-03-20 stsp errx(1, "could not send HELO");
234 ba97b2d7 2024-03-20 stsp if (read_smtp_code(s, "250"))
235 ba97b2d7 2024-03-20 stsp errx(1, "unexpected SMTP response received");
236 ba97b2d7 2024-03-20 stsp
237 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "MAIL FROM:<%s>\r\n", myfromaddr))
238 ba97b2d7 2024-03-20 stsp errx(1, "could not send MAIL FROM");
239 ba97b2d7 2024-03-20 stsp if (read_smtp_code(s, "250"))
240 ba97b2d7 2024-03-20 stsp errx(1, "unexpected SMTP response received");
241 ba97b2d7 2024-03-20 stsp
242 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "RCPT TO:<%s>\r\n", recipient))
243 ba97b2d7 2024-03-20 stsp errx(1, "could not send MAIL FROM");
244 ba97b2d7 2024-03-20 stsp if (read_smtp_code(s, "250"))
245 ba97b2d7 2024-03-20 stsp errx(1, "unexpected SMTP response received");
246 ba97b2d7 2024-03-20 stsp
247 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "DATA\r\n"))
248 ba97b2d7 2024-03-20 stsp errx(1, "could not send MAIL FROM");
249 ba97b2d7 2024-03-20 stsp if (read_smtp_code(s, "354"))
250 ba97b2d7 2024-03-20 stsp errx(1, "unexpected SMTP response received");
251 ba97b2d7 2024-03-20 stsp
252 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "From: %s\r\n", fromaddr))
253 ba97b2d7 2024-03-20 stsp errx(1, "could not send From header");
254 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "To: %s\r\n", recipient))
255 ba97b2d7 2024-03-20 stsp errx(1, "could not send To header");
256 ba97b2d7 2024-03-20 stsp if (replytoaddr) {
257 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "Reply-To: %s\r\n", replytoaddr))
258 ba97b2d7 2024-03-20 stsp errx(1, "could not send Reply-To header");
259 ba97b2d7 2024-03-20 stsp }
260 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "Date: %s +0000 (UTC)\r\n", datestr))
261 ba97b2d7 2024-03-20 stsp errx(1, "could not send Date header");
262 ba97b2d7 2024-03-20 stsp
263 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "Subject: %s\r\n", subject))
264 ba97b2d7 2024-03-20 stsp errx(1, "could not send Subject header");
265 ba97b2d7 2024-03-20 stsp
266 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "\r\n"))
267 ba97b2d7 2024-03-20 stsp errx(1, "could not send body delimiter");
268 ba97b2d7 2024-03-20 stsp
269 ba97b2d7 2024-03-20 stsp while ((linelen = getline(&line, &linesize, stdin)) != -1) {
270 ba97b2d7 2024-03-20 stsp if (line[0] == '.') { /* dot stuffing */
271 ba97b2d7 2024-03-20 stsp error = got_poll_write_full(s, ".", 1);
272 ba97b2d7 2024-03-20 stsp if (error)
273 ba97b2d7 2024-03-20 stsp errx(1, "write: %s", error->msg);
274 ba97b2d7 2024-03-20 stsp }
275 ba97b2d7 2024-03-20 stsp error = got_poll_write_full(s, line, linelen);
276 ba97b2d7 2024-03-20 stsp if (error)
277 ba97b2d7 2024-03-20 stsp errx(1, "write: %s", error->msg);
278 ba97b2d7 2024-03-20 stsp }
279 ba97b2d7 2024-03-20 stsp
280 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "\r\n.\r\n"))
281 ba97b2d7 2024-03-20 stsp errx(1, "could not send data terminator");
282 ba97b2d7 2024-03-20 stsp if (read_smtp_code(s, "250"))
283 ba97b2d7 2024-03-20 stsp errx(1, "unexpected SMTP response received");
284 ba97b2d7 2024-03-20 stsp
285 ba97b2d7 2024-03-20 stsp if (send_smtp_msg(s, "QUIT\r\n"))
286 ba97b2d7 2024-03-20 stsp errx(1, "could not send QUIT");
287 ba97b2d7 2024-03-20 stsp
288 ba97b2d7 2024-03-20 stsp if (read_smtp_code(s, "221"))
289 ba97b2d7 2024-03-20 stsp errx(1, "unexpected SMTP response received");
290 ba97b2d7 2024-03-20 stsp
291 ba97b2d7 2024-03-20 stsp close(s);
292 ba97b2d7 2024-03-20 stsp free(line);
293 ba97b2d7 2024-03-20 stsp }
294 ba97b2d7 2024-03-20 stsp
295 ba97b2d7 2024-03-20 stsp int
296 ba97b2d7 2024-03-20 stsp main(int argc, char *argv[])
297 ba97b2d7 2024-03-20 stsp {
298 ba97b2d7 2024-03-20 stsp char *default_fromaddr = NULL;
299 ba97b2d7 2024-03-20 stsp const char *fromaddr = NULL, *recipient = NULL, *replytoaddr = NULL;
300 ba97b2d7 2024-03-20 stsp const char *subject = "gotd notification";
301 ba97b2d7 2024-03-20 stsp const char *hostname = "127.0.0.1";
302 ba97b2d7 2024-03-20 stsp const char *port = "25";
303 ba97b2d7 2024-03-20 stsp const char *errstr;
304 ba97b2d7 2024-03-20 stsp char *timeoutstr;
305 39910b63 2024-03-20 op int ch, s;
306 ba97b2d7 2024-03-20 stsp
307 ba97b2d7 2024-03-20 stsp while ((ch = getopt(argc, argv, "f:r:s:h:p:")) != -1) {
308 ba97b2d7 2024-03-20 stsp switch (ch) {
309 ba97b2d7 2024-03-20 stsp case 'h':
310 ba97b2d7 2024-03-20 stsp hostname = optarg;
311 ba97b2d7 2024-03-20 stsp break;
312 ba97b2d7 2024-03-20 stsp case 'f':
313 ba97b2d7 2024-03-20 stsp fromaddr = optarg;
314 ba97b2d7 2024-03-20 stsp break;
315 ba97b2d7 2024-03-20 stsp case 'p':
316 ba97b2d7 2024-03-20 stsp port = optarg;
317 ba97b2d7 2024-03-20 stsp break;
318 ba97b2d7 2024-03-20 stsp case 'r':
319 ba97b2d7 2024-03-20 stsp replytoaddr = optarg;
320 ba97b2d7 2024-03-20 stsp break;
321 ba97b2d7 2024-03-20 stsp case 's':
322 ba97b2d7 2024-03-20 stsp subject = optarg;
323 ba97b2d7 2024-03-20 stsp break;
324 ba97b2d7 2024-03-20 stsp default:
325 ba97b2d7 2024-03-20 stsp usage();
326 ba97b2d7 2024-03-20 stsp /* NOTREACHED */
327 ba97b2d7 2024-03-20 stsp break;
328 ba97b2d7 2024-03-20 stsp }
329 ba97b2d7 2024-03-20 stsp }
330 ba97b2d7 2024-03-20 stsp
331 ba97b2d7 2024-03-20 stsp argc -= optind;
332 ba97b2d7 2024-03-20 stsp argv += optind;
333 ba97b2d7 2024-03-20 stsp
334 ba97b2d7 2024-03-20 stsp if (argc != 1)
335 ba97b2d7 2024-03-20 stsp usage();
336 ba97b2d7 2024-03-20 stsp
337 ba97b2d7 2024-03-20 stsp /* used by the regression test suite */
338 ba97b2d7 2024-03-20 stsp timeoutstr = getenv("GOT_NOTIFY_EMAIL_TIMEOUT");
339 ba97b2d7 2024-03-20 stsp if (timeoutstr) {
340 ba97b2d7 2024-03-20 stsp smtp_timeout = strtonum(timeoutstr, 0, 600, &errstr);
341 ba97b2d7 2024-03-20 stsp if (errstr != NULL)
342 ba97b2d7 2024-03-20 stsp errx(1, "timeout in seconds is %s: %s",
343 ba97b2d7 2024-03-20 stsp errstr, timeoutstr);
344 ba97b2d7 2024-03-20 stsp }
345 ba97b2d7 2024-03-20 stsp
346 ba97b2d7 2024-03-20 stsp #ifndef PROFILE
347 ba97b2d7 2024-03-20 stsp if (pledge("stdio dns inet getpw", NULL) == -1)
348 ba97b2d7 2024-03-20 stsp err(1, "pledge");
349 ba97b2d7 2024-03-20 stsp #endif
350 ba97b2d7 2024-03-20 stsp default_fromaddr = set_default_fromaddr();
351 ba97b2d7 2024-03-20 stsp
352 ba97b2d7 2024-03-20 stsp #ifndef PROFILE
353 ba97b2d7 2024-03-20 stsp if (pledge("stdio dns inet", NULL) == -1)
354 ba97b2d7 2024-03-20 stsp err(1, "pledge");
355 ba97b2d7 2024-03-20 stsp #endif
356 ba97b2d7 2024-03-20 stsp
357 ba97b2d7 2024-03-20 stsp recipient = argv[0];
358 ba97b2d7 2024-03-20 stsp if (fromaddr == NULL)
359 ba97b2d7 2024-03-20 stsp fromaddr = default_fromaddr;
360 ba97b2d7 2024-03-20 stsp
361 39910b63 2024-03-20 op s = dial(hostname, port);
362 ba97b2d7 2024-03-20 stsp
363 39910b63 2024-03-20 op #ifndef PROFILE
364 39910b63 2024-03-20 op if (pledge("stdio", NULL) == -1)
365 39910b63 2024-03-20 op err(1, "pledge");
366 39910b63 2024-03-20 op #endif
367 39910b63 2024-03-20 op
368 39910b63 2024-03-20 op send_email(s, default_fromaddr, fromaddr, recipient, replytoaddr,
369 39910b63 2024-03-20 op subject);
370 39910b63 2024-03-20 op
371 ba97b2d7 2024-03-20 stsp free(default_fromaddr);
372 ba97b2d7 2024-03-20 stsp return 0;
373 ba97b2d7 2024-03-20 stsp }