xref: /onnv-gate/usr/src/cmd/lp/model/uri (revision 3999:666384b31577)
10Sstevel@tonic-gate#!/bin/ksh
20Sstevel@tonic-gate#
30Sstevel@tonic-gate# CDDL HEADER START
40Sstevel@tonic-gate#
50Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6*3999Sjacobs# Common Development and Distribution License (the "License").
7*3999Sjacobs# You may not use this file except in compliance with the License.
80Sstevel@tonic-gate#
90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate# See the License for the specific language governing permissions
120Sstevel@tonic-gate# and limitations under the License.
130Sstevel@tonic-gate#
140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate#
200Sstevel@tonic-gate# CDDL HEADER END
210Sstevel@tonic-gate#
220Sstevel@tonic-gate#
23*3999Sjacobs# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate# Use is subject to license terms.
250Sstevel@tonic-gate#
260Sstevel@tonic-gate# ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate#
280Sstevel@tonic-gate#	printer interface script for printers with a URI instead of
290Sstevel@tonic-gate#	device name.
300Sstevel@tonic-gate#
310Sstevel@tonic-gate# The existence of a "PPD" environment variable in the calling environment
320Sstevel@tonic-gate# indicates that Foomatic is to be used for filtering all job data as it is
330Sstevel@tonic-gate# streamed to the output device (printer).
340Sstevel@tonic-gate#
350Sstevel@tonic-gate# The contents of a "DEVICE_URI" environment variable in the calling
360Sstevel@tonic-gate# environment indicates the method and endpoint used in communicating with
370Sstevel@tonic-gate# the output device (printer).  If no DEVICE_URI is present or the value
380Sstevel@tonic-gate# contains a missing or unknown scheme, the URI scheme is assumed to be
390Sstevel@tonic-gate# "file" and output streaming will be handled accordingly.
400Sstevel@tonic-gate
410Sstevel@tonic-gateexport PATH=/bin:/usr/bin:/usr/lib/lp/bin:/usr/sfw/bin
420Sstevel@tonic-gate
430Sstevel@tonic-gateTAG="uri-interface"
440Sstevel@tonic-gate
450Sstevel@tonic-gate
460Sstevel@tonic-gate# Re-arrange fds for later use
470Sstevel@tonic-gateexec 5>&2 2>/dev/null 3>&1
480Sstevel@tonic-gate
490Sstevel@tonic-gate#
500Sstevel@tonic-gate# Exit Codes:
510Sstevel@tonic-gate#
520Sstevel@tonic-gateEXIT_OK=0
530Sstevel@tonic-gateEXIT_FATAL=1
540Sstevel@tonic-gateEXIT_TERM=128
550Sstevel@tonic-gateEXIT_RETRY=129
560Sstevel@tonic-gate
570Sstevel@tonic-gatefail() {	# exit-code "message"
58*3999Sjacobs	logger -p lpr.error -t ${TAG} "${2}"
590Sstevel@tonic-gate	echo ${2} >&5
600Sstevel@tonic-gate	exit ${1}
610Sstevel@tonic-gate}
620Sstevel@tonic-gate
630Sstevel@tonic-gate# signal handling
640Sstevel@tonic-gate#   EXIT   0  - normal exit
650Sstevel@tonic-gate#   HUP    1  - the output stream disconnected
660Sstevel@tonic-gate#   INT    2  - the output stream interupted us
670Sstevel@tonic-gate#   QUIT   3  - the output stream interupted us
680Sstevel@tonic-gate#   TERM  15  - we have been cancelled or shutdown
690Sstevel@tonic-gate
700Sstevel@tonic-gatecatch_exit() {
710Sstevel@tonic-gate	exit $exit_code
720Sstevel@tonic-gate}
730Sstevel@tonic-gate
740Sstevel@tonic-gatecatch_disconnect() {
750Sstevel@tonic-gate	fail ${EXIT_RETRY} "connection to the printer dropped; off-line?"
760Sstevel@tonic-gate}
770Sstevel@tonic-gate
780Sstevel@tonic-gatecatch_interrupt() {
790Sstevel@tonic-gate	fail ${EXIT_RETRY} "interrupt from the printer; baud-rate issues?"
800Sstevel@tonic-gate}
810Sstevel@tonic-gate
820Sstevel@tonic-gatecatch_cancellation() {
830Sstevel@tonic-gate	fail ${EXIT_RETRY} "job cancelled"
840Sstevel@tonic-gate}
850Sstevel@tonic-gate
860Sstevel@tonic-gatetrap 'catch_disconnect()' HUP
870Sstevel@tonic-gatetrap 'catch_interrupt()' INT QUIT
880Sstevel@tonic-gatetrap 'catch_cancellation()' TERM
890Sstevel@tonic-gate
900Sstevel@tonic-gateparse_uri() {	# scheme://[[user[:password]@]host[:port]]/path
910Sstevel@tonic-gate	URI_SCHEME=$(expr "$1" : "\(.*\)://.*")
920Sstevel@tonic-gate}
930Sstevel@tonic-gate
940Sstevel@tonic-gateparse() {
950Sstevel@tonic-gate	echo "$(expr \"$1\" : \"^[^=]*=\(.*\)\")"
960Sstevel@tonic-gate}
970Sstevel@tonic-gate
980Sstevel@tonic-gate#
990Sstevel@tonic-gate#	Generate an ASCII burst page and pass it to the printer
1000Sstevel@tonic-gate# This may be much faster than the PostScript(TM) burst page
1010Sstevel@tonic-gate#
1020Sstevel@tonic-gateascii_burst_page() {
1030Sstevel@tonic-gate	cat <<EOF
1040Sstevel@tonic-gate	${title}
1050Sstevel@tonic-gate	Request: ${request_id}
1060Sstevel@tonic-gate	User: ${user}
1070Sstevel@tonic-gate	Printer: ${printer}
1080Sstevel@tonic-gate	Time: $(date)
1090Sstevel@tonic-gate	Copies: ${copies}
1100Sstevel@tonic-gateEOF
1110Sstevel@tonic-gate	tput ff
1120Sstevel@tonic-gate}
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate#
1150Sstevel@tonic-gate#	Generate a PostScript(TM) burst page (this assumes an 8.5x11 page size)
1160Sstevel@tonic-gate#
1170Sstevel@tonic-gatepostscript_burst_page() {
1180Sstevel@tonic-gate	cat <<-EOF
1190Sstevel@tonic-gate	%!ps
1200Sstevel@tonic-gate	/PrintLine { exch findfont exch scalefont setfont moveto show } def
1210Sstevel@tonic-gate	newpath 4 setlinewidth 1 setlinejoin
1220Sstevel@tonic-gate	15 760 moveto 595 760 lineto 595 585 lineto 15 585 lineto closepath
1230Sstevel@tonic-gate	gsave .75 setgray fill grestore
1240Sstevel@tonic-gate	0 setgray stroke
1250Sstevel@tonic-gate	(${user}) 30 730 /Times-Bold 24 PrintLine
1260Sstevel@tonic-gate	(${request_id}) 415 730 /Times-Bold 24 PrintLine
1270Sstevel@tonic-gate	(${printer}) 30 600 /Times-Bold 16 PrintLine
1280Sstevel@tonic-gate	($(date)) 350 600 /Times-Roman 16 PrintLine
1290Sstevel@tonic-gate	(${title}) 100 660 /Times-Bold 36 PrintLine
1300Sstevel@tonic-gate	(Copies: ${copies}) 30 25 /Times-Roman 16 PrintLine
1310Sstevel@tonic-gate	showpage
1320Sstevel@tonic-gate	EOF
1330Sstevel@tonic-gate}
1340Sstevel@tonic-gate
1350Sstevel@tonic-gatelogger -p lpr.debug -t ${TAG} "$0 $*"
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate#
1380Sstevel@tonic-gate# Detemine if we were called correctly
1390Sstevel@tonic-gate#
1400Sstevel@tonic-gateif [[ $# -lt 5 ]] ; then
1410Sstevel@tonic-gate	fail ${EXIT_FATAL} "wrong number of arguments to interface script"
1420Sstevel@tonic-gatefi
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate
1450Sstevel@tonic-gateprinter=$(basename $0)
1460Sstevel@tonic-gaterequest_id=$1
1470Sstevel@tonic-gateuser=$2
1480Sstevel@tonic-gatetitle=$3
1490Sstevel@tonic-gatecopies=$4
1500Sstevel@tonic-gateoptions=$5
1510Sstevel@tonic-gate
1520Sstevel@tonic-gateshift 5
1530Sstevel@tonic-gatefiles="$*"
1540Sstevel@tonic-gate
1550Sstevel@tonic-gateburst_page="postscript_burst_page"
1560Sstevel@tonic-gate
1570Sstevel@tonic-gatefor i in ${options}
1580Sstevel@tonic-gatedo
1590Sstevel@tonic-gate	case "${i}" in
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate	nobanner )
1620Sstevel@tonic-gate		burst_page=""
1630Sstevel@tonic-gate		;;
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate	nofilebreak )
1660Sstevel@tonic-gate		nofilebreak="yes"
1670Sstevel@tonic-gate		;;
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate	burst-page-type=* )
1700Sstevel@tonic-gate		burst_page="$(parse ${i})_burst_page"
1710Sstevel@tonic-gate		;;
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate	* )
1740Sstevel@tonic-gate		logger -p lpr.error -t ${TAG} \
1750Sstevel@tonic-gate			"unrecognized \"-o ${i}\" option, ignored" 1>&2
1760Sstevel@tonic-gate		;;
1770Sstevel@tonic-gate	esac
1780Sstevel@tonic-gatedone
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate#
1820Sstevel@tonic-gate# Procss the DEVICE_URI if we have one
1830Sstevel@tonic-gate#
1840Sstevel@tonic-gateif [[ -n "${DEVICE_URI}" ]] ; then
1850Sstevel@tonic-gate	parse_uri ${DEVICE_URI}		# split up the URI
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate	URI_SCHEME=${URI_SCHEME:-file}	# if there is no scheme, assume "file"
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate	case "${URI_SCHEME}" in
1900Sstevel@tonic-gate	file|usb|ecpp|serial|parallel)
1910Sstevel@tonic-gate		IO_HANDLER="lp.cat"
1920Sstevel@tonic-gate		IO_HANDLER_ARGS=""
1930Sstevel@tonic-gate		;;
1940Sstevel@tonic-gate	smb)
1950Sstevel@tonic-gate		IO_HANDLER="smbspool"
1960Sstevel@tonic-gate		IO_HANDLER_ARGS="${request_id} ${user} \"${title}\" 1
1970Sstevel@tonic-gate				 \"${options}\""
1980Sstevel@tonic-gate		;;
199*3999Sjacobs	tcp|socket)
200*3999Sjacobs		URI_HOST=$(expr "${DEVICE_URI}" : ".*://\([^:/]*\)")
201*3999Sjacobs		URI_PORT=$(expr "${DEVICE_URI}" : ".*://.*:\([^/]*\)")
202*3999Sjacobs		if [[ -z "${URI_HOST}" ]] ; then
203*3999Sjacobs			fail ${EXIT_FATAL} "invalid device-uri: ${DEVICE_URI}, reset with lpadmin -v"
204*3999Sjacobs		fi
205*3999Sjacobs		URI_PORT=${URI_PORT:-"9100"}
206*3999Sjacobs		IO_HANDLER="telnet"
207*3999Sjacobs		IO_HANDLER_ARGS="-c -E ${URI_HOST} ${URI_PORT}"
208*3999Sjacobs		;;
209*3999Sjacobs	lpd|ipp)
210*3999Sjacobs		IO_HANDLER="lp"
211*3999Sjacobs		IO_HANDLER_ARGS="-s -d ${DEVICE_URI}"
212*3999Sjacobs		;;
2130Sstevel@tonic-gate	*)
2140Sstevel@tonic-gate		IO_HANDLER=${URI_SCHEME}
2150Sstevel@tonic-gate		IO_HANDLER_ARGS=""
2160Sstevel@tonic-gate		;;
2170Sstevel@tonic-gate	esac
2180Sstevel@tonic-gatefi
2190Sstevel@tonic-gateIO_HANDLER=${IO_HANDLER:-"lp.cat"} # if IO_HANDLER is still unset, use lp.cat
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate# determine if the IO handler is available for us to use when communicating with
2220Sstevel@tonic-gate# the output device (printer.)
2230Sstevel@tonic-gatewhence ${IO_HANDLER} >/dev/null
2240Sstevel@tonic-gateif [[ $? -ne 0 ]] ; then
2250Sstevel@tonic-gate	fail ${ERR_FATAL} \
2260Sstevel@tonic-gate		"Interface script unable to locate IO handler: ${IO_HANDLER}"
2270Sstevel@tonic-gatefi
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate#  There is a PPD file specified, so use foomatic
2300Sstevel@tonic-gateif [[ -n "${PPD}" ]] ; then
2310Sstevel@tonic-gate	FILTER_CHAIN="| foomatic-rip"
2320Sstevel@tonic-gatefi
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate#
2350Sstevel@tonic-gate# Start processing the job here
2360Sstevel@tonic-gate#
2370Sstevel@tonic-gateset | logger -p lpr.debug -t "${TAG}"
2380Sstevel@tonic-gate
2390Sstevel@tonic-gate(
2400Sstevel@tonic-gate	if [[ -n "${burst_page}" ]] ; then
2410Sstevel@tonic-gate		eval "${burst_page} ${FILTER_CHAIN}"
2420Sstevel@tonic-gate	fi
2430Sstevel@tonic-gate	while [[ $copies -gt 0 ]] ; do
2440Sstevel@tonic-gate		for file in ${files} ; do
2450Sstevel@tonic-gate			if [[ -r "${file}" ]] ; then
2460Sstevel@tonic-gate				eval "cat ${file} ${FILTER_CHAIN}"
2470Sstevel@tonic-gate			fi
2480Sstevel@tonic-gate		done
2490Sstevel@tonic-gate		copies=$(( copies - 1 ))
2500Sstevel@tonic-gate	done
2510Sstevel@tonic-gate) | ${IO_HANDLER} ${IO_HANDLER_ARGS}
2520Sstevel@tonic-gate
2530Sstevel@tonic-gateexit ${EXIT_OK}
254