home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / tcl / expect / scripts / alpha-pager next >
Encoding:
Text File  |  1993-07-05  |  6.5 KB  |  306 lines

  1. #!/local/bin/expect
  2. #From cme!dove!uunet!haven.umd.edu!cville-srv.wam.umd.edu!ni.umd.edu!sayshell.umd.edu!louie Mon Jul  5 19:40:50 EDT 1993
  3. #Article: 12626 of comp.unix.bsd
  4. #Path: cme!dove!uunet!haven.umd.edu!cville-srv.wam.umd.edu!ni.umd.edu!sayshell.umd.edu!louie
  5. #From: louie@sayshell.umd.edu (Louis A. Mamakos)
  6. #Newsgroups: comp.unix.bsd
  7. #Subject: Re: BSDI and IXO
  8. #Message-ID: <21486h$f5q@ni.umd.edu>
  9. #Date: 3 Jul 93 15:21:53 GMT
  10. #References: <20sp7v$9hr@cyberspace.com>
  11. #Organization: University of Maryland, College Park
  12. #Lines: 290
  13. #NNTP-Posting-Host: sayshell.umd.edu
  14. #
  15. #In article <20sp7v$9hr@cyberspace.com> brc@cyberspace.com (Brian Cartmell) writes:
  16. #>Does anyone have a program that works on BSD that will connect to a device
  17. #>dial a number and transfer Alpha Pager Message via the IXO for alpha pagers?
  18. #
  19. #I have an expect script (actually, two files) that does this.  It can
  20. #use tip(1) to actually talk to the modem.  We also have a different
  21. #module that telnets to an terminal server with dial-out modems too,
  22. #that just uses a different "hardware" file.
  23. #
  24. #This pretty ugly and disgusting, but the implementation of the IXO
  25. #protocol in TCL, I thought, was rather interesting.
  26. #
  27. #It's usually invoked as 
  28. #
  29. #    beep pagerid "It's broken!  Help!"  pagerid2 "Help! It's down!"
  30. #
  31. #there's also a way to pass it a file containing pagerids and messages for
  32. #"bulk" beeping.
  33. #
  34. #Louis Mamakos
  35. #
  36. #
  37. #!/local/bin/expect
  38. #
  39. #  Call a beeper.  By default, uses tip(1c) to establish the modem connection
  40. #  which requires an entry in /etc/remote that looks like this:
  41. #
  42. #    dialer:dv=/dev/cufa:br#38400:pa=even:
  43. #
  44.  
  45. log_user 0
  46. #debug 1
  47.  
  48. # definition of paging service's phone number
  49. set service "474-4657"
  50. # hardware to use
  51. set hardware beep.tip
  52.  
  53. # definitions of various ascii control characters used by the paging
  54. # protocol
  55.  
  56. set STX \002
  57. set ETX \003
  58. set ACK \006
  59. set NAK \025
  60. set RS  \036
  61. set ESC \033
  62. set EOT \004
  63.  
  64.  
  65. # ===
  66.  
  67. proc error { msg } {
  68.     puts stderr "Error: $msg"
  69.     exit
  70. }
  71.  
  72. # ===
  73.  
  74. #
  75. #  compute the checksum over the paging transaction packet.  Return the
  76. #  checksum string
  77. #
  78. proc checksum { s } {
  79.     set sum 0
  80.     foreach ch [split $s {}] {
  81.         scan $ch "%c" v
  82.         incr sum $v
  83.     }
  84.     return [format "%c%c%c" [expr "48 + (($sum >> 8) & 15)"] \
  85.                 [expr "48 + (($sum >> 4) & 15)"] \
  86.                 [expr "48 + ($sum & 15)"]];
  87. }
  88.  
  89. # ===
  90.  
  91. proc get_response {} {
  92.     global ACK NAK RS ESC EOT
  93.  
  94.     expect    "*$ACK\r"     {puts stderr "resp: OK";  return "OK"} \
  95.         "*$NAK\r"     {puts stderr "resp: NAK"; return "NAK"} \
  96.         "*$RS\r"      {puts stderr "resp: ABANDON"; return "ABANDON"} \
  97.         "*$ESC$EOT\r" {puts stderr "resp: DISC"; return "DISC"} \
  98.         timeout          {puts stderr "resp: TIMEOUT"; return "TIMEOUT"}
  99. }
  100.  
  101. # ===
  102.  
  103. #
  104. #  Generate a page to "pin" carrying the message "message"
  105. #
  106. proc page { pin message } {
  107.     global STX ETX
  108.  
  109.     set attempts 0
  110.  
  111.     regsub "\t+" $message " " message
  112.     set message [string range $message 0 238]
  113.  
  114.     set pgstr "${STX}${pin}\r${message}\r${ETX}"
  115.     set block "$pgstr[checksum $pgstr]\r"
  116.  
  117.     send $block
  118.     puts stderr "Sending page to $pin"
  119.     set resp [get_response]
  120.     #
  121.     #  Examine the response.  Only "NAK" responses are retried
  122.     #
  123.     while {! [string compare "NAK" $resp] && $attempts < 5} {
  124.         puts stderr "Resending block due to NAK"
  125.         exec sleep 1
  126.         send $block
  127.         set resp [get_response]
  128.         incr attempts
  129.     }
  130.     return $resp
  131. }
  132.  
  133. # ===
  134.  
  135. #
  136. #  condition the paging system to accept the Paging Entry Terminal protocol,
  137. #  rather than thinking we're a dumb terminal out here.
  138. #
  139. proc dologin {} {
  140.    global ESC
  141.  
  142.    foreach i {once} {
  143.     set timeout 5
  144.     expect {*ID=} break    timeout {}
  145.     set timeout 2
  146.     send "\r"
  147.     expect {*ID=} break    timeout {}
  148.     send "\r"
  149.     expect {*ID=} break    timeout {}
  150.     send "\r"
  151.     expect "*ID=" break    timeout {}
  152.     send "\r"
  153.     expect "*ID=" break    timeout {
  154.         send_user "Error: waiting for id= prompt\r"
  155.         return -1
  156.     }
  157.    }
  158.  
  159.    set timeout 10
  160.  
  161.    # this is the magic bit..
  162.    send "${ESC}PG1000000\r"
  163.  
  164.    case [set resp [get_response]] in {
  165.     OK    {puts stderr "Logged into paging service"}
  166.     NAK   {error "to send of PG1"}
  167.     TIMEOUT {error "timeout of response to PG1"}
  168.     *    {error "Unexpected response '$resp' during login"}
  169.    }
  170.    return 0
  171. }
  172.  
  173. # ===
  174.  
  175. proc logout {} {
  176.  
  177.     global EOT
  178.  
  179.     send "$EOT\r"
  180.     case [get_response] in {
  181.         DISC    {puts stderr "Normal disconnect"}
  182.         RS    {puts stderr "Some pages may have failed"}
  183.     }
  184. }
  185.  
  186. # ============= start of main program =============
  187.  
  188.  
  189. set argc [llength $argv]
  190. set dofile 0
  191.  
  192. set arg 1
  193.  
  194. if {$argc>2 && ([string compare FILES [lindex $argv 1]] == 0)} {
  195.     set dofile 1
  196.     set arg 2
  197. } else {
  198.    if {$argc < 3} {
  199.     puts stderr \
  200.                "usage: [lindex $argv 0] pagerid message \[pagerid message ...\]"
  201.     exit
  202.     }
  203. }
  204.  
  205. source $hardware
  206.  
  207. set success 0
  208. for {set tries 5} {$tries} {set tries [expr $tries-1]} {
  209.     # invoke communication facility specific function to establish
  210.     # a connection with the paging service
  211.     connect $service
  212.  
  213.     # attempt to initiate session protocol
  214.     if {[dologin] == 0} {
  215.         set success 1
  216.         break
  217.     }
  218. }
  219. if { $success == 0 } {
  220.     error "Gave up looking for a working modem at the other end"
  221. }
  222.  
  223. while {!$dofile && ($arg < $argc)} {
  224.     set who [lindex $argv $arg]
  225.     set msg [string range [lindex $argv [expr $arg+1]] 0 238]
  226.     set arg [expr $arg+2]
  227.  
  228.     puts stderr "Paging $who with $msg"
  229.     page $who "$msg"
  230. }
  231.  
  232. if {$dofile} {
  233.    while {$arg < $argc} {
  234.     set dofile [open [set filename [lindex $argv $arg]] r]
  235.     incr arg
  236.  
  237.     if {[gets $dofile who] < 0} {
  238.         puts stderr "EOF reading recpient from $filename"
  239.         exec rm -f $filename
  240.         continue
  241.     }
  242.  
  243.     if {[gets $dofile msg] < 0} {
  244.         puts stderr "EOF reading message from $filename"
  245.         exec rm -f $filename
  246.         continue
  247.     }
  248.  
  249.     if {[regsub "^ID=" $who "" who] == 0} {
  250.         puts stderr "$filename: Missing ID= on pager line"
  251.         exec rm -f $filename
  252.         continue
  253.     }
  254.     if {[regsub "^MSG=" $msg "" msg] == 0} {
  255.         puts stderr  "$filename: Missing ID= on pager line"
  256.         exec rm -f $filename
  257.         continue
  258.     }
  259.     close $dofile
  260.     puts stderr "Paging $who with $msg"
  261.     if {[page $who "$msg"] == "OK"} {
  262.         exec rm -f $filename
  263.     }
  264.    }
  265. }
  266.  
  267. # end session protocol
  268. logout
  269.  
  270. #
  271. # invoke communication facility specific function to disconnect from
  272. # paging service
  273. #
  274. disconnect "Mission sucessful\n"
  275. exit 0
  276.  
  277.  
  278. ----------- beep.tip
  279.  
  280. proc connect { pagerservice } {
  281.    global spawn_id pid
  282.  
  283.    uplevel 1 set pid [spawn tip dialer]
  284.  
  285.    expect "connected*"
  286.  
  287.    send "AT\r"
  288.    expect "*OK*" {}
  289.  
  290.    send "ATE0\r"
  291.    expect "*OK*" {}
  292.  
  293.    send "ATM0&N15&K0DT${pagerservice}\r"
  294.    set timeout 20
  295.    expect "*CONNECT*\r" {}  timeout {error "modem didn't return CONNECT"}
  296.    expect_after     eof    {error "Got EOF (default)"} \
  297.         {\rNO\ CARRIER\r} {error "Lost connection"}
  298. }
  299.  
  300. proc disconnect { msg } {
  301.     send "\r~.\r"
  302.     send_user $msg
  303. }
  304.  
  305.  
  306.