Download raw body.
got-notify-email: spilt dial() out of send_email()
On Wed, Mar 20, 2024 at 11:43:37AM +0100, Omar Polo wrote: > 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? Very nice, 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()