Call-Back Demo: Backing Up an Entire Output Queue

Article ID: 18067

In the January 29, 2004, issue of this newsletter, I presented utilities that can be used to convert a spooled file to a user space and vice-versa. This tip expands on that concept by adding the ability to convert all of the spooled files in a given output queue to user spaces, and back again.

The OUTQ2US utility is intended to be used to convert all of the spooled files on the system to user spaces in a temporary library. Then you can save that library to tape.

For example, to back up all spooled files on the system to tape, you could use this CL program:

PGM

 /* MAKE TEMPORARY LIBRARY FOR SPOOLED FILE BACKUPS */

     DLTLIB LIB(SPLFBACKUP)
     MONMSG MSGID(CPF2110)
     CRTLIB LIB(SPLFBACKUP)

 /* BACK-UP ALL SPOOLED FILES TO THE TEMP LIBRARY */

     OUTQ2US  LIB(SPLFBACKUP) OUTQ(*ALL)

 /* SAVE THE TEMP LIBRARY TO TAPE */

     SAVLIB  LIB(SPLFBACKUP) DEV(TAP01)

 /* CLEAR UP SPACE IN TEMP LIBRARY */

     CLRLIB  LIB(SPLFBACKUP)
ENDPGM

The OUTQ2US utility is also intended to demonstrate a technique called "performing a call-back." While you don't need to understand how this works in order to use the utility, it's a very useful technique and is well worth learning!

OUTQ2US calls program OUTQ2USR4, which passes the address of a subprocedure to the LISTSPLFR4 service program. The service program retrieves a list of spooled files and then calls back the subprocedure for each spooled file that it finds. The subprocedure backs up the spooled file by calling the US2SPLF command.

Because the service program lets you supply your own routine for each spooled file, it's very easy to re-use the routine. For example, you can use it to delete all of the spooled files in a date range or to copy all of a specific user's spooled files to another computer.

To tell the ListSpooledFiles subprocedure (in service program LISTSPLFR4) to call back a routine of your own, pass the address of that routine. For example, if you wanted to delete all of the spooled files for user 'BOB', you could do this:

    c                   callp     ListSpooledFiles(%paddr('DELETESPLF')
    c                                             : 'BOB'
    c                                             : *OMIT
    c                                             : *OMIT
    c                                             : *OMIT
    c                                             : *OMIT)

Note: The %paddr() BIF retrieves a pointer to a subprocedure at run-time. It's this pointer that we want to pass to the service program. Since the ILE RPG compiler converts procedure names to all uppercase, you must use uppercase letters when you call %paddr().

The service program calls your procedure using a prototype where the ExtProc() keyword references your procedure's address. The parameter of ListSpooledFiles() that receives the procedure address is called peCallback, so the prototype looks like this:

    D do_callback     PR                  ExtProc(peCallback) 
    D   Name                        10A   varying const       
    D   JobName                     10A   varying const       
    D   JobUser                     10A   varying const       
    D   JobNbr                       6A   const               
    D   SplfNbr                     10I 0 value          

Now it can call the "do_callback" procedure with the CALLP op-code in the normal manner.

If your goal is to delete all of Bob's spooled files, you could write a procedure like the following to be called by the ListSpooledFiles() routine:

    P DeleteSplf      B
    D DeleteSplf      PI
    D   peName                      10A   varying const
    D   peJob                       10A   varying const
    D   peUser                      10A   varying const
    D   peNbr                        6A   const
    D   peSplfNbr                   10I 0 value

    D QCMDEXC         PR                  ExtPgm('QCMDEXC')
    D   Command                   3000A   const options(*varsize)
    D   Length                      15P 5 const

    D cmd             s           3000A   varying

     /free
        cmd = 'DLTSPLF FILE(' + peName + ') ' +
                      'JOB('+peNbr+'/'+peUser+'/'+peJob+') ' +
                      'SPLNBR(' + %trim(%editc(peSplfNbr:'Z')) + ')';

        QCMDEXC(cmd: %len(cmd));

     /end-free
    P                 E

The OUTQ2US utility that is included in the downloadable source code for this tip is another example of this technique, except it runs the US2SPLF command for each spooled file in an output queue (or all output queues if you specify *ALL) to save the spooled files to a user space.

Also included in the downloadable source is the US2OUTQ utility, which can be used to restore your spooled files.

As mentioned above, these utilities run commands that were included in the January 29, 2004, issue of this newsletter. You can read that article here: http://www.iseriesnetwork.com/resources/clubtech/index.cfm?fuseaction=ShowNewsletterIssue&ID=17970

You can download the source code for this tip from http://www.iseriesnetwork.com/noderesources/code/clubtechcode/Outq2UsrSpc.zip.

NOTE: There was a bug in the original source code for the January 29 tip. If you downloaded a copy prior to February 12, 2004, please download a fresh copy from http://www.iseriesnetwork.com/noderesources/code/clubtechcode/Splf2UsrSpc.zip.

ProVIP Sponsors

ProVIP Sponsors