#!/bin/sh
# Source: http://www.berklix.com/~jhs/src/bsd/jhs/bin/local/lpf_berklix/lpf_berklix
# cd ~/public_html/src/bsd/jhs/bin/local/lpf_berklix; make install
# Author: Julian H. Stacey
# Purpose: Pipe.
#	Inputs & detects various different formats,
#	outputs PCL   format for HP LaserJet 4L printer.
#	outputs ljet4 format for HP LaserJet 1010
#	outputs gdi   format for Samsung ML-4500 laser printer.
# Installs to
#	/usr/local/bin/lpf_berklix_gdi -> /usr/local/bin/lpf_berklix
#	/usr/local/bin/lpf_berklix_pcl -> /usr/local/bin/lpf_berklix
# See Also:		/usr/share/doc/handbook/printing.{html,latin1}
# Alternative I haven't looked at:	/usr/ports/print/apsfilter

# Works mostly, but fails on:
#	- Files with just 1 char (#) in 1st line eg /etc/ttys.
# 	- An ascii file with 2 blank lines,
#	  then all indented 3 spaces is unrecognised
#	  I could add something to discard leading white space.
# 	- date|lpr in /var/log/lpd-errs fails
#	  produces 2 x "[: Tue: unexpected operator"
#	  I presume it''s the input format detector going wrong.
#	  I never wrote it to work on one line files.
#	  I don''t care that it fails. It saves paper, call it a feature ;-)
# 	- Some long lines eg .tiff

feedback="quiet"
name=`basename $0`
log="/var/log/lpf_berklix"
lpq=/var/spool/output/lpd.lpf_berklix
#	~/public_html/src/bsd/jhs/etc/berklix.mtree creates $lpq
who=root
if   [ "$name" = "lpf_berklix_pcl" ] ; then # Normal production usage, data private
	gsdev="-sDEVICE=ljet3"
elif [ "$name" = "lpf_berklix_gdi" ] ; then # Normal production usage, data private
	gsdev="-sDEVICE=gdi"
elif [ "$name" = "lpf_berklix_test" ] ; then
	# Debug sesion, not called from lpr & /etc/printcap, for use by eg:
	#   sh -x /usr/local/bin/lpf_berklix_test < ~/tmp/data > ~/tmp/out
	touch $log
	lpq=$HOME/tmp/lpd.lpf_berklix
	mkdir -p $lpq
	who=`whoami`
	feedback="noisey"
else
	echo "$0: Error: The name of this script $0 should be one of:"
	echo    "lpf_berklix_gdi lpf_berklix_pcl lpf_berklix_test"
	exit 1
fi

if [ "$feedback" = "quiet" ] ; then # Normal production usage, keep quiet.
	dbg="true"
	ls="true"
	rm="rm"
else			# Debug, Verbose
	dbg="echo"
	ls="/bin/ls -l"
	rm="true"
fi

touch $log || ( echo "$0: Failed to touch $log" | \
	mail -s "$0 failed to touch $log" $who ; exit 1 )
# Will fail if run by a normal user.  Should only be run by /usr/bin/lpr.

$dbg " " >> $log
$dbg "`date +%Y_%m_%d_%H_%M` $0" >> $log
$dbg "`id`" >> $log

tmp=$lpq/$$.tmp	# $$ is PID
#	Keep $tmp same as in /etc/printcap
groff=/usr/local/bin/groff
	# /usr/local/bin is only in my human path, not shells

$dbg "tmp=$tmp" >> $log

# Ensure we can write a file into $lpq
#	chkprintcap -d does not tighten permissions.
#	~/public_html/src/bsd/jhs/etc/berklix.mtree creates:
#	  /var/spool/output/lpd.lpf_berklix mode=0775 uname=daemon gname=bin
#	  /var/spool/output/lpd.lpf_berklix mode=0775 uname=daemon gname=bin
#	Files inside $lpq if created by lpr command:
#		-rw-rw-r--   1 daemon  bin     355052 Mar 28 01:42 43962.tmp
#		-rw-rwxr--   1 root    bin       6 Mar 28 01:45 lock*
#		-rw-rw-r--   1 root    bin      18 Mar 28 01:45 status
touch $tmp || ( echo "Failed to touch $tmp" >> $log ; exit 1 )

# man printcap:
#	The if filter is invoked with arguments:
#		if [-c] -wwidth -llength -iindent -n login -h host acct-file
# I just ignore arguments delivered here.
# JJLATER If the "-h host" component has a bjc in it, generate bjc not pcl.

pnmtops=/usr/local/bin/pnmtops
jpegtopnm=/usr/local/bin/jpegtopnm

gs="/usr/local/bin/gs -sPAPERSIZE=a4 -dFIXEDMEDIA -dNOPAUSE -q"
gs="$gs $gsdev -sOutputFile=- -dBATCH -dSAFER -"

# PDF Processing: gs now accepts PDF as input
pdfin="$gs"
$dbg "pdfin=$pdfin" >> $log
# Previously, I used to try to convert PDF to PS with this:
#	pdf2ps="/usr/local/bin/pdf2ps -sPAPERSIZE=a4"
#	Avoid pdf2ps error "exec: gs: not found" in /var/log/lpd-errs
#	PATH=:/bin:/usr/bin:/usr/local/bin ; export PATH
#	Although man pdf2ps says
#		pdf2ps [ options ] input.pdf [output.ps]
#	The second parameter is not actually optional, defaulting to pipe if
#	absent, it's just:	`basename "$1" \.pdf`.ps
#	From /usr/local/bin/pdf2ps: -c save pop -f "$1"
# Suppress Inter Field Seperator so it will not swallow the leading
# white space on the first line of plain text input, between left
# margin & first printable character.
#	IFS=
# Read first characters of first line, to determine file type.
# This syntax was not good enough:
#	read first_line
# because a PCL file contains nulls \0 (a .tiff too).
# None of the shell variables & other unix commands (EG echo printf etc)
# tools I've tried cope with it, so to avoid writing a C program, I swallow
# the first line whole & unchanged with head.
# I lost some PCL data with this:
#	head -1 > $tmp
#	first_line=`cat $tmp`
# So now I swallow whole file (tough if its real big, this proc. wont
# work as a pipe.
cat > $tmp
#	why do I want --dereference ?
type=`file -b --dereference $tmp`
$dbg "Format is: $type" >> $log
ok="Format accepted:"
if [ "$type" = "JPEG image data" ]; then				#{{
	$dbg "$ok $type" >> $log
	# .jpg data as examined from cameras:
	#  Frank:
	#    377 330 377 341   u 344   E   x   i   f  \0  \0   I   I   *  \0
	#    377 330 377 341   w 327   E   x   i   f  \0  \0   I   I   *  \0
	#    377 330 377 341   p 371   E   x   i   f  \0  \0   I   I   *  \0
	#  Julian:
	#    377 330 377 341 023   p   E   x   i   f  \0  \0   I   I   *  \0
	#    377 330 377 341 023   .   E   x   i   f  \0  \0   I   I   *  \0
	#    377 330 377 341 023   D   E   x   i   f  \0  \0   I   I   *  \0
	# Notice that "I   I   *  \0" as at start of tiff.
	$jpegtopnm < $tmp | $pnmtops \
		 | $gs && $ls $tmp >> $log && $rm $tmp && exit 0
	# Alternate filter not tried:
	#	/usr/local/bin/djpeg -pnm < $tmp | \
	#		/usr/local/bin/pnmtotiff > $tmp.tmp
	#	/usr/local/bin/tiff2ps -a $tmp.tmp | \
	#		$gs && $ls $tmp >> $log && $rm $tmp $tmp.tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "TIFF image data, little-endian" ]; then	#}{
	$dbg "$ok $type" >> $log
	# From eg http://www.berklix.com/scanjet/
	/usr/local/bin/tiff2ps -a $tmp | $gs && $ls $tmp >> $log && $rm $tmp \
		&& exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "TIFF image data, big-endian" ]; then		#}{
	# A guess, this code has never been used
	$dbg "$ok $type" >> $log
	/usr/local/bin/tiff2ps -a $tmp | $gs && $ls $tmp >> $log && $rm $tmp \
		&& exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "PDF document, version 1.0" ]; then		#}{
	$dbg "$ok $type" >> $log
	# From ?
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "PDF document, version 1.1" ]; then		#}{
	$dbg "$ok $type" >> $log
	# From
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "PDF document, version 1.2" ]; then		#}{
	$dbg "$ok $type" >> $log
	# From
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "PDF document, version 1.3" ]; then		#}{
	$dbg "$ok $type" >> $log
	# From
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "PDF document, version 1.4" ]; then		#}{
	$dbg "$ok $type" >> $log
	# From MesseMuenchen BauMa 2013-04-17, seen by FreeBSD-8.2
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "PDF document, version 1.5" ]; then		#}{
	$dbg "$ok $type" >> $log
	# From Firefox exporting HTML from HMRC
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "PDF document, version 1.6" ]; then		#}{
	$dbg "$ok $type" >> $log
	# From ?
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "PDF document, version 1.7" ]; then		#}{
	# Feb 2014 EMbedded World seen by FreeBSD-9.2
	$dbg "$ok $type" >> $log
	# From
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$type" = "HP PCL printer data - A4 page size" ]; then	#}{
	# 2023-07-04 12.4-RELEASE a file produced with "gs -sDEVICE=ljet4"
	# is reported by 'file' as "HP PCL printer data"
	$dbg "$ok $type" >> $log ; \
	cat $tmp && \
	printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
else								#}{
	$dbg "End of multiple elif file." >> $log
fi								#}}

giftopnm=/usr/local/bin/giftopnm
#	Do not use gif2ps which expands to full page.  For more notes see
#	http://www.berklix.com/~jhs/
#		src/bsd/fixes/FreeBSD/src/jhs/share/mk/berklix2.mk

$dbg "Inspecting first line." >> $log
# Some .tif, the the 1st line from head -1 can be 360K long.
# So something below here breaks, but hopefully .tiff will be caught above.
first_line=`head -1 $tmp`
# IFS="\040\011\012"	# Restore Inter Field Seperator to space tab nl
first_two_chars=`expr "$first_line" : '\(..\)'`
first_four_chars=`expr "$first_line" : '\(....\)'`
first_five_chars=`expr "$first_line" : '\(.....\)'`
first_six_chars=`expr "$first_line" : '\(......\)'`
# If the input text is
#	/* British calendar <en_UK.ISO8859-1/calendar.events>
# The output is:
#	+ expr '/* British calendar <en_UK.ISO8859-1/calendar.events>' : \
#		'\(...\)'
#	+ [ /Distfile /FIRE /ad4s1 /ad4s2 /ad4s3 /ad4s4 /ad4s4dcrypt \
#		/ad6s1 /ad6s2 /ad6s3 /ad6s4 /av /bin /boot /cdrom /cdrw \
#		/chroot /compat /dev /devfs /devusb /dvd /dvdw /entropy \
#		/etc /home /host /lib /libexec /media /mnt /opt /pri \
#		/proc /pub /rescue /root
# {
if [ "$first_four_chars" = "%!PS" ]; then				#{{
	$dbg "Format (from internal analysis): POSTSCRIPT from GROFF" >> $log
	# PostScript: use Ghostscript to convert and print it
	# $groff generated .ps files start: "%!PS-Adobe-3.0"
	# I do not need	to emit $first_line for gs, as I tested ghostview
	# without first line, & it displayed OK, & ghostview uses gs internaly.
	# Example:
	#	%!PS-Adobe-3.0
	#	%%Creator: Applixware
	$gs $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "$first_four_chars" = "%!ps" ]; then				#}{
	$dbg "Format (from $0 analysis): Postscript not from Groff" >> $log
	$gs $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(...\)'` = '.\"' ]; then			#}{
	$dbg "Format (from internal analysis): GROFF" >> $log
	# Note the backslash while needed in the .rof file, used to be
	# discarded by
	#	read first_line
	# before I received it here, however now using:
	#	cat > $tmp ; first_line=`head -1 $tmp`
	# it is there.
	cat $tmp | $groff -U -b -s -t -Tps -dformat=ps -dumlauts=p | \
		 $gs && $ls $tmp >> $log && $rm $tmp && exit 0
	# I could instead generate pcl direct from $groff.
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(........\)'` = '%PDF-1.2' ]; then	#}{
	$dbg "Format (from internal analysis): PDF-1.2" >> $log
	# from ps2pdf, $groff, external
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(........\)'` = '%PDF-1.3' ]; then	#}{
	$dbg "Format (from internal analysis): PDF-1.3" >> $log
	# From Phil Walters I received %PDF-1.3%âãÏÓ
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(........\)'` = '%PDF-1.4' ]; then	#}{
	$dbg "Format (from internal analysis): PDF-1.4" >> $log
	# From Companies House change of address form
	#	%PDF-1.4?%??????
	#	2544232302EECD00
	#	5046D1E4D523F3DA
	# 0D=Carriage Return
	# From GEA Prog 2008-04.pdf
	#	%PDF-1.4?
	#	254423230
	#	5046D1E4A
	# 0A=New Line
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	#	GNU Ghostscript 7.07: Unrecoverable error, exit code 1
	#	Segmentation fault
	# However xpdf can display it, & can export it to a .ps file
	# which this can print. So I discovered this works OK generating .ps
	#	 pdftops $tmp - > t.ps
	# So merge the 2:
	# /usr/local/bin/pdftops $tmp - | $pdfin && $ls $tmp >> $log && \
		$rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(........\)'` = '%PDF-1.5' ]; then	#}{
	$dbg "Format (from internal analysis): PDF-1.5" >> $log
	# Never seen a 1.5, but presumably they exist.
	/usr/local/bin/pdftops $tmp - | $pdfin && $ls $tmp >> $log && \
		$rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(........\)'` = '%PDF-1.6' ]; then	#}{
	$dbg "Format (from internal analysis): PDF-1.6" >> $log
	# from mk@, scanner@msd.
	/usr/local/bin/pdftops $tmp - | $pdfin && $ls $tmp >> $log && \
		$rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(....\)'` = '%PDF' ]; then		#}{
	$dbg "Format (from internal analysis): PDF Unknown Version" >> $log
	# Not from ps2pdf, upper case
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(....\)'` = '%pdf' ]; then		#}{
	$dbg "Format (from internal analysis): pdf unknown version" >> $log
	# not from ps2pdf, lower case
	$pdfin $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ $first_two_chars = '\033E' ]; then				#}{
	( echo "PCL detected by $0" | mail -s "PCL from $0" $who )
	$dbg "Format (from internal analysis): PCL" >> $log	# Escape E
	#  HP/PCL: The big HP PCL 5 book recomends all PCL files should
	#  start with this, & ghostscript generates it, so it's a safe bet.
	# Example:	"^[E^[&l26A" from gs
	# I hope data in first line is not longer than $first_line can read !
	# Some PCL files go berserk, & the whole damn file has no \n,
	# or just one at end.
	cat $tmp && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ `expr "$first_line" : '\(...\)'` = 'II*' ]; then			#}{
	$dbg "Format (from internal analysis): TIFF, eg from scanner" >> $log
	# From eg http://www.berklix.com/scanjet/
	/usr/local/bin/tiff2ps -a $tmp | $gs && $ls $tmp >> $log && \
		$rm $tmp && exit 0
		# The match pattern should have a null (shows in vi as ^@),
		# ie 'II*\0'
		# but I haven't got the elif to match on that.
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ $first_six_chars = 'GIF87a' ]; then				#}{
	# "GIF image data, version 87a, 837 x 947"
	$dbg "Format (from internal analysis): $first_six_chars,"	>> $log
	$dbg " eg xv frame grabber FreeBSD-9.2-RELEASE"  		>> $log
	$giftopnm < $tmp | $pnmtops | $gs && $ls $tmp >> $log && \
		$rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ $first_six_chars = 'GIF89a' ]; then				#}{
	$dbg "Format (from internal analysis): $first_six_chars,"	>> $log
	$dbg " eg lufthansa.com boardingpass QR code 2015-03"  		>> $log
	# "GIF image data, version 89a, 148 x 172"
	# $dbg "About to: $giftopnm < $tmp | $pnmtops | $gs"		>> $log
	$giftopnm < $tmp | $pnmtops | $gs && $ls $tmp >> $log && \
		$rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ $first_six_chars = 'GIF im' ]; then				#}{
	$dbg "Format (from internal analysis): $first_six_chars,"	>> $log
	$dbg " eg xv frame grabber on FreeBSD-7.1-RELEASE"  		>> $log
	$giftopnm < $tmp | $pnmtops | $gs && $ls $tmp >> $log && \
		$rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
elif [ "`echo \"$first_line\" | file -b -`" = "JPEG image data" ]; then	#}{
	# .jpg data as examined from cameras:
	#  Frank:
	#    377 330 377 341   u 344   E   x   i   f  \0  \0   I   I   *  \0
	#    377 330 377 341   w 327   E   x   i   f  \0  \0   I   I   *  \0
	#    377 330 377 341   p 371   E   x   i   f  \0  \0   I   I   *  \0
	#  Julian:
	#    377 330 377 341 023   p   E   x   i   f  \0  \0   I   I   *  \0
	#    377 330 377 341 023   .   E   x   i   f  \0  \0   I   I   *  \0
	#    377 330 377 341 023   D   E   x   i   f  \0  \0   I   I   *  \0
	# Notice that "I   I   *  \0" as at start of tiff.
	$dbg "Format (from internal analysis): JPG"  >> $log
	$jpegtopnm < $tmp | $pnmtops \
		 | $gs && $ls $tmp >> $log && $rm $tmp && exit 0
	# Alternate filter not tried:
	#	/usr/local/bin/djpeg -pnm < $tmp | \
			#/usr/local/bin/pnmtotiff > $tmp.tmp
	#	/usr/local/bin/tiff2ps -a $tmp.tmp | \
			#$gs && $ls $tmp >> $log && $rm $tmp $tmp.tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
# The next test does not work, I presume the space breaks it.
# elif [ $first_five_chars = 'From ' ]; then				#}{
# 	$dbg "Format (from internal analysis): Refusing mail5 file"	>> $log
# 	# Raw mail files have wasteful header, & may have enclosures,
# 	# so avoid wasting paper.
# 	exit 1
# Testing first 4 is nearly as good.
elif [ $first_four_chars = 'From' ]; then				#}{
	$dbg "Format (from internal analysis): Refusing mail4 file"	>> $log
	# Raw mail files have wasteful header, & may have enclosures,
	# so avoid wasting paper.
	exit 1
else
	# JJLATER MOVE ASCII TEST TO HERE
	$dbg "Testing for ASCII:" >> $log
	#  Hope its not a binary that will consume masses of paper.
	#  Plain text: print a form feed at the end to eject the last page.
	# EscE: Initialise printer to default state with EscE,
	#	in case last use has left it in a mangled state
	#	EG host computer might have died in mid print.
	# EscE: Initialise again for good measure:
	#	maybe the printer might not recognise first Reset if it
	#	gets swallowed into an embedded sequence, or perhaps the
	#	printer is on a flakey dynamic multiplexer, & the first
	#	couple of characters get lost, while the multiplexer is
	#	switching the printer to a different host computer.
	#	Unlike with a hayes escape, a pcl escape does not seem to
	#	require a quiet period afterward, according to the big
	#	HP PCL manual.
	# Esc&k2G: Tell printer to treat LF as CR+LF.
	# EscE	Reset to default for next user (that on a dynamic
	#	multiplexer may not even be Unix+lpd )
	#	A printer reset also has the side effect of causing
	#	the printer to flush the last partial page (if any), whereas
	#	If we sent a FF instead, we could end up printing an
	#	extra blank page, if either { (A) the input stream of data had
	#	terminated with a page aligning FF, or (B) the last line feed
	#	happened to align the printer to end of page. }
	# File reports various sorts of Ascii, eg:
	#	cd /etc ; file -b * | grep -i ascii | sort | uniq
	#		ASCII C++ program text
	#		ASCII English text
	#		ASCII make commands text
	#		ASCII text
	#	cd ~/mail/Inbox; echo [0-9]*|wc -l	# 500+ raw mail files
	#	file -b --dereference [0-9]* | sort | uniq
	#		ASCII text
	#		ASCII text, with very long lines
	#		C source, ASCII text
	#		C source, ISO-8859 text
	#		C source, Non-ISO extended-ASCII text
	#		C++ source, ASCII text
	#		C++ source, UTF-8 Unicode text
	#		HTML document, ASCII text
	#		HTML document, ASCII text, with very long lines
	#		ISO-8859 text
	#		ISO-8859 text, with very long lines
	#		Non-ISO extended-ASCII text
	#		Non-ISO extended-ASCII text, with very long lines
	#		Pascal source, ASCII text
	#		Pascal source, ISO-8859 text
	#		Pascal source, UTF-8 Unicode text
	#		UTF-8 Unicode text
	#		UTF-8 Unicode text, with very long lines
	#		unified diff output, ASCII text
	#	See also: man file & /usr/share/misc/magic
	if [ "$type" = "ASCII text" ]; then			#{{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ASCII English text" ]; then		#}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ASCII make commands text" ]; then	#}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ASCII C++ program text" ]; then	#}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ISO-8859 text" ]; then		#}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ISO-8859 English text" ]; then		#}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "news or mail text" ]; then #}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ISO-8859 mail text, with very long lines" ]; then #}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ASCII news text" ]; then		#}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ASCII C program text" ]; then		#}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "ISO-8859 news text" ]; then		#}{
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	elif [ "$type" = "UTF-8 Unicode text" ]; then		#}{
		# A mail file beginning:	To:
		$dbg "$ok $type" >> $log ; \
			printf "\033E\033&k2G" && cat $tmp && \
			printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	# In a mail, removing 'Received:' lines changes file report
	#	From	"ASCII mail text"
	#	To:	"ASCII HTML document text" OR "ASCII text" if a non MIME
	# so JJLATER detect "ASCII mail text".
	# I could also add Many other strings such as
	#	"POSIX shell script text executable"
	#	"troff or preprocessor input text"
	# But troff should be formatted first anyway
	# (& probably from a Makefile).
	# I could extend to use a switch as below,
	# but I suspect below broke cos of spaces in strings
	# switch ( "$type")
	#         case "ASCII text":
	#         case "ASCII English text":
	#         case "ASCII make commands text":
	#         case "ASCII C++ program text":
	#		$dbg "Format OK to print" >> $log
	#                 breaksw
	#         default:
	#		$dbg "Format not ASCII so skipped" >> $log
	#		breaksw
	#	endsw
	fi							#}}
	$dbg "Format (from internal analysis): Unrecognised"  >> $log
	# Might be valid text or a random binary that might lock up printer.
	$dbg "Warning: Stripping any 8th bits"  >> $log
	printf "\033E\033&k2G" && dd if=$tmp conv=parnone && \
		printf "\033E" && $ls $tmp >> $log && $rm $tmp && exit 0
	$dbg "$0 filtering failed" >> $log
	exit 1
fi									#}}

# About Trailing Form Feed:	JJLATER
# - The trailing Reset (\033E) Form Feed = New Page =Control L = (\014)
#  should be selective, sampling data at end of file, but it's not (yet),
# - Printers can be set up to also require FF or not,
#   generatin their own instead. If both do FF you get a wasted page.
# - If neither do it, the job doesn''t print till next job,
#   or until you manually send an empty page.
# - My HP is set up to generate its own trailing NP=FF
# - My Brother is set up to want an FF from computer.
# - Applixware.pcl does not have a terminating FF.
# - Groff.pcl produced by $groff -U -b -s -t -Tlj4 -dformat=lj4
#	thing.rof > thing.pcl ) Have a terminating ^L^[E
# - .pcl made by $groff -U -b -s -t -Tlj4 -dformat=lj4  thing.rof > thing.pcl
#    Ends with ^L^[E (& has bits of words in, not pure bitmap), for CV ~55K.
# - .pcl made by gs -sDEVICE=ljet3 -sOutputFile=thing.pcl -- thing.ps
#    also ends in ^L^[E (but seems to have no strings, just bit map, & is
#    much larger, for my CV ~650K)
# JJLATER add a trap to $ls $tmp >> $log && $rm $tmp
echo "$0 Error, unrecognised format $tmp" | \
	mail -s "$0 Error, unrecognised format" $who
echo "$0 Error, unrecognised format $tmp" >> $log
exit 2	# Only on error.
# /usr/share/doc/handbook/handbook93.html:
#	The text filter, confusingly called the input filter in LPD
#	documentation, handles regular text printing. Think of it as the
#	default filter. LPD expects every printer to be able to print plain
#	text by default, and it is the text filter's job to make sure
#	backspaces, tabs, or other special characters do not confuse the
#	printer. If you are in an environment where you have to account for
#	printer usage, the text filter must also account for pages printed,
#	usually by counting the number of lines printed and comparing that
#	to the number of lines per page the printer supports. The text
#	filter is started with the following argument list:
#	[-c] -wwidth -llength -iindent -n login -h host acct-file
