home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 200.img / SCO386X3.TD0 / usr / lib / mkdev / lp
Encoding:
Text File  |  1988-12-09  |  16.0 KB  |  692 lines

  1. :
  2. #    @(#) lp.sh 1.23 88/12/09 
  3. #
  4. #    Copyright (C) The Santa Cruz Operation, 1986.
  5. #    This Module contains Proprietary and Confidential
  6. #    Information of The Santa Cruz Operation, Inc.
  7. #
  8.  
  9. #    THIS FILE CONTAINS CODE SPECIFIC TO THE IBM PC/XT AND PC/AT WORK-ALIKES
  10. #    RUNNING SCO XENIX-*86. IT MAY REQUIRE MODIFICATION FOR DIFFERENT MACHINE
  11. #    ARCHITECTURES OR CONFIGURATIONS.
  12. #
  13. #    lpinit - set up a default printer for the LP Spooler on IBM PC/XT and 
  14. #    PC/AT work-alikes. Options now exist for reconfiguring existing printers
  15. #    removing printers and reconfiguring classes of printers.
  16. #
  17. #    only the super-user can execute this script meaningfully.
  18. #
  19.  
  20. PATH=/bin:/usr/bin:/etc
  21.  
  22. SPOOLDIR="/usr/spool/lp"
  23. REQDIR="$SPOOLDIR/request"
  24. IFDIR="$SPOOLDIR/interface"
  25. CLASSDIR="$SPOOLDIR/class"
  26.  
  27. tmp=/tmp/lp$$
  28.  
  29. # Define return values
  30. : ${OK=0} ${FAIL=1} ${STOP=10} ${HALT=11}
  31.  
  32. # pchoices is machine dependent
  33. pchoices="\tlp0\n\tlp0i\n\tlp1\n\tlp1i\n\tlp2\n\tlp2i"
  34.  
  35. trap 'eval $schedrun
  36.       echo "\n\n\007INTERRUPTED">&2
  37.       exit $FAIL'    1 2 3 15
  38.  
  39. ########################
  40. # Function definitions #
  41. ########################
  42.  
  43. #
  44. # Machine dependent functions
  45. #
  46.  
  47. # Check if parallel device is valid - return non-zero if not
  48. validpar () { 
  49.     device=
  50.         case $1 in
  51.     *lp0)   device=/dev/lp0
  52.             ;;
  53.     *lp0i)  device=/dev/lp0i
  54.             ;;
  55.     *lp1)   device=/dev/lp1
  56.             ;;
  57.     *lp1i)  device=/dev/lp1i
  58.             ;;
  59.     *lp2)   device=/dev/lp2
  60.         ;;
  61.     *lp2i)  device=/dev/lp2i
  62.             ;;
  63.     /dev/*)    [ -b $1 -o -c $1 ] && device=$1
  64.         ;;
  65.     dev/*)    [ -b /$1 -o -c /$1 ] && device=/$1
  66.         ;;
  67.     [hH])
  68.         return 1
  69.         ;;
  70.     *)    [ -b /dev/$1 -o -c /dev/$1 ] && device=/dev/$1
  71.         ;;
  72.     esac
  73.     [ $device ] || error "Not a valid parallel device: $1"
  74.     return $?
  75. }
  76.  
  77. # Print help screen for parallel devices
  78. helpparallel () { 
  79.     echo "\nStandard parallel devices on your system are:
  80.  
  81. lp0 ----- Main parallel port
  82. lp0i ---- Main parallel port (sends an init on each open)
  83. lp1 ----- Parallel port on monochrome card
  84. lp1i ---- Parallel port on monochrome card (sends an init on each open)
  85. lp2 ----- Alternate parallel port
  86. lp2i ---- Alternate parallel port (sends an init on each open)
  87.  
  88. Note: On some systems lp0 and lp1 are reversed.\n">&2
  89. }
  90.  
  91. #
  92. # Generic functions
  93. #
  94.  
  95. # Check if serial device is valid - return non-zero if not
  96. validser () { 
  97.     device=
  98.     case $1 in
  99.     /dev/tty[1-9][a-z])  device="$1";;
  100.         dev/tty[1-9][a-z])  device="/$1";;
  101.     tty[1-9][a-z])  device="/dev/$1";;
  102.     [hH])   return 1 ;;
  103.     /dev/*)    [ -b $1 -o -c $1 ] && device=$1
  104.         ;;
  105.     dev/*)    [ -b /$1 -o -c /$1 ] && device=/$1
  106.         ;;
  107.     *)    [ -b /dev/$1 -o -c /dev/$1 ] && device=/dev/$1
  108.         ;;
  109.     esac
  110.     [ $device ] || error "Not a valid serial device: $1"
  111.     return $?
  112. }
  113.  
  114. # Print help screen for serial devices
  115. helpserial () { 
  116.     echo "\nStandard serial devices on your system are:\n" >&2
  117.         sed -n 's/0.\(tty[1-9][a-z]\)/\1/p
  118.     s/1.\(tty[1-9][a-z]\)/\1 ----- enabled for login/p' /etc/ttys | pr -t -l22 -2
  119. }
  120.     
  121. # Print an error message
  122. error() {
  123.     echo "\nError: $*" >&2
  124.     return 1
  125. }
  126.  
  127. # Prompt for yes or no answer - returns non-zero for no
  128. getyn() {
  129.     while    echo "\n$* (y/n) \c">&2
  130.     do    read yn rest
  131.         case $yn in
  132.         [yY])    return 0             ;;
  133.         [nN])    return 1            ;;
  134.         *)    echo "Please answer y or n" >&2    ;;
  135.         esac
  136.     done
  137. }
  138.  
  139. # Prompt with mesg, return non-zero on q
  140. prompt() {
  141.     while    echo "\n${mesg}or enter q to $quit: \c" >&2
  142.     do    read cmd
  143.         case $cmd in
  144.         +x|-x)    set $cmd                    ;;
  145.         Q|q)    return 1                    ;;
  146.         !*)    eval `expr "$cmd" : "!\(.*\)"`            ;;
  147.         "")    # If there is an argument use it as the default
  148.             # else loop until 'cmd' is set
  149.             [ "$1" ] && { 
  150.                 cmd=$1
  151.                 return 0
  152.             }
  153.             : continue
  154.             ;;
  155.         *)    return 0                    ;;
  156.         esac
  157.     done
  158. }
  159.  
  160. # Print existing printer names - return non-zero if there are none
  161. prnames () { 
  162.     printers=`lpstat -v`
  163.     [ "$printers" ] || { 
  164.         echo "\nThere are no existing printers." >&2
  165.         return 1
  166.     }
  167.     echo "\nExisting printers are:" >&2
  168.     echo "$printers" | sed 's/device for \(.*\):.*/\1/p'
  169.     return 0
  170. }
  171.  
  172. # Check printer membership in classes -- returns the number of classes
  173. chkclass () { 
  174.     class=
  175.     inclass=
  176.     classes=`cd $CLASSDIR; echo *`
  177.     [ "$classes" = "*" ] && classes=
  178.     cnt=0
  179.     for i in $classes
  180.     do
  181.             grep $1 $CLASSDIR/$i >/dev/null && { 
  182.             inclass="$inclass $i"
  183.             cnt=`expr $cnt + 1`
  184.             }
  185.     done
  186.     return $cnt
  187. }
  188.  
  189. # Set new device for printers which require special form feed handling
  190. specialdev() { 
  191.     if getyn "Some printers require conversions for line feed, tab and form feed\n(see lpinit(C) in the Users Reference for more information).\nDoes this printer need this special handling? "
  192.     then
  193.         case $device in
  194.         *lp0)
  195.             device="/dev/lp0f"
  196.             ;;
  197.         *lp1)
  198.             device="/dev/lp1f"
  199.             ;;
  200.         *lp2)
  201.             device="/dev/lp2f"
  202.             ;;
  203.         *)
  204.             ;;
  205.         esac
  206.     fi
  207. }
  208.  
  209. # Set up interface menu
  210. menufunc () { 
  211.     currdir=`pwd`
  212.     cd /usr/spool/lp/model
  213.     eval `awk '/^#!/ {
  214.           cnt++; $1 = ". "
  215.           files[cnt] = FILENAME
  216.           menu[cnt] = "\\\n\\\t" cnt $0
  217.         }
  218.     END    { print "count="cnt
  219.           print "files=\""
  220.           for (i = 1; i <= cnt; ++i)
  221.             print files[i]
  222.           print "\"", "menu=\""
  223.           for (i = 1; i <= cnt; ++i)
  224.             print menu[i]
  225.           print "\""
  226.          }' *`
  227.     cd $currdir
  228. }
  229.  
  230. # Choose interface program -- returns non-zero for quit
  231. modelfunc () { 
  232.     ones=z
  233.     tens=z
  234.     plus20=z
  235.     plus20ones=z
  236.     echo '
  237. If you have an unusual printer you must create an interface
  238. program in /usr/spool/lp/model. For a sample interface program
  239. look at /usr/spool/lp/model/dumb.'>&2
  240.     program=
  241.     menufunc
  242.     argc=$count
  243.         while mesg="$menu\n\nEnter one of the interface programs above or the full pathname of an interface
  244. program "
  245.     do  prompt || return 1
  246.         [ $count -gt 9 ] && {
  247.             tens="`expr $count / 10`"
  248.             ones="0-`expr $count % 10`"
  249.             count=9
  250.             [ $tens -gt 1 ] && {
  251.                 plus20=$tens
  252.                 tens="`expr $tens - 1`"
  253.                 plus20ones=$ones
  254.                 ones="0-9"
  255.             }
  256.         }
  257.         case $cmd in
  258.         [1-$count]|[1-$tens][$ones]|[$plus20][$plus20ones])
  259.             set -- dummy $files
  260.             shift $cmd
  261.                 eval program=/usr/spool/lp/model/\$1
  262.             break
  263.             ;;
  264.             /*)    [ -f "$cmd" ] && { 
  265.                 program=$cmd
  266.                 break
  267.             }
  268.             error "\'program\' variable not set"
  269.             ;;
  270.                 *)    echo "\nPlease enter a number between 1 and $argc or an absolute pathname" >&2 ;;
  271.             esac
  272.         done
  273.     file=`basename $program`
  274.     [ $file = network ] && { 
  275.         devflag="-v"
  276.         device="/dev/null"
  277.     }
  278.     # For parallel printers, prompt for special handling of form feeds etc
  279.     [ "$port" = "1" ] && specialdev
  280.     return 0
  281. }
  282.  
  283.  
  284. # Choose device for printer -- returns non-zero if 'device' is not valid
  285. devicefunc () { 
  286.     device=
  287.     serchoices=`cd /dev;ls -C tty[1-9][a-z]`
  288.     case $1 in
  289.     N)  # New printer
  290.             action=adding
  291.             ;;
  292.     R)  # Reconfigure printer
  293.             action=reconfiguring
  294.         echo "\nThe current configuration is:\n`lpstat -v`"
  295.             ;;
  296.     esac
  297.     while mesg="\t1. Parallel printer\n\t2. Serial printer\n\t3. Remote printer\n\nSelect the type of printer you are $action\n"
  298.     do
  299.         prompt || return 1
  300.         port=$cmd
  301.           case $port in
  302.           1)
  303.             echo "\nStandard parallel devices on your system are:\n\n$pchoices">&2
  304.             while mesg="Enter a device or 'h' for help\n"
  305.             do
  306.                 prompt || break
  307.                 reply=$cmd
  308.                 validpar $reply && break 2
  309.                 helpparallel
  310.             done
  311.               ;;
  312.           2)  
  313.                 echo "\nStandard serial devices on your system are:\n\n$serchoices">&2
  314.             while mesg="Enter a device or 'h' for help\n"
  315.             do
  316.                 prompt || break
  317.                 validser $cmd && { 
  318.                     if grep 1.`expr "$device" : "/dev/\(.*\)"` /etc/ttys >/dev/null
  319.                     then
  320.                         echo "\n$device is enabled as a login terminal.\c">&2
  321.                     getyn "Do you wish to continue?" && break 2
  322.                     else
  323.                     break 2
  324.                     fi
  325.                 }
  326.                 helpserial
  327.             done
  328.                   ;;
  329.         3)
  330.             device=/dev/null
  331.             break
  332.             ;;
  333.           *)      error "unknown option: \"$port\""
  334.                   continue
  335.              ;;
  336.           esac
  337.     done    
  338.     [ -c "$device" ] || error "not a character special file"
  339.     return $?
  340. }
  341.  
  342. # Set up a remote printer
  343. setremote() { 
  344.     quit="return to the main menu"
  345.     mesg="Enter the node name of the remote computer to which your printer is connected\n"
  346.     while :
  347.     do
  348.         prompt || return $FAIL
  349.         machine=$cmd
  350.         break
  351.     done
  352.  
  353.     mesg="Enter the name of the printer you wish to use on $machine\n"
  354.     while remname=
  355.     do
  356.         prompt || return $FAIL
  357.         remname=$cmd
  358.         break
  359.     done
  360.  
  361.     connectmenu="Is $machine connected via:\n\n\t1. Micnet\n\t2. Uucp"
  362.     selecterror="\\\nPlease select 1 or 2"
  363.     netremote="echo $selecterror >& 2;continue"
  364.  
  365.     [ -f /etc/perms/net ] && { 
  366.         _currdir=`pwd`
  367.         cd /
  368.         if /etc/fixperm -i -dNET /etc/perms/net
  369.         then
  370.             connectmenu="$connectmenu\n\t3. XENIX-Net"
  371.             netremote='rementry="$prname: /usr/lib/xnet/xnlpc $machine lp -d$remname"'
  372.             selecterror="\nPlease select 1, 2 or 3"
  373.         fi
  374.         cd $_currdir
  375.     }
  376.  
  377.     while    mesg="$connectmenu\n\nSelect an option "
  378.     do
  379.         prompt || return $FAIL
  380.         system=$cmd
  381.         case $system in
  382.         1)
  383.             rementry="$prname: remote - $machine lp -d$remname"
  384.             break
  385.             ;;
  386.         2)
  387.             rementry="$prname: uux - $machine!lp -d$remname"
  388.             break
  389.             ;;
  390.         3)
  391.             eval $netremote 
  392.             break
  393.             ;;
  394.         *)
  395.             echo $selecterror >&2
  396.             ;;
  397.         esac
  398.     done
  399.  
  400.     [ -f /usr/spool/lp/remote ] || > /usr/spool/lp/remote
  401.     grep -s "$rementry" /usr/spool/lp/remote >/dev/null || echo "$rementry" >> /usr/spool/lp/remote
  402.     if getyn "Is your remote printer an Imagen laser printer?"
  403.     then
  404.         if [ -f /usr/spool/lp/model/imagen.rem ]
  405.         then
  406.             program="/usr/spool/lp/model/imagen.rem"
  407.         else
  408.             error "Imagen interface script not found"
  409.             return 1
  410.         fi
  411.     else
  412.         if [ -f /usr/spool/lp/model/network ]
  413.         then
  414.             program="/usr/spool/lp/model/network"
  415.         else
  416.             error "Network interface script not found"
  417.             return 1
  418.         fi
  419.     fi
  420.     return 0
  421. }
  422.  
  423. #
  424. # Top level menu functions
  425. #
  426.  
  427. # Add a new printer - return 0 if successful
  428. addprinter () { 
  429.     devicefunc N || return 1 
  430.     while prname=printer
  431.           mesg="Enter a name for the printer, press <RETURN> to use the default
  432. name ($prname) "
  433.     do    prompt $prname || return 1
  434.           prname=$cmd
  435.           [ -d $REQDIR/"$prname" ] || break 
  436.           error "printer \"$prname\" already exists"
  437.     done
  438.     if [ "$device" = "/dev/null" ]
  439.     then
  440.         setremote || return 1
  441.     else
  442.         modelfunc || return 1
  443.     fi
  444.     /usr/lib/lpadmin -p$prname -v$device -i$program || continue
  445.     chmod 666 $device || error "failed to change mode of $device"
  446.     /usr/lib/accept $prname
  447.     /bin/enable $prname
  448.     if getyn "Is this the default printer"
  449.     then
  450.         rm -f /dev/lp >/dev/null 2>&1
  451.         ln $device /dev/lp >/dev/null 2>&1
  452.         /usr/lib/lpadmin -d$prname
  453.     fi
  454.     schedrun="/usr/lib/lpsched"
  455.     echo "
  456. If you need to modify your interface program after installing it,
  457. the installed version is in $IFDIR/$prname.">&2
  458.     return 0
  459. }
  460.  
  461. # Remove a printer - return zero if successfully removed
  462. removeprinter () { 
  463.     prnames || return 1
  464.     mesg="Enter the name of the printer you want to remove\n"
  465.     prompt || return 1
  466.     rmname=$cmd
  467.     rmdev=`lpstat -v$rmname | sed "s/.*$rmname.*:[     ]*//"`
  468.     if [ "$rmdev" = "/dev/null" ]
  469.     then
  470.     sed "/^${rmname}/d" /usr/spool/lp/remote > $tmp.rm || { 
  471.         error "Failed to remove entry for $rmname from /usr/spool/lp/remote"
  472.         rm -f $tmp.rm
  473.     }
  474.     trap "" 1 2 3 15
  475.     mv $tmp.rm /usr/spool/lp/remote
  476.     trap 1 2 3 15
  477.     fi
  478.     /usr/lib/lpadmin -x$rmname || return 1
  479.     echo "\nPrinter \"$rmname\" removed">&2
  480.     return 0
  481. }
  482.  
  483. # Reconfigure an existing printer
  484. reconprinter () { 
  485.     while :
  486.     do
  487.         prnames || return 1
  488.         mesg="Enter the name of the printer you want to reconfigure\n"
  489.         prompt || return 1
  490.         recprinter=$cmd
  491.         if [ -d $REQDIR/"$recprinter" ]
  492.         then
  493.             recondev=`lpstat -v$recprinter | sed "s/.*$recprinter.*:[     ]*//"`
  494.             [ "$recondev" = "/dev/null" ] && { 
  495.             echo "\n$recprinter is a remote printer." >&2
  496.             getyn "Do you wish to continue" || return 1
  497.         }
  498.         break
  499.         else
  500.             error "\"$recprinter\" is not an existing printer"
  501.         fi
  502.     done
  503.     while mesg='\t1. Insert a printer into a class.
  504.     2. Remove a printer from a class.
  505.     3. Install a new interface program for a printer.
  506.     4. Associate a new device with a printer.
  507.  
  508. Enter an option '
  509.     do prompt || return 1
  510.         rchoice=$cmd
  511.         case $rchoice in
  512.         1)  # Insert a printer into a class
  513.         chkclass $recprinter
  514.         [ "$classes" ] && { 
  515.             echo "\nThe following is a list of existing classe(s) of printers:">&2
  516.             ls -1 $CLASSDIR
  517.         }
  518.         echo "\nYou may choose an existing class or create a new one.">&2
  519.         [ "$inclass" ] && echo "\n\"$recprinter\" is already in the following classe(s):\n\t$inclass" >&2
  520.             mesg="Enter the class into which it is to be inserted\n"
  521.             prompt || continue
  522.             class=$cmd
  523.         /usr/lib/lpadmin -p$recprinter -c$class || return 1
  524.         /usr/lib/accept $class >/dev/null 2>&1
  525.         echo "\n\"$recprinter\" inserted into class \"$class\"">&2
  526.         break
  527.         ;;
  528.         2)  # Remove a printer from a class.
  529.         chkclass $recprinter
  530.         [ "$classes" ] && { 
  531.             echo "\nThe following is a list of existing classes of printers and their members.">&2
  532.             /usr/bin/lpstat -c
  533.         }
  534.         [ "$cnt" = 0 ] && { 
  535.             error "\"$recprinter\" is not a member of any class"
  536.                 return 1
  537.         }
  538.         echo "\n\"$recprinter\" is in class(es): $inclass">&2
  539.             mesg="Enter the class from which it is to be removed\n"
  540.             prompt || continue
  541.             class=$cmd
  542.         /usr/lib/lpadmin -p$recprinter -r$class || continue
  543.         echo "\n\"$recprinter\" removed from class \"$class\"">&2
  544.         break
  545.         ;;
  546.         3)  # Install a new interface program for a printer.
  547.         [ "$recondev" = "/dev/null" ] && echo "\nRemote printers must use one of the network interface scripts."
  548.         modelfunc || continue
  549.         /usr/lib/lpadmin -p$recprinter $devflag$device -i$program || continue
  550.         echo "\nNew interface installed for \"$recprinter\"">&2
  551.         devflag=
  552.         device=
  553.         break
  554.         ;;
  555.         4)  # Associate a new device with a printer
  556.         [ "$recondev" = "/dev/null" ] && echo "\nRemote printers must be associated with /dev/null."
  557.         devicefunc R || continue 
  558.         /usr/lib/lpadmin -p$recprinter -v$device || continue
  559.         echo "\n\"$recprinter\" now attached to $device">&2
  560.         break
  561.         ;;
  562.         *)
  563.         error "unknown option: $rchoice"
  564.         continue
  565.         ;;
  566.         esac
  567.     done
  568.     return 0
  569. }
  570.  
  571. # Assign a default printer
  572. newdefault () { 
  573.     echo
  574.     lpstat -d
  575.     prnames || return 1
  576.     mesg="Enter the name of the new system default destination\n"
  577.     prompt || return 1
  578.     newdef=$cmd
  579.         newdev=`lpstat -v | sed "s/.*$newdef.*:[     ]*\(.*\)[     ]*$/\1/"`
  580.     rm -f /dev/lp >/dev/null 2>&1
  581.     ln $newdev /dev/lp >/dev/null 2>&1
  582.     /usr/lib/lpadmin -p$newdef -i$program
  583.     /usr/lib/lpadmin -d$newdef && echo "\nNew system default destination: $newdef">&2
  584.     return 0
  585. }
  586.  
  587. # Print lp status information
  588. printstatus () { 
  589.     while mesg='\t1. Print existing printer names.
  590.     2. Print class names and their members.
  591.     3. Print system default destination.
  592.     4. Print devices associated with printers.
  593.     5. Print all status information.
  594.  
  595. Enter an option '
  596.     do  prompt || return 1
  597.         schoice=$cmd
  598.         echo
  599.         case $schoice in
  600.         1)    # Print existing printer names
  601.         prnames || return 1
  602.         break
  603.         ;;
  604.         2)  # Print class names and their members
  605.         classes=`ls $CLASSDIR`
  606.         [ "$classes" ] || { 
  607.             echo "\nThere are no existing printer classes."
  608.             return 1
  609.         }
  610.         lpstat -c
  611.         break
  612.         ;;
  613.         3)    # Print system default destination
  614.         lpstat -d
  615.         break
  616.         ;;
  617.         4)  # Print devices associated with printers
  618.         prnames || return 1 
  619.         lpstat -v
  620.         break
  621.         ;;
  622.         5)  # Print all status information
  623.         lpstat -t
  624.         break
  625.         ;;
  626.         *)
  627.         error "unknown option: \"$schoice\""
  628.         esac
  629.     done
  630.     return 0
  631. }
  632.  
  633. #
  634. # main()
  635. #
  636. cd /
  637. [ -f /usr/lib/mkdev/perms/LPR ] && /etc/fixperm -c -dLPR /usr/lib/mkdev/perms/LPR
  638.  
  639. case `lpstat -r` in
  640. *not*)
  641.     schedrun=
  642.     ;;
  643. *is*)
  644.     echo '
  645. WARNING: The scheduler is running. If you have jobs that are being printed
  646. they may be interrupted. Any interrupted printing jobs will be re-printed
  647. in full when the scheduler is restarted.' >&2
  648.     getyn "Do you wish to continue?" || exit $OK
  649.     /usr/lib/lpshut
  650.     schedrun="/usr/lib/lpsched"
  651.     ;;
  652. esac
  653.  
  654. while  
  655.   mesg='\t1. Add a new printer.
  656.     2. Remove a printer.
  657.     3. Reconfigure an existing printer.
  658.     4. Assign a default printer.
  659.     5. Print lp status information.
  660.  
  661. Select an option '
  662.   quit=quit
  663. do
  664.   prompt
  665.   choice=$cmd
  666.   quit="return to the previous menu"
  667.   case $choice in
  668.   1)    # Add a new printer
  669.     addprinter
  670.     ;;
  671.   2)    # Remove a printer
  672.     removeprinter
  673.     ;;
  674.   3)    # Reconfigure an existing printer
  675.     reconprinter
  676.     ;;
  677.   4)    # Assign a default printer
  678.     newdefault
  679.     ;;
  680.   5)    # Print lp status information
  681.     printstatus
  682.     ;;
  683.   [qQ]) break ;;
  684.   *)    error "unknown option: \"$choice\""
  685.     ;;
  686.   esac
  687. done
  688.  
  689. eval $schedrun
  690. exit $OK
  691.