diff options
author | Jacek Masiulaniec <jacekm@cvs.openbsd.org> | 2009-04-21 18:12:06 +0000 |
---|---|---|
committer | Jacek Masiulaniec <jacekm@cvs.openbsd.org> | 2009-04-21 18:12:06 +0000 |
commit | 604abccd0e6aa1fe8eae11effee1b454e839bd87 (patch) | |
tree | 53033a043b6c2b4d4fed3af3785af86690215757 /usr.sbin/smtpd/enqueue.c | |
parent | 65fbea4c6c81c751d2f36dd30b53cb9beffeb9da (diff) |
Make /usr/sbin/sendmail not fail due to smtpd being down.
The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.
ok gilles@
Diffstat (limited to 'usr.sbin/smtpd/enqueue.c')
-rw-r--r-- | usr.sbin/smtpd/enqueue.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/usr.sbin/smtpd/enqueue.c b/usr.sbin/smtpd/enqueue.c index 24c27317646..3c7e79f9088 100644 --- a/usr.sbin/smtpd/enqueue.c +++ b/usr.sbin/smtpd/enqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: enqueue.c,v 1.13 2009/04/17 16:26:18 jacekm Exp $ */ +/* $OpenBSD: enqueue.c,v 1.14 2009/04/21 18:12:05 jacekm Exp $ */ /* * Copyright (c) 2005 Henning Brauer <henning@bulabula.org> @@ -60,7 +60,6 @@ void rcptto(char *); void start_data(void); void send_message(int); void end_data(void); -int enqueue(int, char **); enum headerfields { HDR_NONE, @@ -710,3 +709,50 @@ end_data(void) if ((status = read_reply()) != STATUS_QUIT) errx(1, "server sends error after QUIT"); } + +int +enqueue_offline(int argc, char *argv[]) +{ + char path[MAXPATHLEN]; + FILE *fp; + int i, fd, ch; + + if (! bsnprintf(path, sizeof(path), "%s%s/%d,XXXXXXXXXX", PATH_SPOOL, + PATH_OFFLINE, time(NULL))) + err(1, "snprintf"); + + if ((fd = mkstemp(path)) == -1 || (fp = fdopen(fd, "w+")) == NULL) { + warn("cannot create temporary file %s", path); + if (fd != -1) + unlink(path); + exit(1); + } + + for (i = 1; i < argc; i++) { + if (strchr(argv[i], '|') != NULL) { + warnx("%s contains illegal character", argv[i]); + unlink(path); + exit(1); + } + fprintf(fp, "%s%s", i == 1 ? "" : "|", argv[i]); + } + + fprintf(fp, "\n"); + + while ((ch = fgetc(stdin)) != EOF) + if (fputc(ch, fp) == EOF) { + warn("write error"); + unlink(path); + exit(1); + } + + if (ferror(stdin)) { + warn("read error"); + unlink(path); + exit(1); + } + + fclose(fp); + + return (0); +} |