Home
Ghostscript
Download
Sitemap
Impressum
apsfilter

apsfilter

#! /bin/bash
#
#  apsfilter Line Printer Input Filter
#  Version:     S.u.S.E.-1.6
#
#  Copyright 1996-99 S.u.S.E. GmbH
#  Author:   Werner Fink  <werner@suse.de>
#
#  NOTE: You really NEED bash to run this script
#
#  Heavily based on apsfilter-4.9

## Copyright by Andreas Klemm <andreas@knobel.gun.de> 1993, 1994, 1995
## co-author: Thomas Bueschgens <sledge@hammer.oche.de>
##
## You are permitted to modify and distribute apsfilter in the
## terms of the GNU Public License (GPL) see below.
##
## For Unix Systems With BSD Alike Print Mechanism (lpd, /etc/printcap)
##
## Supports The Following File Types:
##
##  Ascii, DVI, PS, Data (PCL,...), GIFF, TIFF, PBM,
##  Sun Raster, X11 Bitmap
##
## Supports The Following Compression Types:
##
##  Compress, Gzip, Freeze
##
## and various contributors

#
#  Avoid trouble with bash-2.0.x; hash shell functions; export variables.
#  No core dump in our spool queues. Random key for accounting.
#
set +o posix
set -h
set -a
ulimit -c 0  2> /dev/null
declare -r key="$$:$RANDOM"

#
#  For debugging --- see for stderr in /var/spool/.../log
#  for output see under /tmp/ in aps_out.<num>
#
#set -x
#PRINT_TO_FILE="true"

#
#  Using a remote Printer: The printer queue with the choosen name
#                          should be defined in /etc/printcap
#                          or a binary file with full path name.
#
#REMOTE_PRINTER="remote"

#
#  Global environment
#
PATH=/bin:/usr/bin:/usr/local/bin
PATH=${PATH}:/usr/bin/TeX:/usr/X11R6/bin
PATH=${PATH}:/sbin:/usr/sbin
export PATH

     NOTIFY=root
   FAULTMSG="apsfilter: printer fault"
      MAILX=mailx
      XDOTS=0
      YDOTS=0
      SPOOL=/var/spool
  APSFILTER=/var/lib/apsfilter
REWINDSTDIN=${APSFILTER}/rewindstdin
   GIFTOPXM=giftopnm
    SUNRAST=pnm

#
# Now check first temporary files
#
if type mktemp > /dev/null 2>&1 ; then
    TMP_FILE="$(mktemp /tmp/aps.$$.XXXXXX)" || exit 2
else
    TMP_FILE=/tmp/aps.$$
    rm -f $TMP_FILE
    if test -e $TMP_FILE ; then
 echo -e "apsfilter:\n    Our temporary file $TMP_FILE already exists!" \
     > /dev/console
 echo -e "apsfilter:\n    Our temporary file $TMP_FILE already exists!" \
     | $MAILX -s "$" $NOTIFY
 exit 2
    fi
    touch $TMP_FILE
fi

#
# Ignore hangup, keyboard interrupt, quit from keyboard, and broken pipes.
# Other signals for abort and on exit we should remove our temp file
#
trap "echo" SIGHUP SIGINT SIGQUIT SIGPIPE
trap "rm -f $TMP_FILE" EXIT SIGTRAP SIGBUS SIGKILL SIGUSR1 SIGUSR2 SIGTERM

for d in /usr/lib/teTeX /usr/lib/texmf /usr/local/texmf /usr/lib/TeX \
         /usr/local/TeX /usr/local/teTeX /usr/local/tetex /usr/teTeX \
         /usr/TeX /usr/tex /usr/local/tex /usr/lib/tex
do
    if [ -f $d/texmf.cnf ] ; then
 : ${TETEXDIR="$d"}
 break
    fi
done
[ -n "$TETEXDIR" ] && export TETEXDIR

#
#  Why not use the options given by lpd or plp (LPRng?)?
#  Parse options given by the printer Daemon!
#
while test -z "${1%-*}" -a -n "$1" ; do
    y="${1#-}"; shift
    case "$y" in
 P*)    PRNAME="${y#?}" ;; # Ignored
 w*)     WIDTH="${y#?}" ;; # Ignored
 l*)    LENGTH="${y#?}" ;; # Ignored
 i*)    INDENT="${y#?}" ;; # Ignored
 x*)     XDOTS="${y#?}" ;; # Ignored
 y*)     YDOTS="${y#?}" ;; # Ignored
 c*)   LITERAL="true"   ;; # Ignored
 N*)      NAME="${y#?}" ;; # Used if set
 S*)  SCOMMENT="${y#?}" ;; # Ignored
 Y*)     CALLS="${y#?}" ;; # Ignored
 J*)       JOB="${y#?}" ;; # Used if set
 Z*)  ZOPTIONS="${y#?}" ;; # Used if set
 C*)  PRIORITY="${y#?}" ;; # Ignored
 R*)  RACCOUNT="${y#?}" ;; # Ignored
 L*)   LPERSON="${y#?}" ;; # Used if set
 n*)    PERSON="${y#?}" ;; # Used if set
 H*|h*)   HOST="${y#?}" ;; # Used if set
 F*)    FILTER="${y#?}" ;; # Used if set
 k*)        CF="${y#?}" ;; # Used if set
 a*)  ACCTFILE="${y#?}" ;; # Used if set
 e*)        DF="${y#?}" ;; # Used if set
 *)                     ;; # Ignored
    esac
done

if [ -z "$ACCTFILE" ] ; then
    eval y="\${$#}"
    [ -n "$y" -a "$y" != "$0" ] && ACCTFILE="$y"
    unset y
fi

#
# Our data file is identical with stdin of this script
#
[ -z "$DF" ] && DF=/dev/fd/0

#
#  if apsfilter is called as:
#
# djet500-a4-{auto,ascii,raw}-{color,mono}-dpi
#   $1    $2        $3             $4       $5
# then we get printer type and papersize from the apsfilter call itself
# METHOD=auto enables filetype auto recognition
# METHOD=ascii force printing method print ascii
# METHOD=raw write to print device unfiltered ....
# COLOR=color use color-postscript
#  COLOR=mono transform color to b&w postscript... so one is
#    able to save colored pens on a colorprinter
# DPI=<NUM>x<NUM>
# DPI=<NUM> Resolution of the printer type
#
# changes from rene harsch for cdj970
#
# if apsfilter is called as:
#
# cdj970-a4-{auto,ascii,raw}-{color,mono}-{draft,normal,presentation}-
#    $1  $2       $3              $4             $5  
#
# {none,block,book}-{plain,bond,special,glossy,transparency}
#   $6   $7
#
# then we get printer type and pagesizes from the apsfilter call itself
#
# METHOD=auto enables filetype auto recognition
# METHOD=ascii force printing method print ascii
# METHOD=raw write to print device unfiltered ....
#
# COLOR=color use color-postscript
# COLOR=mono transform color to b&w postscript... so one is
#    able to save colored pens on a colorprinter
#
# QUALITY=draft print in draft mode
# QUALITY=normal same in normal mode
# QUALITY=presentation hmm :-)
#
# DUPLEX=none one page on one paper
# DUPLEX=block two pages, duplex mode
# DUPLEX=book two pages book type
#
# PAPERTYPE===>




set -- `echo ${0##*/} | tr '-' ' '`

: ${compat="false"}
[ "$1" = "aps" ] && { shift; compat=true; }

PRINTER="$1"; PAPERSIZE="$2"; METHOD="$3"; COLOR="$4"; QUALITY="$5"; DUPLEX="$6"; PAPERTYPE="$7"; QUEUE="$6"

test "$METHOD" = raw && QUEUE="$4"

#
# Do we additional informations: look into cf file
# lpd will change into spool directory before locking
#
if [ -z "$CF" ] ; then
    if   [ -n "$PWD"        -a -e "${PWD}/lock" ] ; then
 LOCK="${PWD}/lock"
    elif [ -n "${ACCTFILE}" -a -e "${ACCTFILE}" ] ; then
 LOCK="${ACCTFILE%/*}/lock"
    else
 if [ "$compat" = "true" ] ; then
     LOCK="${SPOOL}/${0##*/}/lock"
 else
     LOCK="${SPOOL}/lpd/${0##*/}/lock"
 fi
    fi
    CF=$(tail -1 ${LOCK})
fi

#
# LPRng doesn't write the CF immediately, therefore we have
# to wait on it because we'll read it.
#

declare -i sek=0
while test ! -s $CF ; do
    sleep 1
    sek=$((sek+1))
    test $sek -gt 10 && break
done

#
# Now scan cf file, therefore the inode of the
# open file for standard in is useful.
#
set -- $(ls -L -i $DF)
inodeofstdin=$1
declare -i count=0
declare -i nname=0
while read line ; do
    case "$line" in
 J*) :      ${JOB="${line#?}"} ;; # Used if set
 C*) :    ${CLASS="${line#?}"} ;; # Ignored
 D*) :   ${UNKOWN="${line#?}"} ;; # Ignored
 L*) :  ${LPERSON="${line#?}"} ;; # Used if set
 T*) :    ${TITLE="${line#?}"} ;; # Used if set
 H*) :     ${HOST="${line#?}"} ;; # Used if set
 P*) :   ${PERSON="${line#?}"} ;; # Used if set
 M*) :   ${MAILTO="${line#?}"} ;; # Used if set
 Z*) : ${ZOPTIONS="${line#?}"} ;; # Used if set
 f*) set -- $(ls -L -i ${line#?})
     count=$((count+1))
     if [ $inodeofstdin -eq $1 ] ; then
     :  ${FMTFILE="${line#?}"}    # Ignored
  nname=$count
     fi                        ;;
 l*) :  ${RAWFILE="${line#?}"} ;; # Ignored
 p*) :   ${PRFILE="${line#?}"} ;; # Ignored
 t*) :   ${TFFILE="${line#?}"} ;; # Ignored
 d*) :  ${DVIFILE="${line#?}"} ;; # Ignored
 n*) :  ${DITFILE="${line#?}"} ;; # Ignored
 g*) :   ${GRFILE="${line#?}"} ;; # Ignored
 c*) :  ${CIFFILE="${line#?}"} ;; # Ignored
 v*) :  ${IMGFILE="${line#?}"} ;; # Ignored
 r*) :  ${FORFILE="${line#?}"} ;; # Ignored
 1*) :  ${TFFONTR="${line#?}"} ;; # Ignored
 2*) :  ${TFFONTI="${line#?}"} ;; # Ignored
 3*) :  ${TFFONTB="${line#?}"} ;; # Ignored
 4*) :  ${TFFONTS="${line#?}"} ;; # Ignored
 W*) :    ${WIDTH="${line#?}"} ;; # Ignored
 I*) :   ${INDENT="${line#?}"} ;; # Ignored
 U*) :  ${SPOOLED="${line#?}"} ;; # Ignored
 #
 # Note that the first name wins if NAME is
 # not set by the command line given by the lpd.
 # The old BSD-lpd does not ... plp and LPRng
 # does give the name of every sub printing job
 # by command line. Now determine the right
 # NAME out of the cf file for BSD case.
 #
 # 98/10/05: it seems that plp lpd does have problems
 # with `lpr file1 ; lpr file2'. Therefore we overwrite
 # NAME given by the command line.
 #
 N*) if [ $count -eq $nname ] ; then
      NAME="${line#?}"     # Used if set
     fi                        ;;
 S*) :   ${INODES="${line#?}"} ;; # Ignored
 *)                            ;; # Ignored
    esac
done < ${CF}
[ "$DPI" = "default" ] && DPI=""
[ -z "$NAME" ] && NAME="$JOB"
[ -n "$JOB" ]  && FAULTMSG="$FAULTMSG during job $JOB"

#
# Are there any Z options? Handel this
#
if [ -n "$ZOPTIONS" ]; then
    for z in $(echo "$ZOPTIONS"|tr ',' ' '); do
 case "$z" in
     duplex=off)     ZDUPLEX=off      ;;
     duplex=on)      ZDUPLEX=on       ;;
     duplex=tumble)  ZDUPLEX=tumble   ;;
     tray=[0-9])     ZTRAY=${z#tray=} ;;
     feature=1)      ZFEATURE=1       ;;
     feature=2)      ZFEATURE=2       ;;
     feature=1n)     ZFEATURE=1n      ;;
     feature=2n)     ZFEATURE=2n      ;;
     feature=1l)     ZFEATURE=1l      ;;
     feature=1ln)    ZFEATURE=1ln     ;;
     *)                               ;; # Ignore
 esac
    done
fi

#
# Users home dir ... check nis domain
# if there is a nis domain we will use yp interface
# Note: domainname gives NOT dns domain but nis domain,
#       this is a common rule under UNIX[tm]!
#
YPD="`domainname`"
YPS="`grep -E '^\+' /etc/passwd|head -1c`"

if [ -n "$YPD" -a "$YPS" = "+" ] ; then
    set -- `(cat /etc/passwd; ypcat passwd)|grep "^$PERSON:"|cut -d':' -f6`
else
    set -- `grep "^$PERSON:" /etc/passwd |cut -d':' -f6`
fi
HOMEDIR="$1"

#
#  The user should know what's happen
#
if [ -n "$MAILTO" ] ; then
    NOTIFY="-c $NOTIFY $MAILTO"
else
    [ "$PERSON" != "$NOTIFY" ] && NOTIFY="-c $NOTIFY $PERSON"
fi

#
#  Load some handler
#
. ${APSFILTER}/handler/functions

#
#  FILE TYPE AUTO_RECOGNITION
#    first set output of the ``file'' command to new script arguments:
#    $1, $2, ..., $n ; then throw away $1 and $2 since that is the
#    "file name" = "standard input:" ; the rest is a "string" which
#    consist of one or multiple words describing the file type.
#    For example: "Korn Shell Script"
#
  FILE_TYPE=""
HAVE_UNPACK=""
 DECOMPRESS=""

set_type () { (grep -Ev '^$' $DF 2>/dev/null |file - |tr 'A-Z' 'a-z'); }
#
# Reset stdin for security
#
$REWINDSTDIN
#
case $METHOD in
 ascii|auto)
  set -- `set_type`
  shift ; shift
  FILE_TYPE="$@"
  #
  # check if we have to uncompress something
  case "$FILE_TYPE" in
      *gzip*) { . ${APSFILTER}/unpack/gzip ;     } ;;
      *compress*) { . ${APSFILTER}/unpack/compress ; } ;;
      *frozen*) { . ${APSFILTER}/unpack/melt ;     } ;;
      *packed*) { . ${APSFILTER}/unpack/gzip ;     } ;;
      *)  # it's not compressed !
  esac ;;
 *) # raw method: nothing to do
esac
#
#  For method auto we want to known file type of contents
#
if [ -n "$HAVE_UNPACK" ] ; then
 set_type () { ($HAVE_UNPACK $DF |grep -Ev '^$' 2>/dev/null |file - |tr 'A-Z' 'a-z'); }
 case  $METHOD in
  auto)
   set -- `set_type`
   shift ; shift
   FILE_TYPE="$@"
   DECOMPRESS="eval $HAVE_UNPACK|" ;;
  *)
   DECOMPRESS="eval $HAVE_UNPACK|" ;;
 esac
fi

#
# HP Printer Job Language data
#
case "$FILE_TYPE" in
    hp*printer*job*language*data)
 if [ -n "$HAVE_UNPACK" ] ; then
     set_type () { ($HAVE_UNPACK $DF | \
  grep -Ev '^(%||@PJL)'     2>/dev/null |file - |tr 'A-Z' 'a-z'); }
 else
     set_type () { ( \
  grep -Ev '^(%||@PJL)' $DF 2>/dev/null |file - |tr 'A-Z' 'a-z'); }
 fi
 case $METHOD in
  auto)
   set -- `set_type`
   shift ; shift
   FILE_TYPE="$@" ;;
  *) # nothing todo
 esac
 ;;
    *) # nothing todo
esac

#
#  No color in ascii method!
#
[ "$METHOD" = "ascii" ] && COLOR="mono"
case $COLOR in
 color) # color-mode! set some options so color makes it to
  # the postscript-printer!
  RAS2PS_OPTS="-C"
  DJPEG_OPTS="-colors 256"
  ;;
 *) # mono-printer or mono-mode
  # Unset all color-dependent flags
  ## Does not work with all gs drivers
  ## GS_FEATURES="-dBitsPerPixel=1"
  DJPEG_OPTS="-grayscale"
  ;;
esac

# duplex mode
#
case $DUPLEX in
 none)
  DUPLEX_OPT="-dDuplex=0"
  ;;
 block)
  DUPLEX_OPT="-dDuplex=1"
  ;;
 book)
  DUPLEX_OPT="-dDuplex=2"
  ;;
 *)
  DUPLEX_OPT=""
  ;;
esac

# quality mode
#
case $QUALITY in
 draft)
  QUALITY_OPT="-dQuality=0"
  ;;
 normal)
  QUALITY_OPT="-dQuality=1"
  ;;
 presentation)
  QUALITY_OPT="-dQuality=1"
  ;;
 *)
  QUALITY_OPT=""
  ;;
esac

# papertype mode
#
case $QUALITY in
 plain)
  PAPERTYPE_OPT="-dPapertype=0"
  ;;
 bond)
  PAPERTYPE_OPT="-dPapertype=1"
  ;;
 special)
  PAPERTYPE_OPT="-dPapertype=2"
  ;;
 glossy)
  PAPERTYPE_OPT="-dPapertype=3"
  ;;
 transparency)
  PAPERTYPE_OPT="-dPapertype=3"
  ;;
 *)
  PAPERTYPE_OPT=""
  ;;
esac

#
#  Set some useful(?) defaults for printing and then read
#  the systemwide resource file /etc/apsfilterrc
#
[ "$REMOTE_PRINTER" = "true" ] && REMOTE_PRINTER="remote"
DVIPS_MODE=""
  GS_RESOL="$DPI"
[ "$compat" = "true" ] && GS_RESOL=""

#
#  Usefull settings for raw printing, e.g. LF -> CR+LF
#
case $PRINTER in
 cdj*|*desk*|[dl]jet*|laserjet|lj4*|dnj*|paintjet|pj*|hpdj)
  #Translate LF to CR+LF and FF to CR+FF
  CRLF='\033&k2G'
  # Perforation Skip Mode off (DIN A4: 66 lines/page)
  SKIPOFF='\033&l0L'
  PRINT_RAW_SETUP_PRINTER="${CRLF}${SKIPOFF}"
  ;;
 *)
  # Anybody knows some good initialisation for some
  # printers ?
  PRINT_RAW_SETUP_PRINTER=""
  ;;
esac

#
#  Here we are: the systemwide resource file
#  Note: Maybe we need some special setups for special printers.
#  Therefore a /etc/apsfilterrc.${PRINTER} is useful!?
#
[ -f /etc/apsfilterrc ]            && { . /etc/apsfilterrc ; }
[ -f /etc/apsfilterrc.${PRINTER} ] && { . /etc/apsfilterrc.${PRINTER} ; }
[ -n "$QUEUE" -a \
  -f /etc/apsfilterrc.${QUEUE} ]   && { . /etc/apsfilterrc.${QUEUE} ; }

#
# The user apsfilterrc setup ... parsing and reading only allowed syntax
#
userrc=$HOMEDIR/.apsfilterrc
if [ -n "$HOMEDIR" -a -r $userrc ] ; then
    #
    # We only allow this few VARIABLES in user space
    #
    allowed="TEXINPUTS|PRINT_DVI|GS_FEATURES|USE_RECODE_NOT_A 2PS"
    allowed="$allowed|FEATURE|A2PS_OPTS|DVIPS_MODE|GS_RESOL|PREL OADS"

    #
    # $badchar contains the forbidden characters ... those
    # maybe break this script or fore instance make it insecure
    # notation is given in manual ascii(7)
    #
    badchar="$(echo -e ' \000\003\b\t\n\r\033')"
    extract=$(grep -E "^($allowed)\=[^$badchar]+$" $userrc)

    for line in $extract; do
 eval "$line"
    done
    unset badchar extract line allowed
fi
unset userrc

#
# Overwrite FEATURE if we are called with the Z option feature={1,2,1n,2n,1l,1ln}
#
[ -n "$ZFEATURE" ] && FEATURE="$ZFEATURE"

#
# If TEXINPUTS is set we have to export it
#
if [ -n "$TEXINPUTS" ] ; then
    [ -n "${TEXINPUTS#*:}" ] && TEXINPUTS=${TEXINPUTS}:
    export TEXINPUTS
fi
#
# Make dvips happy
#
if [ -n "$TETEXDIR" -o -s /etc/texmf/texmf.cnf ] ; then
    TEXPICTS=""
    [ -z "$TETEXDIR"  ] && TETEXDIR=/usr/share
    [ -n "$TEXINPUTS" ] && TEXPICTS=${TEXINPUTS%:}
    TEXPICTS=${TEXPICTS}:${TETEXDIR}/texmf/doc//:/usr/doc/Books//:
    export TEXPICTS
fi

#
#  Options for dvips
#
# -M  Don't create fonts automatically using MakeTeXPK
#      since there is a bug in it causing apsfilter to exit
#      after creating the first missing Font.
# -q  Quiet mode
# -r  Print last page first
# -t <papertype> Have a look into /usr/lib/teTeX/texmf/dvips/config.ps
#   And use command texconfig for default
# -D <num> Horizontal and vertical resolution in dpi
# -P <name>  Alternated config file
#   /usr/lib/teTeX/texmf/dvips/config.<name>
# -X <num> Horizontal resolution in dpi
# -Y <num> Vertical   resolution in dpi
# -Z  Compress bitmap fonts
#

setres ()
{
 # $1 is default resolution
 # ignore this one if it is given by our link name
 if [ -n "$GS_RESOL" ]; then
  shift; set -- $GS_RESOL $@
 fi
 RES="-D $1"
 [ ${1%x*} -ne ${1#*x} ] && RES="-D ${1%x*} -X ${1%x*} -Y ${1#*x}"
 shift
 RES="$RES $@"
}

case $PRINTER in
 PS_*dpi)
     r="${PRINTER#PS_}" ; r="${r%dpi}" ; setres $r
     [ `echo $r|grep -cE '^([0-9]+|[0-9]+x[0-9]+)$'` -eq 0 ] && setres 300
     [ -n "$DPI" ] && setres $DPI
     ;;
 PS_*)   setres 300        ;;
 cdj*|*desk*|djet*) setres 300 -r     ;;
 dnj*c)   setres 300 -r     ;;
 hpdj)   setres 300 -r     ;;
 ljet4l)   setres 300        ;;
 ljet4)   setres 600        ;;
 lj4dith)  setres 600        ;;
 laserjet|ljet[23]*) setres 300        ;;
 paintjet|pj*)  setres 300        ;;
 necp6)   setres 360        ;;
 bj10e|bj200|bjc[68]00) setres 360 -r     ;;
 stcolor|st800)  setres 360 -r     ;;
 eps9*)   setres 240x216 -r ;;
 epson)   setres 360x180 -r ;;
 epsonc)   setres 360x180 -r ;;
 *\.upp)   setres 300 -r     ;;
 ppa1000|ppa[87]20) setres 600 -r     ;;
 *)   setres 300 -r     ;;
esac

#
#  The light version of ljet4 acts like a ljet4 at 300dpi
#
[ "$PRINTER" = "ljet4l" ] && PRINTER=ljet4

#
#  Quiet (-q) and compresssed fonts (-Z) set to default
#
DVIPS_OPTS="-q -Z $DVIPS_MODE $RES"
case $PAPERSIZE in
 letter|legal|ledger) DVIPS_OPTS="$DVIPS_OPTS -t $PAPERSIZE" ;;
 tabloid|11x17)  DVIPS_OPTS="$DVIPS_OPTS -t Tabloid" ;;
 a3)   DVIPS_OPTS="$DVIPS_OPTS -t A3"  ;;
 a4)   DVIPS_OPTS="$DVIPS_OPTS -t A4"  ;;
 *)   DVIPS_OPTS="$DVIPS_OPTS -t Letter" ;;
esac
[ "$PAPERSIZE" = "tabloid" ] && PAPERSIZE=11x17

#
# Remote printer:
#   We handel file types local an put the result to a remote queue.
#   Therefore we test if `remote' is set _and_ if the requested
#   remote queue is available.
#
# First set default to local (for using named pipes, which allows
# us to split ghostscript messages from ghostscript results).
#
# Note we redirect regular stdout to stderr for logging and
# open a new fd connected to stdout for the raw data.
#
exec 3>&1 1>&2
PRINT_RAW="cat - 1>&3"
bypass=0
#
[ "$REMOTE_PRINTER" = "true" ] && REMOTE_PRINTER="remote"
if [ -n "$REMOTE_PRINTER" ] ; then
 #
 # Handle remote queue or script/programm which is given
 # with its full patch name and some arguments.
 #
 case "$REMOTE_PRINTER" in
     /*) #
  # A programm or script which should handle the stream
  #
  set -- $REMOTE_PRINTER
  findfilter $1 DUMMY
  bypass=1
  PRINT_RAW="$@"
  ;;
     *) #
  # Queue for a remote printer or printer server
  #
  bypass=$(grep -cE "^$REMOTE_PRINTER(\||:)" /etc/printcap)
  if [ $bypass -ge 1 ] ; then
   LPR_OPTIONS="-P$REMOTE_PRINTER"
   LPR_NAME=""
   # Not supported by old bsd lpr
   #[ -n "$RACCOUNT" ] && LPR_OPTIONS="$LPR_OPTIONS -R$RACCOUNT"
   [ -n "$JOB"    ] && LPR_OPTIONS="$LPR_OPTIONS -J '$JOB'"
   [ -n "$NAME"   ] && LPR_NAME="-T '$NAME'"
   [ -n "$TITLE"  ] && LPR_NAME="-T '$TITLE'"
   LPR_OPTIONS="$LPR_OPTIONS $LPR_NAME"
   # Some plp lprs do not change uid if we are user lp
   [ ! -e /etc/plp.conf -a \
      -n "$PERSON" ] && LPR_OPTIONS="$LPR_OPTIONS -U '$PERSON'"
   PRINT_RAW="lpr -l $LPR_OPTIONS"
  fi
  ;;
 esac
fi

#
#  Now let's see how to print PostScript
#
case $PRINTER in
 PS_*)
  # our printer is a PS printer...
  PRINT_PS="$PRINT_RAW"
  #
  PS_PRELOADS=""
  for pre in ${PRELOADS}; do
   if [ -r "${APSFILTER}/preloads/$pre" ]; then
    PS_PRELOADS="$PS_PRELOADS ${APSFILTER}/preloads/$pre"
   elif [ -r "$pre" ]; then
    PS_PRELOADS="$PS_PRELOADS $pre"
   fi
  done
  [ -n "${PS_PRELOADS}" ] && PS_PRELOADS="$(cat $PS_PRELOADS|grep -v '^%!')"
  #
  download=""
  if [ -n "$ZDUPLEX" -o -n "$ZTRAY" ] ; then
   . ${APSFILTER}/handler/psheads
   [ "$ZDUPLEX" = on ]     && download="${duplexon}\\n${tumbleoff}"
   [ "$ZDUPLEX" = tumble ] && download="${duplexon}\\n${tumbleon}"
   [ "$ZDUPLEX" = off ]    && download="${duplexoff}"
   [ -n "$ZTRAY" ]         && download="${download}\\n${settray}"
  fi
  #
  if [ -n "$download" -o -n "${PS_PRELOADS}" ] ; then
   PRINT_PS="\
   (read first; echo \"\$first\";\
        echo -e \"${beginsec}\";\
        echo -e \"${PS_PRELOADS}\";\
        echo -e \"${download}\";\
        echo -e \"${endsec}\";\
    cat - ) > >($PRINT_RAW)"
  fi
  ;;
 *) # we have a nice non ps printer
  findfilter gs GS
  [ -n "$GS_RESOL" ] && GS_RESOL="-r${GS_RESOL}"
  OUTPIPE="$PRINT_RAW"
  case $PRINTER in
   *\.upp) # PRINTER = option file (e.g. unified printer driver)
    # Note: A resolution in the option file overwrites
    #       the given resolution. This is a `must be'.
    HAVE_GS="$HAVE_GS ${GS_RESOL} @${PRINTER}"
    ;;
   ppa1000|ppa[87]20)
    # PRINTER =   pbm ghostscript device
    #     + post filter pbm2ppa
    #
    HAVE_GS="$HAVE_GS -sDEVICE=pbm ${GS_RESOL}"
    #
    findfilter pbm2ppa PBMTOPPA
    OUTPIPE="$HAVE_PBMTOPPA -v ${PRINTER#ppa}"
    [ $bypass -ge 1 ] && $OUTPIPE="$OUTPIPE|$PRINT_RAW"
    #
    ;;
   *) # PRINTER = ghostscript device
    HAVE_GS="$HAVE_GS -sDEVICE=${PRINTER} ${GS_RESOL}"
    ;;
  esac
  #
  # Some X11 PostScript fonts
  #
  if [ -d /usr/X11R6/lib/X11/fonts/Type1 ] ; then
   GS_FONTPATH=/usr/X11R6/lib/X11/fonts/Type1
  fi
  #
  # gs4.03 has max mem size of 65k, default for unix is 50k.
  #
  GS_OPTIONS=""
  if [ "$(uname -s)" = "Linux" ] ; then
   set -- $(cat /proc/meminfo| grep -E '^MemTotal:')
   mem="$2"
   gs_mem=32
   [ $mem -gt  7750 ] && gs_mem=48
   [ $mem -gt 15500 ] && gs_mem=65
   [ $mem -gt 31000 ] && gs_mem=82
   [ $mem -gt 62000 ] && gs_mem=98
   GS_OPTIONS="-M${gs_mem}"
   unset mem gs_mem
  fi
  #
  # Common options
  GS_OPTIONS="${GS_OPTIONS} -q -dQUIET -dNOPAUSE -dBATCH -dSAFER -dSHORTERRORS"
  #
  DJ970_OPT="${DUPLEX_OPT} ${PAPERTYPE_OPT} ${QUALITY_OPT}"
  # Preloads
  GS_LIB=${APSFILTER}/preloads
  #
  export GS_OPTIONS GS_LIB GS_FONTPATH
  #
  GS_PRELOADS=""
  for pre in ${PRELOADS}; do
   if [ -r "${APSFILTER}/preloads/$pre" ]; then
    GS_PRELOADS="$GS_PRELOADS ${APSFILTER}/preloads/$pre"
   elif [ -r "$pre" ]; then
    GS_PRELOADS="$GS_PRELOADS $pre"
   fi
  done
  #
  # Accounting for and with gs
  # Note: plp or LPRng do their own (wrong: page always 1) accounting
  #       therefore `la@' should be set in /etc/printcap
  DOEND="-c quit"
  if [ "$DO_ACCOUNTING" = "yes" -a -w ${ACCTFILE=acct} ] ; then
   acc_page="currentdevice /PageCount gsgetdeviceprop"
   # acc_file is defined in handler/functions
   DOEND="-c \"($key:) print $acc_page == flush quit\"|acc_file"
  fi
  #
  # Note: stdout is fd 3 (done by us), therefore `>(cat - 1>&3)' works here.
  #
  PRINT_PS="$HAVE_GS -sPAPERSIZE=${PAPERSIZE} ${GS_FEATURES} ${DJ970_OPT}\
       -sOutputFile=>($OUTPIPE) ${GS_PRELOADS} - ${DOEND} 1>&2"
  ;;
esac

echo $PRINT_PS

#
#  Debugging: Overwrite all print commands
#
if [ "$PRINT_TO_FILE"  = "true" ] ; then
    apsdebug=/tmp/aps_out.$$
    rm -f $apsdebug
    [ -e $apsdebug ] && exit 2
    if type mktemp > /dev/null 2>&1 ; then
 apsdebug="$(mktemp ${apsdebug}.XXXXXX)" || exit 2
    fi
     PRINT_PS="(cat 1> ${apsdebug})"
    PRINT_RAW="(cat 1> ${apsdebug})"
fi

#
#  And now ... we choose a method
#
case $METHOD in
 raw) { . $APSFILTER/filter/raw   ; } ;;
 ascii) { . $APSFILTER/filter/ascii ; } ;;
 auto)
  #
  # Maybe we should do this dynamical
  # for f in $APSFILTER/filter/* ; do ... done
  #
  case "$FILE_TYPE" in
   *fig*image*text*)
    { . $APSFILTER/filter/fig ;        } ;;
   *pc*bitmap*data*)
    { . $APSFILTER/filter/bmp ;        } ;;
   *tiff*image*data*)
    { . $APSFILTER/filter/tiff ;       } ;;
   *gif*image*data*)
    { . $APSFILTER/filter/gif ;        } ;;
   *jpeg*image*data*)
    { . $APSFILTER/filter/jpeg ;       } ;;
   *pgm*|*pbm*|*ppm*)
    { . $APSFILTER/filter/pnm ;        } ;;
   *sun*raster*image*data*)
    { . $APSFILTER/filter/sunraster ;  } ;;
   postscript*)
    { . $APSFILTER/filter/postscript ; } ;;
   *pdf*document*)
    { . $APSFILTER/filter/pdf ;        } ;;
   *tex*dvi*file*)
    { . $APSFILTER/filter/dvi ;        } ;;
   *raw*g3*data*|*group*3*fax*)
    { . $APSFILTER/filter/g3 ;         } ;;
   *data*|*escape*|*pcl*|*pjl*|*printer*job*language*)
    # that's certainly not critical,
    # you're on your own ;-)
    { . $APSFILTER/filter/data ;       } ;;
   *troff*preprocessor*)
    { . $APSFILTER/filter/troff ;      } ;;
   *html*)
    { . $APSFILTER/filter/html;        } ;;
   *ascii*|*text*|*english*|*script*)
    { . $APSFILTER/filter/ascii ;      } ;;
   *paul*falstad*zsh*|*neil*brown*ash*|neil*brown*ae*)
    { . $APSFILTER/filter/ascii ;      } ;;
    *) 
    # data we - I'm so sorry - don't know
    fault_filetype
    exit 2 ;;
  esac ;;
 *)
  fault_method
  exit 2 ;;
esac
$REWINDSTDIN

#
# Just do it
#
print_stdin

#
# Puh ... done
#
exit 0
 

(c) 2000 by harsch.net   Last Update: Wednesday, June 07, 2000