8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / lp / model / netstandard
blob0b428fdcd44849a6d7dd93b283b1098e67c3450a
2 # Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3 # Use is subject to license terms.
5 # CDDL HEADER START
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
10 # with the License.
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]
23 # CDDL HEADER END
25 #pragma ident   "%Z%%M% %I%     %E% SMI"
26 ###########
28 ## Network Standard printer interface program.
30 ###########
32 #####
33 # We can't do much except exit if spooler/scheduler
34 # cancels us.
35 #####
36 trap 'eval exit_clean 15' 15
38 ####
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
43 # when we need it
44 ####
45 exec 5>&2 2>/dev/null 3>&1
47 ####
48 # set some global variables
49 ####
51 : ${LPTMPDIR:=/tmp}
52 : ${SPOOLDIR:=/usr/spool/lp}
53 : ${LOCALPATH:=${SPOOLDIR}/bin}
54 PATH="/bin:/usr/bin:${LOCALPATH}"
55 exit_code=0
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.
62 #####
63 if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
64 then
65         fake_lptell () {
66                 header="no"
67                 while read line
68                 do
69                         if [ "no" = "${header}" ]
70                         then
71                                 errmsg ERROR ${E_IP_UNKNOWN} \
72                 "unknown printer/interface failure" \
73                 "consult your system administrator;
74                 reasons for failure (if any) follow:"
75                                 header=yes
76                         fi
77                         echo "${line}" >&2
78                 done
79                 return 1
80         }
81         LPTELL=fake_lptell
82 fi       
84 #####
85 # Error message formatter:
87 # Invoke as
89 #       errmsg severity message-number problem help
90 #                                                   
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.
94 #####
96 LP_ERR_LABEL="UX:lp"
97 E_IP_ARGS=1
98 E_IP_OPTS=2
99 #E_IP_FILTER=3
100 E_IP_UNKNOWN=5
101 E_IP_BADFILE=6
102 E_IP_ERRORS=12  # (in slow.filter)
104 errmsg () {
106         case $1 in
107         ERROR )
108                 sev="  ERROR";
109                 ;;
110         WARNING )
111                 sev="WARNING";
112                 ;;
113         esac
115         echo "${LP_ERR_LABEL}:$2 ${sev}: $3
116         TO FIX: $4" >&5
117 }                       
119 ###########
121 ## Check arguments
122 ###########
124 parse () {
125         echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
126 }         
128 #####
130 ## Error Cleanup and Exit
132 #####
134 exit_clean()
137         if [ -f "${LPTMPDIR}/pr_eexit_code.$$" ]
138         then
139                 /bin/rm ${LPTMPDIR}/pr_eexit_code.$$
140         fi
142         if [ -f "${LPTMPDIR}/small_banner.$$" ]
143         then
144                 /bin/rm ${LPTMPDIR}/small_banner.$$
145         fi
147         if [ -f "${tmpfile}" ]
148         then
149                 /bin/rm "${tmpfile}"
150         fi
152         exit $1
155 #####
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.
166 #####
168 if [ $# -lt 5 ]
169 then
171         errmsg ERROR ${E_IP_ARGS} \
172                 "wrong number of arguments to interface program" \
173                 "consult your system administrator"
174         exit 1
175 fi      
177 printer=`basename $0`
178 request_id=$1
179 user_name=$2
180 title=$3
181 copies=$4
182 option_list=$5
184 shift 5
185 files="$*"
189 # debug sent to file if defined in /etc/syslog.conf
190 # syslog.conf entry: 
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}"
204 ####
205 # default: do print a banner
206 ####
207 nobanner=no
208 nofilebreak="no"
209 inlist=
210 data_file_flag=
212 for i in ${option_list}
214         case "${inlist}${i}" in
216         nobanner )
217                 nobanner="yes"
218                 ;;
220         nofilebreak )
221                 nofilebreak="yes"
222                 ;;
224         #####
225         #
226         # If you want to add simple options (e.g. -o simple)
227         # identify them here.
228         #####
229 #       simple )
230 #               simple="yes"
231 #               ;;
232                    
233         cpi=pica )
234                 cpi=10
235                 ;;
236         cpi=elite )
237                 cpi=12
238                 ;; 
239         cpi=* )
240                 cpi=`parse ${i}`
241                 ;;
243         lpi=* )
244                 lpi=`parse ${i}`
245                 ;;
247         length=* )
248                 length=`parse ${i}`
249                 ;;
251         width=* )
252                 width=`parse ${i}`
253                 ;;
254         dest=* )
255                 dest="-d `parse ${i}`"
256                 ;;
258         protocol=* )
259                 protocol="-P `parse ${i}`"
260                 ;;
261         bsdctrl=* )
262                 controlfile="-c `parse ${i}`"
263                 ;;
264         timeout=* )
265                 timeout="-t `parse ${i}`"
266                 ;;
268         data-file-type=* )
269                 data_file_flag="-f `parse ${i}`"
270                 ;;
272         #####
273         #
274         # If you want to add simple-value options (e.g. -o value=a)
275         # identify them here.
276         #####
277 #       value=* )
278 #               value=`parse ${i}`
279 #               ;;
281         #####
282         #
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).
286         #####
287                                    
288 #       flist=* | lpd=* | options=* )
289         flist=* | lpd=* )
290 #LOPT   stty=* | flist=* | lpd=* | lopt=* )    
292                 inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
293                 case "${i}" in
294                 ${inlist}\'*\' )
295                         item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
296                         ;;
297                 ${inlist}\' )
298                         continue
299                         ;;
300                 ${inlist}\'* )
301                         item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
302                         ;;
303                 ${inlist}* )
304                         item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
305                         ;;
306                 *\' )
307                         item=`expr "${i}" : "^\(.*\)'\$"`
308                         ;;
309                 * )
310                         item="${i}"
311                         ;;
312                 esac
314                 #####
315                 #
316                 # We don't dare use "eval" because a clever user could
317                 # put something in an option value that we'd end up
318                 # exec'ing.
319                 #####
320                 case "${inlist}" in
321                 flist= )
322                         flist="${flist} ${item}"
323                         ;;
324                 lpd= )
325                         lpd="${lpd} ${item}"
326                         ;;
327 #LOPT           lopt= )
328 #LOPT                   lopt="${lopt} ${item}"
329 #LOPT                   ;;
330 #               options= )
331 #                       options="${options} ${item}"
332 #                       ;;
333                 esac
334                      
335                 case "${i}" in
336                 ${inlist}\'*\' )
337                         inlist=
338                         ;;
339                 ${inlist}\'* )
340                         ;;
341                 *\' | ${inlist}* )
342                         inlist=
343                         ;;
344                 esac
345                 ;;
347         * )
348                 errmsg WARNING ${E_IP_OPTS} \
349                         "unrecognized \"-o ${i}\" option" \
350                         "check the option, resubmit if necessary
351                 printing continues"
352                 ;;
353         esac
354 done         
356 logger -p lpr.debug -t "netstandard: ${request_id}"  "term : ${TERM}"
358 if [ -z "${FILTER}" ]
359 then
360         #####
361         #
362         # If no filter is being used, we use netpr to push the
363         # file to the printer.
364         # (QUOTES ARE IMPORTANT!)
365         #####
367         case "$TERM" in
368                 PS )
369                         # make the "postscript" printers use netpr 
370                         FILTER=
371                 ;;
372                 PSR )
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 "
376                         #FILTER=
377                         FILTER="/usr/lib/lp/postscript/postreverse "
378                 ;;
379                 * )
380                         # We don't know the type, so just assume that the
381                         # input and output are the same. Use netpr.
382                         #FILTER=/bin/cat
383                         FILTER=
384                 ;;
385         esac
388 ####
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
392 ####
394 banner_flag=""
395 case "${nobanner}" in
396         yes )
397                 banner_flag="-b"
398         ;;
399 esac
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}"
410 node=`uname -n`
411 pid=$$
412 tmpfile=${LPTMPDIR}/${node}.${pid}
414 logger -p lpr.debug -t "netstandard: ${request_id}" "tmpfile : ${tmpfile}"
416 #####
418 # Set up filter for banner page
420 #####
421 banner_filter=
422 case "${TERM}" in
423 PS | PSR )
424         banner_filter=" | /usr/lib/lp/postscript/postprint "
425         LPTELL_OPTS="-l"
426         ;;
427 esac 
429 #####
431 # Build temporary file that is the banner page
433 #####
434 PAD="#####${NL}"
435 CR="\r"
436 NL="${CR}\n"
439 small_banner() {
440         echo "${CR}\c"
441         echo "${PAD}\c"
442         echo "#####  User: ${user_name}${NL}\c"
443         if [ -n "${title}" ]
444         then
445                 echo "##### Title: ${title}${NL}\c"
446         fi
447         echo "#####  Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
448         echo "#####   Job: ${request_id}${NL}\c"
449         echo "${PAD}\c"
450         if [ -n "${FF}" ]
451         then
452                 echo "${CR}${FF}\c"
453         fi
456 #####
458 # Doing small banner as we don't know what printer is out there
460 #####
461 banner=small_banner
463 if [ "no" = "${nobanner}" ]
464 then
465         eval "${banner} ${banner_filter}" 2>&1 1>${LPTMPDIR}/small_banner.$$ 
468 #####
470 # Print banner page before job unless PSR
472 #####
475 if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" ]
476 then
477         (
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 ]
491         for file in ${files}
492         do
493                 if [ -r "${file}" ]
494                 then
496                         if [ ! -z "${FILTER}" ]
497                         then
498                                 (
499                                         #####
500                                         # There is a filter, use it
501                                         #
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. 
507                                         #####
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}" ]
518                                 then
519                                         if [ "${exit_code}" -eq 0 ]
520                                         then
521                                                 printfile=${tmpfile}
522                                         else
523                                                 ####
524                                                 # The filter did not succeed, so don't try to print
525                                                 ####
526                                                         printfile=
527                                         fi
528                                 fi
530                         else
531                                 printfile=${file}
532                         fi
534                         logger -p lpr.debug -t "netstandard: ${request_id}" \
535                                 "printfile : ${printfile}"
536                         
537                         #####
538                         # Print the file
539                         #####
541                         if [ -r "${printfile}" ]
542                         then
543                                 (
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}" ]
553                                 then
554                                         /bin/rm "${tmpfile}"
555                                 fi
557                                 if [ -n "${exit_code}" ]
558                                 then
559                                         if [ "${exit_code}" -eq 0 ]
560                                         then
561                                                 printone=yes
562                                         else
563                                                 if [ "${exit_code}" -lt 128 ]
564                                                 then
565                                                         noprint=yes
566                                                 else
567                                                         retry=yes
568                                                 fi
569                                         fi
570                                 fi
571                                 
573                         else    
575                                 errmsg WARNING ${E_IP_BADFILE} \
576                                 "cannot read temporary file \"${printfile}\""\
577                                         "see if file still exists,
578                         or consult your system administrator;
579                         printing continues"
581                         fi
582                 else
584                         #####
585                         #
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.
592                         #####
594                         if [ "${i}" -le 1 -o -z "${badfileyet}" ]
595                         then
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;
600                 printing continues"
601                                 badfileyet=yes
602                         fi
604                 fi
606 # for file in ${files}
607         done
608         i=`expr $i + 1`
609 done
611 #####
613 # If printing in reverse order, print the banner page now
615 #####
617 if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
618 then
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}" ]
630 then
631         exit_code=`expr 0`
632 else
633         if [ -n "${retry}" -a -z "${printone}" -a -z "${noprint}" ]
634         then
635                 exit_code=`expr 129`
636         else
637                 exit_code=`expr 1`
638         fi
641 logger -p lpr.debug -t "netstandard: ${request_id}" \
642         "FINAL exit_code : ${exit_code}"
644 exit_clean ${exit_code}