#!/bin/sh

# Copyright 1988-1991 Network Computing Devices, Inc.  All rights reserved.
# An unpublished work.

#ident "$NCDId: @(#)if.sh,v 1.3 1991/11/10 12:36:08 mrj Exp $"


# Determine the current directory, ncd unit name, and printer type.
# The convention used is:  .../if%ptype%pname
# where ptype is the printer type and pname is the hostname of the NCD
# X terminal used.  Valid values for ptype are:
#	ascii	simple ASCII printer
#	dj*	HP DeskJet
#	lj*	HP LaserJet IIP or III
#	lw	Apple LaserWriter using side paper exit
#	lw*up	Apple LaserWriter using top paper exit
#
# The % is used as a seperator (rather than .) for compatability reasons.
# If no seperators are present, the file name is used as the printer name
# and the printer type is assumed to be lw.  If only one seperator is
# present, the part before the seperator is the printer type and that after
# the seperator is the printer name.
#

SEP="%"				# use % as the seperator character
MYNAME=$0
DIR=`expr $0'/' : '\(/\)[^/]*/$' \| $0'/' : '\(.*[^/]\)//*[^/][^/]*//*$' \| .`
BASE=`expr $0'/' : '/\([^/]*\)/$' \| $0'/' : '.*[^/]//*\([^/][^/]*\)//*$' \| $0`
NCD_NAME=xtermb
PRINTER_TYPE=lj

# Define spooler dictated exit code values.
EXIT_OK=0
EXIT_REPRINT=1
EXIT_DISCARD=2

# Define common utilities here!
FOLD=/usr/ucb/fold
# NCD's lwf is built with page reversal as the default!
TXT_TO_PS_REV="/usr/sbin/lptops -U"
TXT_TO_PS="/usr/sbin/lptops"
NCD_LW_DRIVER=/usr/local/bin/ncdprint/ps2ncd
NCD_DRIVER=/usr/local/bin/ncdprint/cat2ncd
CHR=/usr/local/bin/ncdprint/chr
READN=/usr/local/bin/ncdprint/readn
PRINT=/usr/local/bin/ncdprint/print
BANNER=/usr/local/bin/ncdprint/banner
TMP=/tmp

# Initialize parameter values.
landscape=0
fold=1
cols=80
ind=0
width=""
length=""
indent=""
name=unknown
host=serverb
acct_file=""
date=`date +"%a  %h %d, 19%y @ %H:%M"`
sdate1=`date +"%h %d"`
sdate2=`date +"%H:%M"`

# Grab command line arguments
printer=`basename $0`
seqid=$1
name=$2
title="$3"
copies=$4
options="$5"
shift; shift; shift; shift; shift
files="$*"

# Now, based on printer type, define the command pipelines to print.
case "$PRINTER_TYPE" in
    ascii)
	# Text is preceded by banner page and followed by FF.
	#
	# No PostScript
	#
	TX_PIPE="(cat $TMP/$$; cat -; $CHR FF) | $NCD_DRIVER $NCD_NAME"
	PS_PIPE="exit $EXIT_DISCARD"
	PRINTER_TYPE="ascii"
	;;
    dj*)
	# Text:
	#	ESC E			reset
	#	ESC & k 2 G		CR=>CR; LF=>CR+LF; FF=>CR+FF
	#	ESC & l 0 O		portrait orientation
	#	ESC 9			clear margins
	#	ESC ( s 1 2 H		12 pitch
	#	ESC ( s 7 B		extra bold stroke weight
	#				banner page
	#	ESC & l 1 O		landscape orientation (maybe)
	#	ESC ( s 1 2 H		12 pitch
	#	ESC ( s 0 B		normal stroke weight
	#	ESC & a #cols L		set left margin from -i
	#	ESC & a #cols M		set right margin from -w
	#				text
	#	ESC & l 0 H		eject current page
	#
	# No PostScript
	#
	TX_PIPE="\
	    ($CHR ESC E; \
	     $CHR ESC \& k 2 G; \
	     $CHR ESC \& l 0 O; \
	     $CHR ESC 9; \
	     $CHR ESC '(' s 1 2 H; \
	     $CHR ESC '(' s 7 B; \
	     cat $TMP/$$; \
	     if [ $landscape -eq 1 ]; then $CHR ESC \& l 1 O; fi; \
	     $CHR ESC '(' s 1 2 H; \
	     $CHR ESC '(' s 0 B; \
	     $CHR ESC \& a; $PRINT `expr 6 + $ind`; $CHR L; \
	     $CHR ESC \& a; $PRINT `expr 5 + $cols`; $CHR M; \
	     cat -; \
	     $CHR ESC \& l 0 H) | \
	    $NCD_DRIVER $NCD_NAME"
	PS_PIPE="exit $EXIT_DISCARD"
	PRINTER_TYPE="dj"
	;;
    lj*)
	# Text:
	#	ESC E			reset
	#	ESC & k 2 G		CR=>CR; LF=>CR+LF; FF=>CR+FF
	#	ESC & l 0 O		portrait orientation
	#	ESC 9			clear margins
	#	ESC ( s 1 2 H		12 pitch
	#	ESC ( s 7 B		extra bold stroke weight
	#				banner page
	#	ESC & l 1 O		landscape orientation (maybe)
	#	ESC ( s 1 2 H		12 pitch
	#	ESC ( s 0 B		normal stroke weight
	#	ESC & a #cols L		set left margin from -i
	#	ESC & a #cols M		set right margin from -w
	#				text
	#	ESC & l 0 H		eject current page
	#
	# With PostScript option
	#
	TX_PIPE="\
	    ($CHR ESC E; \
	     $CHR ESC \& k 2 G; \
	     $CHR ESC \& l 0 O; \
	     $CHR ESC 9; \
	     $CHR ESC '(' s 1 2 H; \
	     $CHR ESC '(' s 7 B; \
	     cat $TMP/$$; \
	     if [ $landscape -eq 1 ]; then $CHR ESC \& l 1 O; fi; \
	     $CHR ESC '(' s 1 2 H; \
	     $CHR ESC '(' s 0 B; \
	     $CHR ESC \& a; $PRINT `expr 6 + $ind`; $CHR L; \
	     $CHR ESC \& a; $PRINT `expr 5 + $cols`; $CHR M; \
	     cat - ; \
	     $CHR ESC \& l 0 H) | \
	    $NCD_DRIVER $NCD_NAME"
	PS_PIPE="\
		(cat -;\
		$CHR FF) |\
		$NCD_DRIVER $NCD_NAME"
	PRINTER_TYPE="lj"
	;;
    lw*)
	# Text (upper exit):
	#	1) PostScript banner page
	#	2) Convert all text to PostScript (fold if width != 0)
	#	3) Send through PostScript driver
	#
	# Text (side exit):
	#	1) Convert all text to PostScript (fold if width != 0)
	#	2) PostScript banner page
	#	3) Send through PostScript driver
	#
	# PostScript:
	#	Send PostScript banner page and data file in proper order
	#	based on exit orientation through PostScript driver.
	#
	if [ $fold -eq 1 ]
	then
	    TX_PIPE="$FOLD -$cols | "
	else
	    TX_PIPE=""
	fi
	case "$PRINTER_TYPE" in
	    lw*up)
		TX_PIPE="$TX_PIPE (cat $TMP/$$; $TXT_TO_PS) | $NCD_LW_DRIVER $NCD_NAME"
		PS_PIPE="(cat $TMP/$$ -) | $NCD_LW_DRIVER $NCD_NAME"
		;;
	    lw*)
		TX_PIPE="$TX_PIPE ($TXT_TO_PS_REV; cat $TMP/$$) | $NCD_LW_DRIVER $NCD_NAME"
		PS_PIPE="(cat - $TMP/$$) | $NCD_LW_DRIVER $NCD_NAME"
		;;
	esac
	PRINTER_TYPE="lw"
	;;
    *) # Unknown printer type
	echo $MYNAME: Unknown printer type: $PRINTER_TYPE >&2
	exit $EXIT_DISCARD
	;;
esac

# Make sure we always remove any temporary files and exit with proper status.
status=0
trap "rm -f $TMP/$$;exit \$status" 0

# Based on printer type, define a banner page.
true > $TMP/$$
case "$PRINTER_TYPE" in
    ascii) # Simple name, host, and date banner page
	$BANNER "$name"" @" >> $TMP/$$
	$BANNER "$host" >> $TMP/$$
	$BANNER "" >> $TMP/$$
	$BANNER "$sdate1" >> $TMP/$$
	$BANNER "$sdate2" >> $TMP/$$
	$CHR FF >> $TMP/$$			# eject banner page
	;;
    dj*) # Simple name, host, and date banner page with hashed bars
	# 8 inches of 12 hash mark chars per inch
	i=0
	while [ $i -lt 8 ]
	do
	    $CHR DEL DEL DEL DEL DEL DEL DEL DEL DEL DEL DEL DEL >> $TMP/$$
	    i=`expr $i + 1`
	done
	$CHR LF LF >> $TMP/$$			# space down
	echo "User:  $name" >> $TMP/$$		# user name
	$CHR LF >> $TMP/$$
	echo "Host:  $host" >> $TMP/$$		# originating host
	$CHR LF >> $TMP/$$
	echo "Date:  $date" >> $TMP/$$		# date and time of printing
	$CHR LF >> $TMP/$$
	# 8 inches of 12 hash mark chars per inch
	i=0
	while [ $i -lt 8 ]
	do
	    $CHR DEL DEL DEL DEL DEL DEL DEL DEL DEL DEL DEL DEL >> $TMP/$$
	    i=`expr $i + 1`
	done
	$CHR FF >> $TMP/$$			# eject banner page
	;;
    lj) # Simple name, host, and date banner page with 50% black bars
	$CHR ESC \* c 2 4 0 0 A >> $TMP/$$	# 2400/300 inch wide
	$CHR ESC \* c 7 5 B >> $TMP/$$		# 75/300 inch high
	$CHR ESC \* c 5 0 G >> $TMP/$$		# set block pattern to 50% black
	$CHR ESC \* c 2 P >> $TMP/$$		# print a gray scale block
	$CHR LF LF LF LF >> $TMP/$$		# space down
	echo "User:  $name" >> $TMP/$$		# user name
	$CHR LF >> $TMP/$$
	echo "Host:  $host" >> $TMP/$$		# originating host
	$CHR LF >> $TMP/$$
	echo "Date:  $date" >> $TMP/$$		# date and time of printing
	$CHR LF >> $TMP/$$
	$CHR ESC \* c 2 P >> $TMP/$$		# print a gray scale block
	$CHR FF >> $TMP/$$			# eject banner page
	;;
    lw) # Full blown PostScript banner with X and NCD logo
cat << EOF > $TMP/$$
%!PS-Adobe-2.0
%%Creator: $name
%%CreationDate: $date
%%For: $name
%%DocumentFonts: Helvetica
%%Pages: 1
%%EndComments
%%EndProlog
%%Page: 1
%
%  Define some basic constants
%
/inch  { 72 mul }  def
/black  0  def
/gray  0.8 def
/white  1  def

%
%  We will draw concentric boxes with the upper left corner of the
%  outermost box being at (x1,y1) and the lower right corner at
%  (x2,y2).  This later coordinate is defined after the text has been
%  drawn.
%
/x1 0.5 inch def
/y1 10 inch def
/w 7.5 inch def

/psize 24 def
/lead psize 1.5 mul def

/lw 2 def
/lsp lw 2 mul def
/numl 4 def

%---------the text------------

/Helvetica findfont psize scalefont setfont
black setgray
/x x1 lsp numl mul add 18 add def
/y y1 lsp numl mul sub lead sub def
x y moveto
/nl { /y y lead sub def x y moveto } def
gray setgray
(User: ) show
black setgray
($name) show nl
gray setgray
(Host: $host) show nl
(Date: $date) show nl
black setgray

%--------the boxes-----------

lw setlinewidth
/x2 x1 w add def
/y2 y lead add psize sub lsp numl mul sub def

/xul x1 def
/yul y1 def
/xlr x2 def
/ylr y2 def

numl -1 1
  { pop % numl div setgray
    newpath
    xul yul moveto
    xlr yul lineto
    xlr ylr lineto
    xul ylr lineto
    xul yul lineto
    closepath
    stroke
    /xul xul lsp add def
    /yul yul lsp sub def
    /xlr xlr lsp sub def
    /ylr ylr lsp add def
  }
  for

/lsize  0.5 inch  def % change this to change logo size

gsave

xlr lsize sub ylr translate

white -0.01 black
  {     0     0 moveto
    lsize     0 lineto
    lsize lsize lineto
        0 lsize lineto
        0     0 lineto
    setgray fill
  }
  for

/Times-Roman findfont lsize 3 div scalefont setfont

black 0.01 white
  { setgray
    lsize 6 div dup moveto
    { pop pop } (NCD) kshow
  }
  for

grestore

%! xlogo.ps - draw the "official" X Window System Logo, designed by Danny Chong
%
% Copyright (C) 1988 by Jef Poskanzer.
%
% Permission to use, copy, modify, and distribute this software and its
% documentation for any purpose and without fee is hereby granted, provided
% that the above copyright notice appear in all copies and that both that
% copyright notice and this permission notice appear in supporting
% documentation.  This software is provided "as is" without express or
% implied warranty.

/size  6 inch  def % change this to change logo size

gsave

8.5 inch size sub 2 div  1 inch  translate

0  size translate
[ 1 0 0 -1 0 0 ] concat

/d11  size 11 div          def
/d21  d11 3 add 4 div      def
/d31  d11 d11 d21 add add  def
/eps  size 100 div         def

%           -----
%          /    /
%         /    /
%        /    /
%       /    /
%      /____/

size                      0                   moveto
size d31 sub              0                   lineto
0                         size                lineto
d31                       size                lineto
gray  setgray  fill

%           ------
%          /     /
%         /  __ /
%        /  /  /
%       /  /  /
%      /__/__/

d31 2 div                 size                moveto
size 2 div                size 2 div          lineto
size 2 div d31 2 div add  eps add size 2 div  lineto
d31 eps add               size eps add        lineto
white  setgray  fill

%           ------
%          /  /  /
%         /__/  /
%        /     /
%       /     /
%      /_____/

size d31 2 div sub        0                   moveto
size 2 div                size 2 div          lineto
size 2 div d31 2 div sub  eps sub size 2 div  lineto
size d31 sub eps sub      0 eps sub           lineto
white  setgray  fill

% -----
% \    \
%  \    \
%   \    \
%    \    \
%     \____\

0                         0                   moveto
size 4 div                0                   lineto
size                      size                lineto
size size 4 div sub       size                lineto
gray  setgray  fill

%          /
%         /
%        /
%       /
%      /

size d11 sub              0                   moveto
size d11 d21 add sub      0                   lineto
d11                       size                lineto
d11 d21 add               size                lineto
white  setgray  fill

grestore

showpage

%%Trailer
%%Pages: 1
EOF
	;;
    esac

# And, finally, print the job.

echo `date +"%y-%m-%d %T:"` "$MYNAME: Starting job for ${name}@${host}" >&2

cat $files | \
(   A=`$READN 2`; \
    ( $PRINT "$A"; cat ) | \
    if [ "$A" = "%!" ]; \
    then \
	eval $PS_PIPE; \
    else \
	eval $TX_PIPE; \
    fi; \
)
status=$?

echo `date +"%y-%m-%d %T:"` "$MYNAME: End of print job for ${name}@${host} -- status=${status}" >&2

# Accounting is currently not supported.  To do so, we'd need to send a line
# to the file $acct_file which looks like:
#
#   pppp.00<tab>host:name
#
# where pppp is the number of pages printed, host is $host and name is $name.

# Here we try to remap the exit status of ncdprint (cat2ncd or ps2ncd).  Since
# there appears to be no good way to detect a runaway spooler filter, we'll just
# discard any job that gets caught up in the mess.  This is unfortunate, but
# when we tried exiting with the code that tells the spooler to reprint, the
# spooler brought the system to it's knees.  The moral is, make sure the printer
# connection is operational before enabling the spooler!

case $status in
    0) # no errors, job printed
	: status is already set to indicate success
	;;
    1) # read or write failure involving NCD unit; would like to reprint
       # but this causes spooler to spawn filter procs like crazy.
	status=$EXIT_DISCARD
	;;
    2) # printer reported error (PostScript only)
	: status is already set so that the job will be discarded
	;;
    3) # command line usage error
	status=$EXIT_DISCARD
	;;
    4) # unable to connect to printer
	status=$EXIT_DISCARD
	;;
    5) # some internal error (usually select failure)
	status=$EXIT_DISCARD
	;;
    *) # who knows, probably dumped core
	status=$EXIT_DISCARD
	;;
esac

exit $status
