xref: /illumos-gate/usr/src/cmd/lp/model/uri (revision 03831d35f7499c87d51205817c93e9a8d42c4bae)
1#!/bin/ksh
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License, Version 1.0 only
7# (the "License").  You may not use this file except in compliance
8# with the License.
9#
10# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11# or http://www.opensolaris.org/os/licensing.
12# See the License for the specific language governing permissions
13# and limitations under the License.
14#
15# When distributing Covered Code, include this CDDL HEADER in each
16# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17# If applicable, add the following below this CDDL HEADER, with the
18# fields enclosed by brackets "[]" replaced with your own identifying
19# information: Portions Copyright [yyyy] [name of copyright owner]
20#
21# CDDL HEADER END
22#
23#
24# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26#
27# ident	"%Z%%M%	%I%	%E% SMI"
28#
29#	printer interface script for printers with a URI instead of
30#	device name.
31#
32# The existence of a "PPD" environment variable in the calling environment
33# indicates that Foomatic is to be used for filtering all job data as it is
34# streamed to the output device (printer).
35#
36# The contents of a "DEVICE_URI" environment variable in the calling
37# environment indicates the method and endpoint used in communicating with
38# the output device (printer).  If no DEVICE_URI is present or the value
39# contains a missing or unknown scheme, the URI scheme is assumed to be
40# "file" and output streaming will be handled accordingly.
41
42export PATH=/bin:/usr/bin:/usr/lib/lp/bin:/usr/sfw/bin
43
44TAG="uri-interface"
45
46
47# Re-arrange fds for later use
48exec 5>&2 2>/dev/null 3>&1
49
50#
51# Exit Codes:
52#
53EXIT_OK=0
54EXIT_FATAL=1
55EXIT_TERM=128
56EXIT_RETRY=129
57
58fail() {	# exit-code "message"
59	echo ${2} >&5
60	exit ${1}
61}
62
63# signal handling
64#   EXIT   0  - normal exit
65#   HUP    1  - the output stream disconnected
66#   INT    2  - the output stream interupted us
67#   QUIT   3  - the output stream interupted us
68#   TERM  15  - we have been cancelled or shutdown
69
70catch_exit() {
71	exit $exit_code
72}
73
74catch_disconnect() {
75	fail ${EXIT_RETRY} "connection to the printer dropped; off-line?"
76}
77
78catch_interrupt() {
79	fail ${EXIT_RETRY} "interrupt from the printer; baud-rate issues?"
80}
81
82catch_cancellation() {
83	fail ${EXIT_RETRY} "job cancelled"
84}
85
86trap 'catch_disconnect()' HUP
87trap 'catch_interrupt()' INT QUIT
88trap 'catch_cancellation()' TERM
89
90parse_uri() {	# scheme://[[user[:password]@]host[:port]]/path
91	URI_SCHEME=$(expr "$1" : "\(.*\)://.*")
92}
93
94parse() {
95	echo "$(expr \"$1\" : \"^[^=]*=\(.*\)\")"
96}
97
98#
99#	Generate an ASCII burst page and pass it to the printer
100# This may be much faster than the PostScript(TM) burst page
101#
102ascii_burst_page() {
103	cat <<EOF
104	${title}
105	Request: ${request_id}
106	User: ${user}
107	Printer: ${printer}
108	Time: $(date)
109	Copies: ${copies}
110EOF
111	tput ff
112}
113
114#
115#	Generate a PostScript(TM) burst page (this assumes an 8.5x11 page size)
116#
117postscript_burst_page() {
118	cat <<-EOF
119	%!ps
120	/PrintLine { exch findfont exch scalefont setfont moveto show } def
121	newpath 4 setlinewidth 1 setlinejoin
122	15 760 moveto 595 760 lineto 595 585 lineto 15 585 lineto closepath
123	gsave .75 setgray fill grestore
124	0 setgray stroke
125	(${user}) 30 730 /Times-Bold 24 PrintLine
126	(${request_id}) 415 730 /Times-Bold 24 PrintLine
127	(${printer}) 30 600 /Times-Bold 16 PrintLine
128	($(date)) 350 600 /Times-Roman 16 PrintLine
129	(${title}) 100 660 /Times-Bold 36 PrintLine
130	(Copies: ${copies}) 30 25 /Times-Roman 16 PrintLine
131	showpage
132	EOF
133}
134
135logger -p lpr.debug -t ${TAG} "$0 $*"
136
137#
138# Detemine if we were called correctly
139#
140if [[ $# -lt 5 ]] ; then
141	fail ${EXIT_FATAL} "wrong number of arguments to interface script"
142fi
143
144
145printer=$(basename $0)
146request_id=$1
147user=$2
148title=$3
149copies=$4
150options=$5
151
152shift 5
153files="$*"
154
155burst_page="postscript_burst_page"
156
157for i in ${options}
158do
159	case "${i}" in
160
161	nobanner )
162		burst_page=""
163		;;
164
165	nofilebreak )
166		nofilebreak="yes"
167		;;
168
169	burst-page-type=* )
170		burst_page="$(parse ${i})_burst_page"
171		;;
172
173	* )
174		logger -p lpr.error -t ${TAG} \
175			"unrecognized \"-o ${i}\" option, ignored" 1>&2
176		;;
177	esac
178done
179
180
181#
182# Procss the DEVICE_URI if we have one
183#
184if [[ -n "${DEVICE_URI}" ]] ; then
185	parse_uri ${DEVICE_URI}		# split up the URI
186
187	URI_SCHEME=${URI_SCHEME:-file}	# if there is no scheme, assume "file"
188
189	case "${URI_SCHEME}" in
190	file|usb|ecpp|serial|parallel)
191		IO_HANDLER="lp.cat"
192		IO_HANDLER_ARGS=""
193		;;
194	smb)
195		IO_HANDLER="smbspool"
196		IO_HANDLER_ARGS="${request_id} ${user} \"${title}\" 1
197				 \"${options}\""
198		;;
199	*)
200		IO_HANDLER=${URI_SCHEME}
201		IO_HANDLER_ARGS=""
202		;;
203	esac
204fi
205IO_HANDLER=${IO_HANDLER:-"lp.cat"} # if IO_HANDLER is still unset, use lp.cat
206
207# determine if the IO handler is available for us to use when communicating with
208# the output device (printer.)
209whence ${IO_HANDLER} >/dev/null
210if [[ $? -ne 0 ]] ; then
211	fail ${ERR_FATAL} \
212		"Interface script unable to locate IO handler: ${IO_HANDLER}"
213fi
214
215#  There is a PPD file specified, so use foomatic
216if [[ -n "${PPD}" ]] ; then
217	FILTER_CHAIN="| foomatic-rip"
218fi
219
220#
221# Start processing the job here
222#
223set | logger -p lpr.debug -t "${TAG}"
224
225(
226	if [[ -n "${burst_page}" ]] ; then
227		eval "${burst_page} ${FILTER_CHAIN}"
228	fi
229	while [[ $copies -gt 0 ]] ; do
230		for file in ${files} ; do
231			if [[ -r "${file}" ]] ; then
232				eval "cat ${file} ${FILTER_CHAIN}"
233			fi
234		done
235		copies=$(( copies - 1 ))
236	done
237) | ${IO_HANDLER} ${IO_HANDLER_ARGS}
238
239exit ${EXIT_OK}
240