#!/bin/sh

################################################################################
#
# apsfilter-2.3 ------ TEXT / PS / DVI input filter  -----------
#                      ============================
#
#	for Unix Systems with BSD alike print mechanism (lpd, printcap)
#
#	by Andreas Klemm <andreas@knobel.knirsch.de>
#
#			and various contributors
#
#				Tue Apr 19 15:25:46 GMT+0100 1994
#
################################################################################

################################################################################
# changes 2.2 -> 2.3:
# -------------------
# TEXINPUTS trickery, enables dvips to find ps images which should be included
# added -nu option to a2ps global options
# ljet4: changed gs && dvips resolution to 600x600dpi
# added /usr/gnu to PATH variable for FreeBSD 
# added support for real postscript printers (300, 600 and 800 dpi)
# simple modification for FreeBSD's cut utility (order of arguments)
# further enhancements/patches of a2ps (job, user, host option) and apsfilter
# print ascii texts (using gs) black & white if you have a color printer
# some fixes in test directory tree, new example for dvips "include ps" feature
# enhanced installation script, more specific info about different gs filters
# mkdatabase script to update paths where ps dumps reside, when using
#    dvips' feature to include ps images into a dvi file during printing
################################################################################

################################################################################
#
#			C O P Y R I G H T 
#
################################################################################
#
#
# You are permitted to use this script in the terms of the 
#
# 		    GNU GENERAL PUBLIC LICENSE
# 		       Version 2, June 1991
# 
#
#  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
#                           675 Mass Ave, Cambridge, MA 02139, USA
#  Everyone is permitted to copy and distribute verbatim copies
#  of this license document, but changing it is not allowed.
# 

################################################################################
# Thanks to:
################################################################################
#
#	bsmart@bsmart.tti.com (Bob Smart)
#	dfrey@stud.ee.ethz.ch (David Frey)
#	dirk@flop.escape.de (Dirk Sturzebecher)
#	gtaylor@cs.tufts.edu (Grant Taylor)
#	jstern@eclectic.ss.uci.edu (Jeff Stern)
#	ljo@ljo-slip.DIALIN.CWRU.Edu (L Jonas Olsson)
#	sar@beehive.mn.org (Steven A. Reisman)
#	sch2@crux5.cit.cornell.edu (Stephen Hsieh)
#	sledge@hammer.oche.de (Thomas Bueschgens)
#	strassma@orgel.informatik.uni-stuttgart.de (Markus Strasser)
#
#	and many others for their contributions, suggestions, patience 
#		and bugfixes ...
#
#	Note: Because of the major redesign in 2.X some features are lost.
#	      Some parts I left in the script, perhaps somebody needs it.
#	      i.e.: the handling of the commandline parameters from lpd.
#
#	      I deceided to remove the very long "history of changes".
#	      Or do you like a script where you have more comments in it
#	      than features ?! ;-)

################################################################################
# Only for debugging purposes. You can find debugging output in
# the logfile (see /etc/printcap definition lf=/var/spool/.../log)
################################################################################
#
set -x


#
# on what kind of system we are running ?
#
SYSTEM=`uname -s`


#\	evaluate command line arguments that are given to the
# \	input filter 
#  \  
#   >	apsfilter [-c] -wwidth -llength -iindent -n login -h host acct-file     
#  /			  $1      $2       $3    $4   $5  $6  $7     $8
# /	defaults: width=0, length=66, indent=0
#/

	WIDTH=`echo $1 | awk '{ print substr($1,3) }'`
	if [ "$WIDTH" = "" -o "$WIDTH" = "0" ]; then WIDTH=80; fi

	LENGTH=`echo $2 | awk '{ print substr($1,3) }'`
	if [ ! $LENGTH ]; then LENGTH=66; fi

	INDENT=`echo $3 | awk '{ print substr($1,3) }'`
	if [ ! $INDENT ]; then INDENT=0; fi

	LOGINNAME=$5
	HOST=$7
	ACCTFILE=$8

################################################################################
#
# NEW: auto configuration
#
################################################################################
#
# if apsfilter is called as:
#
#	aps-djet500-a4-{auto,ascii}-{1,2,1n,2n}
#	$1   $2     $3      $4          $5
#	then we get printer type and papersize from the apsfilter call itself
#	after some trickery with cut and sed (where cut is hopefully part of
#	every Unix disrtibution, otherwise get the gnu version of cut
#	METHOD=auto	enables filetype auto recognition
#	METHOD=ascii	force printing method print ascii
#	METHOD=raw	write to print device unfiltered ....
#	FEATURE=1	tell a2ps to print 1 page  on one sheet with    header
#	FEATURE=2	tell a2ps to print 2 pages on one sheet with    header
#	FEATURE=1n	tell a2ps to print 1 page  on one sheet without header
#	FEATURE=2n	tell a2ps to print 2 pages on one sheet without header

case $SYSTEM in
	*BSD*|*bsd*)
		set -- `echo $0 | cut -f1 -d\ | sed -e 's/-/ /g'`
		;;
	*)
		set -- `echo $0 | cut -d\  -f1 - | sed -e 's/-/ /g'`
		;;
esac

LABEL=$1; PRINTER=$2; PAPERSIZE=$3; METHOD=$4; FEATURE=$5

case $LABEL in
	*aps)	# jup, seems to be that we are installed properly
		;;
	*)	# unknown filter - therefore EXIT APSFILTER
		echo "$1 wrong input filter" 2>&1
		exit 0
		;;
esac


################################################################################
#
# ENVIRONMENT SECTION - Global settings - in most cases nothing to change here
#
################################################################################
#
# Reference of Shell Variables:
# -----------------------------
#
#	(1)  PATH		<- Command search path
#				   should fit everybodies needs
#	(2)  TMP_DIR		<- directory for temporary files
#				   (/var/tmp should be ok for everybody)
#	(3)  NOTIFY		<- who gets mail when printer fault occurrs
#				   root is a sane default
#	(4)  MAILX		<- Your mailx program (can -s "Subject" option)
# 	(5)  GS_RESOL		<- printer resolution, used for gs(1)
#				   computed automatically for some printers
#				   depends on PRINTER variable
#	(6)  DVIPS_OPTS		<- options for dvips
#				   some options are defaults some are computed
#				   automatically. Depends on the following
#				   variables:
#					PRINTER, GS_RESOL, PAPERSIZE
#	(7)  ECHO		<- the echo command, that does control character
#				   expansion
#
################################################################################

#-------------------------------------------------------------------------------
#
# (1)  PATH - SET SEARCH PATH
#	
#-------------------------------------------------------------------------------

# PATH=......:$PATH
# Note !       ^------- This goes wrong, don't know why, perhaps a Linux
#			release specific problem
#

PATH=/usr/lib/apsfilter/bin:/usr/bin:/bin:/sbin:/usr/sbin:/usr/local/bin:\
/usr/TeX/bin:/local/bin:/usr/gnu/bin


#-------------------------------------------------------------------------------
#
# (2)  TMP_DIR - SET LOCATION FOR TEMPORARY FILES
#
#-------------------------------------------------------------------------------

case $SYSTEM in
	*BSD*|*bsd*)		TMP_DIR=/var/tmp        ;;
	Linux|linux)		TMP_DIR=/var/tmp	;;
	Solaris|solaris)	TMP_DIR=/var/tmp	;;
	Sun*|sun*)		TMP_DIR=/var/tmp	;;
	*)			TMP_DIR=/tmp		;;
esac

#-------------------------------------------------------------------------------
#
# (3)  NOTIFY - SET E-MAIL ADRESS OF PRINTER ADMINISTRATOR
# 
#-------------------------------------------------------------------------------

NOTIFY=root

#-------------------------------------------------------------------------------
#
# (4)  MAILX - your favourite mail program that understands "-s" (except elm !)
#      
#	typical Linux problems: /bin/mail is often a symlink to elm which
#	doesn't work since it misses the Mail folder directory, etc ....
#	Use the mailx program instead. Another advantage of mailx is, that
#	you can give a Subject with -s on the command line.
#	SunOS 4.1.X, Solaris 1 note: I think there is a program "Mail" which does
#	the job.
#
#-------------------------------------------------------------------------------

case $SYSTEM in
	*BSD*|*bsd*)		MAILX=Mail	;;
	Linux|linux)		MAILX=mailx	;;
	Solaris|solaris)	MAILX=Mail	;;
	Sun*|sun*)		MAILX=Mail	;;
	*)			MAILX=mailx	;;
esac


#-------------------------------------------------------------------------------
#
# (5) PRINTER RESOLUTION - GS_RESOL
#
#		if you have other Printers than HP's with 300x300 pixel or 
#		nec's with 360x360 then you have to add something reasonable 
#		for your printer !!!
#
#-------------------------------------------------------------------------------

case $PRINTER in
	PS_300dpi)			GS_RESOL=300x300 ;;
	PS_400dpi)			GS_RESOL=400x400 ;;
	PS_600dpi)			GS_RESOL=600x600 ;;
	PS_800dpi)			GS_RESOL=800x800 ;;
	cdesk*|cdj*|desk*|djet*)	GS_RESOL=300x300 ;;
	laserjet|ljet[23]*)		GS_RESOL=300x300 ;;
	ljet4)				GS_RESOL=600x600 ;;
	paintjet|pj*)			GS_RESOL=300x300 ;;
	necp6|bj200)			GS_RESOL=360x360 ;;
	*)				# when printer is not known exactly
					# we assume a default of 300x300
					#
					GS_RESOL=300x300 ;;
esac


#-------------------------------------------------------------------------------
#
# (6) OPTIONS for dvips - DVIPS_OPTS
#
#		-q quiet mode
#		-r print last page first
#		-t papertype
#			(look known formats in the config file config.ps
#			 on Linux Slackware usually in /usr/TeX/lib/tex/ps)
#		-D num horizontal + vertical resolution in dpi 
#		   or:	-X num horizontal resolution in dpi 
#			-Y num vertical   resolution in dpi 
#		-Z compress bitmap fonts
#		   usually only when resolution is >= 400
#
#-------------------------------------------------------------------------------

case $PRINTER in
	PS_300dpi)			DVIPS_OPTS="-q -D 300 -Z"	;;
	PS_400dpi)			DVIPS_OPTS="-q -D 400"		;;
	PS_600dpi)			DVIPS_OPTS="-q -D 600"		;;
	PS_800dpi)			DVIPS_OPTS="-q -D 600"		;;
	cdesk*|cdj*|desk*|djet*)	DVIPS_OPTS="-q -D 300 -r -Z"	;;
	ljet4)				DVIPS_OPTS="-q -D 600"		;;
	laserjet|ljet[23]*)		DVIPS_OPTS="-q -D 300"		;;
	paintjet|pj*)			DVIPS_OPTS="-q -D 300"		;;
	necp6|bj200)			DVIPS_OPTS="-q -D 360 -r"	;;
	*)				DVIPS_OPTS="-q -D 300 -r"	;;
esac

case $GS_RESOL in
	360x360|400x400|600x600|800x800) # compress bitmap fonts if you have a 
					 # high resolution printer
					 DVIPS_OPTS="$DVIPS_OPTS -Z"	;;
esac

case $PAPERSIZE in
	letter|legal|ledger)	DVIPS_OPTS="$DVIPS_OPTS -t $PAPERSIZE"	;;
	a3)			DVIPS_OPTS="$DVIPS_OPTS -t A3"		;;
	a4)			DVIPS_OPTS="$DVIPS_OPTS -t A4"		;;
	*)			DVIPS_OPTS="$DVIPS_OPTS -t letter"	;;
esac


#-------------------------------------------------------------------------------
#
# (7) Your echo command that handels control characters in strings
#
#-------------------------------------------------------------------------------

# Linux - bash
ECHO="echo -e"

# Rest of the world...?
#ECHO=echo

#-------------------------------------------------------------------------------
#
# (8)	Margin for a2ps utility
#
#	Deskjet like printers have an unprintable region, with a2ps's
#	default margin of 1.4" I got incomplete printouts ... I think it's
#	deskjet specific. Don't know exactly, what other printer need, 
#	please try it yourself !
#
#-------------------------------------------------------------------------------

case $PRINTER in
	cdesk*|cdj*|desk*|djet*)	A2PS_MARGIN=1.6
					;;
	*)				# default 1.4"
					A2PS_MARGIN=1.4
					;;
esac

################################################################################
################################################################################
################################################################################
#####
##### S h e l l  -  F u n c t i o n s
#####
################################################################################
################################################################################
################################################################################

#===============================================================================
#
# print ps using gs if we don't have a Postscript printer
#
#===============================================================================

print_ps()
{
	case $PRINTER in

		PS_*dpi)	# our printer is a PS printer...	
				cat -		
				;;

		*)		# we have a nice non ps printer
				gs					\
					-q				\
					-sDEVICE=${PRINTER}		\
					-r${GS_RESOL}			\
					-sPAPERSIZE=${PAPERSIZE}	\
					-dNOPAUSE			\
					-dSAFER				\
					-sOutputFile=-			\
					-
				;;
	esac
}


#===============================================================================
#
# print dvi files using dvips->gs
#
#===============================================================================

print_dvi()
{

	# NEW * aps-23 *
	#
	# TEXINPUTS trickery, enables dvips to find ps images that should be 
	# included during printing of the dvi file ... does's anybody have a 
	# better one ?! No ?! Thanks to sledge (the real hammer ;-) 
	# Thomas Bueschgens <sledge@hammer.oche.de>
	#
	# Needs mkdatabase and mkdatabase.awk regulary called by cron !!!
	# See comments in /usr/lib/apsfilter/bin/mkdatabase !!!
	#
	# Slightly modified to find xgrab (x11 screen dumps ".dmp"), too.
	#
	# 
	
	# Check which databases exist and create a list of databases to
	# be included into the TEXINPUTS-searchpath

	# This one MUST be there, if not, big trouble ahead
	if [ -f /usr/lib/apsfilter/bin/database.var ]; then
		DATABASES='/usr/lib/apsfilter/bin/database.var'
	fi

	# database.fix is optional, see README.database for details
	if [ -f /usr/lib/apsfilter/bin/database.fix ]; then
		DATABASES=$DATABASES' /usr/lib/apsfilter/bin/database.fix'
	fi

	# If DATABASES is empty right now, something strange has happened. 
	# Anyone should call Sigourney Weaver right now, since there is a
	# chance of an alien snoopin' around...
	if [ -z "$DATABASES" ] ; then
		# No database files present ... we drop a line for the log-file.
		echo "Check /usr/lib/apsfilter/bin/database.{var,fix}" 2>&1
		echo "Expect missing pictures in your document" 2>&1
	else
		TEXINPUTS=`cat $DATABASES | tr '\n' :`
		# tmp dirs and .../apsfilter/test went into database.fix
		# so we have a file with sane default's ;-)
		export TEXINPUTS
	fi

	case $PRINTER in

		PS_*dpi)	# our printer is a PS printer...	
				dvips -f $DVIPS_OPTS
				;;

		*)		# non PS printer
				dvips -f $DVIPS_OPTS		\
				| gs				\
					-q			\
					-sDEVICE=${PRINTER}	\
					-r${GS_RESOL}		\
					-sPAPERSIZE=${PAPERSIZE}\
					-dNOPAUSE		\
					-dSAFER			\
					-sOutputFile=-		\
					-
				;;
	esac
}


#===============================================================================
#
# print raw ascii (perhaps you need a _fast_ listing, eh ;-)
#
#===============================================================================

print_raw()
{
	case $PRINTER in
		*desk*|*djet*|laserjet|ljet*)
			#Translate LF to CR+LF and FF to CR+FF
			printf "\033&k2G"
                        # Perforation Skip Mode off (DIN A4: 66 lines/page)
                        printf "\033&l0L"
			;;
	esac

	# not needed any more ... lpr -p does the job...
	# pr -r -f -w $WIDTH -l $LENGTH -o $INDENT -h $LOGINNAME@$HOST -
	# pr -t -r -f -w $WIDTH -l $LENGTH -o $INDENT -
	cat -
	printf "\014"
}

#===============================================================================
#
# print ascii using a2ps
#
#===============================================================================

print_ascii()
{

	# get job, user and host ...
	# ljo@ljo-slip.DIALIN.CWRU.Edu (L Jonas Olsson)

	LOCK=`dirname ${ACCTFILE}`/lock
	CF=`tail -1 ${LOCK}`
	JOB=`egrep '^J' ${CF} | tail +2c`
	USER=`egrep '^P' ${CF} | tail +2c`
	HOST=`egrep '^H' ${CF} | tail +2c`

	# global a2ps options:
	#
	#	-Xxxx	papersize (a4, a3, letter, ...)
	#	-Mxxx	print margins
	#	-Hxxx	filename
	#	-Qxxx	username
	#	-Zxxx	hostname
	#	-8	print non ascii chracters (high bit set) as 
	#		ISO Latin 1 chars
	#	-m	print unix manual pages
	#	-r	reset sheet numbering for each new file
	#	-ns	don't print page surrounding borders
	#	-nP	send output to stdout (a2ps as filter)
	#	-nu	don't print filename at bottom of page

	#	-B	print using boldface font (causes some trouble
	#		printing Unix manual pages, so not used ....

	if [ "$JOB" = "stdin" ]; then JOB=""; fi

	A2PS_OPTS1="-X$PAPERSIZE -M$A2PS_MARGIN -H$JOB -Q$USER -Z$HOST"
	A2PS_OPTS2="-8 -m -r -ns -nu -nP"

	# feature dependend a2ps options:
	#
	#	-nH	don't print page headers
	#	-p	print pages in portrait mode
	#	-Fx.y	change font size. Default in
	#			landscape = 6.4
	#			portrait  = 9.0

	case $FEATURE in
		1)	A2PS_FEATURES="-p -F9.0"	;;
		2)	A2PS_FEATURES="-F6.9"		;;
		1n)	A2PS_FEATURES="-p -F9.0 -nH"	;;
		2n)	A2PS_FEATURES="-F6.9 -nH"	;;
	esac

	A2PS_OPTS="${A2PS_OPTS1} ${A2PS_OPTS2} ${A2PS_FEATURES}"

	case $PRINTER in

		PS_*dpi)	# our printer is a PS printer...	

				a2ps ${A2PS_OPTS}
				;;

		*)		# on a non PS printer ...

				case $PRINTER in
				    djet*|pj*)
					# print ascii texts black&white
					GS_FEATURES="-dBitsPerPixel=1"	;;
				    *)
					GS_FEATURES=""			;;
				esac

				a2ps ${A2PS_OPTS}		\
				| gs				\
					-q			\
					-sDEVICE=${PRINTER}	\
					-r${GS_RESOL}		\
					-sPAPERSIZE=${PAPERSIZE}\
					-dNOPAUSE		\
					-dSAFER			\
					$GS_FEATURES		\
					-sOutputFile=-		\
					-
				;;
	esac
}

#===============================================================================
#
# print data files and fine tune printer settings ...
#
#===============================================================================

print_data()
{
	cat -
}


#===============================================================================
#
# UNKNOWN file or method type, too bad ;->
#
#===============================================================================

fault_filetype()
{
	# make noise on system console
	echo "apsfilter: unknown filetype $FILE_TYPE" > /dev/console

	# mail to printer admin
	echo "apsfilter: $TMP_FILE: unknown filetype $FILE_TYPE" \
	| $MAILX -s "apsfilter: printer fault" $NOTIFY \
	2> /dev/null

	# don't remove print file
	Preserve=Yes
}

fault_method()
{
	# make noise on system console
	echo "apsfilter: unknown print method $METHOD" > /dev/console

	# mail to printer admin
	echo "apsfilter: unknown print method $METHOD" \
	| $MAILX -s "apsfilter: printer fault" $NOTIFY \
	2> /dev/null

	# don't remove print file
	Preserve=Yes
}
	

#  / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
# / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
#  / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
#
#   M A I N  ( )
#
#  / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
# / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
#  / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /


#
# Here we choose between the general print method
# file type auto-recognition or force ascii_printing
#

case $METHOD in

	raw)	print_raw
		;;

	ascii)	print_ascii
		;;

	auto)	# 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"

		set -- `file -`
		shift ; shift
		FILE_TYPE=$*

		# make it possible to lseek from stdin
		# from hathi (hathi.Informatik.RWTH-Aachen.DE), good stuff !
		rewindstdin

		case $FILE_TYPE in
			PostScript*)		print_ps	;;
			*DVI*)			print_dvi	;;
			*ascii*|*text*|*script*)print_ascii	;;
			data)			print_data	;;
			*)			fault_filetype	;;
		esac
		;;
	*)	fault_method
		;;
esac

# Preserve tmp File in $TMP_DIR for later examination
# if error conndition occurred.
# Perhaps you have to modify /etc/magic ... who knows ...

if [ "$Preserve" = "Yes" ]
then 
	# don't remove tmp file
	exit 0
else
	rm -f $TMP_FILE
	exit 0
fi
