4 # The contents of this file are subject to the terms of the
5 # Common Development and Distribution License (the "License").
6 # You may not use this file except in compliance with the License.
8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 # or http://www.opensolaris.org/os/licensing.
10 # See the License for the specific language governing permissions
11 # and limitations under the License.
13 # When distributing Covered Code, include this CDDL HEADER in each
14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 # If applicable, add the following below this CDDL HEADER, with the
16 # fields enclosed by brackets "[]" replaced with your own identifying
17 # information: Portions Copyright [yyyy] [name of copyright owner]
22 #ident "%Z%%M% %I% %E% SMI"
24 # Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
30 ## Network Standard printer interface program for foomatic.
35 # We can't do much except exit if spooler/scheduler
38 trap 'eval exit_clean 15' 15
42 # Send standard error messages to /dev/null rather than to
43 # the spooler. Avoids "Terminated" messages that shell puts out
44 # when gets SIGTERM. Save standard error so it can be used
47 exec 5>&2 2>/dev/null 3>&1
50 # set some global variables
54 : ${SPOOLDIR:=/usr/spool/lp}
55 : ${LOCALPATH:=${SPOOLDIR}/bin}
56 PATH="/bin:/usr/bin:${LOCALPATH}"
60 # ${LPTELL} is the name of a program that will send its
61 # standard input to the Spooler. It is used to forward
62 # the description of a printer fault to the Spooler,
63 # which uses it in an alert to the administrator.
65 if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
71 if [ "no" = "${header}" ]
73 errmsg ERROR ${E_IP_UNKNOWN} \
74 "unknown printer/interface failure" \
75 "consult your system administrator;
76 reasons for failure (if any) follow:"
87 # ${LPTSOLSEPARATOR} is the name of a program to put banner and trailer
88 # pages around the job.
90 if [ -x ${LOCALPATH}/lp.tsol_separator ]
92 LPTSOLSEPARATOR=${LOCALPATH}/lp.tsol_separator
94 echo "${LOCALPATH}/lp.tsol_separator not found." >&2
99 # Error message formatter:
103 # errmsg severity message-number problem help
105 # where severity is "ERROR" or "WARNING", message-number is
106 # a unique identifier, problem is a short description of the
107 # problem, and help is a short suggestion for fixing the problem.
116 E_IP_ERRORS=12 # (in slow.filter)
129 echo "${LP_ERR_LABEL}:$2 ${sev}: $3
139 echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
144 ## Error Cleanup and Exit
151 if [ -f "${LPTMPDIR}/pr_eexit_code.$$" ]
153 /bin/rm ${LPTMPDIR}/pr_eexit_code.$$
156 if [ -f "${LPTMPDIR}/small_banner.$$" ]
158 /bin/rm ${LPTMPDIR}/small_banner.$$
161 if [ -f "${LPTMPDIR}/banner.exit_code.$$" ]
163 /bin/rm ${LPTMPDIR}/banner.exit_code.$$
166 if [ -f "${LPTMPDIR}/banner.errmsg.$$" ]
168 /bin/rm ${LPTMPDIR}/banner.errmsg.$$
171 if [ -f "${tmpfile}" ]
181 # This program is invoked as
183 # ${SPOOLDIR}/.../printer request-id user title copies options files...
185 # The first three arguments are simply reprinted on the banner page,
186 # the fourth (copies) is used to control the number of copies to print,
187 # the fifth (options) is a blank separated list (in a single argument)
188 # of user or Spooler supplied options (without the -o prefix),
189 # and the last arguments are the files to print.
195 errmsg ERROR ${E_IP_ARGS} \
196 "wrong number of arguments to interface program" \
197 "consult your system administrator"
201 printer=`basename $0`
213 # debug sent to file if defined in /etc/syslog.conf
215 # lpr.debug /path/filename
217 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" " "
218 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" "INPUT"
219 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
220 " printer : ${printer}"
221 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
222 " request_id : ${request_id}"
223 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
224 " user_name : ${user_name}"
225 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
227 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
228 " copies : ${copies}"
229 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
230 " option_list : ${option_list}"
231 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
233 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
234 " spooler_key ${SPOOLER_KEY}"
237 # default: do print a banner
245 for i in ${option_list}
247 case "${inlist}${i}" in
263 # If you want to add simple options (e.g. -o simple)
264 # identify them here.
292 dest="-d `parse ${i}`"
296 protocol="-P `parse ${i}`"
299 controlfile="-c `parse ${i}`"
302 timeout="-t `parse ${i}`"
306 data_file_flag="-f `parse ${i}`"
310 # The IPP/PAPI attributes are handled by the foomatic-rip filter so
311 # all we need to do here is ignore them so that they don't invoke the
312 # "unrecognized option" message.
315 finishing=* | page-ranges=* | sides=* )
317 number-up=* | orientation-requested=* | media=* )
319 printer-resolution=* | print-quality=* )
324 # If you want to add simple-value options (e.g. -o value=a)
325 # identify them here.
333 # If you want to add options that,
334 # take a list (e.g. -o lopt='a b c'), identif
335 # them here and below (look for LOPT).
338 # flist=* | lpd=* | options=* )
340 #LOPT stty=* | flist=* | lpd=* | lopt=* )
342 inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
345 item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
351 item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
354 item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
357 item=`expr "${i}" : "^\(.*\)'\$"`
366 # We don't dare use "eval" because a clever user could
367 # put something in an option value that we'd end up
372 flist="${flist} ${item}"
378 #LOPT lopt="${lopt} ${item}"
381 # options="${options} ${item}"
398 errmsg WARNING ${E_IP_OPTS} \
399 "unrecognized \"-o ${i}\" option" \
400 "check the option, resubmit if necessary
406 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
409 if [ -z "${FILTER}" ]
413 # If no filter is being used, we use netpr to push the
414 # file to the printer.
415 # (QUOTES ARE IMPORTANT!)
420 # make the "postscript" printers use cat
421 # (TSOL banners are added during filtering, so we have
422 # to use some filter.)
426 # make the "reverse postscript" printers reverse the
427 # output and the use postio to talk to the printer
428 #FILTER="/usr/lib/lp/postscript/postreverse "
430 FILTER="/usr/lib/lp/postscript/postreverse "
433 # We don't know the type, so just assume that the
434 # input and output are the same. Use netpr.
442 # sets default value for ordering of data and control files with
443 # bsd protocol. Default: data files first. Administrator
444 # may set to control file first with lpadmin -o bsdctrl=first
448 case "${nobanner}" in
454 NETPR="/usr/lib/lp/bin/netpr ${banner_flag} ${data_file_flag} \
455 -I ${request_id} -U ${user_name} \
456 -p ${printer} ${dest} -T \"${title}\" \
457 ${timeout} ${protocol} ${controlfile} "
458 LPTELL_OPTS="-l" # netpr sends LaserWriter style messages back
459 PPDFILTER=/usr/lib/lp/bin/foomatic-rip
460 PPDFILTERA="${PPDFILTER} ${request_id} ${user_name} \"${title}\" ${copies} \"${option_list}\""
462 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
464 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
466 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
467 "ppdfilter : ${PPDFILTERA}"
471 tmpfile=${LPTMPDIR}/${node}.${pid}
472 tmpfilefoo=${LPTMPDIR}/${node}.${pid}.1
474 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
475 "tmpfile : ${tmpfile}"
479 # Set up filter for banner page
485 banner_filter=" | /usr/lib/lp/postscript/postprint "
492 # Build temporary file that is the banner page
503 echo "##### User: ${user_name}${NL}\c"
506 echo "##### Title: ${title}${NL}\c"
508 echo "##### Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
509 echo "##### Job: ${request_id}${NL}\c"
519 # Doing small banner as we don't know what printer is out there
524 ## Skip this for PS/PSR printers, since lp.tsol_separator handles the banners
525 if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
527 eval "${banner} ${banner_filter}" 2>&1 1>${LPTMPDIR}/small_banner.$$
532 ## Surround the job by PostScript code to produce banner
533 ## and trailerpages and page headers and footers.
537 BANNER_EXIT_CODE=${LPTMPDIR}/banner.exit_code.$$
538 echo 0 > ${BANNER_EXIT_CODE}
539 TSOLSEPARATOR_LOG=${LPTMPDIR}/banner.errmsg.$$
542 TSOLSEPARATOR_OPTS="-e ${TSOLSEPARATOR_LOG}"
544 if [ "yes" = "${nolabels}" ]
546 TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -l"
549 if [ "yes" = "${nobanner}" ]
551 TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -t /dev/null -b /dev/null"
554 if [ "${TERM}" = "PSR" ]
556 TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -r"
559 # Get rid of the #, TAB and NL characters in the title
560 tsol_title=`echo $title`
561 tsol_title=`echo $tsol_title | sed 's/#//g'`
563 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" \
564 "banner command: ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} \
565 ${printer} ${request_id} ${user_name} \"${tsol_title}\" ${file}"
566 ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} ${printer} \
567 ${request_id} ${user_name} "${tsol_title}" ${file}
569 echo $? > ${BANNER_EXIT_CODE}
573 bannerize=tsol_bannerize
575 if [ "yes" = "${nobanner}" -a "yes" = "${nolabels}" ]
580 if [ "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
587 # Print banner page before job unless PSR or PS
592 ## Skip this for PS/PSR printers, since lp.tsol_separator handles the banners
593 if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
596 eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
597 echo $? > ${LPTMPDIR}/pr_eexit_code.$$
598 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
600 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
601 logger -p lpr.debug -t \
602 "tsol_netstandard_foomatic: ${request_id}" \
603 "banner page exit code : ${exit_code}"
608 while [ $i -le $copies ]
615 if [ ! -z "${FILTER}" ]
619 # There is a filter, use it
621 # Put 0<${file} before the "eval" to keep
622 # clever users from giving a file name that
623 # evaluates as something to execute.
624 # Redirect stderr to stdout so LPTELL will
625 # get error messages from pipe.
628 0<${file} $bannerize | eval ${FILTER} 2>&1 1>${tmpfile}
629 echo $? > ${LPTMPDIR}/pr_eexit_code.$$
630 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
632 # if lp.tsol_separator had an error,
633 # send its logged error message to LPTELL.
634 banner_exit_code=`cat ${BANNER_EXIT_CODE}`
635 if [ -n "${banner_exit_code}" -a \
636 0 -ne "${banner_exit_code}" -a \
638 -r "${TSOLSEPARATOR_LOG}" ]
640 cat ${TSOLSEPARATOR_LOG} | ${LPTELL} ${printer}
641 echo 77 > ${LPTMPDIR}/pr_eexit_code
644 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
645 logger -p lpr.debug -t \
646 "tsol_netstandard_foomatic: ${request_id}" \
647 "filter exit_code : ${exit_code}"
649 if [ -n "${exit_code}" ]
651 if [ "${exit_code}" -eq 0 ]
656 # The filter did not succeed, so don't try to print
666 logger -p lpr.debug -t \
667 "tsol_netstandard_foomatic: ${request_id}" \
668 "printfile : ${printfile}"
674 if [ -r "${printfile}" ]
677 logger -p lpr.debug -t \
678 "@1 tsol_netstandard_foomatic: printfile = ${printfile}" ""
679 logger -p lpr.debug -t \
680 "tsol_netstandard_foomatic: ${NETPR} ${printfile}" ""
681 #eval ${NETPR} ${printfile} 2>&1
682 cat ${printfile} | ${PPDFILTER} \
683 ${request_id} ${user_name} "${title}" ${copies} "${option_list}" \
684 > ${tmpfilefoo} 2> /dev/null
685 eval ${NETPR} ${tmpfilefoo} 2>&1
686 echo $? > ${LPTMPDIR}/pr_eexit_code.$$
687 /bin/rm -f ${tmpfilefoo}
688 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
690 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
691 logger -p lpr.debug -t \
692 "@2 netstandard_foomatic: ${request_id}" \
693 "netpr exit_code : ${exit_code}"
695 # if [ -f "${tmpfile}" ]
697 # /bin/rm "${tmpfile}"
700 if [ -n "${exit_code}" ]
702 if [ "${exit_code}" -eq 0 ]
706 if [ "${exit_code}" -lt 128 ]
718 errmsg WARNING ${E_IP_BADFILE} \
719 "cannot read temporary file \"${printfile}\""\
720 "see if file still exists,
721 or consult your system administrator;
729 # Don't complain about not being able to read
730 # a file on second and subsequent copies, unless
731 # we've not complained yet. This removes repeated
732 # messages about the same file yet reduces the
733 # chance that the user can remove a file and not
734 # know that we had trouble finding it.
737 if [ "${i}" -le 1 -o -z "${badfileyet}" ]
739 errmsg WARNING ${E_IP_BADFILE} \
740 "cannot read file \"${file}\"" \
741 "see if the file still exists and is readable,
742 or consult your system administrator;
749 # for file in ${files}
756 # If printing in reverse order, print the banner page now
757 # Skip this for TSOL, since lp.tsol_separator handles the banners
761 #if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
764 # eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
765 # echo $? > ${LPTMPDIR}/pr_eexit_code.$$
766 #) | ${LPTELL} ${LPTELL_OPTS} ${printer}
769 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
770 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
771 "banner page exit code : ${exit_code}"
773 if [ -n "${printone}" -a -z "${retry}" -a -z "${noprint}" ]
777 if [ -n "${retry}" -a -z "${printone}" -a -z "${noprint}" ]
785 logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
786 "FINAL exit_code : ${exit_code}"
788 exit_clean ${exit_code}