pager
#!/usr/local/bin/perl5 -w
#
# pager
#
# Page somebody when they have e-mail.
#
# Put this into your cron script running at times that you
# are willing to receive pages.
#
# Configuration
$User = "joe.cool";
$Phone = "555 1212";
$TTY = "ttyS3";
$Port = "/dev/$TTY";
$Lock = "/usr/spool/uucp/LCK..$TTY";
# See if he has mail to read
chdir("/users1/$User");
print scalar(localtime()), "\n";
# Perl has a number of operators which test various
# attributes of files. This is very useful for automated
# tasks. You can check for the existence of files (-e),
# if the file is zero length (-z), the modification date
# of a file (-M), as well as file ownership, if the file
# is a directory or regular file, as well as about any
# attribute about a file. These tests don't deal
# with the contents of the file, just the "meta"
# information.
exit 0 if (! -e "/usr/spool/mail/$User" ||
-z "/usr/spool/mail/$User");
# There is mail.
# Only page if we haven't paged since the last time we logged in.
if (-f ".paged")
{
# The -M returns the age of the file in days since the
# file was last modified. Note that this number is
# typically not an integer. This bit of code attempts
# to page the recipient when they get new mail since the
# last time they logged in (and presumably read their mail),
# but also repeat the page periodically in case they are
# out of range of the paging site.
if (-M ".paged" < 0.1666)
{
exit 0 if (-M ".paged" < -M ".lastlogin");
}
}
# There is mail, and he doesn't know about it yet.
# Time to page him
# Get the lock file.
# The following ugly code deals with lock files which in
# this case Unix systems use to keep multiple programs
# from interfering with each other getting to the modem.
die "Can't get lock file" if -e $Lock;
open(LOCK,"+>$Lock") || die "Can't get lock file: $!";
# The "$$" variable is the current process ID which gets
# written into the lock file.
printf(LOCK "%10d\n", $$);
close(LOCK);
# Perl lets the programmer catch certain signals. In this case
# I want the Perl script to give up the modem after a short period
# of time, even if something unexpected goes wrong. So I set an
# alarm to go off in 60 seconds, and tell Perl if the timer goes
# off to call the death subroutine.
alarm 60; # Panic timer
$SIG{'ALRM'} = &death;
$SIG{'INT'} = &death;
# The other examples so far deal with only the console. In this
# example we needed to get to various files such as the lock
# file and the modem. The open function is used to describe
# which file to use. The line containing the select function
# is used to ensure that characters written to the modem go out
# immediately instead of waiting for a complete line or buffer of
# text. This is important for interactive devices, and not needed
# for disk files.
open(TTY, "+>$Port") || die "Can't open modem";
select(TTY); $| = 1; select(STDOUT); $| = 1;
# The following commands talk to the modem while putting in
# pauses to let the modem and phone system respond as needed.
print "Send the paging\n";
sleep 1;
print TTY "\r";
sleep 1;
print TTY "atz\r";
sleep 4;
print "Dial string is: atm0dt$Phone,,,,,,,,,,*39\n\n";
print TTY "atm0dt$Phone,,*39#\r";
sleep 10;
print TTY "\r";
print TTY "atz\r";
# Release the lock file
`touch .paged`;
death();
###
### Death does the clean up processing
###
# Subroutines are declared like this. This particular subroutine
# does not take parameters. In another example we will show how
# parameters are handled. The other thing of note is that all
# variables are global variables unless you use the local
# statement. More on that later as well.
sub death
{
print TTY "\ratz\r";
close(TTY);
unlink($Lock);
exit(0);
}