* Copyright (c) 1983, 1987 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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
"@(#) Copyright (c) 1983, 1987 Regents of the University of California.\n\
static char sccsid
[] = "@(#)vacation.c 5.19 (Berkeley) 3/23/91";
** Copyright (c) 1983 Eric P. Allman
* 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
#define MAXLINE 1024 /* max line from mail header */
#define VDB ".vacation.db" /* dbm's database */
#define VMSG ".vacation.msg" /* vacation message */
extern int optind
, opterr
;
while ((ch
= getopt(argc
, argv
, "a:Iir:")) != EOF
)
if (!(cur
= (ALIAS
*)malloc((u_int
)sizeof(ALIAS
))))
case 'I': /* backward compatible */
case 'i': /* init the database */
interval
= atol(optarg
) * SECSPERDAY
;
if (!(pw
= getpwuid(getuid()))) {
"vacation: no such user uid %u.\n", getuid());
else if (!(pw
= getpwnam(*argv
))) {
syslog(LOG_ERR
, "vacation: no such user %s.\n", *argv
);
"vacation: no such directory %s.\n", pw
->pw_dir
);
db
= hash_open(VDB
, O_CREAT
|O_RDWR
| (iflag
? O_TRUNC
: 0),
S_IRUSR
|S_IWUSR
, (HASHINFO
*)NULL
);
syslog(LOG_NOTICE
, "vacation: %s: %s\n", VDB
, strerror(errno
));
if (!(cur
= malloc((u_int
)sizeof(ALIAS
))))
sendmessage(pw
->pw_name
);
while (fgets(buf
, sizeof(buf
), stdin
) && *buf
!= '\n')
if (!strncmp(buf
, "From ", 5)) {
for (p
= buf
+ 5; *p
&& *p
!= ' '; ++p
);
(void)strcpy(from
, buf
+ 5);
if (p
= index(from
, '\n'))
case 'P': /* "Precedence:" */
if (strncasecmp(buf
, "Precedence", 10) ||
buf
[10] != ':' && buf
[10] != ' ' && buf
[10] != '\t')
if (!(p
= index(buf
, ':')))
while (*++p
&& isspace(*p
));
if (!strncasecmp(p
, "junk", 4) ||
!strncasecmp(p
, "bulk", 4))
if (strncmp(buf
, "Cc:", 3))
if (strncmp(buf
, "To:", 3))
if (!isspace(*buf
) || !cont
|| tome
) {
findme
: for (cur
= names
; !tome
&& cur
; cur
= cur
->next
)
tome
+= nsearch(cur
->name
, buf
);
syslog(LOG_NOTICE
, "vacation: no initial \"From\" line.\n");
* do a nice, slow, search of a string for a substring.
register char *name
, *str
;
for (len
= strlen(name
); *str
; ++str
)
if (*str
== *name
&& !strncasecmp(name
, str
, len
))
* read the header and return if automagic/junk/bulk mail
"-request", 8, "postmaster", 10, "uucp", 4,
"mailer-daemon", 13, "mailer", 6, "-relay", 6,
register struct ignore
*cur
;
* 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
, '!'))
for (cur
= ignore
; cur
->name
; ++cur
)
!strncasecmp(cur
->name
, p
- cur
->len
, cur
->len
))
#define VIT "__VACATION__INTERVAL__TIMER__"
* find out if user has gotten a vacation message recently.
* use bcopy for machines with alignment restrictions
if ((db
->get
)(db
, &key
, &data
, 0))
next
= SECSPERDAY
* DAYSPERWEEK
;
bcopy(data
.data
, &next
, sizeof(next
));
/* get record for this address */
if (!(db
->get
)(db
, &key
, &data
, 0)) {
bcopy(data
.data
, &then
, sizeof(then
));
if (next
== LONG_MAX
|| then
+ next
> time(NULL
))
* store the reply interval
data
.size
= sizeof(interval
);
(void)(db
->put
)(db
, &key
, &data
, R_PUT
);
* store that this user knows about the vacation.
(void)(db
->put
)(db
, &key
, &data
, R_PUT
);
* exec sendmail to send the vacation file to sender
if (!freopen(VMSG
, "r", stdin
)) {
syslog(LOG_NOTICE
, "vacation: no ~%s/%s file.\n", myname
, VMSG
);
execl(_PATH_SENDMAIL
, "sendmail", "-f", myname
, from
, NULL
);
syslog(LOG_ERR
, "vacation: can't exec %s.\n", _PATH_SENDMAIL
);
syslog(LOG_NOTICE
, "uid %u: usage: vacation [-i] [-a alias] login\n",