From: support@jfdi.demon.co.uk (DSS Unix Support)
To: libes@cme.nist.gov
Subject: Re: Pager software
Date: Mon, 27 Mar 95 12:16:39 GMT

Don, here's the beast, Perl, Expect and some sample data files.

                                     .oOo.

The package (maybe that's *too* strong a word!) we use is a mixture of
Perl, TCL and expect. All 3 are available in source form from the ftp
sites. Expect is a TCL application package.

Here's the software that we use for autopaging (tried tpage and had
problems - re-inventing the wheel was easier!).

There's 4 files here :

	1. autopage
	   The Perl script called from our overnight batch when something
	   goes wrong. It sorts out who to call, messages, phone numbers
	   etc.

	2. autopage.dial
	   An expect script which catually handles the modem.

	3. mercury
	   The config file holding details of Mercury Communications (the
	   pager service provider) - read by autopage.

	4. sysadmin
	   The config file for one of the pager groups - defines pager group
	   numbers and messages.

Hope this helps.

Regards,

Paul

============================================================================
1.	autopage
----------------------------------------------------------------------------
#!/usr/local/bin/perl
#==================================================================
# Copyright:     CWS Ltd
# Name:          autopage
# Author:        Paul Wilson
# Date:          13 February 1995
# Description:
#	This is designed to automatically page someone. It gets
#	called from the batch jobs or the sysadmin jobs, and gets
#	given 2 or 3 parameters (explained below.
# Parameters:
#	1. Group/individual to page
#	2. Message key
#	3. Additional information [ optional ]
# Maintenance:
#	cc140 Paul  Re-write the autopager in Perl
#==================================================================

require "cws.pl";

&init;
$msg = "Autopager invoked for " . $who;
&logmsg ($msg);


&readmercury;
&getmessage;
&sendmessage;
&closedown;

#=============================================================
#---------->CLOSEDOWN
# Tidy up and finish
#
sub closedown
{
	local ($msg) = "Paging successful";

	&logmsg ($msg);
}

#---------->GETMESSAGE
# Get the message from the file. In case the specified message key
# doesn't exist, look for "msg=";
#
sub getmessage
{
	local ($key) = $mkey;
	local ($fname) = $pagedir . $who;
	local ($err) = 0;
	local ($msg, $pmsg1, $pmsg2);

	unless (-f $fname)
	{
		$msg = "Pager file " . $who . " doesn't exist";
		&logmsg ($msg);
		exit 1;
	}

	$pagerno = "%";
	$pmsg1 = "%";
	$pmsg2 = "%";

	open (PF, "<$fname");
	while (<PF>)
	{
		next if (/^#/);
		chop;
		($key, $data) = split (/=/, $_);
		$pagerno = $data, next  if ($key =~ /^pager/);
		$pmsg1   = $data, next  if ($key =~ /^$mkey/);
		$pmsg2   = $data, next  if ($key =~ /^msg/);
	}
	close PF;

	if ($pagerno =~ /%/)
	{
		$msg = "Pager number not found";
		&logmsg ($msg);
		$err = 1;
	}
	if ($pmsg1 =~ /%/)
	{
		if ($pmsg2 =~ /%/)
		{
			$msg = "Can't locate specified message key or default";
			&logmsg ($msg);
			$err = 1;
		}
		else
		{
			$msg = "Message key " . $mkey .
			       " not found, using 'msg'";
			&logmsg ($msg);
			$pmsg1 = $pmsg2;
		}
	}
	if ($err == 0)
	{
		$message = $pmsg1;
	}
	else
	{
		$msg = "One or more errors found, aborting";
		&logmsg ($msg);
		exit 1;
	}
}

#---------->INIT
# Initialisation
#
sub init
{
	$[ = 0;

	$sysjob = "(autopage)";
	if ($#ARGV < 1  ||  $#ARGV > 2)
	{
		local ($msg);
		
		$msg = "Invalid argument count (" . sprintf ("%d", $#ARGV) .
		       ")";
		&logmsg ($msg);
		exit;
	}
	$who  = $ARGV [0];
	$mkey = $ARGV [1];
	$xtra = ($#ARGV == 2) ? $ARGV [2] : "";

	$pagedir = "/support/data/paging/";
	$tmpfile1 = "/tmp/tmp.auto.1";
}

#---------->READMERCURY
# Get the Mercury information from the file
#
sub readmercury
{
	local ($fname) = $pagedir . "mercury";
	local ($err) = 0;
	local ($msg, $key, $data);

	unless (-f $fname)
	{
		$msg = "Mercury data doesn't exist";
		&logmsg ($msg);
		exit 1;
	}

	$phone     = "%";
	$alternate = "%";
	$user      = "%";
	$password  = "%";
	$modeminit = "%";
	$modemhup  = "%";

	open (MD, "<$fname");
	while (<MD>)
	{
		next if (/^#/);
		chop;
		($key, $data) = split (/=/, $_);
		$phone     = $data, next  if ($key =~ /^phone/);
		$alternate = $data, next  if ($key =~ /^alternate/);
		$user      = $data, next  if ($key =~ /^user/);
		$password  = $data, next  if ($key =~ /^password/);
		($key, $data) = split (/:/, $_);
		$modeminit = $data, next  if ($key =~ /^modeminit/);
		$modemhup  = $data, next  if ($key =~ /^modemhup/);
	}
	close MD;

# Check that all the data was read from the file

	if ($phone =~ /%/)
	{
		$msg = "Mercury phone number not found";
		&logmsg ($msg);
		$err = 1;
	}
	if ($user =~ /%/)
	{
		$msg = "Mercury user name not found";
		&logmsg ($msg);
		$err = 1;
	}
	if ($password =~ /%/)
	{
		$msg = "Mercury password not found";
		&logmsg ($msg);
		$err = 1;
	}
	if ($modeminit =~ /%/)
	{
		$msg = "Mercury modeminit not found";
		&logmsg ($msg);
		$err = 1;
	}
	if ($modemhup =~ /%/)
	{
		$msg = "Mercury modemhup not found";
		&logmsg ($msg);
		$err = 1;
	}
	if ($err != 0)
	{
		$msg = "One or more errors found, aborting";
		&logmsg ($msg);
		exit 1;
	}
}

#---------->SENDMESSAGE
# Tidy up and finish
#
sub sendmessage
{
	local ($msg);
	local (@command);

	@command = ("/support/bin/autopage.dial", $phone, $user,
		    $password, $pagerno, $message . " - " . $xtra);
	system @command;
	return if ($? == 0);

	$msg = $phone . " failed, trying alternate";
	&logmsg ($msg);

	if ($alternate =~ /%/)
	{
		$msg = $phone . " failed - no alternate";
		&logmsg ($msg);
	}
	else
	{
		@command = ("/support/bin/autopage.dial", $phone, $user,
			    $password, $pagerno, $message . " - " . $xtra);
		system @command;
		return if ($? == 0);

		$msg = $alternate . " failed, message discarded";
		&logmsg ($msg);
	}
	exit 1;
}
----------------------------------------------------------------------------
2.	autopage.dial
----------------------------------------------------------------------------
#!/usr/local/bin/expect
#####################################################################
# Copyright   : CWS Ltd.
# Name	      : pager.exp
# Author      : Steve Hart  CWS Ltd.
# Date	      : 08-Feb-1995
# Description : Autopager expect script
#
# Maintenance :
#
#####################################################################



###########################
# Spawn the cu process
###########################
proc StartCU {} {
   global spawn_id
   spawn cu -s2400 -lcul0p6 -m dir
   expect {
          "Connected" {} 
           timeout    {puts "unexpected error starting cu" ;exit 1}
          }
}
###########################
# Initialize modem
###########################
proc InitModem {} {
#  send   "atz\r"
   send   "at e1 q v1\r"
   expect {
          "OK"        {} 
           timeout    {puts "error initializing modem" ;exit 1}
          }
}

###########################
# Dial pager service
###########################
proc DialOut {Phone} {
   set timeout 30
   send "atdt $Phone\r"
   expect "OK"
   expect {
          "CONNECT*"   {} 
          "NO CARRIER" {puts "no carrier"               ;exit 1}
          "BUSY*"      {puts "phone number busy"        ;exit 1}
           timeout     {puts "error dialling $Phone"    ;exit 1}
          }
}

###########################
# enter 4 returns
###########################
proc AwaitUser {} {
   set timeout 30
   send   "\r\r\r\r\r" 
   expect "ENTER USER*"
}

###########################
# Pass user and password
###########################
proc UserName {User PassWd} {
   set timeout 30
   send   "$User.$PassWd,,page\r"
   expect {
          "WELCOME*"      {}
           timeout        {puts "timeout waiting for welcome screen"    ;exit 1}
          }
}

###########################
# Pager number
###########################
proc PageNo {Pager} {
   set timeout 30
   send   "$Pager\r"
   expect "240 CHAR*"
}

###########################
#
###########################
proc SendMess {Message Pager} {
   set timeout 30
   send   "$Message\r"
   expect {
          "PAGE ACCEPTED" {puts "message to $Pager accepted"}
          "INACTIVE*"    {puts "error pager $Pager is invalid }
           timeout        {puts "error paging $Pager"    ;exit 1}
          }
}
###########################
#
###########################
proc GoodBye {} {
   set timeout 30
   expect "ENTER THE *"
   send   "bye\r"
   expect {
          "DISCONNECTED*" {}
           timeout        {puts "error disconnecting";exit 0}
          }
}
###########################
# Send hangup to modem
###########################
proc HangIt {} {
   set timeout 30
   send   "ath\r"
   expect "OK"
}



   set argc [llength $argv]
   if {$argc < 5} {
      puts "usage :$argv0 (phone No) (user id) (password) (pager) (message)"
      exit 1
      }

   set Phone   [lindex $argv 0]
   set User    [lindex $argv 1]
   set PassWd  [lindex $argv 2]
   set Pager   [lindex $argv 3]
   set Message [lindex $argv 4]
   global timeout
   set timeout 5

   log_user 0

   puts "Starting cu - parameters $Phone $User $PassWd $Pager $Message"
   StartCU
   InitModem
   DialOut  $Phone
   AwaitUser
   UserName $User $PassWd

   foreach SPager [split $Pager "-"] {
      PageNo   $SPager
      SendMess $Message $SPager
   }

   GoodBye
   HangIt


close
----------------------------------------------------------------------------
3.	mercury
----------------------------------------------------------------------------
#-------------------------------------------------------------
#	This file holds the details of the mercury paging service.
#	The keywords are all mandatory, and are (in lower case) :-
#
#		phone=
#		alternate=
#		user=
#		password=
#		modeminit:
#		modemhup:
#
#	Note that the keywords for the modem control strings use a
#	colon rather than equals -- this is deliberate.
#-------------------------------------------------------------
#
#-->main phone number
#
phone=9,0619530240
#
#-->alternate number
#
alternate=9,0914010100
#
#-->user name
#
user=****
#
#-->Password
#
password=****
#
#-->Modem initialisation string (note the colon!)
#
modeminit:atzs0=0s7=45v1f5
#
#-->Modem hangup string (note the colon!)
#
modemhup:ATH0
#
----------------------------------------------------------------------------
4.	sysadmin
----------------------------------------------------------------------------
#-------------------------------------------------------------
# This is a data file which holds enough information to page someone -
# either an individual or a group.
#
# Comments (lines that start with '#') are ignored.
#
# There are 2 keywords which must be present, and must be in lower
# case (the order isn't relevant) :-
#
#	pager=<pager number>
#	msg=<message to be sent>
#
# Additional messages can be built in using a similar approach
# (i.e. <message id>=<message string>
#
#-------------------------------------------------------------
#
# -- First the pager number ..
#
#pager=815499
pager=815503-815510-847839
#
# -- Now the messages (each on a single line)
#
msg=Undetermined PSM error message
#
tokenring=token ring connection from gold has failed
#
shark=CPF machine isn't responding
#
amber=CSE machine isn't responding
#
dali=Dev Aviion isn't responding
#
localhost=localhost for gold doesn't respond
#
bridge=PSM bridge doesn't respond
#
codeserv=PSM code server doesn't respond
#
router=IP router won't respond
#
print=print server doesn't respond
#
orphan=Oracle orphans
#
testmsg=Autopager test message
#
============================================================================
-- 
Paul Wilson
CWS Unix Support
