Example Shell AIX Printer Backend Program


About this document
    Related documentation
Goal and overview
The shell script
The C program
Creating the queue
Viewing the queue stanzas in /etc/qconfig
Testing the queue
An expanded printing shell script
Obtaining the source

About this document

Many AIX and UNIX administrators find it easy to write ksh scripts, but have fewer skills when it comes to writing C programs. When you are writing an AIX printing backend program, there are certain pieces of information that are much easier to obtain with a C program. This document shows how a shell script backend can call a simple C program to retrieve the queue-specific information, such as the user name, file name, and job number. Using this simple script, you can expand the shell script to do logging and problem diagnostics. Information on creating and testing an AIX queue to use the custom backend is also supplied.

This script and program work at all levels of AIX.

Related documentation

  • Printer Backend Overview for Programming
  • AIX Guide to Printers and Printing SC23-2783-01

    Goal and overview

    This backend is a combination of two programs.

    1. A shell script that is actually the backend program
    2. A C program called by the shell program to get queue information

    This program was written as an illustration in response to a question regarding writing print backends as a shell script and obtaining the job number. Similar questions have also been asked about obtaining the user ID.

    The shell script

    The shell script that is provided as an example does not actually print the file, but gathers information about the queue. To add printing capability, you could call one of the standard AIX print commands to print to a separate queue, possibly supplying new print flags. If you are using a local printer, the FILE = parameter in the queue stanza in /etc/qconfig will become a standard out to the script. For this reason, you could simply use the cat command to send the file to the port once you have processed the output.

    Some of the things that you should keep in mind when writing the script are that the last parameter passed to the script by the qdaemon is the print file. The flags prior to this that will be treated are the actual print flags passed by enq. The script prints all of the flags to the file /tmp/queue_name in the statement:

      echo $* >> /tmp/$Q
    The C program is called in the line:
    The parameters are returned in the shell array FT.

    Create the following file as /usr/local/bin/subque. This file must have execute permissions and should be owned by group printq.

    # This is the printer backend file.  It is just a shell for now, so look
    # in the /tmp file that is pointed at by the name in /etc/qconfig.
    # /etc/qconfig line format:
    #       backend = /usr/local/bin/subque /tmp/log.file
    #REMEMBER: what we put into /etc/qconfig always gives the queue name first
    # In other words when we make the queue, put a queue name after the backend.
    Q=$1; shift
    # For debug purposes you can echo some variables to a file
    echo "============================ \c" >> /tmp/$Q
    /usr/bin/date >> tmp/$Q
    echo $* >> /tmp/$Q
    # This code gets the USER name and TITLE for the original file
    # This is used to log the information, but also to get the info
    # needed to pass this on to the next queue with an 'enq -T and -Z'
    # see example later.
        integer j=0
        typeset  fr
        for ft in $FT
            let j=j+1
            echo "From = ${fr[0]}" >> /tmp/$Q
            echo "Title = ${fr[1]}" >> /tmp/$Q
            echo "Job # = ${fr[2]}" >> /tmp/$Q
    echo STOP >> /tmp/$Q
    exit 0

    The C program

    The details of this program are similar to the information in the technical document Basic AIX Printer Backend Program Example.

    The key feature of this program is that it calls the library routing log_init() to set up the queue information. The output is returned to the shell script by printing to stdout. When compiling the program, you must link in the libqb library with the cc flag -lqb.

    This is a short example:

    /* This is getqinfo example header maker */
    /* Compile with cc -o getqinfo -lqb getqinfo.c  */
    /* It doesn't do anything to the data, but
       shows how to get at the information and use
       the routines           */
    #include <stdio.h>
    #include <IN/backend.h>
    #include <IN/standard.h>
    #include <string.h>
    char *qdate;
    char *cmdline;
    char *to;
    char *devname;
    char *title;
    char *qname;
    char *qdname;
    char *from;
    char *at;
    char *enqflags;
    int   mail_only;
    int   jobno;
    unsigned argc;
    char **argv;
      int   rc, i, c;
      char* pfile;
      FILE *pf;
    /*  This is an obligatory routine for getting access to
        all the other routines - log_init           */
      rc = log_init();
      if (rc == -1)
    /* So we see something if log_init fails - Output Error */
    /*  Some of the standard backend subroutine calls are */
    /*  Then are described in info explorer                 */
        from      = get_from();
        title     = get_title();
        jobno     = get_job_number();
    /* Return information to shell script   */
            printf("%s %s %d\n",from,title,jobno);

    Creating the queue

    The smit page shown below is from AIX 4, but a similar screen appears at AIX 3.2 when you are adding a queue with smitty spooler.

    1. touch /dev/testl
    2. smitty mkpq
    3. Choose:
      other       User Defined Backend
    4. From the "Add a print queue" screen, add the following and press enter or DO.
    * Name of QUEUE to add                               [testq]
    * Name of QUEUE DEVICE to add                        [testd]
    * BACKEND PROGRAM pathname     [/usr/local/bin/subque q.log]
      ACTIVATE the queue?                                 yes
      Should this become the DEFAULT queue?               no
      Queuing DISCIPLINE                   first come first serve
      ACCOUNTING FILE pathname                           []
      HOSTNAME of remote server                          []
      Name of QUEUE on remote server                     []
      Pathname of the SHORT FORM FILTER for queue        []
       status output
      Pathname of the LONG FORM FILTER for queue         []
       status output
      BACKEND OUTPUT FILE pathname             [/dev/testl]

    Viewing the queue stanzas in /etc/qconfig

    View the /etc/qconfig file with view /etc/qconfig. The queue should look like this in /etc/qconfig.

            device = testd
            up = TRUE
            file = /dev/testl
            backend = /usr/local/bin/subque q.log

    Testing the queue

    First, make sure the queue shows READY for a status command.

    Next, print to the queue:

    Test output to /tmp/testq.log

    After you ran the preceding print command, a print of the test file showed:

    ================== Mon Jan 13 13:26:31 CST 1997
    /usr/local/bin/subque log.file /etc/motd
    From = root
    Title = /etc/motd
    Job # = 188

    An expanded printing shell script

    The following shell script was written specifically to print output from HCON. The script was written to override the default flags sent by HCON and to add desired AIX flags when submitting the data to a new queue. This script illustrates how you can capture the flags from a print job and convert them to your own use. The C program is used to specify the header page parameters in the new queue.

    # This testpr.sh script is designed to print overlays
    # when initiated by HCON, but should also work for other
    # types of printing.
    while getopts :J:L:X:Z:b:ci:j:l:p:f:s:t:u:v:w:x:y:z: arguments
     case $arguments in
    ## $OPTARG
          X) Xflags="-X $OPTARG" ;;
          J) Jflags="-J $OPTARG" ;;
          L) Lflags="-L $OPTARG" ;;
          Z) Zflags="-Z $OPTARG" ;;
          b) bflags="-b $OPTARG" ;;
          c) cflags="-c $OPTARG" ;;
          f) fflags="-f $OPTARG" ;;
          g) gflags="-g $OPTARG" ;;
          i) iflags="-i $OPTARG" ;;
          j) jflags="-j $OPTARG" ;;
          l) lflags="-l $OPTARG" ;;
          p) pflags="-p $OPTARG" ;;
          s) sflags="-s $OPTARG" ;;
          t) tflags="-t $OPTARG" ;;
          u) uflags="-u $OPTARG" ;;
          v) vflags="-v $OPTARG" ;;
          w) wflags="-w $OPTARG" ;;
          x) xflags="-x $OPTARG" ;;
          y) yflags="-y $OPTARG" ;;
          z) zflags="-z $OPTARG" ;;
          \?)  ;;
     ((current_position = OPTIND -1))
     shift $current_position
    date >> /tmp/flags.out
    ###############  Call C code to get queue info ###################
        integer j=0
        typeset  fr
        for ft in $FT
            let j=j+1
            echo "From = ${fr[0]}" >> /tmp/flags.out
            echo "Title = ${fr[1]}" >> /tmp/flags.out
            echo "Job # = ${fr[2]}" >> /tmp/flags.out
    echo "Number of files to print $#" >> /tmp/flags.out
    echo "Filenames were: $*" >> /tmp/flags.out
    # Use the -c option so we don't lose the file in the next queue
    #qprt -c -Ppcl -Z! -p14 -f2 -dp -z+ -v8 $*
    enq -Ban -c -Ppcl -o-Z! -o-p14 -o-fp -o-z+ -o-v8 -T ${fr[1]} -Z ${fr[0]}
    sleep 2

    Obtaining the source

    The source is printed in the preceding section.

    [ Doc Ref: 91790919311402     Publish Date: Feb. 13, 2001     4FAX Ref: 6437 ]