2 # Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 # Use is subject to license terms.
7 # The contents of this file are subject to the terms of the
8 # Common Development and Distribution License, Version 1.0 only
9 # (the "License"). You may not use this file except in compliance
12 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
13 # or http://www.opensolaris.org/os/licensing.
14 # See the License for the specific language governing permissions
15 # and limitations under the License.
17 # When distributing Covered Code, include this CDDL HEADER in each
18 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
19 # If applicable, add the following below this CDDL HEADER, with the
20 # fields enclosed by brackets "[]" replaced with your own identifying
21 # information: Portions Copyright [yyyy] [name of copyright owner]
25 #pragma ident "%Z%%M% %I% %E% SMI"
28 ## Network Standard printer interface program.
33 # We can't do much except exit if spooler/scheduler
36 trap 'eval exit_clean 15' 15
40 # Send standard error messages to /dev/null rather than to
41 # the spooler. Avoids "Terminated" messages that shell puts out
42 # when gets SIGTERM. Save standard error so it can be used
45 exec 5>&2 2>/dev/null 3>&1
48 # set some global variables
52 : ${SPOOLDIR:=/usr/spool/lp}
53 : ${LOCALPATH:=${SPOOLDIR}/bin}
54 PATH="/bin:/usr/bin:${LOCALPATH}"
58 # ${LPTELL} is the name of a program that will send its
59 # standard input to the Spooler. It is used to forward
60 # the description of a printer fault to the Spooler,
61 # which uses it in an alert to the administrator.
63 if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
69 if [ "no" = "${header}" ]
71 errmsg ERROR ${E_IP_UNKNOWN} \
72 "unknown printer/interface failure" \
73 "consult your system administrator;
74 reasons for failure (if any) follow:"
85 # Error message formatter:
89 # errmsg severity message-number problem help
91 # where severity is "ERROR" or "WARNING", message-number is
92 # a unique identifier, problem is a short description of the
93 # problem, and help is a short suggestion for fixing the problem.
102 E_IP_ERRORS=12 # (in slow.filter)
115 echo "${LP_ERR_LABEL}:$2 ${sev}: $3
125 echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
130 ## Error Cleanup and Exit
137 if [ -f "${LPTMPDIR}/pr_eexit_code.$$" ]
139 /bin/rm ${LPTMPDIR}/pr_eexit_code.$$
142 if [ -f "${LPTMPDIR}/small_banner.$$" ]
144 /bin/rm ${LPTMPDIR}/small_banner.$$
147 if [ -f "${tmpfile}" ]
157 # This program is invoked as
159 # ${SPOOLDIR}/.../printer request-id user title copies options files...
161 # The first three arguments are simply reprinted on the banner page,
162 # the fourth (copies) is used to control the number of copies to print,
163 # the fifth (options) is a blank separated list (in a single argument)
164 # of user or Spooler supplied options (without the -o prefix),
165 # and the last arguments are the files to print.
171 errmsg ERROR ${E_IP_ARGS} \
172 "wrong number of arguments to interface program" \
173 "consult your system administrator"
177 printer=`basename $0`
189 # debug sent to file if defined in /etc/syslog.conf
191 # lpr.debug /path/filename
193 logger -p lpr.debug -t "netstandard: ${request_id}" " "
194 logger -p lpr.debug -t "netstandard: ${request_id}" "INPUT"
195 logger -p lpr.debug -t "netstandard: ${request_id}" " printer : ${printer}"
196 logger -p lpr.debug -t "netstandard: ${request_id}" " request_id : ${request_id}"
197 logger -p lpr.debug -t "netstandard: ${request_id}" " user_name : ${user_name}"
198 logger -p lpr.debug -t "netstandard: ${request_id}" " title : ${title}"
199 logger -p lpr.debug -t "netstandard: ${request_id}" " copies : ${copies}"
200 logger -p lpr.debug -t "netstandard: ${request_id}" " option_list : ${option_list}"
201 logger -p lpr.debug -t "netstandard: ${request_id}" " files : ${files}"
202 logger -p lpr.debug -t "netstandard: ${request_id}" " spooler_key ${SPOOLER_KEY}"
205 # default: do print a banner
212 for i in ${option_list}
214 case "${inlist}${i}" in
226 # If you want to add simple options (e.g. -o simple)
227 # identify them here.
255 dest="-d `parse ${i}`"
259 protocol="-P `parse ${i}`"
262 controlfile="-c `parse ${i}`"
265 timeout="-t `parse ${i}`"
269 data_file_flag="-f `parse ${i}`"
274 # If you want to add simple-value options (e.g. -o value=a)
275 # identify them here.
283 # If you want to add options that,
284 # take a list (e.g. -o lopt='a b c'), identif
285 # them here and below (look for LOPT).
288 # flist=* | lpd=* | options=* )
290 #LOPT stty=* | flist=* | lpd=* | lopt=* )
292 inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
295 item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
301 item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
304 item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
307 item=`expr "${i}" : "^\(.*\)'\$"`
316 # We don't dare use "eval" because a clever user could
317 # put something in an option value that we'd end up
322 flist="${flist} ${item}"
328 #LOPT lopt="${lopt} ${item}"
331 # options="${options} ${item}"
348 errmsg WARNING ${E_IP_OPTS} \
349 "unrecognized \"-o ${i}\" option" \
350 "check the option, resubmit if necessary
356 logger -p lpr.debug -t "netstandard: ${request_id}" "term : ${TERM}"
358 if [ -z "${FILTER}" ]
362 # If no filter is being used, we use netpr to push the
363 # file to the printer.
364 # (QUOTES ARE IMPORTANT!)
369 # make the "postscript" printers use netpr
373 # make the "reverse postscript" printers reverse the
374 # output and the use postio to talk to the printer
375 #FILTER="/usr/lib/lp/postscript/postreverse "
377 FILTER="/usr/lib/lp/postscript/postreverse "
380 # We don't know the type, so just assume that the
381 # input and output are the same. Use netpr.
389 # sets default value for ordering of data and control files with
390 # bsd protocol. Default: data files first. Administrator
391 # may set to control file first with lpadmin -o bsdctrl=first
395 case "${nobanner}" in
401 NETPR="/usr/lib/lp/bin/netpr ${banner_flag} ${data_file_flag} \
402 -I ${request_id} -U ${user_name} \
403 -p ${printer} ${dest} -T \"${title}\" \
404 ${timeout} ${protocol} ${controlfile} "
405 LPTELL_OPTS="-l" # netpr sends LaserWriter style messages back
407 logger -p lpr.debug -t "netstandard: ${request_id}" "NETPR= ${NETPR}"
408 logger -p lpr.debug -t "netstandard: ${request_id}" "filter : ${FILTER}"
412 tmpfile=${LPTMPDIR}/${node}.${pid}
414 logger -p lpr.debug -t "netstandard: ${request_id}" "tmpfile : ${tmpfile}"
418 # Set up filter for banner page
424 banner_filter=" | /usr/lib/lp/postscript/postprint "
431 # Build temporary file that is the banner page
442 echo "##### User: ${user_name}${NL}\c"
445 echo "##### Title: ${title}${NL}\c"
447 echo "##### Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
448 echo "##### Job: ${request_id}${NL}\c"
458 # Doing small banner as we don't know what printer is out there
463 if [ "no" = "${nobanner}" ]
465 eval "${banner} ${banner_filter}" 2>&1 1>${LPTMPDIR}/small_banner.$$
470 # Print banner page before job unless PSR
475 if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" ]
478 eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
479 echo $? > ${LPTMPDIR}/pr_eexit_code.$$
480 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
482 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
483 logger -p lpr.debug -t "netstandard: ${request_id}" \
484 "banner page exit code : ${exit_code}"
489 while [ $i -le $copies ]
496 if [ ! -z "${FILTER}" ]
500 # There is a filter, use it
502 # Put 0<${file} before the "eval" to keep
503 # clever users from giving a file name that
504 # evaluates as something to execute.
505 # Redirect stderr to stdout so LPTELL will
506 # get error messages from pipe.
509 0<${file} eval ${FILTER} 2>&1 1>${tmpfile}
510 echo $? > ${LPTMPDIR}/pr_eexit_code.$$
511 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
513 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
514 logger -p lpr.debug -t "netstandard: ${request_id}" \
515 "filter exit_code : ${exit_code}"
517 if [ -n "${exit_code}" ]
519 if [ "${exit_code}" -eq 0 ]
524 # The filter did not succeed, so don't try to print
534 logger -p lpr.debug -t "netstandard: ${request_id}" \
535 "printfile : ${printfile}"
541 if [ -r "${printfile}" ]
544 eval ${NETPR} ${printfile} 2>&1
545 echo $? > ${LPTMPDIR}/pr_eexit_code.$$
546 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
548 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
549 logger -p lpr.debug -t "netstandard: ${request_id}" \
550 "netpr exit_code : ${exit_code}"
552 if [ -f "${tmpfile}" ]
557 if [ -n "${exit_code}" ]
559 if [ "${exit_code}" -eq 0 ]
563 if [ "${exit_code}" -lt 128 ]
575 errmsg WARNING ${E_IP_BADFILE} \
576 "cannot read temporary file \"${printfile}\""\
577 "see if file still exists,
578 or consult your system administrator;
586 # Don't complain about not being able to read
587 # a file on second and subsequent copies, unless
588 # we've not complained yet. This removes repeated
589 # messages about the same file yet reduces the
590 # chance that the user can remove a file and not
591 # know that we had trouble finding it.
594 if [ "${i}" -le 1 -o -z "${badfileyet}" ]
596 errmsg WARNING ${E_IP_BADFILE} \
597 "cannot read file \"${file}\"" \
598 "see if the file still exists and is readable,
599 or consult your system administrator;
606 # for file in ${files}
613 # If printing in reverse order, print the banner page now
617 if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
620 eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
621 echo $? > ${LPTMPDIR}/pr_eexit_code.$$
622 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
625 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
626 logger -p lpr.debug -t "netstandard: ${request_id}" \
627 "banner page exit code : ${exit_code}"
629 if [ -n "${printone}" -a -z "${retry}" -a -z "${noprint}" ]
633 if [ -n "${retry}" -a -z "${printone}" -a -z "${noprint}" ]
641 logger -p lpr.debug -t "netstandard: ${request_id}" \
642 "FINAL exit_code : ${exit_code}"
644 exit_clean ${exit_code}