DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T U

⟦784238f8f⟧ TextFile

    Length: 11185 (0x2bb1)
    Types: TextFile
    Notes: Uncompressed file

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦d6148e1d7⟧ »EurOpenD3/misc/vacation.Z« 
        └─⟦this⟧ 

TextFile

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	vacation.1
#	vacation.c
#
echo x - vacation.1
sed 's/^X//' >vacation.1 << 'END-of-vacation.1'
X.\" Copyright (c) 1985, 1987 Regents of the University of California.
X.\" All rights reserved.
X.\"
X.\" Redistribution and use in source and binary forms are permitted
X.\" provided that this notice is preserved and that due credit is given
X.\" to the University of California at Berkeley. The name of the University
X.\" may not be used to endorse or promote products derived from this
X.\" software without specific prior written permission. This software
X.\" is provided ``as is'' without express or implied warranty.
X.\"
X.\"	@(#)vacation.1	6.5 (Berkeley) 12/26/87
X.\"
X.TH VACATION 1 "December 26, 1987"
X.UC 6
X.SH NAME
Xvacation \- return ``I am not here'' indication
X.SH SYNOPSIS
X.B vacation
X.B -i
X.br
X.B vacation
X[
X.B -a
Xalias ] login
X.SH DESCRIPTION
X\fIVacation\fP returns a message to the sender of a message telling
Xthem that you are currently not reading your mail.  The intended use
Xis in a \fI.forward\fP file.  For example, your \fI.forward\fP file
Xmight have:
X.PP
X.ti +5
X\eeric, "|/usr/ucb/vacation -a allman eric"
X.PP
Xwhich would send messages to you (assuming your login name was eric) and
Xreply to any messages for ``eric'' or ``allman''.
X.PP
XNo message will be sent unless \fIlogin\fP or an \fIalias\fP supplied
Xusing the \fB-a\fP option is a substring of either the ``To:'' or ``Cc:''
Xheaders of the mail.  No messages from ``???-REQUEST'', ``Postmaster'',
X``UUCP'', ``MAILER'', or ``MAILER-DAEMON'' will be replied to, nor is a
Xnotification sent if a ``Precedence: bulk'' or ``Precedence: junk'' line
Xis included in the mail headers.  Only one message per week will be sent
Xto each unique sender.  The people who have sent you messages are
Xmaintained as an \fIndbm\fP(3) database in the files \fI.vacation.pag\fP
Xand \fI.vacation.dir\fP in your home directory.
X.PP
XThe \fB-i\fP flag initializes the vacation database files.  It should be
Xused before you modify your \fI.forward\fP file.
X.PP
X\fIVacation\fP expects a file \fI.vacation.msg\fP, in your home directory,
Xcontaining a message to be sent back to each sender.  It should be an entire
Xmessage (including headers).  For example, it might say:
X.PP
X.in +5
X.nf
XFrom: eric@ucbmonet.Berkeley.EDU (Eric Allman)
XSubject: I am on vacation
XDelivered-By-The-Graces-Of: The Vacation program
XPrecedence: bulk
X
XI am on vacation until July 22.  If you have something urgent,
Xplease contact Joe Kalash <kalash@ucbingres.Berkeley.EDU>.
X	--eric
X.fi
X.in -5
X.PP
X\fIVacation\fP reads the first line from the standard input for
Xa \s-1UNIX\s0-style ``From'' line to determine the sender.
X\fISendmail\fP(8) includes this ``From'' line automatically.
X.PP
XFatal errors, such as calling \fIvacation\fP with incorrect arguments,
Xor with non-existent \fIlogin\fPs, are logged in the system log file,
Xusing \fIsyslog\fP(8).
X.SH FILES
X.nf
X.ta \w'~/.vacation.msg    'u
X~/.vacation.dir	database file
X~/.vacation.msg	message to send
X~/.vacation.pag	database file
X.fi
X.SH "SEE ALSO"
Xsendmail(8), syslog(8)
END-of-vacation.1
echo x - vacation.c
sed 's/^X//' >vacation.c << 'END-of-vacation.c'
X/*
X * Copyright (c) 1983, 1987 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xchar copyright[] =
X"@(#) Copyright (c) 1983, 1987 Regents of the University of California.\n\
X All rights reserved.\n";
X#endif /* not lint */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)vacation.c	5.9 (Berkeley) 3/24/88";
X#endif /* not lint */
X
X/*
X**  Vacation
X**  Copyright (c) 1983  Eric P. Allman
X**  Berkeley, California
X*/
X
X#include <sys/param.h>
X#include <sys/file.h>
X#include <pwd.h>
X#include <stdio.h>
X#include <ctype.h>
X#include <syslog.h>
X
X/*
X**  VACATION -- return a message to the sender when on vacation.
X**
X**	This program could be invoked as a message receiver when someone is
X**	on vacation.  It returns a message specified by the user to whoever
X**	sent the mail, taking care not to return a message too often to
X**	prevent "I am on vacation" loops.
X*/
X
X#define	MAXLINE	500			/* max line from mail header */
X#define	PERIOD	(60L*60L*24L*7L)	/* week between notifications */
X#define	VMSG	".vacation.msg"		/* vacation message */
X#define	VACAT	".vacation"		/* dbm's database prefix */
X#define	VDIR	".vacation.dir"		/* dbm's DB prefix, part 1 */
X#define	VPAG	".vacation.pag"		/* dbm's DB prefix, part 2 */
X
Xtypedef struct alias {
X	struct alias *next;
X	char	*name;
X} ALIAS;
XALIAS	*names;
X
Xstatic char from[MAXLINE];		/* sender's address */
X
Xmain(argc, argv)
X	int argc;
X	char **argv;
X{
X	extern int optind;
X	extern char *optarg;
X	struct passwd *pw;
X	ALIAS *cur;
X	int ch, iflag;
X	char *malloc();
X	uid_t getuid();
X
X	iflag = 0;
X	while ((ch = getopt(argc, argv, "a:Ii")) != EOF)
X		switch((char)ch) {
X		case 'a':			/* alias */
X			if (!(cur = (ALIAS *)malloc((u_int)sizeof(ALIAS))))
X				break;
X			cur->name = optarg;
X			cur->next = names;
X			names = cur;
X			break;
X		case 'i':			/* init the database */
X		case 'I':			/* backward compatible */
X			iflag = 1;
X			break;
X		case '?':
X		default:
X			goto usage;
X		}
X	argc -= optind;
X	argv += optind;
X
X	if (argc != 1) {
X		if (!iflag) {
Xusage:			syslog(LOG_ERR, "uid %u: usage: vacation [-i] [-a alias] login\n", getuid());
X			exit(1);
X		}
X		if (!(pw = getpwuid(getuid()))) {
X			syslog(LOG_ERR, "vacation: no such user uid %u.\n", getuid());
X			exit(1);
X		}
X	}
X	else if (!(pw = getpwnam(*argv))) {
X		syslog(LOG_ERR, "vacation: no such user %s.\n", *argv);
X		exit(1);
X	}
X	if (chdir(pw->pw_dir)) {
X		syslog(LOG_ERR, "vacation: no such directory %s.\n", pw->pw_dir);
X		exit(1);
X	}
X
X	if (iflag) {
X		initialize();
X		exit(0);
X	}
X
X	if (!(cur = (ALIAS *)malloc((u_int)sizeof(ALIAS))))
X		exit(1);
X	cur->name = pw->pw_name;
X	cur->next = names;
X	names = cur;
X
X	readheaders();
X
X	if (access(VDIR, F_OK))
X		initialize();
X	else
X		dbminit(VACAT);
X
X	if (!recent()) {
X		setreply();
X		sendmessage(pw->pw_name);
X	}
X	exit(0);
X}
X
X/*
X * readheaders --
X *	read mail headers
X */
Xstatic
Xreadheaders()
X{
X	register ALIAS *cur;
X	register char *p;
X	int tome, cont;
X	char buf[MAXLINE], *strcpy(), *index();
X
X	cont = tome = 0;
X	while (fgets(buf, sizeof(buf), stdin) && *buf != '\n')
X		switch(*buf) {
X		case 'F':		/* "From " */
X			cont = 0;
X			if (!strncmp(buf, "From ", 5)) {
X				for (p = buf + 5; *p && *p != ' '; ++p);
X				*p = '\0';
X				(void)strcpy(from, buf + 5);
X				if (junkmail())
X					exit(0);
X			}
X			break;
X		case 'P':		/* "Precedence:" */
X			cont = 0;
X			if (strncasecmp(buf, "Precedence", 10) || buf[10] != ':' && buf[10] != ' ' && buf[10] != '\t')
X				break;
X			if (!(p = index(buf, ':')))
X				break;
X			while (*++p && isspace(*p));
X			if (!*p)
X				break;
X			if (!strncasecmp(p, "junk", 4) || !strncasecmp(p, "bulk", 4))
X				exit(0);
X			break;
X		case 'C':		/* "Cc:" */
X			if (strncmp(buf, "Cc:", 3))
X				break;
X			cont = 1;
X			goto findme;
X		case 'T':		/* "To:" */
X			if (strncmp(buf, "To:", 3))
X				break;
X			cont = 1;
X			goto findme;
X		default:
X			if (!isspace(*buf) || !cont || tome) {
X				cont = 0;
X				break;
X			}
Xfindme:			for (cur = names; !tome && cur; cur = cur->next)
X				tome += nsearch(cur->name, buf);
X		}
X	if (!tome)
X		exit(0);
X	if (!*from) {
X		syslog(LOG_ERR, "vacation: no initial \"From\" line.\n");
X		exit(1);
X	}
X}
X
X/*
X * nsearch --
X *	do a nice, slow, search of a string for a substring.
X */
Xstatic
Xnsearch(name, str)
X	register char *name, *str;
X{
X	register int len;
X
X	for (len = strlen(name); *str; ++str)
X		if (*str == *name && !strncasecmp(name, str, len))
X			return(1);
X	return(0);
X}
X
X/*
X * junkmail --
X *	read the header and return if automagic/junk/bulk mail
X */
Xstatic
Xjunkmail()
X{
X	static struct ignore {
X		char	*name;
X		int	len;
X	} ignore[] = {
X		"-REQUEST", 8,	"Postmaster", 10,
X		"uucp", 4,	"MAILER-DAEMON", 13,
X		"MAILER", 6,	NULL, NULL,
X	};
X	register struct ignore *cur;
X	register int len;
X	register char *p;
X	char *index(), *rindex();
X
X	/*
X	 * This is mildly amusing, and I'm not positive it's right; trying
X	 * to find the "real" name of the sender, assuming that addresses
X	 * will be some variant of:
X	 *
X	 * From site!site!SENDER%site.domain%site.domain@site.domain
X	 */
X	if (!(p = index(from, '%')))
X		if (!(p = index(from, '@'))) {
X			if (p = rindex(from, '!'))
X				++p;
X			else
X				p = from;
X			for (; *p; ++p);
X		}
X	len = p - from;
X	for (cur = ignore; cur->name; ++cur)
X		if (len >= cur->len && !strncasecmp(cur->name, p - cur->len, cur->len))
X			return(1);
X	return(0);
X}
X
Xtypedef struct {
X	char	*dptr;
X	int	dsize;
X} DATUM;
X
Xtypedef struct {
X	time_t	sentdate;
X} DBREC;
X
X/*
X * recent --
X *	find out if user has gotten a vacation message recently.
X */
Xstatic
Xrecent()
X{
X	DATUM k, d, fetch();
X	time_t now, then, time();
X
X	k.dptr = from;
X	k.dsize = strlen(from) + 1;
X	d = fetch(k);
X	if (d.dptr) {
X		/* be careful on machines with alignment restrictions */
X		bcopy((char *)&((DBREC *)d.dptr)->sentdate, (char *)&then, sizeof(then));
X		(void)time(&now);
X		if (!then || then + PERIOD > now)
X			return(1);
X	}
X	return(0);
X}
X
X/*
X * setreply --
X *	store that this user knows about the vacation.
X */
Xstatic
Xsetreply()
X{
X	DBREC xrec;
X	DATUM k, d;
X	time_t time();
X
X	k.dptr = from;
X	k.dsize = strlen(from) + 1;
X	(void)time(&xrec.sentdate);
X	d.dptr = (char *)&xrec;
X	d.dsize = sizeof(xrec);
X	store(k, d);
X}
X
X/*
X * sendmessage --
X *	exec sendmail to send the vacation file to sender
X */
Xstatic
Xsendmessage(myname)
X	char *myname;
X{
X	if (!freopen(VMSG, "r", stdin)) {
X		syslog(LOG_ERR, "vacation: no ~%s/%s file.\n", myname, VMSG);
X		exit(1);
X	}
X	execl("/usr/lib/sendmail", "sendmail", "-f", myname, from, NULL);
X	syslog(LOG_ERR, "vacation: can't exec /usr/lib/sendmail.\n");
X	exit(1);
X}
X
X/*
X * initialize --
X *	initialize the dbm database
X */
Xstatic
Xinitialize()
X{
X	extern int errno;
X	extern char *sys_errlist[];
X	int fd;
X
X	if ((fd = open(VDIR, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
X		syslog(LOG_ERR, "vacation: %s: %s\n", VDIR, sys_errlist[errno]);
X		exit(1);
X	}
X	(void)close(fd);
X	if ((fd = open(VPAG, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
X		syslog(LOG_ERR, "vacation: %s: %s\n", VPAG, sys_errlist[errno]);
X		exit(1);
X	}
X	(void)close(fd);
X	dbminit(VACAT);
X}
END-of-vacation.c
exit