summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/enqueue.c
diff options
context:
space:
mode:
authorJacek Masiulaniec <jacekm@cvs.openbsd.org>2009-04-21 18:12:06 +0000
committerJacek Masiulaniec <jacekm@cvs.openbsd.org>2009-04-21 18:12:06 +0000
commit604abccd0e6aa1fe8eae11effee1b454e839bd87 (patch)
tree53033a043b6c2b4d4fed3af3785af86690215757 /usr.sbin/smtpd/enqueue.c
parent65fbea4c6c81c751d2f36dd30b53cb9beffeb9da (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.c50
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);
+}