* Copyright (c) 1983, 1987 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1983, 1987 Regents of the University of California.\n\
static char sccsid
[] = "@(#)vacation.c 5.13 (Berkeley) %G%";
** 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 500 /* max line from mail header */
#define VMSG ".vacation.msg" /* vacation message */
#define VACAT ".vacation" /* dbm's database prefix */
#define VDIR ".vacation.dir" /* dbm's DB prefix, part 1 */
#define VPAG ".vacation.pag" /* dbm's DB prefix, part 2 */
#define VIT "__VACATION__INTERVAL__TIMER__"
static char from
[MAXLINE
];
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
;
usage
: syslog(LOG_NOTICE
, "uid %u: usage: vacation [-i] [-a alias] login\n", getuid());
if (!(pw
= getpwuid(getuid()))) {
syslog(LOG_ERR
, "vacation: no such user uid %u.\n", getuid());
else if (!(pw
= getpwnam(*argv
))) {
syslog(LOG_ERR
, "vacation: no such user %s.\n", *argv
);
syslog(LOG_NOTICE
, "vacation: no such directory %s.\n", pw
->pw_dir
);
if (iflag
|| access(VDIR
, F_OK
))
if (!(db
= dbm_open(VACAT
, O_RDWR
, 0))) {
syslog(LOG_NOTICE
, "vacation: %s: %s\n", VACAT
,
if (!(cur
= (ALIAS
*)malloc((u_int
)sizeof(ALIAS
))))
sendmessage(pw
->pw_name
);
char buf
[MAXLINE
], *strcpy(), *index();
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");
* 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
;
char *index(), *rindex();
* 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
)
if (len
>= cur
->len
&& !strncasecmp(cur
->name
, p
- cur
->len
, cur
->len
))
* find out if user has gotten a vacation message recently.
* use bcopy for machines with alignment restrictions
time_t then
, next
, time();
bcopy(d
.dptr
, (char *)&ldbrec
, sizeof ldbrec
); /* realign data */
return ldbrec
.sentdate
+ Timeout
>= time((time_t *)0);
register char *to
, *from
;
* store the reply interval
key
.dsize
= sizeof(VIT
) - 1;
data
.dptr
= (char *)&interval
;
data
.dsize
= sizeof(interval
);
dbm_store(db
, key
, data
, DBM_REPLACE
);
* store that this user knows about the vacation.
key
.dsize
= strlen(from
);
data
.dptr
= (char *)&now
;
data
.dsize
= sizeof(now
);
dbm_store(db
, key
, data
, DBM_REPLACE
);
* 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("/usr/lib/sendmail", "sendmail", "-f", myname
, from
, NULL
);
syslog(LOG_ERR
, "vacation: can't exec /usr/lib/sendmail.\n");
* initialize the dbm database
if ((fd
= open(VDIR
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644)) < 0) {
syslog(LOG_NOTICE
, "vacation: %s: %s\n", VDIR
, strerror(errno
));
if ((fd
= open(VPAG
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0644)) < 0) {
syslog(LOG_NOTICE
, "vacation: %s: %s\n", VPAG
, strerror(errno
));