Download raw body.
got-notify-email: spilt dial() out of send_email()
By splitting out a dial() function from send_mail(), we can further
reduce the pledge() in main down to "stdio". Other than being nice on
its own, this also helps -portable, for e.g. on freebsd we could use
capsicum(4).
While here, do the usual loop around getaddrinfo() in case we fail to
connect to the first result.
ok?
diff /home/op/w/got
commit - dfa6ae4cb7d2e0474c8458b5622eca0385470c01
path + /home/op/w/got
blob - d2e507fdfece9c9538bfe12b6cd820f899d7a552
file + gotd/libexec/got-notify-email/got-notify-email.c
--- gotd/libexec/got-notify-email/got-notify-email.c
+++ gotd/libexec/got-notify-email/got-notify-email.c
@@ -17,6 +17,7 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -42,6 +43,48 @@ usage(void)
exit(1);
}
+static int
+dial(const char *host, const char *port)
+{
+ struct addrinfo hints, *res, *res0;
+ const char *cause = NULL;
+ int s, error, save_errno;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(host, port, &hints, &res0);
+ if (error)
+ errx(1, "failed to resolve %s:%s: %s", host, port,
+ gai_strerror(error));
+
+ s = -1;
+ for (res = res0; res; res = res->ai_next) {
+ s = socket(res->ai_family, res->ai_socktype,
+ res->ai_protocol);
+ if (s == -1) {
+ cause = "socket";
+ continue;
+ }
+
+ if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
+ cause = "connect";
+ save_errno = errno;
+ close(s);
+ errno = save_errno;
+ s = -1;
+ continue;
+ }
+
+ break;
+ }
+
+ freeaddrinfo(res0);
+ if (s == -1)
+ err(1, "%s", cause);
+ return s;
+}
+
static char *
set_default_fromaddr(void)
{
@@ -156,16 +199,14 @@ get_datestr(time_t *time, char *datebuf)
}
static void
-send_email(const char *myfromaddr, const char *fromaddr,
+send_email(int s, const char *myfromaddr, const char *fromaddr,
const char *recipient, const char *replytoaddr,
- const char *subject, const char *hostname, const char *port)
+ const char *subject)
{
const struct got_error *error;
char *line = NULL;
size_t linesize = 0;
ssize_t linelen;
- struct addrinfo hints, *res = NULL;
- int s = -1, ret;
time_t now;
char datebuf[26];
char *datestr;
@@ -173,21 +214,6 @@ send_email(const char *myfromaddr, const char *fromadd
now = time(NULL);
datestr = get_datestr(&now, datebuf);
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
-
- ret = getaddrinfo(hostname, port, &hints, &res);
- if (ret)
- errx(1, "getaddrinfo: %s", gai_strerror(ret));
-
- s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (s == -1)
- err(1, "socket");
-
- if (connect(s, res->ai_addr, res->ai_addrlen) == -1)
- err(1, "connect %s:%s", hostname, port);
-
if (read_smtp_code(s, "220"))
errx(1, "unexpected SMTP greeting received");
if (skip_to_crlf(s))
@@ -266,8 +292,6 @@ send_email(const char *myfromaddr, const char *fromadd
close(s);
free(line);
- if (res)
- freeaddrinfo(res);
}
int
@@ -280,7 +304,7 @@ main(int argc, char *argv[])
const char *port = "25";
const char *errstr;
char *timeoutstr;
- int ch;
+ int ch, s;
while ((ch = getopt(argc, argv, "f:r:s:h:p:")) != -1) {
switch (ch) {
@@ -336,9 +360,16 @@ main(int argc, char *argv[])
if (fromaddr == NULL)
fromaddr = default_fromaddr;
- send_email(default_fromaddr, fromaddr, recipient, replytoaddr,
- subject, hostname, port);
+ s = dial(hostname, port);
+#ifndef PROFILE
+ if (pledge("stdio", NULL) == -1)
+ err(1, "pledge");
+#endif
+
+ send_email(s, default_fromaddr, fromaddr, recipient, replytoaddr,
+ subject);
+
free(default_fromaddr);
return 0;
}
got-notify-email: spilt dial() out of send_email()