Bug 15227

Summary: New option for vacation(1) -- dir to use instead of $HOME
Product: Base System Reporter: Mikhail Teterin <mi>
Component: binAssignee: Gregory Neil Shapiro <gshapiro>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 3.3-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff
none
file.diff none

Description Mikhail Teterin 1999-12-02 18:20:01 UTC
	The existing vacation(1) program is nice, but you can only have
	one database and message with it. Yet, I found it neccessary on
	several occasions to have different responses send in response
	to different e-mails, and even created a special user once, just
	for that.

	You still need some smart mail-handling software such as procmail,
	but using it can be much simpler if you do not need to script what
	vacation(1) already provides.

Fix: Before the patches below are committed, the only alternative is
	to use home-cooked scripts.
Comment 1 Sheldon Hearn 1999-12-03 11:45:28 UTC
On Thu, 02 Dec 1999 13:14:38 EST, Mikhail Teterin wrote:

> >Synopsis:       New option for vacation(1) -- dir to use instead of $HOME

Hmmm, would it not be more flexible to add to vacation two options for
specifying alternative .vacation.db and .vacation.msg files?  If so,
would you be interested in submitting a patch for _that_ instead? :-)

Ciao,
Sheldon.
Comment 2 Mikhail Teterin 1999-12-03 15:30:24 UTC
Sheldon Hearn once stated:

=On Thu, 02 Dec 1999 13:14:38 EST, Mikhail Teterin wrote:
=
=> >Synopsis:  New option for vacation(1) -- dir to use instead of $HOME
=
=Hmmm, would it not be more flexible  to add to vacation two options for
=specifying  alternative .vacation.db  and .vacation.msg  files? If  so,
=would you be interested in submitting a patch for _that_ instead? :-)

I thought about this, and figured  this is less intrusive, there is less
of  a chance  to overstep  the option  names used  by vacation  on other
systems, and this gives just as  much flexibility -- with symbolic links
you can share the messages and/or databases as you wish.

Also, this is the  directory it chdir()s to. If, oh no,  it dies -- this
is where it  will leave core, or whatever else  the future modifications
will do to it.  Even if someone wants to add the  options to specify the
file locations separately in the future, this one should, IMHO, still be
there.

Since the  potential users will  likely keep the related  files (mailing
list  archives, mailboxes,  killfiles, etc.)  in the  same directory  as
well, I think this is enough. Uhm? Yours,

	-mi
Comment 3 sprice 1999-12-04 15:07:42 UTC
---------- Forwarded message ----------
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

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
Comment 4 Sheldon Hearn freebsd_committer freebsd_triage 1999-12-07 16:28:45 UTC
Responsible Changed
From-To: freebsd-bugs->sheldonh

If we're not going to bring in the new sendmail beta before 4.0-RELEASE 
I'll update our existing vacation to the one supplied with it. 

Otherwise, this'll be taken care of by markm.  I'll keep an eye on it. 

By the way, you're not going to get exactly the same options you asked 
for, but rather the options that the new vacation(1) offers which 
provide similar functionality. 
Comment 5 Sheldon Hearn freebsd_committer freebsd_triage 2000-07-17 20:56:48 UTC
Responsible Changed
From-To: sheldonh->gshapiro

This one will be taken care of when our vacation(1) is replaced 
with the version in the new sendmail distribution.
Comment 6 Gregory Neil Shapiro freebsd_committer freebsd_triage 2000-10-10 19:21:02 UTC
State Changed
From-To: open->closed

Now using senmdail's version of vacation, which includes the ability to 
override the message and database files on the command line as requested.