8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / lp / model / tsol_netstandard
blob6a04d5061d64b97178c437b3afb199db0cc21653
2 # CDDL HEADER START
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]
19 # CDDL HEADER END
22 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23 # Use is subject to license terms.
25 #pragma ident   "%Z%%M% %I%     %E% SMI"
27 ###########
29 ## Network Standard printer interface program.
31 ###########
33 #####
34 # We can't do much except exit if spooler/scheduler
35 # cancels us.
36 #####
37 trap 'eval exit_clean 15' 15
39 ####
41 # Send standard error messages to /dev/null rather than to
42 # the spooler. Avoids "Terminated" messages that shell puts out
43 # when gets SIGTERM. Save standard error so it can be used
44 # when we need it
45 ####
46 exec 5>&2 2>/dev/null 3>&1
48 ####
49 # set some global variables
50 ####
52 : ${LPTMPDIR:=/tmp}
53 : ${SPOOLDIR:=/usr/spool/lp}
54 : ${LOCALPATH:=${SPOOLDIR}/bin}
55 PATH="/bin:/usr/bin:${LOCALPATH}"
56 exit_code=0
59 # ${LPTELL} is the name of a program that will send its
60 # standard input to the Spooler. It is used to forward
61 # the description of a printer fault to the Spooler,
62 # which uses it in an alert to the administrator.
63 #####
64 if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
65 then
66         fake_lptell () {
67                 header="no"
68                 while read line
69                 do
70                         if [ "no" = "${header}" ]
71                         then
72                                 errmsg ERROR ${E_IP_UNKNOWN} \
73                 "unknown printer/interface failure" \
74                 "consult your system administrator;
75                 reasons for failure (if any) follow:"
76                                 header=yes
77                         fi
78                         echo "${line}" >&2
79                 done
80                 return 1
81         }
82         LPTELL=fake_lptell
83 fi       
85 #####
86 # ${LPTSOLSEPARATOR} is the name of a program to put banner and trailer
87 # pages around the job.
88 #####
89 if [ -x ${LOCALPATH}/lp.tsol_separator ]
90 then
91         LPTSOLSEPARATOR=${LOCALPATH}/lp.tsol_separator
92 else
93         echo "${LOCALPATH}/lp.tsol_separator not found." >&2
94         exit 1
97 #####
98 # Error message formatter:
100 # Invoke as
102 #       errmsg severity message-number problem help
103 #                                                   
104 # where severity is "ERROR" or "WARNING", message-number is
105 # a unique identifier, problem is a short description of the
106 # problem, and help is a short suggestion for fixing the problem.
107 #####
109 LP_ERR_LABEL="UX:lp"
110 E_IP_ARGS=1
111 E_IP_OPTS=2
112 #E_IP_FILTER=3
113 E_IP_UNKNOWN=5
114 E_IP_BADFILE=6
115 E_IP_ERRORS=12  # (in slow.filter)
117 errmsg () {
119         case $1 in
120         ERROR )
121                 sev="  ERROR";
122                 ;;
123         WARNING )
124                 sev="WARNING";
125                 ;;
126         esac
128         echo "${LP_ERR_LABEL}:$2 ${sev}: $3
129         TO FIX: $4" >&5
130 }                       
132 ###########
134 ## Check arguments
135 ###########
137 parse () {
138         echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
139 }         
141 #####
143 ## Error Cleanup and Exit
145 #####
147 exit_clean()
150         if [ -f "${LPTMPDIR}/pr_eexit_code.$$" ]
151         then
152                 /bin/rm ${LPTMPDIR}/pr_eexit_code.$$
153         fi
155         if [ -f "${LPTMPDIR}/small_banner.$$" ]
156         then
157                 /bin/rm ${LPTMPDIR}/small_banner.$$
158         fi
160         if [ -f "${LPTMPDIR}/banner.exit_code.$$" ]
161         then
162                 /bin/rm ${LPTMPDIR}/banner.exit_code.$$
163         fi
165         if [ -f "${LPTMPDIR}/banner.errmsg.$$" ]
166         then
167                 /bin/rm ${LPTMPDIR}/banner.errmsg.$$
168         fi
170         if [ -f "${tmpfile}" ]
171         then
172                 /bin/rm "${tmpfile}"
173         fi
175         exit $1
178 #####
180 # This program is invoked as
182 # ${SPOOLDIR}/.../printer request-id user title copies options files...
184 # The first three arguments are simply reprinted on the banner page,
185 # the fourth (copies) is used to control the number of copies to print,
186 # the fifth (options) is a blank separated list (in a single argument)
187 # of user or Spooler supplied options (without the -o prefix),
188 # and the last arguments are the files to print.
189 #####
191 if [ $# -lt 5 ]
192 then
194         errmsg ERROR ${E_IP_ARGS} \
195                 "wrong number of arguments to interface program" \
196                 "consult your system administrator"
197         exit 1
198 fi      
200 printer=`basename $0`
201 request_id=$1
202 user_name=$2
203 title=$3
204 copies=$4
205 option_list=$5
207 shift 5
208 files="$*"
212 # debug sent to file if defined in /etc/syslog.conf
213 # syslog.conf entry: 
214 #       lpr.debug       /path/filename
216 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " "
217 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "INPUT"
218 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "    \
219     printer : ${printer}"
220 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "    \
221     request_id : ${request_id}"
222 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "    \
223     user_name : ${user_name}"
224 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "    title : ${title}"
225 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "    \
226     copies : ${copies}"
227 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "    \
228     option_list : ${option_list}"
229 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "    files : ${files}"
230 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "       \
231     spooler_key ${SPOOLER_KEY}"
233 ####
234 # default: do print a banner
235 ####
236 nobanner=no
237 nolabels="no"
238 nofilebreak="no"
239 inlist=
240 data_file_flag=
242 for i in ${option_list}
244         case "${inlist}${i}" in
246         nobanner )
247                 nobanner="yes"
248                 ;;
250         nofilebreak )
251                 nofilebreak="yes"
252                 ;;
254         nolabels )
255                 nolabels="yes"
256                 ;;
258         #####
259         #
260         # If you want to add simple options (e.g. -o simple)
261         # identify them here.
262         #####
263 #       simple )
264 #               simple="yes"
265 #               ;;
266                    
267         cpi=pica )
268                 cpi=10
269                 ;;
270         cpi=elite )
271                 cpi=12
272                 ;; 
273         cpi=* )
274                 cpi=`parse ${i}`
275                 ;;
277         lpi=* )
278                 lpi=`parse ${i}`
279                 ;;
281         length=* )
282                 length=`parse ${i}`
283                 ;;
285         width=* )
286                 width=`parse ${i}`
287                 ;;
288         dest=* )
289                 dest="-d `parse ${i}`"
290                 ;;
292         protocol=* )
293                 protocol="-P `parse ${i}`"
294                 ;;
295         bsdctrl=* )
296                 controlfile="-c `parse ${i}`"
297                 ;;
298         timeout=* )
299                 timeout="-t `parse ${i}`"
300                 ;;
302         data-file-type=* )
303                 data_file_flag="-f `parse ${i}`"
304                 ;;
306         #####
307         #
308         # If you want to add simple-value options (e.g. -o value=a)
309         # identify them here.
310         #####
311 #       value=* )
312 #               value=`parse ${i}`
313 #               ;;
315         #####
316         #
317         # If you want to add options that, 
318         # take a list (e.g. -o lopt='a b c'), identif
319         # them here and below (look for LOPT).
320         #####
321                                    
322 #       flist=* | lpd=* | options=* )
323         flist=* | lpd=* )
324 #LOPT   stty=* | flist=* | lpd=* | lopt=* )    
326                 inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
327                 case "${i}" in
328                 ${inlist}\'*\' )
329                         item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
330                         ;;
331                 ${inlist}\' )
332                         continue
333                         ;;
334                 ${inlist}\'* )
335                         item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
336                         ;;
337                 ${inlist}* )
338                         item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
339                         ;;
340                 *\' )
341                         item=`expr "${i}" : "^\(.*\)'\$"`
342                         ;;
343                 * )
344                         item="${i}"
345                         ;;
346                 esac
348                 #####
349                 #
350                 # We don't dare use "eval" because a clever user could
351                 # put something in an option value that we'd end up
352                 # exec'ing.
353                 #####
354                 case "${inlist}" in
355                 flist= )
356                         flist="${flist} ${item}"
357                         ;;
358                 lpd= )
359                         lpd="${lpd} ${item}"
360                         ;;
361 #LOPT           lopt= )
362 #LOPT                   lopt="${lopt} ${item}"
363 #LOPT                   ;;
364 #               options= )
365 #                       options="${options} ${item}"
366 #                       ;;
367                 esac
368                      
369                 case "${i}" in
370                 ${inlist}\'*\' )
371                         inlist=
372                         ;;
373                 ${inlist}\'* )
374                         ;;
375                 *\' | ${inlist}* )
376                         inlist=
377                         ;;
378                 esac
379                 ;;
381         * )
382                 errmsg WARNING ${E_IP_OPTS} \
383                         "unrecognized \"-o ${i}\" option" \
384                         "check the option, resubmit if necessary
385                 printing continues"
386                 ;;
387         esac
388 done         
390 logger -p lpr.debug -t "tsol_netstandard: ${request_id}"  "term : ${TERM}"
392 if [ -z "${FILTER}" ]
393 then
394         #####
395         #
396         # If no filter is being used, we use netpr to push the
397         # file to the printer.
398         # (QUOTES ARE IMPORTANT!)
399         #####
401         case "$TERM" in
402                 PS )
403                         # make the "postscript" printers use cat
404                         # (TSOL banners are added during filtering, so we have
405                         # to use some filter.)
406                         FILTER=/bin/cat
407                 ;;
408                 PSR )
409                         # make the "reverse postscript" printers reverse the
410                         # output and the use postio to talk to the printer
411                         #FILTER="/usr/lib/lp/postscript/postreverse "
412                         #FILTER=
413                         FILTER="/usr/lib/lp/postscript/postreverse "
414                 ;;
415                 * )
416                         # We don't know the type, so just assume that the
417                         # input and output are the same. Use netpr.
418                         #FILTER=/bin/cat
419                         FILTER=
420                 ;;
421         esac
424 ####
425 # sets default value for ordering of data and control files with
426 # bsd protocol. Default: data files first. Administrator
427 # may set to control file first with lpadmin -o bsdctrl=first
428 ####
430 banner_flag=""
431 case "${nobanner}" in
432         yes )
433                 banner_flag="-b"
434         ;;
435 esac
437 NETPR="/usr/lib/lp/bin/netpr ${banner_flag} ${data_file_flag} \
438         -I ${request_id} -U ${user_name} \
439         -p ${printer} ${dest} -T \"${title}\"  \
440         ${timeout}  ${protocol} ${controlfile} "
441 LPTELL_OPTS="-l"        # netpr sends LaserWriter style messages back
443 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "NETPR= ${NETPR}"
444 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "filter : ${FILTER}"
446 node=`uname -n`
447 pid=$$
448 tmpfile=${LPTMPDIR}/${node}.${pid}
450 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "tmpfile : ${tmpfile}"
452 #####
454 # Set up filter for banner page
456 #####
457 banner_filter=
458 case "${TERM}" in
459 PS | PSR )
460         banner_filter=" | /usr/lib/lp/postscript/postprint "
461         LPTELL_OPTS="-l"
462         ;;
463 esac 
465 #####
467 # Build temporary file that is the banner page
469 #####
470 PAD="#####${NL}"
471 CR="\r"
472 NL="${CR}\n"
475 small_banner() {
476         echo "${CR}\c"
477         echo "${PAD}\c"
478         echo "#####  User: ${user_name}${NL}\c"
479         if [ -n "${title}" ]
480         then
481                 echo "##### Title: ${title}${NL}\c"
482         fi
483         echo "#####  Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
484         echo "#####   Job: ${request_id}${NL}\c"
485         echo "${PAD}\c"
486         if [ -n "${FF}" ]
487         then
488                 echo "${CR}${FF}\c"
489         fi
492 #####
494 # Doing small banner as we don't know what printer is out there
496 #####
497 banner=small_banner
499 ## Skip this for PS/PSR printers, since lp.tsol_separator handles the banners
500 if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
501 then
502         eval "${banner} ${banner_filter}" 2>&1 1>${LPTMPDIR}/small_banner.$$ 
505 ###########
507 ## Surround the job by PostScript code to produce banner 
508 ## and trailerpages and page headers and footers.
510 ###########
512 BANNER_EXIT_CODE=${LPTMPDIR}/banner.exit_code.$$
513 echo 0 > ${BANNER_EXIT_CODE}
514 TSOLSEPARATOR_LOG=${LPTMPDIR}/banner.errmsg.$$
516 tsol_bannerize () {
517         TSOLSEPARATOR_OPTS="-e ${TSOLSEPARATOR_LOG}"
519         if [ "yes" = "${nolabels}" ]
520         then
521                 TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -l"
522         fi
524         if [ "yes" = "${nobanner}" ]
525         then
526                 TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -t /dev/null -b /dev/null"
527         fi
529         if [ "${TERM}" = "PSR" ]
530         then
531                 TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -r"
532         fi
534         # Get rid of the #, TAB and NL characters in the title
535         tsol_title=`echo $title`
536         tsol_title=`echo $tsol_title | sed 's/#//g'`
538         logger -p lpr.debug -t "tsol_netstandard: ${request_id}" \
539             "banner command: ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} \
540             ${printer} ${request_id} ${user_name} \"${tsol_title}\" ${file}"
541         ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} ${printer} \
542             ${request_id} ${user_name} "${tsol_title}" ${file}
544         echo $? > ${BANNER_EXIT_CODE}
545         true
548 bannerize=tsol_bannerize
550 if [ "yes" = "${nobanner}" -a  "yes" = "${nolabels}" ]
551 then
552         bannerize=cat
555 if [ "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
556 then
557         bannerize=cat
560 #####
562 # Print banner page before job unless PS or PSR.
564 #####
566 if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
567 then
568         (
569                 eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
570                 echo $? > ${LPTMPDIR}/pr_eexit_code.$$
571         ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
573         exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
574         logger -p lpr.debug -t "tsol_netstandard: ${request_id}"        \
575                 "banner page exit code : ${exit_code}"
580 while [ $i -le $copies ]
582         for file in ${files}
583         do
584                 if [ -r "${file}" ]
585                 then
587                         if [ ! -z "${FILTER}" ]
588                         then
589                                 (
590                                         #####
591                                         # There is a filter, use it
592                                         #
593                                         # Put 0<${file} before the "eval" to keep
594                                         # clever users from giving a file name that
595                                         # evaluates as something to execute.
596                                         # Redirect stderr to stdout so LPTELL will
597                                         # get error messages from pipe. 
598                                         #####
599                                         0<${file} $bannerize | eval ${FILTER} 2>&1 1>${tmpfile}
600                                         echo $? > ${LPTMPDIR}/pr_eexit_code.$$
601                                 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
603                                 # if lp.tsol_separator had an error, send its logged
604                                 # error message to LPTELL.
605                                 banner_exit_code=`cat ${BANNER_EXIT_CODE}`
606                                 if [ -n "${banner_exit_code}" -a \
607                                         0 -ne "${banner_exit_code}" -a \
608                                          -n "${LPTELL}" -a \
609                                         -r "${TSOLSEPARATOR_LOG}" ]
610                                 then
611                                         cat ${TSOLSEPARATOR_LOG} | ${LPTELL} ${printer}
612                                         echo 77 > ${LPTMPDIR}/pr_eexit_code
613                                 fi
615                                 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$` 
616                                 logger -p lpr.debug \
617                                     -t "tsol_netstandard: ${request_id}" \
618                                         "filter exit_code : ${exit_code}"
620                                 if [ -n "${exit_code}" ]
621                                 then
622                                         if [ "${exit_code}" -eq 0 ]
623                                         then
624                                                 printfile=${tmpfile}
625                                         else
626                                                 ####
627                                                 # The filter did not succeed, so don't try to print
628                                                 ####
629                                                         printfile=
630                                         fi
631                                 fi
633                         else
634                                 printfile=${file}
635                         fi
637                         logger -p lpr.debug \
638                             -t "tsol_netstandard: ${request_id}" \
639                                 "printfile : ${printfile}"
640                         
641                         #####
642                         # Print the file
643                         #####
645                         if [ -r "${printfile}" ]
646                         then
647                                 (
648                                         eval ${NETPR} ${printfile} 2>&1
649                                         echo $? > ${LPTMPDIR}/pr_eexit_code.$$
650                                 ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
652                                 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$` 
653                                 logger -p lpr.debug \
654                                     -t "tsol_netstandard: ${request_id}" \
655                                         "netpr exit_code : ${exit_code}"
657 #                               if [ -f "${tmpfile}" ]
658 #                               then
659 #                                       /bin/rm "${tmpfile}"
660 #                               fi
662                                 if [ -n "${exit_code}" ]
663                                 then
664                                         if [ "${exit_code}" -eq 0 ]
665                                         then
666                                                 printone=yes
667                                         else
668                                                 if [ "${exit_code}" -lt 128 ]
669                                                 then
670                                                         noprint=yes
671                                                 else
672                                                         retry=yes
673                                                 fi
674                                         fi
675                                 fi
676                                 
678                         else    
680                                 errmsg WARNING ${E_IP_BADFILE} \
681                                 "cannot read temporary file \"${printfile}\""\
682                                         "see if file still exists,
683                         or consult your system administrator;
684                         printing continues"
686                         fi
687                 else
689                         #####
690                         #
691                         # Don't complain about not being able to read
692                         # a file on second and subsequent copies, unless
693                         # we've not complained yet. This removes repeated
694                         # messages about the same file yet reduces the
695                         # chance that the user can remove a file and not
696                         # know that we had trouble finding it.
697                         #####
699                         if [ "${i}" -le 1 -o -z "${badfileyet}" ]
700                         then
701                                 errmsg WARNING ${E_IP_BADFILE} \
702                                         "cannot read file \"${file}\"" \
703                                         "see if the file still exists and is readable,
704                 or consult your system administrator;
705                 printing continues"
706                                 badfileyet=yes
707                         fi
709                 fi
711 # for file in ${files}
712         done
713         i=`expr $i + 1`
714 done
716 #####
718 # If printing in reverse order, print the banner page now
719 # Skip this for TSOL, since lp.tsol_separator handles the banners
721 #####
724 # if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
725 # then
726 # (
727 #       eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
728 #       echo $? > ${LPTMPDIR}/pr_eexit_code.$$
729 # ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
730 # fi
732 exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
733 logger -p lpr.debug -t "tsol_netstandard: ${request_id}"     \
734                 "banner page exit code : ${exit_code}"
736 if [ -n "${printone}" -a -z "${retry}" -a -z "${noprint}" ]
737 then
738         exit_code=`expr 0`
739 else
740         if [ -n "${retry}" -a -z "${printone}" -a -z "${noprint}" ]
741         then
742                 exit_code=`expr 129`
743         else
744                 exit_code=`expr 1`
745         fi
748 logger -p lpr.debug -t "tsol_netstandard: ${request_id}" \
749         "FINAL exit_code : ${exit_code}"
751 exit_clean ${exit_code}