#! /bin/bash # # apsfilter.setup for configuration of apsfilter # # Copyright 1996 S.u.S.E. GmbH # Author: Werner Fink # # Version: @@version@@ # # Note: it _is_ complicated # # Global environment # APSFILTER=@@/var/lib/apsfilter@@ APSRC=/etc/apsfilterrc SPOOL=/var/spool/lpd LP_OWNER="lp" LP_GROUP="lp" METHODS="ascii auto raw" PRINTCAP="/etc/printcap" OLDCAP="${PRINTCAP}.old" TMPPCAP="/tmp/printcap.aps$$" LABEL="" SLABEL="### BEGIN apsfilter:" WLABEL="# Warning: Configured for apsfilter, do not edit the labels!" DLABEL="# apsfilter setup `date`" ELABEL="### END apsfilter:" OLABEL="LABEL apsfilter" PNAME="" TODO="add" CLEAR="" HOST="" DEVICE="" SERIAL="" PRINTER="" PAPER="" COLOR="mono" DPI="" DVIPS="" NO_FF_SEP="" declare -i lp=0 declare -i ascii=0 declare -i raw=0 declare -i auto=0 declare -i remote=0 # # Check first # rm -f $TMPPCAP if [ -e $TMPPCAP ] ; then echo "Our temporary file $TMPPCAP already exists" 1>&2 exit 1 fi # # On an interrupt we want exit cleanly # trap "rm -f $TMPPCAP; exit" 0 1 3 5 9 10 13 15 trap "exit 1" 2 # # We want be called in a simple way # usage () { echo -e "$0: Usage: For help: $0 --help Overwrite|Add local printer entry in printcap: $0 [-O|-A] -d -G [-s ] \\ -t (-c|-m) -r [-nf] [-M ] [-N ] Delete local printer entry in printcap: $0 -D -G -t (-c|-m) -r [-N ] Overwrite|Add a remote default printer of a host in local printcap: $0 [-O|-A] -h -R [-nf] [-N ] Delete a remote default printer of a host in local printcap: $0 -D -h -R [-N ] List apsfilter printer entries in printcap: $0 -L" 1>&2 exit 1 } apshelp () { echo "$0: Help and Usage of $0 Operations: -A Add an new entry in /etc/printcap. -O Overwrite an existing entry in /etc/printcap. -O Delete an existing entry in /etc/printcap. -L List all existing entries in /etc/printcap done by $0. Specifications: -G The name of the ghostscript driver for the printer. -d The full path to an existing device/interface. -s The optional baud rate of a parallel interface. -t The paper size of the printer. -c Colorfull printer or -m Monochrome printer. -r The resolution in DPI (i.e.: 300, 300x600, ...) -nf Set \`sf' in printcap entry (suppress form feeds between two print jobs). -M The name of an optional dvips printer, should be configured (e.g.: with texconfig under the tetex package). -h The hostname a remote printer server. -R The name of the remote printer. -N The optional starting name of a printer. (a|b) \`a' or \`b' not both settings [a] \`a' is an optional setting Examples: Overwrite|Add local printer entry in printcap: $0 (-O|-A [--clear]) -d -G [-s ] \\ -t (-c|-m) -r [-nf] [-M ] [-N ] Delete local printer entry in printcap: $0 -D -G -t (-c|-m) -r [-N ] Overwrite|Add a remote default printer of a host in local printcap: $0 (-O|-A [--clear]) -h -R [-nf] [-N ] Delete a remote default printer of a host in local printcap: $0 -D -h -R [-N ] List apsfilter printer entries in printcap: $0 -L " 1>&2 exit 0 } ## ## If we write to the /etc/printcap ## printpc () { echo -e "$*" >> $PRINTCAP } ## ## Uh .. do it verbosely ## printlg () { echo -e "$*" 1>&2 } ## ## Read options ## [ -z "$1" ] && usage while [ -n "$1" ] ; do case $1 in -h) HOST=${2} ; shift ; shift ;; -A) TODO="add" ; shift ;; -O) TODO="ovw" ; shift ;; -D) TODO="del" ; shift ;; -L) TODO="shw" ; shift ;; -nf) NO_FF_SEP="yes" ; shift ;; -d) DEVICE=${2} ; shift ; shift ;; -s) SERIAL=${2} ; shift ; shift ;; -G) PRINTER=${2} ; shift ; shift ;; -R) RPRINTER=${2} ; shift ; shift ;; -N) PNAME=${2} ; shift ; shift ;; -t) PAPER=${2} ; shift ; shift ;; -c) COLOR="color" ; shift ;; -m) COLOR="mono" ; shift ;; -r) DPI=${2} ; shift ; shift ;; -M) DVIPS=${2} ; shift ; shift ;; --clear) CLEAR="yes" ; shift ;; --help) apshelp ;; *) usage ;; esac done [ "$CLEAR" = "yes" -a "$TODO" != "add" ] && usage [ -z "$DPI" ] && DPI="default" ## ## List all printer enties of apsfilter in /etc/printcap ## if [ "$TODO" = "shw" ] ; then sed "/^${SLABEL}\$/,/^${ELABEL}\$/d" < $PRINTCAP | \ grep -E "^($SLABEL|[a-z0-9A-Z\-]+\|)" | \ sed "s/^${SLABEL}//g;\ s/\:\\\\//g" 1>&2 # # Ok .. done # exit 0 fi ## ## Check options, set defaults and lables ## if [ -n "$HOST" ] ; then # # Paranoid # if [ "${HOST%%.*}" = "lp" ] ; then echo "$0: Conflicting names of host and default printer queue" 1>&2 exit 1 fi # SHOST="${HOST%%.*}" SHOST="${HOST}" # # These things belongs to the remote printer server # DEVICE="/dev/null" PRINTER="remote" [ -z "$RPRINTER" ] && usage PAPER="unknown" DPI="unknown" METHODS="remote" # # LABEL for identification of the remote printer # if [ -n "$PNAME" ]; then LABEL="### $PRINTER $SHOST $RPRINTER $PNAME ###" else LABEL="### $PRINTER $SHOST $RPRINTER ###" fi else # # if we want to delete an entry we don't look one the device # but on the printer name # [ "$TODO" = "del" ] && { DEVICE="unknown"; } # # We need it # [ -z "$DEVICE" -o -z "$PRINTER" -o \ -z "$PAPER" -o -z "$COLOR" -o -z "$DPI" ] && usage case $PAPER in letter|legal|ledger) ;; 11x17) ;; a[0123456789]) ;; a10) ;; b[012345]) ;; arch[EDCBA]) ;; fls[ae]) ;; halfletter|note) ;; *) usage ;; esac [ `echo $DPI|grep -cE '^(default|[0-9]+|[0-9]+x[0-9]+)$'` -eq 0 ] && usage # # Shorten the resolution if horizontal resolution # is equal to vertical resolution # set -- `echo ${DPI}| tr 'x' ' '` [ -n "$2" ] && [ $1 -eq $2 ] && DPI="$1" # # LABEL for identification for local printers # if [ -n "$PNAME" ]; then LABEL="### $PRINTER $PAPER $COLOR $DPI $PNAME ###" else LABEL="### $PRINTER $PAPER $COLOR $DPI ###" fi fi ## ## Color methods: on color we want mono too ## second="" if [ "$COLOR" = "color" ] ; then COLOR="$COLOR mono" # If we have a color Printer # we have a `only mono' device too second="mono" fi # # Save original /etc/printcap # and clean example entry of /etc/printcap # out of the packages lprold/plp # touch $PRINTCAP # # Save original /etc/printcap to /etc/printcap.orig # [ ! -f ${PRINTCAP}.orig ] && cp $PRINTCAP ${PRINTCAP}.orig # # Clean the stupid example # sed 's@^\(lp:lp=/dev/lp1:sd=/usr/spool/lp1:sh\)@#\1@g' < $PRINTCAP > $OLDCAP # # Our working files: changes going to /etc/printcap # refrence is /etc/printcap.old # cp $OLDCAP $PRINTCAP ## ## Special for YaST: the old overwrite of apsfilter removes all ## aps entries. Therefore, if we are called with --clear ## we will clear /etc/printcap ## if [ "$CLEAR" = "yes" -a "$TODO" = "add" ] ; then # # Clear /etc/printcap ... means remove all # entries of this script or an old aps-SETUP # cp $PRINTCAP $TMPPCAP lines=$(cat $TMPPCAP| wc -l) sed "/${OLABEL}$\|^${SLABEL}/,${lines}d" < $TMPPCAP > $PRINTCAP # fi ## ## Now set extended Start and End label of our special entry ## SLABEL="$SLABEL $LABEL" ELABEL="$ELABEL $LABEL" ## ## Befor adding an entry we will check lp names ## if [ "$TODO" = "add" ] ; then # # Paranoid ... maybe there is a hand written entry # ... we have to count lp1 .. lpN names correctly !! # cp $PRINTCAP $TMPPCAP cat $TMPPCAP | awk 'BEGIN { n=0 } \ { \ if (/lp([0-9]+)\|/) { \ n++ ; gsub(/lp([0-9]+)\|/,"lp" n "|" ) \ } \ print $0 \ }' > $PRINTCAP # # We add a printer only if lines not zero # ... means there is no equal entry # lines=$(sed -n "/^${SLABEL}\$/,/^${ELABEL}\$/p" < $PRINTCAP | wc -l) # # lines > 0 ... oops there IS an entry # if [ $lines -gt 0 ] ; then echo "$0: Entry $LABEL exists" 1>&2 exit 1 fi # fi ## ## Overwrite, delete, or append existing apsfilter entry in /etc/printcap ## if [ "$TODO" = "ovw" -o "$TODO" = "del" ] ; then # # Check # check=$(grep -cE "^${SLABEL}" $PRINTCAP) [ $check -eq 0 ] && { echo "$0: No entry $LABEL" 1>&2 ; exit 1; } # # Maybe we have to remove some links and spool directories # if [ "$TODO" = "del" ] ; then remove=$(sed -n "/^${SLABEL}\$/,/^${ELABEL}\$/p" < $PRINTCAP | \ grep -E ':sd=|:if=' | sed 's/:\|\\/ /g') fi # # Remove an existing apsfilter entry out of /etc/printcap # sed "/^${SLABEL}\$/,/^${ELABEL}\$/d" < $PRINTCAP > $TMPPCAP # # If we overwrite or delete an entry we have to # update the lp1 ... lpN names in the remaining entries # cat $TMPPCAP | awk 'BEGIN { n=0 } \ { \ if (/lp([0-9]+)\|/) { \ n++ ; gsub(/lp([0-9]+)\|/,"lp" n "|" ) \ } \ print $0 \ }' > $PRINTCAP # # On delete action our work is done # if [ "$TODO" = "del" ] ; then # # Remove if and only if links and spool directories # not used by another entry # for d in $remove ; do check=$(grep -c ":${d}:" $PRINTCAP) if [ $check -eq 0 ] ; then case $d in sd=*) rm -rf ${d#*=} ;; if=*) rm -f ${d#*=} ;; esac fi done exit 0 fi # # Puh, now we can act like `adding a new entry' # TODO="add" # fi ## ## Never needed any more ## rm -f $TMPPCAP ## ## Now we want to add an new entry ... ## [ "$TODO" != "add" ] && exit 0 # # Let's count some printer entries # lp=0 ascii=0 raw=0 auto=0 remote=0 # # We count all lp1 ... lpN entries # lp=$(cat $PRINTCAP | awk 'BEGIN {n=0} {if (/lp([0-9]+)\|/) n++} END {print n}') lp=$((lp + 1)) # # These are all entries of the default printer # ascii=`grep -cE "^ascii\|" $PRINTCAP` raw=`grep -cE "^raw\|" $PRINTCAP` auto=`grep -cE "^lp(-mono|)\|" $PRINTCAP` remote=`grep -cE "^remote\|" $PRINTCAP` # # mono printer: one entry counts like 2 auto entries # of a color one ... # [ $auto -eq 1 ] && auto=2 # # Now built all possible printer entries # for our printer # name="" for m in $METHODS ; do # # local APS-conform printer spool # name := ${PRINTER}-${PAPER}-${m}[-${c}-${DPI}] # PRINTER= # PAPER= # m=ascii,auto,raw # c=mono,color # DPI= # case $m in ascii) # # if ascii=0 we have the default entry belonging to `lp' main="${PRINTER}-ascii" [ -n "$PNAME" ] && main="${PNAME}-ascii" [ $ascii -eq 0 ] && main="ascii" ascii=$((ascii + 1)) lpN="lp${lp}" ; lp=$((lp + 1)) comment="${PRINTER}~${PAPER}~${m}~mono~${DPI}" spool="${PRINTER}-${PAPER}-${m}-mono-${DPI}" name="$name ${main}|${lpN}|${spool}|${comment}" ;; auto) # # if auto=0 we have the default entry `lp' # if auto=1 we have the mono entry belonging to `lp' # ... therefore we have to count a mono `lp' twice for c in $COLOR ; do main="${PRINTER}" [ -n "$PNAME" ] && main="$PNAME" [ "$c" = "$second" ] && main="${main}-${c}" [ $auto -eq 0 ] && main="lp" [ $auto -eq 1 ] && main="lp-${c}" auto=$((auto + 1)) lpN="lp${lp}" ; lp=$((lp + 1)) comment="${PRINTER}~${PAPER}~${m}~${c}~${DPI}" spool="${PRINTER}-${PAPER}-${m}-${c}-${DPI}" name="$name ${main}|${lpN}|${spool}|${comment}" done ;; raw) # # if raw=0 we have the default entry belonging to `lp' main="${PRINTER}-raw" [ -n "$PNAME" ] && main="${PNAME}-raw" [ $raw -eq 0 ] && main="raw" raw=$((raw + 1)) lpN="lp${lp}" ; lp=$((lp + 1)) comment="${PRINTER}~${PAPER}~${m}" spool="${PRINTER}-${PAPER}-${m}" name="$name ${main}|${lpN}|${spool}|${comment}" ;; remote) main="${SHOST}-${RPRINTER}" [ -n "$PNAME" ] && main="$PNAME" [ $remote -eq 0 ] && main="remote" remote=$((remote + 1)) lpN="lp${lp}" ; lp=$((lp + 1)) comment="${SHOST}~${RPRINTER}" spool="${SHOST}-${RPRINTER}" name="$name ${main}|${lpN}|${spool}|${comment}" ;; esac done # # Now append the new entry # printpc "${SLABEL}" printlg " ${LABEL}" printpc "${WLABEL}" printpc "${DLABEL}" printpc "#" for d in $name ; do # comment : last name in printer names is a comment # SPOOLDIR : the spool direcrory for any possibility main="$(echo $d|tr '~' ' ')" FILTER="$(echo $d|cut -d'|' -f3)" SPOOLDIR="${SPOOL}/${FILTER}" if [ -n "$HOST" ] ; then RP="$(echo $FILTER|sed "s/${SHOST}\-//")" fi # # # write main entry printlg "${main}" printpc "${main}:\\" # # the rest if [ -n "$HOST" ] ; then # lp : lp=NULL ... there is no local printer device # rm : the remote printer server # rp : the remote printer queue (apsfilter conform) printpc "\t:lp=:\\" printpc "\t:rm=${HOST}:\\" printpc "\t:rp=${RP}:\\" else # lp : we need a parallel or serial printer device printpc "\t:lp=${DEVICE}:\\" if [ -n "$SERIAL" ] ; then # br : baud rate for a serial printer device # ty : some settings on a serial device (man stty) printpc "\t:br#${SERIAL}:\\" printpc "\t:ty=ixon -imaxbel -ixany -ixoff -crtscts:\\" fi fi # sd : our spool directory # lf : loging goes to log file # af : the accouting file # lo : we should lock for printer job control printpc "\t:sd=${SPOOLDIR}:\\" printpc "\t:lf=${SPOOLDIR}/log:\\" printpc "\t:af=${SPOOLDIR}/acct:\\" # # This should be done automatically by lpd # Note: bsd-lpd only want lock without fully path # #printpc "\t:lo=${SPOOLDIR}/lock:\\" if [ -n "$HOST" ] ; then # ar : write remote accounting informations # bk : plp should be bsd lpd compatible # mx : No limit on mx=0 printpc "\t:ar:bk:mx#0:\\" else # if : our filter # la : @ means do not write local accounting informations # mx : No limit on mx=0 printpc "\t:if=${APSFILTER}/bin/${FILTER}:\\" printpc "\t:la@:mx#0:\\" fi # sh : no banner pages # sf : no page feeds between jobs if [ "$NO_FF_SEP" = "yes" ] ; then printpc "\t:sh:sf:" else printpc "\t:sh:" fi printpc "#" # # Now should initialize the hole queue # if [ ! -d ${SPOOLDIR} ] ; then mkdir -p ${SPOOLDIR} : > ${SPOOLDIR}/log : > ${SPOOLDIR}/acct : > ${SPOOLDIR}/lock : > ${SPOOLDIR}/status chown -R ${LP_OWNER}:${LP_GROUP} ${SPOOLDIR} > /dev/null 2>&1 chmod 0755 ${SPOOLDIR} > /dev/null 2>&1 chmod 0640 ${SPOOLDIR}/log > /dev/null 2>&1 chmod 0640 ${SPOOLDIR}/acct > /dev/null 2>&1 chmod 0640 ${SPOOLDIR}/lock > /dev/null 2>&1 chmod 0640 ${SPOOLDIR}/status > /dev/null 2>&1 fi # # The name of the game :-) # if [ -z "$HOST" ] ; then [ -d ${APSFILTER}/bin/ ] || mkdir -p ${APSFILTER}/bin/ rm -f ${APSFILTER}/bin/${FILTER} [ -e ${APSFILTER}/bin/${FILTER} ] || \ ln -sf ../apsfilter ${APSFILTER}/bin/${FILTER} fi done printpc "${ELABEL}" # # Global resource file # [ -f "$APSRC" ] || cp $APSFILTER/template/apsfilterrc $APSRC # # Remote printer # [ -n "$HOST" ] && exit 0 # # A local printer needs its own resource file # TEMPLATE="$APSFILTER/template/apsfilterrc.gs_device_name" if [ ! -f "${APSRC}.${PRINTER}" ] ; then if [ -n "$DVIPS" ] ; then sed "s/^#DVIPS_MODE=/DVIPS_MODE=-P${DVIPS}/;\ s//${PRINTER}/g" < ${TEMPLATE} > ${APSRC}.${PRINTER} else sed "s//${PRINTER}/g" < ${TEMPLATE} > ${APSRC}.${PRINTER} fi else if [ -n "$DVIPS" ] ; then cp ${APSRC}.${PRINTER} ${APSRC}.${PRINTER}.old sed "s/^\(\|#\)\(DVIPS_MODE=\)\([^#]*\)/\2-P${DVIPS}/" \ < ${APSRC}.${PRINTER}.old > ${APSRC}.${PRINTER} fi fi # # Puh ... done # exit 0