home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / bell < prev    next >
Encoding:
Korn shell script  |  1997-08-26  |  8.2 KB  |  315 lines

  1. #!/bin/ksh
  2. # @(#) bell.ksh 1.1 96/02/02
  3. # 93/03/07 john h. dubois iii (john@armory.com)
  4. # 93/03/13 Warn if visual is attempted on a non-console tty.
  5. # 93/04/02 When given visual, make screens switch to other screens on the
  6. #          same adapter.  When given "visual console", map only screens
  7. #          that can be opened and are not running line discipline 2 (ev).
  8. # 93/04/03 Work around need for /dev/stdin
  9. # 94/10/24 If given list of ttys, only try to map those that are readable.
  10. # 94/11/06 Added h option.
  11. # 94/11/17 Added read from /dev/string/cfg
  12.  
  13. # Sets global Adapters[1..n] to the types of adapters present,
  14. # from the set (mono cga ega vga).
  15. # Returns number of adapters found.
  16. function FindAdapters {
  17.     typeset Name dev=/dev/string/cfg
  18.     typeset -i j=0
  19.     
  20.     if [ -c $dev -a -r $dev ]; then
  21.     # This will work under 3.2v4
  22.     awk '
  23. BEGIN {
  24.     A["mono"] A["cga"] A["ega"] A["vga"]
  25. }
  26. $1 == "%console" {
  27.     sub("^unit=","",$5)
  28.     if ($5 in A)
  29.     print $5
  30. }' /dev/string/cfg | while read Name; do
  31.         Adapters[j]=$Name
  32.         let j+=1
  33.     done
  34.     else    
  35.     # This test will fail if proc has no controlling tty,
  36.     # due to a silly test in the /dev/adapter driver.
  37.     for Name in in vga ega cga mono; do
  38.         if ( < /dev/$Name ) > /dev/null 2>&1; then
  39.         Adapters[j]=$Name
  40.         let j+=1
  41.         fi
  42.     done
  43.     fi
  44.     [ j -gt 2 ] &&
  45.     print -u2 "$name: found $j video adapters; should not be more than two."
  46.     return $j
  47. }
  48.  
  49. # Usage: FindConsTTYTypes ttyname ...
  50. # MonoTTYs[1..m] and ColorTTYs[1..c] are set to the tty numbers
  51. # of the mono and color ttys.  
  52. # ttyType[ttynum] is set to $Mono or $Color for each tty number.
  53. # The test used is based on only color adapters having the 8x8 font.
  54. typeset -i ttyType MonoTTYs ColorTTYs
  55. function FindConsTTYTypes {
  56.     typeset -i mi=1 ci=1 l w c=0 ttynum
  57.  
  58.     for tty; do
  59.     tty=${tty#/dev/}        # Get rid of leading /dev
  60.     ttynum=${tty##*([!0-9])}    # Get rid of non-numeric part
  61.     # tr is defined to always delete null chars from the input
  62.     vidi -d font8x8 < "/dev/$tty" 2>/dev/null | tr | wc -c | read c
  63.     # c (number of non-null chars emitted by vidi) will be
  64.     # 0 if the input was a mono adapter
  65.     if [ c -eq 0 ]; then
  66.         MonoTTYs[mi]=ttynum
  67.         ttyType[ttynum]=Mono
  68.         let mi+=1
  69.     else
  70.         ColorTTYs[ci]=ttynum
  71.         ttyType[ttynum]=Color
  72.         let ci+=1
  73.     fi
  74.     let ttynum+=1
  75.     done
  76. }
  77.  
  78. # Usage:
  79. # ReplaceBell ttyname sequence [test]
  80. # ttyname is the console tty to change the bell sequence on.
  81. # sequence is the sequence to replace the bell with.
  82. # If sequence is not given, bell mapping is turned off.
  83. # If a third arg is given, no mapping is done.
  84. function ReplaceBell {
  85.  
  86.     typeset tty=/dev/${1#/dev/} tmpfile
  87.     typeset -i test
  88.  
  89.     if [ ! -r $tty ]; then
  90.     echo "Cannot read $tty to get current mapping."
  91.     return
  92.     fi
  93.  
  94.     # Generate tmpfile name if we need one.
  95.     # If the system has /dev/stdin, we don't.
  96.     if [ ! -r /dev/stdin -o LeaveFiles -eq 1 ]; then
  97.     tmpfile=/tmp/bell.$$.${tty#/dev/tty}
  98.     [ verbose -eq 1 ] && echo "mapchan file name: $tmpfile"
  99.     else
  100.     tmpfile=
  101.     fi
  102.  
  103.     [ $# -ne 3 ]
  104.     test=$?
  105.  
  106.     mapchan $tty | awk '
  107.     $0 == "output" { 
  108.     InOutput = 1
  109.     }
  110.  
  111.     # If replacement has not been done yet and we are in the output section
  112.     # and (the old bell mapping or the end of the section) has been found...
  113.     !Done && InOutput && ($1 ~ "^(0x7|dead|compose|control)$") {
  114.     if (replacement != "")
  115.         map = map "7 " replacement "\n"
  116.     Done = 1
  117.     if ($1 == "0x7")  # Replacing bell sequence, so do not print old one
  118.         next
  119.     }
  120.  
  121.     # Channel previously had no mapping
  122.     $0 == "null" {
  123.     if (replacement != "")
  124.         map = map "input\noutput\n7 " replacement "\n"
  125.     Done = 1
  126.     exit 0
  127.     }
  128.  
  129.     {
  130.     map = map $0 "\n"
  131.     }
  132.  
  133.     END {
  134.     if (!Done) {
  135.         # Old map had only input & output sections & no old map for bell
  136.         if (InOutput) {
  137.         if (replacement != "")
  138.             map = map "7 " replacement "\n"
  139.         }
  140.         else {
  141.         print "Error interpreting map." | "cat 1>&2"
  142.         exit 1
  143.         }
  144.     }
  145. #    if (verbose)
  146. #        print "mapchan input:\n" map
  147.     if (!test) {
  148.         if (tmpfile == "") {
  149.         procname = "exec mapchan -f /dev/stdin " tty
  150.         print map | procname
  151.         }
  152.         else {
  153.         print map > tmpfile
  154.         Cmd =  "mapchan -f " tmpfile " " tty
  155.         if (LeaveFiles == 0)
  156.             Cmd = Cmd "; exec rm " tmpfile
  157.         system(Cmd)
  158.         }
  159.     }
  160.     }
  161.     ' replacement="$2" tty="$tty" test=$test tmpfile=$tmpfile \
  162.     verbose=$verbose LeaveFiles=$LeaveFiles
  163. }
  164.  
  165. # Start of main program
  166.  
  167. name=${0##*/}
  168.  
  169. Usage="Usage: $name [-fhvt] [on|off|visual] [console|ttyname ...]"
  170. typeset -i verbose=0 Color=0 Mono=1 LeaveFiles=0
  171.  
  172. while getopts fhvt opt; do
  173.     case $opt in
  174.     h)
  175.     echo \
  176. "$name: Change the effect of receiving a bell character.
  177. $Usage
  178. $name modifies the bell mapping on the named tty, or on the current tty if
  179. no ttyname is given.  tty names may be given with or without a leading
  180. /dev/.  If console is given, mapping is attempted on all console ttys
  181. (tty01..tty12).  Use /dev/console to specifically map it.  Mapping cannot
  182. be done on a tty that is using the event driver.  Any non-bell mapping
  183. currently in effect on the tty is not changed.
  184. Options:
  185. off    turns off the bell by mapping the bell character (^G) to ^A,
  186.     which does not display anything on most terminals.
  187. on    turns the bell back on by removing any mapping.
  188. visual    replaces the console bell with a visual indication by mapping
  189.     the bell character to a sequence which switches to another
  190.     tty on the same adapter and back.  If -v is given, the switching
  191.     actions that are set up are reported.  visual should only be used
  192.     on console ttys.  
  193. Note: if \"$name visual console\" is going to be done (mapping bell on all
  194. console ttys to visual bell) and all 12 console multiscreens exist (NSCRN =
  195. 12), the kernel parameter NEMAP should be increased, since this will result in
  196. 12 distinct maps and the default for NEMAP is 10.
  197. Options:
  198. -h: Print this help.
  199. -t: Test.  Do not perform any mapping.
  200. -f: Leave mapchan files in place in /tmp/bell.pid.tty
  201. -v: Set verbose mode.  Show what is being done."
  202.     exit 0
  203.     ;;
  204.     f)
  205.     LeaveFiles=1
  206.     ;;
  207.     t)
  208.     test=1
  209.     ;;
  210.     v)
  211.     verbose=1
  212.     ;;
  213.     x)
  214.     debug=true
  215.     ;;
  216.     +?)
  217.     print -u2 "$name: options should not be preceded by a '+'."
  218.     exit 1
  219.     ;;
  220.     ?) 
  221.     print -u2 "Use -h for help."
  222.     exit 1
  223.     ;;
  224.     esac
  225. done
  226.  
  227. # remove args that were options
  228. let OPTIND=OPTIND-1
  229. shift $OPTIND
  230.  
  231. cmd=$1
  232.  
  233. case "$2" in
  234. console)
  235.     # Map all console ttys that are readable & are not using the event driver.
  236.     for tty in /dev/tty[01][0-9]; do
  237.     ( < $tty ) 2>/dev/null && [[ "`stty < $tty`" != *"line = 2"* ]] &&
  238.     ttys="$ttys $tty"
  239.     done
  240.     ;;
  241. "")    # Map current tty.
  242.     ttys=$(tty)
  243.     ;;
  244. *)    # Map named ttys that are readable
  245.     shift
  246.     for tty; do
  247.     [[ "$tty" != /* ]] && tty="/dev/$tty"
  248.     ( < $tty ) 2>/dev/null && ttys="$ttys $tty"
  249.     done
  250.     ;;
  251. esac
  252.  
  253. case "$cmd" in
  254. on)
  255.     for tty in $ttys; do
  256.     ReplaceBell $tty
  257.     done
  258.     ;;
  259. off)
  260.     for tty in $ttys; do
  261.     ReplaceBell $tty 1
  262.     done
  263.     ;;
  264. visual)
  265.     # Make the always 2 digits to simplify generation of escape sequences.
  266.     typeset -Z2 ToName From
  267.     typeset -i First Last ToNum
  268.  
  269.     # Only the return value of FindAdapters is currently used.
  270.     FindAdapters    # Find which types of adapters are present
  271.     case $? in
  272.     0)  print -u2 "$name: Warning: no adapters found."
  273.     exit 1
  274.     ;;
  275.     1) ;;
  276.     *) 
  277.     # If more than one type of adapter present,
  278.     # need to know which adapter each console tty is on.
  279.     FindConsTTYTypes $ttys
  280.     ;;
  281.     esac
  282.     # Set Last[] and First[] to the last & first ttys of each type, so that
  283.     # all but the last can switch to the last tty, and the last can switch to
  284.     # the first.
  285.     Last[Color]=ColorTTYs[${#ColorTTYs[*]}]
  286.     Last[Mono]=MonoTTYs[${#MonoTTYs[*]}]
  287.     First[Color]=ColorTTYs[1]
  288.     First[Mono]=MonoTTYs[1]
  289.     for tty in $ttys; do
  290.     tty=${tty#/dev/}
  291.     ttynum=${tty##*([!0-9])}
  292.     if [[ "$ttynum" != [01][0-9] ]]; then
  293.         echo "$tty: Not a console tty."
  294.         continue
  295.     fi
  296.     if [ ttynum -eq Last[ttyType[ttynum]] ]; then
  297.         ToNum=First[ttyType[ttynum]]
  298.     else
  299.         ToNum=Last[ttyType[ttynum]]
  300.     fi
  301.     ToName=$ToNum
  302.     [ verbose -eq 1 ] && echo "$tty switches to tty$ToName and back."
  303.     From=$((ttynum-1))
  304.     ToName=$((ToName-1))
  305.     Sequence=\
  306. "033 '[' '${ToName%?}' '${ToName#?}' 'z' 033 '[' '${From%?}' '${From#?}' 'z'"
  307.     [ verbose -eq 1 ] && echo "Bell map: $Sequence"
  308.     ReplaceBell $tty "$Sequence" $test
  309.     done
  310.     ;;
  311. *)
  312.     print -u2 "$Usage\nUse -h for help."
  313.     ;;
  314. esac
  315.