/******************************************************************************/ /* */ /* The information contained in this document has not been submitted */ /* to any formal tests and is distributed on an 'As is' basis */ /* without any warranty either expressed or implied. The use of this */ /* information or the implementation of any of these techniques is a */ /* customer responsibility and depends on the customer's ability to */ /* evaluate and integrate them into the customer's operation */ /* environment. While each item may have been reviewed by IBM */ /* for accuracy in a specific situation, there is no guarantee that the */ /* same or similar results will be obtained elsewhere. Customers */ /* attempting to adapt these techniques to their environments do so */ /* at their own risk. */ /* */ /******************************************************************************/ /******************************************************************************/ /* */ /* IPEXITPGM */ /* */ /* This exit program example retrieves job information and writes it to a */ /* log file. Because of the technique used to write to the log file, it */ /* must be created as a "flat file", a file with a single character field */ /* with a CCSID of 65535. To create the log file, use this command: */ /* CRTPF FILE(QGPL/EXITLOG) RCDLEN(512) */ /* Increase the maximum size of the file so that it doesn't fail when the */ /* file hits 13000 records. */ /* CHGPF FILE(EXITLOG) SIZE(10000 10000 32767) */ /* Make sure everyone is authorized to write to the file: */ /* GRTOBJAUT OBJ(QGPL/EXITLOG) OBJTYPE(*FILE) USER(*PUBLIC) */ /* */ /* */ /* This program is to used on the initialization exit point for the */ /* optimized database host server, you can modify it for other exit */ /* points by changing the &REQUEST parameter and the data extracted from */ /* it to match the exit point you are using. */ /* */ /* To register it you must first compile it. I would recommend compiling */ /* it as a *SECOFR and compiling it to use adopted authority like the */ /* following example: */ /* */ /* CRTBNDCL PGM(QGPL/IPEXITPGM) SRCFILE(MIKSWENS/MYCLSRC) + */ /* SRCMBR(IPEXITPGM) OPTION(*EVENTF) USRPRF(*OWNER) + */ /* REPLACE(*YES) AUT(*USE) DBGVIEW(*SOURCE) */ /* */ /* Once compiled, the program can be registered on the exit point. For the */ /* database host server initialization exit point, you would do the */ /* following: */ /* */ /* ADDEXITPGM EXITPNT(QIBM_QZDA_INIT) FORMAT(ZDAI0100) PGMNBR(1) + */ /* PGM(QGPL/IPEXITPGM) + */ /* TEXT('Exit program to log: user, job, client IP, time') */ /* */ /* Then you would need to end the QZDA* prestart jobs and restart them so */ /* that the new connections pick up the exit program: */ /* */ /* ENDPJ SBS(QUSRWRK) PGM(QZDASOINIT) OPTION(*IMMED) */ /* ENDPJ SBS(QUSRWRK) PGM(QZDASSINIT) OPTION(*IMMED) */ /* STRHOSTSVR *DATABASE */ /* */ /* */ /******************************************************************************/ PGM PARM(&STATUS &REQUEST) /********************************************************************/ /* PROGRAM CALL PARAMETER DECLARES */ /********************************************************************/ DCL VAR(&STATUS) TYPE(*CHAR) LEN(1) /* ACCEPT/REJECT */ DCL VAR(&REQUEST) TYPE(*CHAR) LEN(2000) /* PARM STRUCTURE */ /********************************************************************/ /* PARAMETER DECLARATIONS */ /********************************************************************/ DCL VAR(&USER) TYPE(*CHAR) LEN(10) /* USER ID */ DCL VAR(&IPV4ADDR) TYPE(*CHAR) LEN(15) VALUE(' ') DCL VAR(&JOBNAME) TYPE(*CHAR) LEN(10) DCL VAR(&JOBUSER) TYPE(*CHAR) LEN(10) DCL VAR(&JOBNUM) TYPE(*CHAR) LEN(6) DCL VAR(&RECORD) TYPE(*CHAR) LEN(512) DCL VAR(&DATA) TYPE(*CHAR) LEN(100) VALUE(' ') DCL VAR(&JOBI) TYPE(*CHAR) LEN(700) VALUE(' ') DCL VAR(&JOBILEN) TYPE(*DEC) LEN(4 0) VALUE(700) DCL VAR(&FMTNAME) TYPE(*CHAR) LEN(8) VALUE(JOBI0600) DCL VAR(&QUALJN) TYPE(*CHAR) LEN(26) VALUE('*') DCL VAR(&INJOB) TYPE(*CHAR) LEN(16) VALUE(' ') /* CHGJOB LOG CL COMMAND *NO, keeps the joblog a bit cleaner */ CHGJOB LOGCLPGM(*NO) MONMSG MSGID(CPF0000) /* Use CHKOBJ to make sure that our output file is available */ CHKOBJ OBJ(QGPL/EXITLOG) OBJTYPE(*FILE) MBR(EXITLOG) MONMSG MSGID(CPF9801) EXEC(DO) /* No File */ SNDPGMMSG MSG('Log file, QGPL/EXITLOG, is missing or unusable. IPEXITPGM + ending without logging data.') MSGTYPE(*COMP) RETURN ENDDO /* Set the &STATUS variable to a 1 to allow the job to continue */ CHGVAR VAR(&STATUS) VALUE('1') /* Extract the user from the input parm */ CHGVAR VAR(&USER) VALUE(%SST(&REQUEST 1 10)) /* Call QUSRJOBI to retrieve job information */ CALL PGM(QSYS/QUSRJOBI) PARM(&JOBI &JOBILEN &FMTNAME &QUALJN &INJOB) /* Extract data from the output of QUSRJOBI */ CHGVAR VAR(&IPV4ADDR) VALUE(%SST(&JOBI 308 15)) CHGVAR VAR(&JOBNAME) VALUE(%SST(&JOBI 9 10)) CHGVAR VAR(&JOBUSER) VALUE(%SST(&JOBI 19 10)) CHGVAR VAR(&JOBNUM) VALUE(%SST(&JOBI 29 6)) /* Stick the job information into the &RECORD variable */ CHGVAR VAR(&RECORD) VALUE('User: ' *CAT &USER *CAT ' connected to job: ' + *CAT &JOBNUM *TCAT '/' *TCAT &JOBUSER *TCAT '/' *TCAT &JOBNAME *CAT + ' from IPv4 address: ' *TCAT &IPV4ADDR) /* Copy the contents of &RECORD into an enviroment variable, TM */ ADDENVVAR ENVVAR(TM) VALUE(&RECORD) REPLACE(*YES) /* Use qshell to echo TM contents and the system time into the log */ CHGVAR VAR(&DATA) VALUE('echo $TM '' at: ''"`date`">>' *BCAT + '/qsys.lib/qgpl.lib/exitlog.file/exitlog.mbr') QSH CMD(&DATA) RMVENVVAR ENVVAR(TM) MONMSG MSGID(CPFA981) EXIT: ENDPGM