X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/0590cedca75c01811972b2f694f60f24028ee973..985bb670b4e07d35cb1580780253ded2524a342e:/lib/sendmail.c
diff --git a/lib/sendmail.c b/lib/sendmail.c
index f7b0155..5b9a82c 100644
--- a/lib/sendmail.c
+++ b/lib/sendmail.c
@@ -1,27 +1,29 @@
/*
* This file is part of DisOrder
- * Copyright (C) 2007 Richard Kettlewell
+ * Copyright (C) 2007-2008 Richard Kettlewell
*
- * This program is free software; you can redistribute it and/or modify
+ * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * along with this program. If not, see .
*/
+/** @file lib/sendmail.c
+ * @brief Sending email
+ *
+ * Can send email either via a local MTA or by connecting to an SMTP TCP port.
+ * The former is preferred as there is a strong implication that the local MTA
+ * will queue for you than some random TCP SMTP server you found.
+ */
+#include "common.h"
-#include
-#include "types.h"
-
-#include
#include
#include
#include
@@ -39,6 +41,7 @@
#include "hostname.h"
#include "sendmail.h"
#include "base64.h"
+#include "wstat.h"
/** @brief Get a server response
* @param tag Server name
@@ -208,33 +211,55 @@ int sendmail(const char *sender,
char *tag;
int fdin, fdout, rc;
FILE *in, *out;
+ pid_t pid = -1;
static const struct addrinfo pref = {
- 0,
- PF_INET,
- SOCK_STREAM,
- IPPROTO_TCP,
- 0,
- 0,
- 0,
- 0
+ .ai_flags = 0,
+ .ai_family = PF_INET,
+ .ai_socktype = SOCK_STREAM,
+ .ai_protocol = IPPROTO_TCP,
};
/* Find the SMTP server */
- a.n = 2;
- a.s = s;
- s[0] = config->smtp_server;
- s[1] = (char *)"smtp";
- if(!(ai = get_address(&a, &pref, &tag)))
- return -1;
- fdin = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if(connect(fdin, ai->ai_addr, ai->ai_addrlen) < 0) {
- error(errno, "error connecting to %s", tag);
- xclose(fdin);
- return -1;
+ if(config->sendmail && config->sendmail[0]) {
+ int inpipe[2], outpipe[2];
+
+ /* If it's a path name, use -bs mode. Exim, Postfix and Sendmail all claim
+ * to support this. */
+ xpipe(inpipe); /* sendmail's stdin */
+ xpipe(outpipe); /* sendmail's stdout */
+ if(!(pid = xfork())) {
+ exitfn = _exit;
+ signal(SIGPIPE, SIG_DFL);
+ xdup2(inpipe[0], 0);
+ xclose(inpipe[1]);
+ xclose(outpipe[0]);
+ xdup2(outpipe[1], 1);
+ execlp(config->sendmail,
+ config->sendmail, "-bs", (char *)0);
+ fatal(errno, "executing %s", config->sendmail);
+ }
+ xclose(inpipe[0]);
+ xclose(outpipe[1]);
+ fdin = outpipe[0]; /* read from sendmail's stdout */
+ fdout = inpipe[1]; /* write to sendmail's stdin */
+ tag = config->sendmail;
+ } else {
+ a.n = 2;
+ a.s = s;
+ s[0] = config->smtp_server;
+ s[1] = (char *)"smtp";
+ if(!(ai = get_address(&a, &pref, &tag)))
+ return -1;
+ fdin = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if(connect(fdin, ai->ai_addr, ai->ai_addrlen) < 0) {
+ error(errno, "error connecting to %s", tag);
+ xclose(fdin);
+ return -1;
+ }
+ if((fdout = dup(fdin)) < 0)
+ fatal(errno, "error calling dup2");
}
- if((fdout = dup(fdin)) < 0)
- fatal(errno, "error calling dup2");
if(!(in = fdopen(fdin, "rb")))
fatal(errno, "error calling fdopen");
if(!(out = fdopen(fdout, "wb")))
@@ -243,6 +268,19 @@ int sendmail(const char *sender,
encoding, content_type, body);
fclose(in);
fclose(out);
+ if(pid != -1) {
+ int w;
+
+ while(waitpid(pid, &w, 0) < 0 && errno == EINTR)
+ ;
+ if(w < 0)
+ fatal(errno, "error calling waitpid");
+ if(w)
+ info("warning: %s -bs: %s", config->sendmail, wstat(w));
+ /* Not fatal - we determine success/failure from the SMTP conversation.
+ * Some MTAs exit nonzero if you don't QUIT, which is just stupidly
+ * picky. */
+ }
return rc;
}