home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March B / SCO_CASTOR4RRT.iso / expect / root / usr / bin / xkibitz / xkibitz~
Text File  |  1998-08-19  |  4KB  |  203 lines

  1. #!/usr/bin/expect --
  2.  
  3. # share an xterm with other users
  4. # See xkibitz(1) man page for complete info.
  5. # Compare with kibitz.
  6. # Author: Don Libes, NIST
  7. # Version: 1.2
  8.  
  9. proc help {} {
  10.     puts "Commands          Meaning"
  11.     puts "--------          -------"
  12.     puts "return            return to program"        
  13.     puts "=                 list"
  14.     puts "+ <display>       add"
  15.     puts "- <tag>           drop"
  16.     puts "where <display> is an X display name such as nist.gov or nist.gov:0.0"
  17.     puts "and <tag> is a tag from the = command."
  18.     puts "+ and - require whitespace before argument."
  19.     puts {return command must be spelled out ("r", "e", "t", ...).}
  20. }
  21.  
  22. proc prompt1 {} {
  23.     return "xkibitz> "
  24. }
  25.  
  26. proc h {} help
  27. proc ? {} help
  28. proc unknown {args} {
  29.     puts "$args: invalid command"
  30.     help
  31. }
  32.  
  33. set tag2pid(0)            [pid]
  34. set pid2tty([pid])        "/dev/tty"
  35. if [info exists env(DISPLAY)] {
  36.     set pid2display([pid])    $env(DISPLAY)
  37. } else {
  38.     set pid2display([pid])    ""
  39. }
  40.  
  41. # small int allowing user to more easily identify display
  42. # maxtag always points at highest in use
  43. set maxtag 0
  44.  
  45. proc + {display} {
  46.     global ids pid2display pid2tag tag2pid maxtag pid2sid
  47.     global pid2tty env
  48.  
  49.     if ![string match *:* $display] {
  50.         append display :0.0
  51.     }
  52.  
  53.     if {![info exists env(XKIBITZ_XTERM_ARGS)]} {
  54.         set env(XKIBITZ_XTERM_ARGS) ""
  55.     }
  56.  
  57.     set dummy1 [open /dev/null]
  58.     set dummy2 [open /dev/null]
  59.     spawn -pty -noecho
  60.     close $dummy1
  61.     close $dummy2
  62.  
  63.     stty raw -echo < $spawn_out(slave,name)
  64.     # Linux needs additional stty, sounds like a bug in its stty to me.
  65.     # raw should imply this stuff, no?
  66.     stty -icrnl -icanon < $spawn_out(slave,name)
  67.  
  68.     regexp ".*(.)(.)" $spawn_out(slave,name) dummy c1 c2
  69.     if {[string compare $c1 "/"] == 0} {
  70.         # On Pyramid and AIX, ttynames such as /dev/pts/1
  71.         # requre suffix to be padded with a 0
  72.         set c1 0
  73.     }
  74.  
  75.     set pid [eval exec xterm \
  76.             -display $display \
  77.             -geometry [stty columns]x[stty rows] \
  78.             -S$c1$c2$spawn_out(slave,fd) \
  79.                         $env(XKIBITZ_XTERM_ARGS) &]
  80.     close -slave
  81.  
  82.     # xterm first sends back window id, discard
  83.     log_user 0
  84.     expect {
  85.         eof {wait;return}
  86.         \n
  87.     }
  88.     log_user 1
  89.  
  90.     lappend ids $spawn_id
  91.     set pid2display($pid) $display
  92.     incr maxtag
  93.     set tag2pid($maxtag) $pid
  94.     set pid2tag($pid) $maxtag
  95.     set pid2sid($pid) $spawn_id
  96.     set pid2tty($pid) $spawn_out(slave,name)
  97.     return
  98. }
  99.  
  100. proc = {} {
  101.     global pid2display tag2pid pid2tty
  102.  
  103.     puts "Tag  Size Display"
  104.     foreach tag [lsort -integer [array names tag2pid]] {
  105.         set pid $tag2pid($tag)
  106.         set tty $pid2tty($pid)
  107.         
  108.         puts [format "%3d [stty columns < $tty]x[stty rows < $tty] $pid2display($pid)" $tag]
  109.     }
  110. }
  111.  
  112. proc - {tag} {
  113.     global tag2pid pid2tag pid2display maxtag ids pid2sid
  114.     global pid2tty
  115.  
  116.     if ![info exists tag2pid($tag)] {
  117.         puts "no such tag"
  118.         return
  119.     }
  120.     if {$tag == 0} {
  121.         puts "cannot drop self"
  122.         return
  123.     }
  124.  
  125.     set pid $tag2pid($tag)
  126.  
  127.     # close and remove spawn_id from list
  128.     set spawn_id $pid2sid($pid)
  129.     set index [lsearch $ids $spawn_id]
  130.     set ids [lreplace $ids $index $index]
  131.  
  132.     exec kill -9 $pid
  133.     close
  134.     wait
  135.  
  136.     unset tag2pid($tag)
  137.     unset pid2tag($pid)
  138.     unset pid2display($pid)
  139.     unset pid2sid($pid)
  140.     unset pid2tty($pid)
  141.  
  142.     # lower maxtag if possible
  143.     while {![info exists tag2pid($maxtag)]} {
  144.         incr maxtag -1
  145.     }
  146. }
  147.  
  148. exit -onexit {
  149.     unset pid2display([pid])    ;# avoid killing self
  150.  
  151.     foreach pid [array names pid2display] {
  152.         catch {exec kill -9 $pid}
  153.     }
  154. }
  155.  
  156. trap {
  157.     set r [stty rows]
  158.     set c [stty columns]
  159.     stty rows $r columns $c < $app_tty
  160.     foreach pid [array names pid2tty] {
  161.         if {$pid == [pid]} continue
  162.         stty rows $r columns $c < $pid2tty($pid)
  163.     }
  164. } WINCH
  165.  
  166. set escape \035        ;# control-right-bracket
  167. set escape_printable "^\]"
  168.  
  169. while [llength $argv]>0 {
  170.     set flag [lindex $argv 0]
  171.     switch -- $flag \
  172.     "-escape" {
  173.         set escape [lindex $argv 1]
  174.         set escape_printable $escape
  175.         set argv [lrange $argv 2 end]
  176.     } "-display" {
  177.         + [lindex $argv 1]
  178.         set argv [lrange $argv 2 end]
  179.     } default {
  180.         break
  181.     }
  182. }
  183.  
  184. if [llength $argv]>0 {
  185.     eval spawn -noecho $argv
  186. } else {
  187.     spawn -noecho $env(SHELL)
  188. }
  189. set prog $spawn_id
  190. set app_tty $spawn_out(slave,name)
  191.  
  192. puts "Escape sequence is $escape_printable"
  193.  
  194. interact {
  195.     -input $user_spawn_id -reset $escape {
  196.         puts "\nfor help enter: ? or h or help"
  197.         interpreter
  198.     } -output $prog
  199.     -input ids -output $prog
  200.     -input $prog -output $user_spawn_id -output ids
  201. }
  202.  
  203.