SCCSID(@
(#)vacation.c 3.9 %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.
** For best operation, this program should run setuid to
** root or uucp or someone else that sendmail will believe
** a -f flag from. Otherwise, the user must be careful
** to include a header on his .vacation.msg file.
** Positional Parameters:
** the user to collect the vacation message from.
** -I initialize the database.
** -tT set the timeout to T. messages arriving more
** often than T will be ignored to avoid loops.
** A message is sent back to the sender.
# define MAXLINE 256 /* max size of a line */
# define MAXNAME 128 /* max size of one name */
# 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 */
case 't': /* set timeout */
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) */
/* check if this person is already informed */
/* mark this person as knowing */
/* send the message back */
(void) strcpy(buf
, homedir
);
(void) strcat(buf
, "/.vacation.msg");
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
];
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 */
p
= index(&line
[5], ' ');
usrerr("Funny From line '%s'", line
);
/* return the sender address */
** 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;
if (d
.dptr
== NULL
|| ((struct dbrec
*) d
.dptr
)->sentdate
+ Timeout
< now
)
** 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(strlen(s
) + 1);
syserr("newstr: cannot alloc memory");