From owner-freebsd-bugs Fri Dec 3 16:39:27 1999 Delivered-To: freebsd-bugs@freebsd.org Received: from misha.cisco.com (misha.cisco.com [171.69.206.50]) by hub.freebsd.org (Postfix) with ESMTP id BB14314D7B; Fri, 3 Dec 1999 16:39:16 -0800 (PST) (envelope-from mi@misha.cisco.com) Received: (from mi@localhost) by misha.cisco.com (8.9.3/8.9.1) id TAA27558; Fri, 3 Dec 1999 19:39:15 -0500 (EST) (envelope-from mi) Message-Id: <199912040039.TAA27558@misha.cisco.com> Subject: Re: bin/15227: New option for vacation(1) -- dir to use instead of $HOME In-Reply-To: <199912021820.KAA20948@freefall.freebsd.org> from "gnats-admin@FreeBSD.org" at "Dec 2, 1999 10:20:01 am" To: gnats-admin@FreeBSD.org, freebsd-bugs@FreeBSD.org Date: Fri, 3 Dec 1999 19:39:15 -0500 (EST) Reply-To: mi@aldan.algebra.com From: Mikhail Teterin X-Mailer: ELM [version 2.4ME+ PL60 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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