** Copyright (c) 1983 Eric P. Allman
** Copyright (c) 1983 Regents of the University of California.
** All rights reserved. The Berkeley software License Agreement
** specifies the terms and conditions for redistribution.
static char SccsId
[] = "@(#)vacation.c 4.1.1.1 (Berkeley) %G%";
** VACATION -- return a message to the sender when on vacation.
** This program could be invoked as a message receiver
** when someone is on vacation. It returns a message
** specified by the user to whoever sent the mail, taking
** care not to return a message too often to prevent
** "I am on vacation" loops.
** Positional Parameters:
** the user to collect the vacation message from.
** -I initialize the database.
** A message is sent back to the sender.
# define MAXLINE 256 /* max size of a line */
# define ONEWEEK (60L*60L*24L*7L)
time_t Timeout
= ONEWEEK
; /* timeout between notices per user */
extern struct passwd
*getpwnam();
extern time_t convtime();
while (--argc
> 0 && (p
= *++argv
) != NULL
&& *p
== '-')
case 'I': /* initialize */
usrerr("Unknown flag -%s", p
);
/* verify recipient argument */
usrerr("Usage: vacation username (or) vacation -I");
/* find user's home directory */
usrerr("Unknown user %s", myname
);
homedir
= newstr(pw
->pw_dir
);
(void) strcpy(buf
, homedir
);
(void) strcat(buf
, "/.vacation");
/* read message from standard input (just from line) */
from
= getfrom(&shortfrom
);
printf("from='%s'\nshortfrom='%s'\n", from
, shortfrom
);
/* check if junk mail or this person is already informed */
if (!junkmail(from
) && !knows(from
))
/* mark this person as knowing */
/* send the message back */
(void) strcpy(buf
, homedir
);
(void) strcat(buf
, "/.vacation.msg");
printf("Sending %s to %s\n", buf
, from
);
sendmessage(buf
, from
, myname
);
** GETFROM -- read message from standard input and return sender
** pointer to the sender address.
** Reads first line from standard input.
static char line
[MAXLINE
];
register char *p
, *start
, *at
, *bang
;
if (fgets(line
, sizeof line
, stdin
) == NULL
||
strncmp(line
, "From ", 5) != NULL
)
usrerr("No initial From line");
/* find the end of the sender address and terminate it */
usrerr("Funny From line '%s'", line
);
* Strip all but the rightmost UUCP host
* to prevent loops due to forwarding.
* Start searching leftward from the leftmost '@'.
* a!b!c!d yields a short name of c!d
* a!b!c!d@e yields a short name of c!d@e
* e@a!b!c yields the same short name
printf("start='%s'\n", start
);
*shortp
= start
; /* assume whole addr */
if ((at
= index(start
, '@')) == NULL
) /* leftmost '@' */
at
= p
; /* if none, use end of addr */
if ((bang
= rindex(start
, '!')) != NULL
) { /* rightmost '!' */
if ((bang2
= rindex(start
, '!')) != NULL
) /* 2nd rightmost '!' */
*shortp
= bang2
+ 1; /* move past ! */
printf("place='%s'\n", *shortp
);
/* return the sender address */
** JUNKMAIL -- read the header and tell us if this is junk/bulk mail.
** from -- the Return-Path of the sender. We assume that
** anything from "*-REQUEST@*" is bulk mail.
** TRUE -- if this is junk or bulk mail (that is, if the
** sender shouldn't receive a response).
** FALSE -- if the sender deserves a response.
** May read the header from standard input. When this
** returns the position on stdin is undefined.
/* test for inhuman sender */
if (sameword(&p
[-8], "-REQUEST") ||
sameword(&p
[-10], "Postmaster") ||
sameword(&p
[-13], "MAILER-DAEMON"))
/* read the header looking for a "Precedence:" line */
while (fgets(buf
, MAXLINE
, stdin
) != NULL
&& buf
[0] != '\n')
/* should ignore case, but this is reasonably safe */
if (strncmp(buf
, "Precedence", 10) != 0 ||
!(buf
[10] == ':' || buf
[10] == ' ' || buf
[10] == '\t'))
/* find the value of this field */
while (*++p
!= '\0' && isspace(*p
))
/* see if it is "junk" or "bulk" */
if (sameword(p
, "junk") || sameword(p
, "bulk"))
** KNOWS -- predicate telling if user has already been informed.
** user -- the user who sent this message.
** TRUE if 'user' has already been informed that the
** recipient is on vacation.
k
.dsize
= strlen(user
) + 1;
bcopy(d
.dptr
, (char *)&ldbrec
, sizeof ldbrec
); /* realign data */
return ldbrec
.sentdate
+ Timeout
>= time((time_t *)0);
register char *to
, *from
;
** SETKNOWS -- set that this user knows about the vacation.
** user -- the user who should be marked.
** The dbm file is updated as appropriate.
k
.dsize
= strlen(user
) + 1;
** SENDMESSAGE -- send a message to a particular user.
** msgf -- filename containing the message.
** user -- user who should receive it.
** sends mail to 'user' using /usr/lib/sendmail.
sendmessage(msgf
, user
, myname
)
/* find the message to send */
f
= freopen(msgf
, "r", stdin
);
f
= freopen("/usr/lib/vacation.def", "r", stdin
);
syserr("No message to send");
execl("/usr/lib/sendmail", "sendmail", "-f", myname
, user
, NULL
);
syserr("Cannot exec /usr/lib/sendmail");
** INITIALIZE -- initialize the database before leaving for vacation
** Initializes the files .vacation.{pag,dir} in the
** caller's home directory.
homedir
= getenv("HOME");
(void) strcpy(buf
, homedir
);
(void) strcat(buf
, "/.vacation.dir");
if (close(creat(buf
, 0644)) < 0)
syserr("Cannot create %s", buf
);
(void) strcpy(buf
, homedir
);
(void) strcat(buf
, "/.vacation.pag");
if (close(creat(buf
, 0644)) < 0)
syserr("Cannot create %s", buf
);
** USRERR -- print user error
fprintf(stderr
, "vacation: ");
** SYSERR -- print system error
fprintf(stderr
, "vacation: ");
** NEWSTR -- copy a string
** s -- the string to copy.
p
= malloc((unsigned)strlen(s
) + 1);
syserr("newstr: cannot alloc memory");
** SAMEWORD -- return TRUE if the words are the same
** a, b -- the words to compare.
** TRUE if a & b match exactly (modulo case)
if (isascii(ca
) && isupper(ca
))
if (isascii(cb
) && isupper(cb
))
} while (ca
!= '\0' && ca
== cb
);