Index | Thread | Search

From:
Sven M. Hallberg <pesco@khjk.org>
Subject:
Re: vacation(1): consume all input
To:
Omar Polo <op@omarpolo.com>
Cc:
gilles@openbsd.org, tech@openbsd.org
Date:
Tue, 04 Mar 2025 19:30:48 +0100

Download raw body.

Thread
Omar Polo on Fri, Aug 23 2024:
> I'd like to double-check with gilles@ that our current requirement for
> mda script to consume all the input is on purpose.  Skimming through
> postfix documentation I don't see mentions of this, but sendmail'
> vacation has a eatmsg() function that is equivalent to your done().

Ping.

> Otherwise, your diff looks fine to me, maybe just with fread() instead
> of a fgets(), but that's a nitpick.

Updated patch against current and with fread() instead of fgets():


Index: usr.bin/vacation/vacation.c
===================================================================
RCS file: /cvs/src/usr.bin/vacation/vacation.c,v
retrieving revision 1.39
diff -u -p -r1.39 vacation.c
--- usr.bin/vacation/vacation.c	29 Aug 2024 21:04:16 -0000	1.39
+++ usr.bin/vacation/vacation.c	4 Mar 2025 18:29:36 -0000
@@ -73,6 +73,7 @@ DB *db;
 char from[MAXLINE];
 char subj[MAXLINE];
 
+void done(void);
 int junkmail(void);
 int nsearch(char *, char *);
 void readheaders(void);
@@ -175,11 +176,28 @@ main(int argc, char *argv[])
 		sendmessage(pw->pw_name);
 	} else
 		(void)(db->close)(db);
-	exit(0);
+	done();
 	/* NOTREACHED */
 }
 
 /*
+ * done --
+ *	consume all remaining input and exit with success
+ *
+ * This is a waste, but smtpd might interpret anything else as "premature
+ * termination" and keep the message queued as undelivered.
+ */
+void
+done(void)
+{
+	char buf[MAXLINE];
+
+	while (fread(buf, 1, sizeof(buf), stdin) == sizeof(buf))
+		;
+	exit(0);
+}
+
+/*
  * readheaders --
  *	read mail headers
  */
@@ -213,7 +231,7 @@ readheaders(void)
 				if (*p == '\0')
 					break;	/* Auto-Submitted: no */
 			}
-			exit(0);
+			done();
 		case 'F':		/* "From " */
 		case 'f':
 			cont = 0;
@@ -224,7 +242,7 @@ readheaders(void)
 				(void)strlcpy(from, buf + 5, sizeof(from));
 				from[strcspn(from, "\n")] = '\0';
 				if (junkmail())
-					exit(0);
+					done();
 			}
 			break;
 		case 'L':		/* "List-Id:" */
@@ -235,7 +253,7 @@ readheaders(void)
 			 * mailing list, cf. RFC2919.
 			 */
 			if (strncasecmp(buf, "List-Id:", 8) == 0)
-				exit(0);
+				done();
 			break;
 		case 'R':		/* "Return-Path:" */
 		case 'r':
@@ -257,7 +275,7 @@ readheaders(void)
 			}
 			from[strcspn(from, "\n")] = '\0';
 			if (junkmail())
-				exit(0);
+				done();
 			break;
 		case 'P':		/* "Precedence:" */
 		case 'p':
@@ -269,7 +287,7 @@ readheaders(void)
 			if (!strncasecmp(p, "junk", 4) ||
 			    !strncasecmp(p, "bulk", 4) ||
 			    !strncasecmp(p, "list", 4))
-				exit(0);
+				done();
 			break;
 		case 'S':		/* Subject: */
 		case 's':
@@ -308,7 +326,7 @@ findme:			for (cur = names; !tome && cur
 				tome += nsearch(cur->name, buf);
 		}
 	if (!tome || !*from)
-		exit(0);
+		done();
 }
 
 /*