home *** CD-ROM | disk | FTP | other *** search
- #! /usr/local/bin/perl4.019
-
- # tpaged -- back-end to tpage system.
- # by Tom Limoncelli, tal@warren.mentorg.com
- # Copyright (c) 1992, Tom Limoncelli
- # The sources can be freely copied for non-commercial use only
- # and only if they are unmodified.
-
- # Version 1.0 -- See file HISTORY for details.
-
- ####################################################################
- #
- # Parameters that the user can set:
- #
- ####################################################################
-
- $debug = 0;
- $QUEUE_DIR = '/home/adm/lib/tpage/pqueue/'; # same as in tpage.pl
- $IXOCICO = '/home/tal/work/beep2/ixocico'; # where is ixocico?
- $MAIL = '/usr/ucb/mail'; # which mail to use?
-
- # list of devices to rotate through.
- @DEVICES = ( "/dev/ttyz4" ); # currently they are all spoken
- # to at the same speed and same parameters. Some day I'll set up
- # a modemtab system, but I don't think more than one modem is
- # really needed for this system.
-
- # amount of time to sleep between scans
- $SLEEP_TIME = 30;
-
- ####################################################################
- # QUEUE FILES FORMAT:
- #
- # Files in the queue have the name of the format in the
- # first line. Currently there is only one format and it
- # is named "A". The first line marks it as the "A" format.
- # a subroutine called read_format_A reads this format. Other
- # formats can be written (see comments by read_format_A)
- #
- # The "A" format:
- # line contents
- # 1: A\n
- # 2: number to dial\n
- # 3: pin\n
- # 4: entire message\n
- # 5: X\n
-
- # read_format_* -- modules that read various data formats.
- # Currently implemented: The "A" format.
- # do_proto_* -- modules that do various beeper protocols.
- # Currently implmented: the ixo protocol.
- # Future protocols: numeric-only pagers.
-
- ####################################################################
- # Here's the actual program
-
- # define some globals
-
- local(%ixo_dial);
- local(%protocols);
-
- while (1) {
- local ($first,$allfiles);
-
- # We could scoop up all the files and process them, but chances
- # are if one file is found, more are on the way. So, instead
- # we scoop, if any are found we sleep 5 seconds and re-scoop.
- while (1) {
- opendir(QDIR, $QUEUE_DIR) || die "$0: Can't open $QUEUE_DIR: $!";
- @allfiles = grep( !/^\./, readdir(QDIR) );
- closedir(QDIR);
-
- if ($#allfiles!=-1) { # files? take 5 and then process.
- sleep 5;
- last;
- } else { # no files? hibernate.
- sleep $SLEEP_TIME;
- next;
- }
- }
-
- print "DEBUG: allfiles= ", join(' ', @allfiles), "\n" if $debug;
- opendir(QDIR, $QUEUE_DIR) || die "$0: Can't open $QUEUE_DIR: $!";
- @allfiles = grep( !/^\./, readdir(QDIR) );
- closedir(QDIR);
- print "DEBUG: allfiles= ", join(' ', @allfiles), "\n" if $debug;
-
- foreach $file (@allfiles) {
- print "DEBUG: Doing $file\n" if $debug;
- open(DATA, "<" . $QUEUE_DIR . $file) || print "Can't open $file: $!";
- chop( $first = <DATA> );
- print "DEBUG: first=$first\n" if $debug;
- eval "do read_format_$first();";
- }
-
- foreach $proto (sort keys %protocol) {
- next unless $protocol{ $proto };
- eval "do do_protocol_$proto();";
- $protocol{ $proto } = 0;
- sleep $SLEEP_TIME;
- }
- }
-
- # Each read_format_ must:
- # read from <DATA> and then close(DATA).
- # %protocol{ protocol name } = 1 (for the protocol to use)
- # and stuff the right data into the right variables for that protocol
- # to use.
-
- sub read_format_A
- {
- local($dial,$pin,$error,$mess,$X);
- print "DEBUG: reading format A\n" if $debug;
- chop( $dial = <DATA> );
- chop( $pin = <DATA> );
- chop( $error = <DATA> );
- chop( $mess = <DATA> );
- chop( $X = <DATA> );
-
- return if $X ne "X"; # file isn't in correct format or isn't done.
- return if $dial eq "";
- return if $pin eq "";
- return if $mess eq "";
-
- $protocol{ 'ixo' } = 1;
- $ixo_dial{ $dial } = 1;
- eval "unshift(@ixo_${dial}_pin, \$pin)";
- eval "unshift(@ixo_${dial}_error, \$error)";
- eval "unshift(@ixo_${dial}_mess, \$mess)";
- eval "unshift(@ixo_${dial}_file, \$file)";
- }
-
- # Each do_protocol_ must:
- # delete files out of the queue that are successful.
- # delete files out of the queue that are aged.
- # clean up so that the routine can be called again.
-
- sub do_protocol_ixo {
- print "DEBUG: doing protocol IXO\n" if $debug;
- # local($pin, $error, $mess, $file, $cmd, $empty);
- local($pin, $error, $mess, $file, $cmd);
- # $empty = 1;
- # build the temp file and the command line
- local($tmpfile) = "/tmp/tpaged.$$";
- foreach $dial (keys %ixo_dial) {
- next unless $ixo_dial{ $dial };
- print "DEBUG: Number to dial is $dial\n" if $debug;
- open(IX, ">$tmpfile" ) || die "$0: Can't create $tmpfile: $!";
- foreach (eval "@ixo_${dial}_pin") {
- print IX eval "pop(@ixo_${dial}_pin )", "\n";
- print IX eval "pop(@ixo_${dial}_mess)", "\n";
- unshift(@ixo_list, eval "pop(@ixo_${dial}_error)" );
- unshift(@ixo_list, eval "pop(@ixo_${dial}_file )" );
- # $empty = 0;
- }
- close IX;
- print "DEBUG: ", ($#ixo_list) / 2, " messages to send.\n" if $debug;
- # if ($empty) {
- # print "DEBUG: nothing to do!\n" if $debug;
- # unlink $tmpfile;
- # return;
- # }
- $cmd = $IXOCICO . " <" . $tmpfile . " "
- . push(@DEVICES, shift @DEVICES) . " " . $dial;
- print "DEBUG: About to execute: $cmd\n" if $debug;
- open(IX, $cmd . "|") || die "$0: Can't execute ixocico: $!";
- $mesgnum = 0; # count the messages as they're processed
- $success = 0;
- # get to the next message (same as #MESOK)
- $error = pop(@ixo_list);
- $file = pop(@ixo_list);
- print "DEBUG: ERROR=$error; FILE=$file\n" if $debug;
- while (<IX>) {
- print if $debug;
- next unless /^#/;
-
- print unless $debug;
-
- /^#WRONGARGS / &&
- die("$0: Major program bug: $!");
- /^#NOCONN / && do {
- printf("$0: Nobody answered the phone!\n") if $debug;
- last;
- };
- /^#UNKNOWNPROTO / && do {
- print "$0: Uhhh, are you sure that's a pager service?\n" if $debug;
- last;
- };
- /^\#MESOK (\d) / && do {
- print "DEBUG: message $1 done.\n" if $debug;
- if ($1 == $mesgnum++) {
- print "DEBUG: unlinking " . $QUEUE_DIR . $file . "\n" if $debug;
- unlink $QUEUE_DIR . $file;
- # get to the next message (same as #MESREJECT)
- $error = pop(@ixo_list);
- $file = pop(@ixo_list);
- print "DEBUG: ERROR=$error; FILE=$file\n" if $debug;
- } else {
- print "Things have gotten out of sync. Restarting.\n" if $debug;
- last;
- }
- };
- /^#MESREJECT (\d) / && do {
- if ($1 == $mesgnum++) {
- if ($error) {
- $cmd = "$MAIL <" . $QUEUE_DIR . $file . " -s 'the following pin and message was rejected' " . $error;
- print "DEBUG: About to execute $cmd\n" if $debug;
- }
- print "DEBUG: unlinking " . $QUEUE_DIR . $file . "\n" if $debug;
- unlink $QUEUE_DIR . $file;
- # get to the next message (same as #MESOK)
- $error = pop(@ixo_list);
- $file = pop(@ixo_list);
- print "DEBUG: ERROR=$error; FILE=$file\n" if $debug;
- } else {
- print "Things have gotten out of sync. Restarting.\n" if $debug;
- last;
- }
- };
- /^#FORDIS / && do {
- print "Forced disconnect from server.\n" if $debug;
- last;
- };
- /^#PROTERR / && do {
- print "Server not following protocol.\n" if $debug;
- last;
- };
- ( /^#DONE / || /#BYE / ) && do {
- if ($#ixo_list) {
- print "Done with sending batch. Waiting BYE.\n" if $debug;
- $success = 1;
- next;
- } else {
- print "ixocico is done but more data waiting to be sent! Program bug.\n" if $debug;
- last;
- }
- };
- /^#WRONGANY / && do {
- print "We've been notified that one of the batch may have been not xmited.\n(great protocol, eh?)\n" if $debug;
- next;
- };
- /^#BADQUEUE / && do {
- die "$0: Programmer error. Data in queue is bad: $_\n";
- };
- /^#MODOPEN / && do {
- print "Modem can't be opened\n" if $debug;
- last;
- };
- /^#PACKLEN / && do {
- die "$0: Protocol error. Should never happen: $_\n";
- };
- /^#GOTMESSEQ / && do {
- print "MESSAGE: $_\n" if $debug;
- };
- /^#LONELY / && do {
- print "Hello? Hello? Either I'm getting the silent treatment or the server is dead." if $debug;
- last;
- };
- }
- close IX;
- unlink $tmpfile;
- $ixo_dial{ $dial } = 0;
- }
-
- print "DEBUG: ixo_dial = " if $debug;
- foreach $i (keys %ixo_dial) {
- next unless $ixo_dial{ $dial };
- print $i if $debug;
- };
- print "\n" if $debug;
-
- eval "@ixo_${dial}_pin = ()";
- eval "@ixo_${dial}_mess = ()";
- eval "@ixo_${dial}_error = ()";
- eval "@ixo_${dial}_file = ()";
- $ixo_list = ();
- }
-