Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Dec 1999 19:39:15 -0500 (EST)
From:      Mikhail Teterin <mi@aldan.algebra.com>
To:        gnats-admin@FreeBSD.org, freebsd-bugs@FreeBSD.org
Subject:   Re: bin/15227: New option for vacation(1) -- dir to use instead of $HOME
Message-ID:  <199912040039.TAA27558@misha.cisco.com>
In-Reply-To: <199912021820.KAA20948@freefall.freebsd.org> from "gnats-admin@FreeBSD.org" at "Dec 2, 1999 10:20:01 am"

next in thread | previous in thread | raw e-mail | index | archive | help
Please, consider this patch instead. It adds:

	* ability to force the reply address with -F option
	* uses From and Reply-To headers if any -- the fact
	  that our old vacation is NOT doing this, should've
	  been send-pr-ed long time ago
	* invokes sendmail with -t -- plain and simple
	* finally! replaces $SUBJECT with the original
	  message's subject anywhere in .vacation.msg

Thanks!

	-mi

--- /usr/src/usr.bin/vacation/vacation.c.orig	Tue Sep 28 18:42:09 1999
+++ usr.bin/vacation/vacation.c	Fri Dec  3 18:55:46 1999
@@ -82,2 +82,4 @@
 #define	VMSG	".vacation.msg"		/* vacation message */
+#define	VSBJ	"$SUBJECT"		/* the string in .vacation.msg to be replaced */
+					/* with the message's subject */
 
@@ -92,2 +94,6 @@
 char from[MAXLINE];
+char *From = from;
+char subject[MAXLINE];
+int  sawsubj = 0;
+
 void (*msglog)(int, const char *, ...) = &syslog;
@@ -117,2 +123,3 @@
 	int ch, iflag, lflag, mfail, ufail;
+	char *dir = NULL;
 
@@ -120,3 +127,3 @@
 	interval = -1;
-	while ((ch = getopt(argc, argv, "a:dIilr:")) != -1) {
+	while ((ch = getopt(argc, argv, "a:dIilr:D:F:")) != -1) {
 		switch((char)ch) {
@@ -150,2 +157,8 @@
 			break;
+		case 'D':
+			dir = optarg;
+			break;
+		case 'F':
+			From = optarg;
+			break;
 		case '?':
@@ -183,5 +196,7 @@
 	}
-	if (chdir(pw->pw_dir)) {
+	if (!dir)
+		dir = pw->pw_dir;
+	if (chdir(dir)) {
 		msglog(LOG_NOTICE,
-		    "vacation: no such directory %s.\n", pw->pw_dir);
+		    "vacation: %s: %s.\n", dir, strerror(errno));
 		exit(1);
@@ -235,18 +250,52 @@
 	register char *p;
-	int tome, cont;
+	int tome, cont, replyto;
 	char buf[MAXLINE];
 
-	cont = tome = 0;
+	cont = tome = replyto = 0;
 	while (fgets(buf, sizeof(buf), stdin) && *buf != '\n')
 		switch(*buf) {
-		case 'F':		/* "From " */
+		case 'S':		/* "Subject: " */
+			cont = 0;
+			if (!strncmp(buf, "Subject: ", 9)) {
+				(void)strcpy(subject, buf + 9);
+				if ((p = index(subject, '\n')))
+					*p = '\0';
+				sawsubj = 1;
+			}
+			break;
+		case 'F':		/* "From " or "From: " */
 			cont = 0;
-			if (!strncmp(buf, "From ", 5)) {
+			if(From != from || replyto) /* return address was given on the */
+				break;		    /* command line, or saw Reply-To   */
+			if (buf[1] != 'r' || buf[2] != 'o' || buf[3] != 'm' ||
+			    (buf[4] != ' ' && buf[4] != ':'))
+				break;
+			if (buf[4] == ' ') { /* Deal with the first, "From " line */
 				for (p = buf + 5; *p && *p != ' '; ++p);
 				*p = '\0';
-				(void)strcpy(from, buf + 5);
-				if ((p = index(from, '\n')))
+				if ((p = index(buf, '\n')))
 					*p = '\0';
+				(void)strcpy(from, buf + 5);
 				if (junkmail())
 					exit(0);
+			} else {	/* Deal with the "official" From: line */
+				if ((p = index(buf, '\n')))
+					*p = '\0';
+				(void)strcpy(from, buf + 5);
+			}
+			break;
+		case 'R':		/* Reply-To: */
+			cont = 0;
+			if(From != from)	/* Return address forced by cmd line */
+				break;
+			if (!strncasecmp(buf, "Reply-To: ", 10)) {
+				if ((p = index(buf, '\n')))
+					*p = '\0';
+				(void)strcpy(from, buf + 10);
+				if(replyto) {
+					msglog(LOG_NOTICE, "vacation: multiple (%d) Reply-To:"
+						" headers. Only using the last one (%s)\n",
+						replyto, from);
+				}
+				replyto++;
 			}
@@ -288,4 +337,4 @@
 		exit(0);
-	if (!*from) {
-		msglog(LOG_NOTICE, "vacation: no initial \"From\" line.\n");
+	if (!*From) {
+		msglog(LOG_NOTICE, "vacation: no initial \"From\" line and no -F option.\n");
 		exit(1);
@@ -315,2 +364,3 @@
  *	read the header and return if automagic/junk/bulk/list mail
+ *	only invoked if the -F option was not given on command line
  */
@@ -376,4 +426,4 @@
 	/* get record for this address */
-	key.data = from;
-	key.size = strlen(from);
+	key.data = From;
+	key.size = strlen(From);
 	if (!(db->get)(db, &key, &data, 0)) {
@@ -413,4 +463,4 @@
 
-	key.data = from;
-	key.size = strlen(from);
+	key.data = From;
+	key.size = strlen(From);
 	(void)time(&now);
@@ -433,2 +483,3 @@
 	char buf[MAXLINE];
+	char *beg, *end;
 
@@ -453,3 +504,3 @@
 		close(fileno(mfp));
-		execl(_PATH_SENDMAIL, "sendmail", "-f", myname, "--", from, NULL);
+		execl(_PATH_SENDMAIL, "sendmail", "-t", NULL);
 		msglog(LOG_ERR, "vacation: can't exec %s: %s",
@@ -460,5 +511,17 @@
 	sfp = fdopen(pvect[1], "w");
-	fprintf(sfp, "To: %s\n", from);
-	while (fgets(buf, sizeof buf, mfp))
-		fputs(buf, sfp);
+	fprintf(sfp, "To: %s\n", From);
+	/* Output every line, substitutin every $SUBJECT with the subject */
+	while (fgets(buf, sizeof buf, mfp)) {
+		for(beg = buf; (end = strstr(beg, VSBJ)); beg = end + sizeof(VSBJ) - 1) {
+			*end = '\0';
+			fputs(beg, sfp);
+			if (!sawsubj) {
+				msglog(LOG_NOTICE, "vacation: message with no subject\n");
+				subject[0] = '\0';
+				sawsubj = 1;
+			}
+			fputs(subject, sfp);
+		}
+		fputs(beg, sfp);
+	}
 	fclose(mfp);
@@ -470,3 +533,4 @@
 {
-	msglog(LOG_NOTICE, "uid %u: usage: vacation [-d] [-i [-rinterval]] [-l] [-a alias] login\n",
+	msglog(LOG_NOTICE, "uid %u: usage: vacation [-d] [-i [-rinterval]] [-l] "
+		"[-a alias [-a alias ...]] [-D dir] [-F correspondent] login\n",
 	    getuid());

--- /usr/src/usr.bin/vacation/vacation.1.orig	Mon Aug 30 03:15:30 1999
+++ usr.bin/vacation/vacation.1	Fri Dec  3 19:31:55 1999
@@ -45,2 +45,3 @@
 .Op Fl r Ar interval
+.Op Fl D Ar dir
 .Nm vacation
@@ -48,4 +49,7 @@
 .Fl l
+.Op Fl D Ar dir
 .Nm vacation
 .Op Fl d
+.Op Fl D Ar dir
+.Op Fl F Ar address
 .Op Fl a Ar alias
@@ -78,2 +82,17 @@
 Enable debugging mode. See below.
+.It Fl D Ar dir
+Use
+.Ar dir
+instead  of the  user's  home directory.  This  can be  used
+to  allow the  same  user respond  differently to  different
+messages, or to  simply speed up mail  processing by placing
+the database  "closer" to  the mailserver  (local filesystem
+vs. NFS, for example).
+.It Fl F Ar address
+Use
+.Ar address
+instead of whatever address can be found in the message headers.
+This may be usefull if you have something else (like procmail)
+figure out the address, or you just want to notify the same person
+or mailing list periodicly.
 .It Fl i
@@ -132,3 +151,3 @@
 .Pa .vacation.db
-in your home directory.
+in your home directory (see also -D option).
 .Pp
@@ -137,5 +156,8 @@
 .Pa .vacation.msg ,
-in your home directory, containing a message to be sent back to each
-sender.  It should be an entire message (including headers).  For
-example, it might contain:
+in your home directory (see also  -D option), containing a message to be
+sent back  to each  sender. It  should be  an entire  message (including
+headers). If the  string $SUBJECT appears in the  .vacation.msg file, it
+will be replaced with the subject of the original message in the reply.
+
+For example, it might contain:
 .Pp
@@ -143,3 +165,3 @@
 From: eric@CS.Berkeley.EDU (Eric Allman)
-Subject: I am on vacation
+Subject: I am on vacation (Re: $SUBJECT)
 Delivered-By-The-Graces-Of: The Vacation program
@@ -152,7 +174,6 @@
 .Pp
-.Nm Vacation
-reads the first line from the standard input for a
-.Ux
-.Dq From
-line to determine the sender.
+Older
+.Nm vacation
+only used the first line with "From "
+from the standard input to determine the sender.
 .Xr Sendmail 8
@@ -161,2 +182,13 @@
 line automatically.
+Now FreeBSD's
+.Nm vacation
+properly handles
+.Dq From:
+and
+.Dq Reply-To:
+headers. The  last
+.Dq From:
+header found  is used. If there  are any
+.Dq Reply-To:
+headers,  the last  one  of them  is used instead.
 .Pp


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199912040039.TAA27558>