home *** CD-ROM | disk | FTP | other *** search
Wrap
: # @(#) lp.sh 1.23 88/12/09 # # Copyright (C) The Santa Cruz Operation, 1986. # This Module contains Proprietary and Confidential # Information of The Santa Cruz Operation, Inc. # # # THIS FILE CONTAINS CODE SPECIFIC TO THE IBM PC/XT AND PC/AT WORK-ALIKES # RUNNING SCO XENIX-*86. IT MAY REQUIRE MODIFICATION FOR DIFFERENT MACHINE # ARCHITECTURES OR CONFIGURATIONS. # # lpinit - set up a default printer for the LP Spooler on IBM PC/XT and # PC/AT work-alikes. Options now exist for reconfiguring existing printers # removing printers and reconfiguring classes of printers. # # only the super-user can execute this script meaningfully. # PATH=/bin:/usr/bin:/etc SPOOLDIR="/usr/spool/lp" REQDIR="$SPOOLDIR/request" IFDIR="$SPOOLDIR/interface" CLASSDIR="$SPOOLDIR/class" tmp=/tmp/lp$$ # Define return values : ${OK=0} ${FAIL=1} ${STOP=10} ${HALT=11} # pchoices is machine dependent pchoices="\tlp0\n\tlp0i\n\tlp1\n\tlp1i\n\tlp2\n\tlp2i" trap 'eval $schedrun echo "\n\n\007INTERRUPTED">&2 exit $FAIL' 1 2 3 15 ######################## # Function definitions # ######################## # # Machine dependent functions # # Check if parallel device is valid - return non-zero if not validpar () { device= case $1 in *lp0) device=/dev/lp0 ;; *lp0i) device=/dev/lp0i ;; *lp1) device=/dev/lp1 ;; *lp1i) device=/dev/lp1i ;; *lp2) device=/dev/lp2 ;; *lp2i) device=/dev/lp2i ;; /dev/*) [ -b $1 -o -c $1 ] && device=$1 ;; dev/*) [ -b /$1 -o -c /$1 ] && device=/$1 ;; [hH]) return 1 ;; *) [ -b /dev/$1 -o -c /dev/$1 ] && device=/dev/$1 ;; esac [ $device ] || error "Not a valid parallel device: $1" return $? } # Print help screen for parallel devices helpparallel () { echo "\nStandard parallel devices on your system are: lp0 ----- Main parallel port lp0i ---- Main parallel port (sends an init on each open) lp1 ----- Parallel port on monochrome card lp1i ---- Parallel port on monochrome card (sends an init on each open) lp2 ----- Alternate parallel port lp2i ---- Alternate parallel port (sends an init on each open) Note: On some systems lp0 and lp1 are reversed.\n">&2 } # # Generic functions # # Check if serial device is valid - return non-zero if not validser () { device= case $1 in /dev/tty[1-9][a-z]) device="$1";; dev/tty[1-9][a-z]) device="/$1";; tty[1-9][a-z]) device="/dev/$1";; [hH]) return 1 ;; /dev/*) [ -b $1 -o -c $1 ] && device=$1 ;; dev/*) [ -b /$1 -o -c /$1 ] && device=/$1 ;; *) [ -b /dev/$1 -o -c /dev/$1 ] && device=/dev/$1 ;; esac [ $device ] || error "Not a valid serial device: $1" return $? } # Print help screen for serial devices helpserial () { echo "\nStandard serial devices on your system are:\n" >&2 sed -n 's/0.\(tty[1-9][a-z]\)/\1/p s/1.\(tty[1-9][a-z]\)/\1 ----- enabled for login/p' /etc/ttys | pr -t -l22 -2 } # Print an error message error() { echo "\nError: $*" >&2 return 1 } # Prompt for yes or no answer - returns non-zero for no getyn() { while echo "\n$* (y/n) \c">&2 do read yn rest case $yn in [yY]) return 0 ;; [nN]) return 1 ;; *) echo "Please answer y or n" >&2 ;; esac done } # Prompt with mesg, return non-zero on q prompt() { while echo "\n${mesg}or enter q to $quit: \c" >&2 do read cmd case $cmd in +x|-x) set $cmd ;; Q|q) return 1 ;; !*) eval `expr "$cmd" : "!\(.*\)"` ;; "") # If there is an argument use it as the default # else loop until 'cmd' is set [ "$1" ] && { cmd=$1 return 0 } : continue ;; *) return 0 ;; esac done } # Print existing printer names - return non-zero if there are none prnames () { printers=`lpstat -v` [ "$printers" ] || { echo "\nThere are no existing printers." >&2 return 1 } echo "\nExisting printers are:" >&2 echo "$printers" | sed 's/device for \(.*\):.*/\1/p' return 0 } # Check printer membership in classes -- returns the number of classes chkclass () { class= inclass= classes=`cd $CLASSDIR; echo *` [ "$classes" = "*" ] && classes= cnt=0 for i in $classes do grep $1 $CLASSDIR/$i >/dev/null && { inclass="$inclass $i" cnt=`expr $cnt + 1` } done return $cnt } # Set new device for printers which require special form feed handling specialdev() { 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? " then case $device in *lp0) device="/dev/lp0f" ;; *lp1) device="/dev/lp1f" ;; *lp2) device="/dev/lp2f" ;; *) ;; esac fi } # Set up interface menu menufunc () { currdir=`pwd` cd /usr/spool/lp/model eval `awk '/^#!/ { cnt++; $1 = ". " files[cnt] = FILENAME menu[cnt] = "\\\n\\\t" cnt $0 } END { print "count="cnt print "files=\"" for (i = 1; i <= cnt; ++i) print files[i] print "\"", "menu=\"" for (i = 1; i <= cnt; ++i) print menu[i] print "\"" }' *` cd $currdir } # Choose interface program -- returns non-zero for quit modelfunc () { ones=z tens=z plus20=z plus20ones=z echo ' If you have an unusual printer you must create an interface program in /usr/spool/lp/model. For a sample interface program look at /usr/spool/lp/model/dumb.'>&2 program= menufunc argc=$count while mesg="$menu\n\nEnter one of the interface programs above or the full pathname of an interface program " do prompt || return 1 [ $count -gt 9 ] && { tens="`expr $count / 10`" ones="0-`expr $count % 10`" count=9 [ $tens -gt 1 ] && { plus20=$tens tens="`expr $tens - 1`" plus20ones=$ones ones="0-9" } } case $cmd in [1-$count]|[1-$tens][$ones]|[$plus20][$plus20ones]) set -- dummy $files shift $cmd eval program=/usr/spool/lp/model/\$1 break ;; /*) [ -f "$cmd" ] && { program=$cmd break } error "\'program\' variable not set" ;; *) echo "\nPlease enter a number between 1 and $argc or an absolute pathname" >&2 ;; esac done file=`basename $program` [ $file = network ] && { devflag="-v" device="/dev/null" } # For parallel printers, prompt for special handling of form feeds etc [ "$port" = "1" ] && specialdev return 0 } # Choose device for printer -- returns non-zero if 'device' is not valid devicefunc () { device= serchoices=`cd /dev;ls -C tty[1-9][a-z]` case $1 in N) # New printer action=adding ;; R) # Reconfigure printer action=reconfiguring echo "\nThe current configuration is:\n`lpstat -v`" ;; esac while mesg="\t1. Parallel printer\n\t2. Serial printer\n\t3. Remote printer\n\nSelect the type of printer you are $action\n" do prompt || return 1 port=$cmd case $port in 1) echo "\nStandard parallel devices on your system are:\n\n$pchoices">&2 while mesg="Enter a device or 'h' for help\n" do prompt || break reply=$cmd validpar $reply && break 2 helpparallel done ;; 2) echo "\nStandard serial devices on your system are:\n\n$serchoices">&2 while mesg="Enter a device or 'h' for help\n" do prompt || break validser $cmd && { if grep 1.`expr "$device" : "/dev/\(.*\)"` /etc/ttys >/dev/null then echo "\n$device is enabled as a login terminal.\c">&2 getyn "Do you wish to continue?" && break 2 else break 2 fi } helpserial done ;; 3) device=/dev/null break ;; *) error "unknown option: \"$port\"" continue ;; esac done [ -c "$device" ] || error "not a character special file" return $? } # Set up a remote printer setremote() { quit="return to the main menu" mesg="Enter the node name of the remote computer to which your printer is connected\n" while : do prompt || return $FAIL machine=$cmd break done mesg="Enter the name of the printer you wish to use on $machine\n" while remname= do prompt || return $FAIL remname=$cmd break done connectmenu="Is $machine connected via:\n\n\t1. Micnet\n\t2. Uucp" selecterror="\\\nPlease select 1 or 2" netremote="echo $selecterror >& 2;continue" [ -f /etc/perms/net ] && { _currdir=`pwd` cd / if /etc/fixperm -i -dNET /etc/perms/net then connectmenu="$connectmenu\n\t3. XENIX-Net" netremote='rementry="$prname: /usr/lib/xnet/xnlpc $machine lp -d$remname"' selecterror="\nPlease select 1, 2 or 3" fi cd $_currdir } while mesg="$connectmenu\n\nSelect an option " do prompt || return $FAIL system=$cmd case $system in 1) rementry="$prname: remote - $machine lp -d$remname" break ;; 2) rementry="$prname: uux - $machine!lp -d$remname" break ;; 3) eval $netremote break ;; *) echo $selecterror >&2 ;; esac done [ -f /usr/spool/lp/remote ] || > /usr/spool/lp/remote grep -s "$rementry" /usr/spool/lp/remote >/dev/null || echo "$rementry" >> /usr/spool/lp/remote if getyn "Is your remote printer an Imagen laser printer?" then if [ -f /usr/spool/lp/model/imagen.rem ] then program="/usr/spool/lp/model/imagen.rem" else error "Imagen interface script not found" return 1 fi else if [ -f /usr/spool/lp/model/network ] then program="/usr/spool/lp/model/network" else error "Network interface script not found" return 1 fi fi return 0 } # # Top level menu functions # # Add a new printer - return 0 if successful addprinter () { devicefunc N || return 1 while prname=printer mesg="Enter a name for the printer, press <RETURN> to use the default name ($prname) " do prompt $prname || return 1 prname=$cmd [ -d $REQDIR/"$prname" ] || break error "printer \"$prname\" already exists" done if [ "$device" = "/dev/null" ] then setremote || return 1 else modelfunc || return 1 fi /usr/lib/lpadmin -p$prname -v$device -i$program || continue chmod 666 $device || error "failed to change mode of $device" /usr/lib/accept $prname /bin/enable $prname if getyn "Is this the default printer" then rm -f /dev/lp >/dev/null 2>&1 ln $device /dev/lp >/dev/null 2>&1 /usr/lib/lpadmin -d$prname fi schedrun="/usr/lib/lpsched" echo " If you need to modify your interface program after installing it, the installed version is in $IFDIR/$prname.">&2 return 0 } # Remove a printer - return zero if successfully removed removeprinter () { prnames || return 1 mesg="Enter the name of the printer you want to remove\n" prompt || return 1 rmname=$cmd rmdev=`lpstat -v$rmname | sed "s/.*$rmname.*:[ ]*//"` if [ "$rmdev" = "/dev/null" ] then sed "/^${rmname}/d" /usr/spool/lp/remote > $tmp.rm || { error "Failed to remove entry for $rmname from /usr/spool/lp/remote" rm -f $tmp.rm } trap "" 1 2 3 15 mv $tmp.rm /usr/spool/lp/remote trap 1 2 3 15 fi /usr/lib/lpadmin -x$rmname || return 1 echo "\nPrinter \"$rmname\" removed">&2 return 0 } # Reconfigure an existing printer reconprinter () { while : do prnames || return 1 mesg="Enter the name of the printer you want to reconfigure\n" prompt || return 1 recprinter=$cmd if [ -d $REQDIR/"$recprinter" ] then recondev=`lpstat -v$recprinter | sed "s/.*$recprinter.*:[ ]*//"` [ "$recondev" = "/dev/null" ] && { echo "\n$recprinter is a remote printer." >&2 getyn "Do you wish to continue" || return 1 } break else error "\"$recprinter\" is not an existing printer" fi done while mesg='\t1. Insert a printer into a class. 2. Remove a printer from a class. 3. Install a new interface program for a printer. 4. Associate a new device with a printer. Enter an option ' do prompt || return 1 rchoice=$cmd case $rchoice in 1) # Insert a printer into a class chkclass $recprinter [ "$classes" ] && { echo "\nThe following is a list of existing classe(s) of printers:">&2 ls -1 $CLASSDIR } echo "\nYou may choose an existing class or create a new one.">&2 [ "$inclass" ] && echo "\n\"$recprinter\" is already in the following classe(s):\n\t$inclass" >&2 mesg="Enter the class into which it is to be inserted\n" prompt || continue class=$cmd /usr/lib/lpadmin -p$recprinter -c$class || return 1 /usr/lib/accept $class >/dev/null 2>&1 echo "\n\"$recprinter\" inserted into class \"$class\"">&2 break ;; 2) # Remove a printer from a class. chkclass $recprinter [ "$classes" ] && { echo "\nThe following is a list of existing classes of printers and their members.">&2 /usr/bin/lpstat -c } [ "$cnt" = 0 ] && { error "\"$recprinter\" is not a member of any class" return 1 } echo "\n\"$recprinter\" is in class(es): $inclass">&2 mesg="Enter the class from which it is to be removed\n" prompt || continue class=$cmd /usr/lib/lpadmin -p$recprinter -r$class || continue echo "\n\"$recprinter\" removed from class \"$class\"">&2 break ;; 3) # Install a new interface program for a printer. [ "$recondev" = "/dev/null" ] && echo "\nRemote printers must use one of the network interface scripts." modelfunc || continue /usr/lib/lpadmin -p$recprinter $devflag$device -i$program || continue echo "\nNew interface installed for \"$recprinter\"">&2 devflag= device= break ;; 4) # Associate a new device with a printer [ "$recondev" = "/dev/null" ] && echo "\nRemote printers must be associated with /dev/null." devicefunc R || continue /usr/lib/lpadmin -p$recprinter -v$device || continue echo "\n\"$recprinter\" now attached to $device">&2 break ;; *) error "unknown option: $rchoice" continue ;; esac done return 0 } # Assign a default printer newdefault () { echo lpstat -d prnames || return 1 mesg="Enter the name of the new system default destination\n" prompt || return 1 newdef=$cmd newdev=`lpstat -v | sed "s/.*$newdef.*:[ ]*\(.*\)[ ]*$/\1/"` rm -f /dev/lp >/dev/null 2>&1 ln $newdev /dev/lp >/dev/null 2>&1 /usr/lib/lpadmin -p$newdef -i$program /usr/lib/lpadmin -d$newdef && echo "\nNew system default destination: $newdef">&2 return 0 } # Print lp status information printstatus () { while mesg='\t1. Print existing printer names. 2. Print class names and their members. 3. Print system default destination. 4. Print devices associated with printers. 5. Print all status information. Enter an option ' do prompt || return 1 schoice=$cmd echo case $schoice in 1) # Print existing printer names prnames || return 1 break ;; 2) # Print class names and their members classes=`ls $CLASSDIR` [ "$classes" ] || { echo "\nThere are no existing printer classes." return 1 } lpstat -c break ;; 3) # Print system default destination lpstat -d break ;; 4) # Print devices associated with printers prnames || return 1 lpstat -v break ;; 5) # Print all status information lpstat -t break ;; *) error "unknown option: \"$schoice\"" esac done return 0 } # # main() # cd / [ -f /usr/lib/mkdev/perms/LPR ] && /etc/fixperm -c -dLPR /usr/lib/mkdev/perms/LPR case `lpstat -r` in *not*) schedrun= ;; *is*) echo ' WARNING: The scheduler is running. If you have jobs that are being printed they may be interrupted. Any interrupted printing jobs will be re-printed in full when the scheduler is restarted.' >&2 getyn "Do you wish to continue?" || exit $OK /usr/lib/lpshut schedrun="/usr/lib/lpsched" ;; esac while mesg='\t1. Add a new printer. 2. Remove a printer. 3. Reconfigure an existing printer. 4. Assign a default printer. 5. Print lp status information. Select an option ' quit=quit do prompt choice=$cmd quit="return to the previous menu" case $choice in 1) # Add a new printer addprinter ;; 2) # Remove a printer removeprinter ;; 3) # Reconfigure an existing printer reconprinter ;; 4) # Assign a default printer newdefault ;; 5) # Print lp status information printstatus ;; [qQ]) break ;; *) error "unknown option: \"$choice\"" ;; esac done eval $schedrun exit $OK