Writing an LP Interface Script
Writing an LP Interface Script   By Norman A. Jacobs, April 2002  

What Is an LP Interface Script?


An LP interface script is the component of the printing system that performs the final processing of a print job and actually sends it to the printer. Its sole purpose is to "print" the job. Upon completion, the script should either have completed the job and exited with a normal exit status, or have failed to complete, but exited with a non-normal exit status.

Interfaces


An interface script utilizes a number of interfaces both to both gather information for its operation and to return information about its processing and results. These interfaces include the use of:

  • Inbound command-line arguments
  • Inbound environment variables
  • File descriptors (for input and results)
  • Received signals
  • Exit status code

Command-Line Arguments


The first place an interface script gathers information about what it is to do is in the command-line arguments. The arguments provide information about the job, its submitter, the features requested, and the data to handle.

ArgumentNameDescription $0.../{printer}This argument is the name of the interface script that was called. On the Solaris OE, this will always be /etc/lp/interfaces/{printer}. $1Request-idThis is actually the first argument used in calling the interface script. It contains an identifier for the job. The intention is that this identifier is placed on any burst pages printed with the job. The format of the identifier is usually in the form of {printer}-{number}. $2UserThis the user that submitted the print job. It is generally in the form of user@host and is to be used on any burst pages printed wit the job. $3TitleThis is a title for the print job. Again, this is to be used on any burst pages printed with the job. A default title of the file name is normally supplied here, but lp -t or lpr -J will override the default. $4CopiesThis is the number of copies of each document to print. $5Options (lp -o)This contains a string of "transparent" options that were passed from the command line through the spooling system to this script. Options are generally used to turn on and off printer features like duplex printing, stapling, and so on. It can also be used to pass additional required information like a fax number, if the script is driving a fax modem. $6+File listThe rest of the arguments contain a list of all of the data files to send to the output device. This list of files is referenced through full path names.


Environment Variables


VariableSubjectDescription CHARSETThe character set to useWhen this environment variable is set, it contains the name of the character set to be used when printing the job. The value is generally used during printer initialization. FILTERA fast filter to inline on the way to the printerWhen set, this variable defines a "fast" filter stream to be used inline on the way to the printer. All "good" interface scripts should heed this value when set. LANGI18n  LC_COLLATEI18n  LC_CTYPEI18n  LC_MESSAGESI18n  LC_MONETARYI18n  LC_NUMERICI18n  LC_TIMEI18nValues to use when localizing any interface script-derived output. These are primarily defined so that they can be passed to any programs called by the script. PATHDefault path/usr/sbin:/usr/bin SPOOLER_KEYUsed by lp.tell for backchannel to lpschedThis value is used by lp.tell (private interface) to uniquely specify the instance of the interface script that is running. lp.tell passes this value along with a fault message, or fault clear message to the scheduler when a problem occurs, or is resolved. TERMPrinter typeThis value contains the printer type of the printer that this interface script is processing for. The type is defined with lpadmin -T. TZYour time zone--


File Descriptors


File DescriptorDescription 0Unused (lpsched opens /dev/null for reading only at this descriptor) 1Printer device (use /dev/null for network-attached printers) 2Backchannel to lpsched


Signals


Exit Codes


Exit CodeSubjectDescription 0SuccessIf the interface script completed without any error, it should exit with this exit code. 1 - 127Failure, don't restartIf the interface script had an error in processing the job and it's likely that the error is in the data, the script should probably exit with one of these codes. 128N/ADo not use >128Failure, wait or restartIf the interface script encounters an error that is recoverable, the script should probably exit.


Effective UID


The interface script is run using one of two effective user IDs. If the print job appears to the scheduler to have come from the local host, the euid will be that of the calling user. If the print job appears to have come from a remote source, the euid will be that of lp. This should give the script the necessary privilege to access any of the files it needs to print.

If you are using a set-uid program inside of the interface script to perform some of the processing, you should make sure that you check for any security hole that it may introduce while operating under the interface script, as well as if called by hand.

Example Scripts


Here are a number of sample interface scripts that can be used as a starting point for implementing an interface script of your own.

Example NameDescription GSinterfaceA simple example of using GhostScript* to drive a PCL printer under LP. SPARCprinterA simple example of using GhostScript to drive a SPARCprinter under LP. NeWSprinterCL+A simple example of using GhostScript to drive a NeWSprinterCL+ printer under LP. PSinterfaceA simple example of driving a PostScript printer under LP. exampleA template example of an interface script.

* An older version of the GSinterface script can be found in the SFWgs package on the Solaris companion CD. This article includes an updated version that allows similar functionality of the NeWSprinterCL+ and SPARCprinter scripts via the following configuration:

  SPARCprinter
  # lpadmin -p printer -v /dev/null -TPS -Ipostscript \ 
      -i /opt/sfw/share/ghostscript/interfaces/GSinterface \ 
      -o GS_DEVICE=sparc -o OutputFile=/dev/lpvi0 \ 
      -o banner-type=postscript

  NeWSprinterCL+ 
  # lpadmin -p printer -v /dev/bpp0 -TPS -Ipostscript \ 
      -i /opt/sfw/share/ghostscript/interfaces/GSinterface \ 
      -o GS_DEVICE=bjc800"

Finally, here is a shell of an interface script to be used as a start to implementing your own.

#/bin/sh
#
#       Copyright (c) 1997, by Sun Microsystems Inc.
#       All Rights Reserved
#
#pragma ident   "@(#)interface.html   1.2   98/05/22 SM"
#
#   This is an example interface script to help you get 
# an idea of how to integrate support for your printer 
# under lp.  This is by no means the definitive source 
# for information.  You should look at included interface
# scripts as examples and at the Solaris System 
# Administrators Answerbook.
#
# This script is run as 'lp' on the print server if the 
# job came in via the network.  It runs as the submitting 
# user if the job is local.  You should also note that 
# the data files are owned by the user running the script.
#
# Command Line Arguments:
#       $0      - .../{printer}
#       $1      - request-id
#       $2      - user
#       $3      - title
#       $4      - copies
#       $5      - options (lp -o)
#       $6+     - file list
# Environment Variables:
#       CHARSET         - the character set to use
#       FILTER          - fast filter to inline on the 
#			  way to the printer
#       LC_COLLATE      - I18n
#       LC_CTYPE        - I18n
#       LC_MESSAGES     - I18n
#       LC_MONETARY     - I18n
#       LC_NUMERIC      - I18n
#       LC_TIME         - I18n
#       PATH            - default path (/usr/sbin:/usr/bin)
#       SPOOLER_KEY     - used by lp.tell for backchannel 
#			  to lpsched
#       TERM            - printer type
#       TZ              - our timezone
# File Descriptors:
#       0       - don't recall
#       1       - printer device (use /dev/null for network 
#	          attached printers)
#       2       - backchannel to lpsched
# Signals:
#
# Exit Codes:
#       0       - success
#       1 - 127 - failure, don't restart
#       128     - don't use
#       >128    - failure, wait or restart
#

if [ $# -lt 5 ] ; then
        echo "wrong number of arguments to interface 
              program" 1>&2
        exit 1
fi


printer=`basename $0`
request_id=$1
user_name=$2
title=$3
copies=$4
option_list=$5

shift 5
files="$*"

stty=

parse () {
        echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
}

nobanner="no"
nofilebreak="no"
inlist=
for i in ${option_list}
do
        case "${inlist}${i}" in

        nobanner )
                nobanner="yes"
                ;;

        nofilebreak )
                nofilebreak="yes"
                ;;

# lp -o key
#       key )
#               key="whatever"
#               ;;

# lp -o key=value
#       key=* )
#               key=`parse ${i}`
#               ;;

# lp -o key='list ...'
#       stty=* )
#               inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
#               case "${i}" in
#               ${inlist}\'*\' )
#                       item=`expr "${i}" : 
#			     "^[^=]*='*\(.*\)'\$"`
#                       ;;
#               ${inlist}\' )
#                       continue
#                       ;;
#               ${inlist}\'* )
#                       item=`expr "${i}" : 
#		             "^[^=]*='*\(.*\)\$"`
#                       ;;
#               ${inlist}* )
#                       item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
#                       ;;
#               *\' )
#                       item=`expr "${i}" : "^\(.*\)'\$"`
#                       ;;
#               * )
#                       item="${i}"
#                       ;;
#               esac
#
#               #####
#               #
#               # We don't dare use "eval" because a clever 
#		# user could put something in an option 
# 		# value that we'd end up
#               # exec'ing.
#               #####
#               case "${inlist}" in
#               key= )
#                       key="${key} ${item}"
#                       ;;
#               esac
#
#               case "${i}" in
#               ${inlist}\'*\' )
#                       inlist=
#                       ;;
#               ${inlist}\'* )
#                       ;;
#               *\' | ${inlist}* )
#                       inlist=
#                       ;;
#               esac
#               ;;
        * )
                echo "unrecognized \"-o ${i}\" option check 
		      the option, resubmit if necessary 
	              printing continues" 1>&2
                ;;
        esac
done

#
# should create a banner
#

#
# process the files
#

i=1
while [ $i -le $copies ]
do
        for file in $files
        do
                cat $file
        done
        i=`expr $i + 1`
done
exit 0

Additional Reading


More technical articles on printing from the Solaris Developer Connection site:

Rate and Review Tell us what you think of the content of this page. Excellent   Good   Fair   Poor   Comments:
If you would like a reply to your comment, please submit your email address:
Note: We may not respond to all submitted comments.
Close    To Top
  • Prev Article-OS:
  • Next Article-OS:
  • Now: Tutorial for Web and Software Design > OS > Solaris > OS Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction