diff --git a/lib/Makefile b/lib/Makefile index e24a75ea2db0..6e0a3f9fa10e 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,7 +26,7 @@ SUBDIR= ${_csu} libcom_err ${_libcrypt} msun libmd \ libftpio libgnumalloc ${_libio} libipsec libipx libkvm libmenu \ ${_libncp} \ libnetgraph libopie libpam libpanel libpcap \ - libposix1e libresolv librpcsvc ${_libsmdb} libss ${_libsmutil} \ + libposix1e libresolv librpcsvc libsmdb libss libsmutil \ libstand ${_libtelnet} libusb ${_libvgl} libwrap libxpg4 liby libz .if exists(${.CURDIR}/csu/${MACHINE_ARCH}-${OBJFORMAT}) @@ -43,11 +43,6 @@ _libc_r= libc_r _libbind= libbind .endif -.if !defined(NO_SENDMAIL) -_libsmdb= libsmdb -_libsmutil= libsmutil -.endif - _libcrypt= libcrypt .if exists(${.CURDIR}/../secure) && !defined(NOSECURE) && !defined(NOCRYPT) && !defined(NO_DESCRYPT) # Build both libraries. They have different names, so no harm, diff --git a/usr.bin/vacation/Makefile b/usr.bin/vacation/Makefile index ee668d894e64..fbe1f8197e79 100644 --- a/usr.bin/vacation/Makefile +++ b/usr.bin/vacation/Makefile @@ -1,7 +1,36 @@ -# From: @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +SENDMAIL_DIR=${.CURDIR}/../../contrib/sendmail +.PATH: ${SENDMAIL_DIR}/vacation + PROG= vacation -CFLAGS+= -Wall +SRCS= vacation.c +MAN8= vacation.1 +CFLAGS+=-I${SENDMAIL_DIR}/src -I${SENDMAIL_DIR}/include +CFLAGS+=-DNEWDB -DNOT_SENDMAIL +CFLAGS+=-D_FFR_LISTDB -D_FFR_DEBUG + +.if exists(${.OBJDIR}/../../lib/libsmdb) +LIBSMDBDIR:= ${.OBJDIR}/../../lib/libsmdb +.else +LIBSMDBDIR!= cd ${.CURDIR}/../../lib/libsmdb; make -V .OBJDIR +.endif +LIBSMDB:= ${LIBSMDBDIR}/libsmdb.a + +.if exists(${.OBJDIR}/../../lib/libsmutil) +LIBSMUTILDIR:= ${.OBJDIR}/../../lib/libsmutil +.else +LIBSMUTILDIR!= cd ${.CURDIR}/../../lib/libsmutil; make -V .OBJDIR +.endif +LIBSMUTIL:= ${LIBSMUTILDIR}/libsmutil.a + +DPADD+= ${LIBSMDB} ${LIBSMUTIL} +LDADD+= ${LIBSMDB} ${LIBSMUTIL} + +# User customizations to the sendmail build environment +CFLAGS+=${SENDMAIL_CFLAGS} +LDFLAGS+=${SENDMAIL_LDFLAGS} +LDADD+=${SENDMAIL_LDADD} +DPADD+=${SENDMAIL_DPADD} .include diff --git a/usr.bin/vacation/vacation.1 b/usr.bin/vacation/vacation.1 deleted file mode 100644 index b5db13922d0b..000000000000 --- a/usr.bin/vacation/vacation.1 +++ /dev/null @@ -1,202 +0,0 @@ -.\" Copyright (c) 1985, 1987, 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" From: @(#)vacation.1 8.1 (Berkeley) 6/16/93 -.\" $FreeBSD$ -.\" -.Dd June 16, 1993 -.Dt VACATION 1 -.Os BSD 4.3 -.Sh NAME -.Nm vacation -.Nd return ``I am not here'' indication -.Sh SYNOPSIS -.Nm vacation -.Op Fl d -.Fl i -.Op Fl r Ar interval -.Nm vacation -.Op Fl d -.Fl l -.Nm vacation -.Op Fl d -.Op Fl a Ar alias -.Ar login -.Sh DESCRIPTION -.Nm Vacation -returns a message to the sender of a message telling them that you -are currently not reading your mail. The intended use is in a -.Pa .forward -file. For example, your -.Pa .forward -file might have: -.Bd -literal -offset indent -\eeric, "|/usr/bin/vacation -a allman eric" -.Ed -which would send messages to you (assuming your login name was eric) and -reply to any messages for -.Dq eric -or -.Dq allman . -.Pp -Available options: -.Bl -tag -width Ds -.It Fl a Ar alias -Handle messages for -.Ar alias -in the same manner as those received for the user's -login name. -.It Fl d -Enable debugging mode. -See below. -.It Fl i -Initialize the vacation database files. It should be used -before you modify your -.Pa .forward -file. -.It Fl r -Set the reply interval to -.Ar interval -days. The default is one week. An interval of -.Dq 0 -means that -a reply is sent to each message, and an interval of -.Dq Li infinite -(actually, any non-numeric character) will never send more than -one reply. It should be noted that intervals of -.Dq Li \&0 -are quite -dangerous, as it allows mailers to get into -.Dq I am on vacation -loops. -.It Fl l -Print the contents of the vacation database files. For each entry, -the address the reply has been sent to and the associated time will -be printed to standard output. -.El -.Pp -No message will be sent unless -.Ar login -(or an -.Ar alias -supplied using the -.Fl a -option) is part of either the -.Dq To: -or -.Dq Cc: -headers of the mail. -No messages from -.Dq ???-REQUEST , -.Dq Postmaster , -.Dq Tn UUCP , -.Dq MAILER , -or -.Dq MAILER-DAEMON -will be replied to (where these strings are -case insensitive) nor is a notification sent if a -.Dq Precedence: bulk -or -.Dq Precedence: junk -line is included in the mail headers. -The people who have sent you messages are maintained as a -.Xr hash 3 -database in the file -.Pa .vacation.db -in your home directory. -.Pp -.Nm Vacation -expects a file -.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: -.Pp -.Bd -unfilled -offset indent -compact -From: eric@CS.Berkeley.EDU (Eric Allman) -Subject: I am on vacation -Delivered-By-The-Graces-Of: The Vacation program -Precedence: bulk - -I am on vacation until July 22. If you have something urgent, -please contact Keith Bostic . ---eric -.Ed -.Pp -.Nm Vacation -reads the first line from the standard input for a -.Ux -.Dq From -line to determine the sender. -.Xr Sendmail 8 -includes this -.Dq From -line automatically. -.Pp -Fatal errors, such as calling -.Nm vacation -with incorrect arguments, or with non-existent -.Ar login Ns Ar s , -are logged in the system log file, using -.Xr syslog 3 -unless debugging mode is enabled with the -.Fl d -option, in which case they are written to the standard error output. -.Pp -Building on the example provided above, you might choose to have errors -redirected to a file while you are testing vacation's operation with -the following in your -.Pa .forward -file: -.Pp -.Bd -literal -offset indent -\eeric, "|/bin/sh -c '/usr/bin/vacation -d -a allman eric' 2>/home/eric/.vacation.log" -.Ed -.Sh DIAGNOSTICS -The -.Nm -utility exits 0 on success, and >0 if an error occurs. -.Sh FILES -.Bl -tag -width "vacation.dirxxx" -compact -.It Pa ~/.vacation.db -database file -.It Pa ~/.vacation.msg -message to send -.El -.Sh SEE ALSO -.Xr syslog 3 , -.Xr sendmail 8 , -.Xr syslogd 8 -.Sh HISTORY -The -.Nm vacation -command appeared in -.Bx 4.3 . diff --git a/usr.bin/vacation/vacation.c b/usr.bin/vacation/vacation.c deleted file mode 100644 index 9a5790ea7ad0..000000000000 --- a/usr.bin/vacation/vacation.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (c) 1983, 1987, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1983, 1987, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)from: vacation.c 8.2 (Berkeley) 1/26/94"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -/* -** Vacation -** Copyright (c) 1983 Eric P. Allman -** Berkeley, California -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * VACATION -- return a message to the sender when on vacation. - * - * This program is invoked as a message receiver. It returns a - * message specified by the user to whomever sent the mail, taking - * care not to return a message too often to prevent "I am on - * vacation" loops. - */ - -#define MAXLINE 1024 /* max line from mail header */ -#define VDB ".vacation.db" /* dbm's database */ -#define VMSG ".vacation.msg" /* vacation message */ - -typedef struct alias { - struct alias *next; - char *name; -} ALIAS; -ALIAS *names; - -DB *db; - -char from[MAXLINE]; -void (*msglog)(int, const char *, ...) = &syslog; - -static int isdelim __P((int)); -static int junkmail __P((void)); -static void listdb __P((void)); -static int nsearch __P((char *, char *)); -static void readheaders __P((void)); -static int recent __P((void)); -static void sendmessage __P((char *)); -static void setinterval __P((time_t)); -static void setreply __P((void)); -static void usage __P((void)); -static void debuglog __P((int, const char *, ...)); - -int -main(argc, argv) - int argc; - char **argv; -{ - struct passwd *pw; - ALIAS *cur; - time_t interval; - int ch, iflag, lflag, mfail, ufail; - - opterr = iflag = lflag = mfail = ufail = 0; - interval = -1; - while ((ch = getopt(argc, argv, "a:dIilr:")) != -1) { - switch((char)ch) { - case 'a': /* alias */ - if (!(cur = (ALIAS *)malloc((u_int)sizeof(ALIAS)))) { - mfail++; - break; - } - cur->name = optarg; - cur->next = names; - names = cur; - break; - case 'd': /* debug mode */ - msglog = &debuglog; - break; - case 'I': /* backward compatible */ - case 'i': /* init the database */ - iflag = 1; - break; - case 'l': - lflag = 1; /* list the database */ - break; - case 'r': - if (isdigit(*optarg)) { - interval = atol(optarg) * 86400; - if (interval < 0) - ufail++; - } - else - interval = LONG_MAX; - break; - case '?': - default: - ufail++; - } - } - - /* - * Only die on the above malloc and usage errors here so that the - * correct logging medium is used. - */ - if (mfail) { - msglog(LOG_ERR, "vacation: malloc failed\n"); - exit(EX_TEMPFAIL); - } - else if (ufail) - usage(); - - argc -= optind; - argv += optind; - - if (argc != 1) { - if (!iflag && !lflag) - usage(); - if (!(pw = getpwuid(getuid()))) { - msglog(LOG_ERR, - "vacation: no such user uid %u.\n", getuid()); - exit(1); - } - } - else if (!(pw = getpwnam(*argv))) { - msglog(LOG_ERR, "vacation: no such user %s.\n", *argv); - exit(1); - } - if (chdir(pw->pw_dir)) { - msglog(LOG_NOTICE, - "vacation: no such directory %s.\n", pw->pw_dir); - exit(1); - } - - db = dbopen(VDB, O_CREAT|O_RDWR | (iflag ? O_TRUNC : 0), - S_IRUSR|S_IWUSR, DB_HASH, NULL); - if (!db) { - msglog(LOG_NOTICE, "vacation: %s: %s\n", VDB, strerror(errno)); - exit(1); - } - - if (lflag) - listdb(); - else if (interval != -1) - setinterval(interval); - - if (iflag || lflag) { - (void)(db->close)(db); - exit(0); - } - - if (!(cur = malloc((u_int)sizeof(ALIAS)))) { - msglog(LOG_ERR, "vacation: malloc failed\n"); - exit(EX_TEMPFAIL); - } - cur->name = pw->pw_name; - cur->next = names; - names = cur; - - readheaders(); - if (!recent()) { - setreply(); - (void)(db->close)(db); - sendmessage(pw->pw_name); - } - else - (void)(db->close)(db); - exit(0); - /* NOTREACHED */ -} - -/* - * readheaders -- - * read mail headers - */ -static void -readheaders() -{ - register ALIAS *cur; - register char *p; - int tome, cont; - char buf[MAXLINE]; - - cont = tome = 0; - while (fgets(buf, sizeof(buf), stdin) && *buf != '\n') - switch(*buf) { - case 'F': /* "From " */ - cont = 0; - if (!strncmp(buf, "From ", 5)) { - for (p = buf + 5; *p && *p != ' '; ++p); - *p = '\0'; - (void)strcpy(from, buf + 5); - if ((p = index(from, '\n'))) - *p = '\0'; - if (junkmail()) - exit(0); - } - break; - case 'P': /* "Precedence:" */ - cont = 0; - if (strncasecmp(buf, "Precedence", 10) || - (buf[10] != ':' && buf[10] != ' ' && buf[10] != '\t')) - break; - if (!(p = index(buf, ':'))) - break; - while (*++p && isspace(*p)); - if (!*p) - break; - if (!strncasecmp(p, "junk", 4) || - !strncasecmp(p, "bulk", 4) || - !strncasecmp(p, "list", 4)) - exit(0); - break; - case 'C': /* "Cc:" */ - if (strncmp(buf, "Cc:", 3)) - break; - cont = 1; - goto findme; - case 'T': /* "To:" */ - if (strncmp(buf, "To:", 3)) - break; - cont = 1; - goto findme; - default: - if (!isspace(*buf) || !cont || tome) { - cont = 0; - break; - } -findme: for (cur = names; !tome && cur; cur = cur->next) - tome += nsearch(cur->name, buf); - } - if (!tome) - exit(0); - if (!*from) { - msglog(LOG_NOTICE, "vacation: no initial \"From\" line.\n"); - exit(1); - } -} - -/* - * nsearch -- - * do a nice, slow, search of a string for a substring. - */ -static int -nsearch(name, str) - register char *name, *str; -{ - register int len; - - for (len = strlen(name); *str; ++str) - if (*str == *name && - !strncasecmp(name, str, len) && - isdelim((unsigned char)str[len])) - return(1); - return(0); -} - -/* - * junkmail -- - * read the header and return if automagic/junk/bulk/list mail - */ -static int -junkmail() -{ - static struct ignore { - char *name; - int len; - } ignore[] = { - {"-request", 8}, {"postmaster", 10}, {"uucp", 4}, - {"mailer-daemon", 13}, {"mailer", 6}, {"-relay", 6}, - {NULL, 0}, - }; - register struct ignore *cur; - register int len; - register char *p; - - /* - * This is mildly amusing, and I'm not positive it's right; trying - * to find the "real" name of the sender, assuming that addresses - * will be some variant of: - * - * From site!site!SENDER%site.domain%site.domain@site.domain - */ - if (!(p = index(from, '%'))) - if (!((p = index(from, '@')))) { - if ((p = rindex(from, '!'))) - ++p; - else - p = from; - for (; *p; ++p); - } - len = p - from; - for (cur = ignore; cur->name; ++cur) - if (len >= cur->len && - !strncasecmp(cur->name, p - cur->len, cur->len)) - return(1); - return(0); -} - -#define VIT "__VACATION__INTERVAL__TIMER__" - -/* - * recent -- - * find out if user has gotten a vacation message recently. - * use bcopy for machines with alignment restrictions - */ -static int -recent() -{ - DBT key, data; - time_t then, next; - - /* get interval time */ - key.data = VIT; - key.size = sizeof(VIT); - if ((db->get)(db, &key, &data, 0)) - next = 86400 * 7; - else - bcopy(data.data, &next, sizeof(next)); - - /* get record for this address */ - key.data = from; - key.size = strlen(from); - if (!(db->get)(db, &key, &data, 0)) { - bcopy(data.data, &then, sizeof(then)); - if (next == LONG_MAX || then + next > time(NULL)) - return(1); - } - return(0); -} - -/* - * setinterval -- - * store the reply interval - */ -static void -setinterval(interval) - time_t interval; -{ - DBT key, data; - - key.data = VIT; - key.size = sizeof(VIT); - data.data = &interval; - data.size = sizeof(interval); - (void)(db->put)(db, &key, &data, 0); -} - -/* - * setreply -- - * store that this user knows about the vacation. - */ -static void -setreply() -{ - DBT key, data; - time_t now; - - key.data = from; - key.size = strlen(from); - (void)time(&now); - data.data = &now; - data.size = sizeof(now); - (void)(db->put)(db, &key, &data, 0); -} - -/* - * sendmessage -- - * exec sendmail to send the vacation file to sender - */ -static void -sendmessage(myname) - char *myname; -{ - FILE *mfp, *sfp; - int i; - int pvect[2]; - char buf[MAXLINE]; - - mfp = fopen(VMSG, "r"); - if (mfp == NULL) { - msglog(LOG_NOTICE, "vacation: no ~%s/%s file.\n", myname, VMSG); - exit(1); - } - if (pipe(pvect) < 0) { - msglog(LOG_ERR, "vacation: pipe: %s", strerror(errno)); - exit(1); - } - i = fork(); - if (i < 0) { - msglog(LOG_ERR, "vacation: fork: %s", strerror(errno)); - exit(1); - } - if (i == 0) { - dup2(pvect[0], 0); - close(pvect[0]); - close(pvect[1]); - close(fileno(mfp)); - execl(_PATH_SENDMAIL, "sendmail", "-f", myname, "--", from, NULL); - msglog(LOG_ERR, "vacation: can't exec %s: %s", - _PATH_SENDMAIL, strerror(errno)); - _exit(1); - } - close(pvect[0]); - sfp = fdopen(pvect[1], "w"); - fprintf(sfp, "To: %s\n", from); - while (fgets(buf, sizeof buf, mfp)) - fputs(buf, sfp); - fclose(mfp); - fclose(sfp); -} - -static void -usage() -{ - msglog(LOG_NOTICE, "uid %u: usage: vacation [-d] [-i [-rinterval]] [-l] [-a alias] login\n", - getuid()); - exit(1); -} - -static void -listdb() -{ - DBT key, data; - int rv; - time_t t; - char user[MAXLINE]; - - while((rv = db->seq(db, &key, &data, R_NEXT)) == 0) { - bcopy(key.data, user, key.size); - user[key.size] = '\0'; - if (strcmp(user, VIT) == 0) - continue; - bcopy(data.data, &t, data.size); - printf("%-40s %-10s", user, ctime(&t)); - } - if (rv == -1) - perror("IO error in database"); -} - -/* - * Is `c' a delimiting character for a recipient name? - */ -static int -isdelim(c) - int c; -{ - /* - * NB: don't use setlocale() before, headers are supposed to - * consist only of ASCII (aka. C locale) characters. - */ - if (isalnum(c)) - return(0); - if (c == '_' || c == '-' || c == '.') - return(0); - return(1); -} - -/* - * Append a message to the standard error for the convenience of end-users - * debugging without access to the syslog messages. - */ -static void -debuglog(int i, const char *fmt, ...) -{ - va_list ap; - - i = 0; /* Printing syslog priority not implemented */ - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -}