Without the licensed program information, determining if your system has a particular PTF already applied is a
real pain in the neck. You usually have to search through the PTFs of several licensed programs to find (or not find as the case may be) a particular PTF. Personally, I had had enough several years ago, so I created a utility to alleviate the problem.
Building a better mouse trap
The Find PTF utility lets you quickly determine the status of any PTF, without specifying a licensed program identifier. Once "loaded," it can tell you in rapid-fire action whether or not a PTF is installed on your system, what the licensed program ID is, and what the status of the PTF is. All you need to enter is a PTF identifier -- no licensed program information required.
The program, which is fronted with a command interface (FINDPTF) for ease of use, employs the DSPPTF ( Display PTF) command, whose output is directed to a database file (the template for this file is the QADSPPTF file, found in library QSYS). The first time the FINDPTF command is run, its CPP (command processing program) runs the DSPPTF command to fill up a database file with information on all the PTFs loaded on your system. You can request the command to update this file with current PTF information anytime thereafter.
The CPP, which is a CL program, uses the OPNQRYF command to search the database file for the PTF ID you specify on the FINDPTF command. If it finds a matching record, the RCVF command will read it. The fields in the record are then used to create a completion message that is sent to the user and contains the PTF ID, the licensed program ID and the PTF status.
Keeping it easy with simple code
The code for the FINDPTF command interface is shown below. It is uncomplicated, defining just two simple parameters.
CMD PROMPT('Find PTF on system') PARM KWD(PTFID) TYPE(*CHAR) LEN(7) MIN(1) + PROMPT('PTF identifer') PARM KWD(UPDFILE) TYPE(*LGL) RSTD(*YES) DFT(*NO) + SPCVAL((*YES '1') (*NO '0')) + PROMPT('Update PTF file')
The CPP, also named FINDPTF, is simple as well. CL and the OPNQRYF command are used to avoid having to set up a logical file and using RPG. The latter would have been considered for a more frequently used utility, but for something that will be used a few times each month, the "quick and dirty" method is quite appropriate.
PGM PARM(&PTFID &UPDFILE) DCL VAR(&PTFID) TYPE(*CHAR) LEN(7) DCL VAR(&UPDFILE) TYPE(*LGL) /* Declare the template file. This file will be + overridden by the file and library specified + in the following variables. */ DCLF FILE(QSYS/QADSPPTF) DCL VAR(&FILE) TYPE(*CHAR) LEN(10) VALUE('FINDPTF') DCL VAR(&LIB) TYPE(*CHAR) LEN(10) VALUE('QUSRSYS') /* Check if file exists. */ CHKOBJ OBJ(&LIB/&FILE) OBJTYPE(*FILE) + MBR(*FIRST) AUT(*NONE) MONMSG MSGID(CPF9801 CPF9815) EXEC(CHGVAR + VAR(&UPDFILE) VALUE('1')) /* Update file if requested. */ IF COND(&UPDFILE) THEN(DO) DSPPTF LICPGM(*ALL) SELECT(*ALL) RLS(*ALL) + COVERONLY(*NO) OUTPUT(*OUTFILE) + OUTFILE(&LIB/&FILE) OUTMBR(*FIRST + *REPLACE) ENDDO OVRDBF FILE(QADSPPTF) TOFILE(&LIB/&FILE) + SHARE(*YES) OPNQRYF FILE((&LIB/&FILE)) QRYSLT('SCPTFID = + ''' || &PTFID || '''') RCVF MONMSG MSGID(CPF0864) EXEC(DO) /* PTF not found. */ SNDPGMMSG MSG('PTF ' || &PTFID || ' not found on + system!') MSGTYPE(*COMP) GOTO ENDPGM ENDDO /* PTF found! */ SNDPGMMSG MSG('PTF ' || &SCPTFID || ' for licensed + program ' || &SCPPID || ' found with + status "' || &SCSTATUS *TCAT '."') + MSGTYPE(*COMP) ENDPGM: CLOF OPNID(&FILE) DLTOVR FILE(QADSPPTF) ENDPGM
Lay aside performance worries
The first time you run the FINDPTF command, the system will have to build a temporary access path (keyed by PTF identifier) for the OPNQRYF command, so the utility will take a few moments to run. However, the system will not delete the temporary access path right away. Instead it will be kept for possible reuse. So, if you use the command again soon thereafter, it will produce near-instantaneous results.
However, if you wait too long between uses, the automated system cleanup routines will delete the access path and it will have to be rebuilt. If it comes to this, don't worry; it won't take more than a couple of moments for the system to rebuild the access path.
Note: There will be a short wait if you want the database file updated (by specifying *YES for the UPDFILE parameter). Of course, the wait time depends on the usual suspects (i.e., processor speed, CPU usage, etc.), but it is also highly dependent on the number of PTFs installed on your system.
About the author: Ron Turull is editor of Inside Version 5. He has more than 20 years' experience programming for and managing AS/400-iSeries systems.