aboutsummaryrefslogtreecommitdiffstats
path: root/CVSROOT/mailsend.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-04-13 20:12:50 +0800
committerpeter <peter@FreeBSD.org>1999-04-13 20:12:50 +0800
commit8006551f3a5664a3ca74dbc5d4973d870f346d4c (patch)
tree7ca7875d4e82707f356c138a56d0ff342961a2b1 /CVSROOT/mailsend.c
parent8a95406899053ec10e93215c0106684535e04128 (diff)
downloadfreebsd-ports-gnome-8006551f3a5664a3ca74dbc5d4973d870f346d4c.tar.gz
freebsd-ports-gnome-8006551f3a5664a3ca74dbc5d4973d870f346d4c.tar.zst
freebsd-ports-gnome-8006551f3a5664a3ca74dbc5d4973d870f346d4c.zip
I was meaning to check this in.. We use this on freefall and it's
referenced in log_accum.pl
Diffstat (limited to 'CVSROOT/mailsend.c')
-rw-r--r--CVSROOT/mailsend.c379
1 files changed, 379 insertions, 0 deletions
diff --git a/CVSROOT/mailsend.c b/CVSROOT/mailsend.c
new file mode 100644
index 000000000000..1de50aa41870
--- /dev/null
+++ b/CVSROOT/mailsend.c
@@ -0,0 +1,379 @@
+/*-
+ * Copyright (c) 1999, Peter Wemm <peter@netplex.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * Actually, this is a hack that I've used for a zillion years
+ * elsewhere originating on a SVR4 machine. But hey, it works.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <paths.h>
+#include <time.h>
+
+
+char *wday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+char *Prog;
+
+static int
+writestr(int fd, char *buf)
+{
+ return write(fd, buf, strlen(buf));
+}
+
+static void
+usage(void)
+{
+ writestr(2, "Usage: ");
+ writestr(2, Prog);
+ writestr(2, " [ -s subject ] [ -r reply-to ] [ -f from ] [ -f From: ]..\n");
+ writestr(2, " [ -b bcc ] [ -c cc ] [-H] [-I/-B/-Q] [-v] address [address]...\n");
+ exit(1);
+}
+
+static char *
+makerfc822date(time_t now)
+{
+ struct tm *tm;
+ static char buf[1024];
+ time_t tzo;
+
+#ifdef BSD
+ tm = localtime(&now);
+
+ tzo = tm->tm_gmtoff;
+
+ tzo = tzo / 60; /* minutes */
+ tzo = (tzo % 60) + (tzo / 60 * 100);
+
+ snprintf(buf, sizeof(buf), "%s, %d %s %d %02d:%02d:%02d %+05ld (%s)",
+ wday[tm->tm_wday],
+ tm->tm_mday,
+ mon[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ tzo,
+ tm->tm_zone
+ );
+#else
+ tzset();
+ tm = localtime(&now);
+
+ tzo = - (tm->tm_isdst <= 0 ? timezone : altzone);
+
+ tzo = tzo / 60; /* minutes */
+ tzo = (tzo % 60) + (tzo / 60 * 100);
+
+ snprintf(buf, sizeof(buf), "%s, %d %s %d %02d:%02d:%02d +%04d (%s)",
+ wday[tm->tm_wday],
+ tm->tm_mday,
+ mon[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ tzo,
+ tm->tm_isdst <= 0 ? tzname[0] : tzname[1]
+ );
+#endif
+ return buf;
+}
+
+
+
+int
+main(int ac, char **av)
+{
+ int c, i;
+ pid_t pid;
+ int pfd[2];
+ char *smvec[1024];
+ char **vec = smvec;
+ char buf[1024];
+ char Frombuf[256]; /* Long enough */
+ char frombuf[256]; /* Long enough */
+ char *s;
+
+ char *subj = NULL;
+ char *reply = NULL;
+ char *from = NULL;
+ char *From = NULL;
+ char *cc = NULL;
+ char *bcc = NULL;
+ char *delmode = NULL;
+ char *verbose = NULL;
+ char *hostname = NULL;
+ int headers = 0;
+
+ struct passwd *pw;
+
+ Prog = av[0];
+
+ while ((c = getopt(ac, av, "s:f:F:h:r:c:b:IBQHv")) != EOF) {
+ switch (c) {
+
+ case 's': /* -s Subject: */
+ if (subj)
+ usage();
+ subj = optarg;
+ break;
+
+ case 'f': /* -f From_ */
+ if (from)
+ usage();
+ from = optarg;
+ break;
+
+ case 'F': /* -F From: */
+ if (From)
+ usage();
+ From = optarg;
+ break;
+
+ case 'h': /* -h hostname */
+ if (hostname)
+ usage();
+ hostname = optarg;
+ break;
+
+ case 'H': /* -H = headers coming in via stdin too */
+ headers++;
+ break;
+
+ case 'r': /* -r Reply-To: */
+ if (reply)
+ usage();
+ reply = optarg;
+ break;
+
+ case 'b': /* -b Bcc: */
+ if (bcc)
+ usage();
+ bcc = optarg;
+ break;
+
+ case 'c': /* -b cc: */
+ if (cc)
+ usage();
+ cc = optarg;
+ break;
+
+ case 'I': /* -I interactive delivery */
+ delmode = "-odi";
+ break;
+
+ case 'B': /* -B background delivery */
+ delmode = "-odb";
+ break;
+
+ case 'Q': /* -Q queue up only */
+ delmode = "-odq";
+ break;
+
+ case 'v':
+ verbose = "-v";
+ break;
+
+ default:
+ case '?': /* err */
+ writestr(2, "Unknown switch: '");
+ buf[0] = optopt;
+ buf[1] = '\0';
+ writestr(2, buf);
+ writestr(2, "'\n");
+ usage();
+ break;
+ }
+ }
+ ac -= optind;
+ av += optind;
+ if (ac < 1) {
+ writestr(2, "you must supply an address!\n");
+ usage();
+ }
+
+ if (hostname == NULL) {
+ gethostname(buf, sizeof(buf));
+ buf[sizeof(buf)-1] = '\0'; /* academic.. */
+ hostname = buf;
+ }
+ Frombuf[0] = '\0';
+
+ if (From) {
+ snprintf(Frombuf, sizeof(Frombuf), "%s@%s", From, hostname); /* From@hostname */
+ pw = getpwnam(From);
+ } else {
+ pw = getpwuid(getuid());
+ }
+ if (pw && hostname == buf) {
+ if (pw->pw_gecos) {
+ if ((s = strchr(pw->pw_gecos, ',')))
+ *s = '\0';
+ if ((s = strchr(pw->pw_gecos, ';')))
+ *s = '\0';
+ snprintf(Frombuf, sizeof(Frombuf), "%s <%s@%s>", pw->pw_gecos, pw->pw_name, hostname);
+ } else {
+ snprintf(Frombuf, sizeof(Frombuf), "%s@%s", pw->pw_name, hostname); /* From@hostname */
+ }
+ }
+ endpwent();
+ if (verbose) {
+ writestr(2, "From: ");
+ writestr(2, Frombuf);
+ writestr(2, "\n");
+ }
+
+ *vec++ = "sendmail";
+ *vec++ = "-oi";
+ *vec++ = "-oem";
+
+ if (delmode) {
+ *vec++ = delmode;
+ }
+
+ if (verbose) {
+ *vec++ = verbose;
+ }
+
+ if (from) {
+ *vec++ = "-f";
+ snprintf(frombuf, sizeof(frombuf), "%s@%s", from, hostname);
+ *vec++ = frombuf;
+ }
+
+ for (i = 0; i < ac; i++)
+ *vec++ = av[i];
+
+ if (bcc)
+ *vec++ = bcc;
+
+ *vec++ = NULL;
+
+ if (verbose) {
+ writestr(1, "Executing:");
+ vec = smvec;
+ while (*vec) {
+ writestr(1, " ");
+ writestr(1, *vec);
+ vec++;
+ }
+ writestr(1, "\n");
+ }
+
+
+ if (pipe(pfd) < 0) {
+ perror("pipe");
+ exit(1);
+ }
+
+ pid = fork();
+
+ switch(pid) {
+
+ case 0: /* child */
+ close(0);
+ dup(pfd[0]);
+ for (i = 3; i < 64; i++)
+ close(i);
+ execv(_PATH_SENDMAIL, smvec);
+ perror(_PATH_SENDMAIL);
+ _exit(1);
+ break;
+
+ case -1: /* error */
+ perror("fork");
+ exit(1);
+ break;
+
+ default: /* parent */
+ close(pfd[0]);
+ break;
+ }
+
+ if (Frombuf[0]) {
+ writestr(pfd[1], "From: ");
+ writestr(pfd[1], Frombuf);
+ writestr(pfd[1], "\n");
+ }
+ writestr(pfd[1], "Date: ");
+ writestr(pfd[1], makerfc822date(time(0)));
+ writestr(pfd[1], "\n");
+
+ if (subj) {
+ writestr(pfd[1], "Subject: ");
+ writestr(pfd[1], subj);
+ writestr(pfd[1], "\n");
+ }
+ if (reply) {
+ writestr(pfd[1], "Reply-To: ");
+ writestr(pfd[1], reply);
+ writestr(pfd[1], "\n");
+ }
+ if (cc) {
+ writestr(pfd[1], "Cc: ");
+ writestr(pfd[1], cc);
+ writestr(pfd[1], "\n");
+ }
+
+ writestr(pfd[1], "To: ");
+ writestr(pfd[1], av[0]);
+
+ for (i = 1; i < ac; i++) {
+ writestr(pfd[1], ", ");
+ writestr(pfd[1], av[i]);
+ }
+ writestr(pfd[1], "\n");
+
+ /* Headers from stdin */
+ if (!headers)
+ writestr(pfd[1], "\n");
+
+ while ((c = read(0, buf, sizeof(buf))) > 0) {
+ write(pfd[1], buf, c);
+ }
+
+ close(pfd[1]);
+
+ alarm(600); /* drop dead in 10 minutes */
+
+ while (wait(NULL) > 0)
+ ;
+
+ exit(0);
+}