I am trying to retrieve the source date from an RPGLE program. I'm sure that there is an API but I haven't been able to find one. The closest I came was QBNRMODI but it seems to require an actual module, not the bound program.
Software/Hardware used:
ASKED:
September 15, 2006 2:45 PM
UPDATED:
December 12, 2010 6:43 AM
There is no source date for an ILE program as there is no source. An ILE program is comprised of a number of modules which are bound together to make the program and the modules can be of different languages.
To retrieve the source date you will have to pick up the attributes of the particular module.
Here’s a sample program that should demonstrate basic retrieval of module info. It’s an ILE CL program that accepts a library name. It lists the modules of all ILE programs into a user space. Then it loops through the list printing a line per module showing program name, module, source file and member and source change date/time:
pgm ( + &pLib + ) dcl &pLib *char 10 dcl &qObj *char 20 dcl &qUsrSpc *char 20 value( 'LSTPGMMOD QTEMP' ) dcl &Pgm *char 10 value( ' ' ) dcl &PgmLib *char 10 value( ' ' ) dcl &Mod *char 10 value( ' ' ) dcl &ModLib *char 10 value( ' ' ) dcl &SrcF *char 10 value( ' ' ) dcl &SrcFLib *char 10 value( ' ' ) dcl &SrcMbr *char 10 value( ' ' ) dcl &ModCrt *char 13 value( ' ' ) dcl &SrcChg *char 13 value( ' ' ) /* General fields for retrieve *USRSPC header... */ dcl &offslst *int dcl &nbrlste *int dcl &sizlste *int dcl &NbrLE *int dcl &us_hdr *char 150 dcl &ModEnt *char 512 dcl &rc *int value( 0 ) dcl &nl *char 1 value( x'15' ) dcl &ff *char 1 value( x'0C' ) dcl &nul *char 1 value( x'00' ) dcl &PagHdr *char 134 dcl &MsgTxt *char 134 dcl &lines *int value( 3 ) /* Create a *USRSPC... */ call QUSCRTUS ( + &qusrspc + 'PGMMOD ' + x'00004000' + X'00' + '*ALL ' + 'List *PGM module info ' + '*YES ' + x'0000000000000000' + ) /* List *ALL program's modules into *USRSPC... */ chgvar &qObj ( '*ALL ' *cat &pLib ) call QBNLPGMI ( + &qusrspc + 'PGML0100' + &qObj + x'0000000000000000' + ) /* Retrieve *USRSPC header for offset, count and size of entries... */ call QUSRTVUS ( + &qusrspc + x'00000001' + x'00000096' + &us_hdr + ) /* */ /* Get the offset to the list within the space, the number */ /* of list entries and size of each entry from the header. */ /* */ chgvar &offslst %bin( &us_hdr 125 4 ) chgvar &nbrlste %bin( &us_hdr 133 4 ) chgvar &sizlste %bin( &us_hdr 137 4 ) /* If no entries, then get out of here... */ if ( &nbrlste *eq 0 ) do sndpgmmsg msgid( CPF9897 ) msgf( QCPFMSG ) + msgdta( 'No modules found.' ) goto End_Mod enddo /* Set the offset to the list within the space... */ chgvar &offslst ( &offslst + 1 ) chgvar &NBRLE &nbrlste /* Set up report; print first heading... */ ovrprtf stdout qsysprt + dfrwrt( *NO ) + splfname( PGMMODLST ) + ovrscope( *ACTGRPDFN ) + opnscope( *ACTGRPDFN ) chgvar &PagHdr ( + 'Program Library Module + Mod Lib Src File Src Lib + Member Chg Date' *cat + &NL *cat + ' ' *cat + &NL *cat + &nul + ) callprc 'printf' ( + &PagHdr + ) + rtnval( &rc ) /* Loop through the list, printing the info... */ dountil (&NbrLE *lt 1 ) call QUSRTVUS ( + &qusrspc + &offslst + &sizlste + &ModENT + ) /* Get the module, program and library from the list... */ chgvar &Pgm %sst( &ModENT 1 10 ) chgvar &PgmLib %sst( &ModENT 11 10 ) chgvar &Mod %sst( &ModENT 21 10 ) chgvar &ModLib %sst( &ModENT 31 10 ) chgvar &SrcF %sst( &ModENT 41 10 ) chgvar &SrcFLib %sst( &ModENT 51 10 ) chgvar &SrcMbr %sst( &ModENT 61 10 ) chgvar &ModCrt %sst( &ModENT 81 13 ) chgvar &SrcChg %sst( &ModENT 94 13 ) sndpgmmsg msgid( CPF9897 ) msgf( QCPFMSG ) + msgdta( + 'Found' *bcat &ModLib *tcat '/' *cat + &Mod + ) + topgmq( *EXT ) msgtype( *STATUS ) chgvar &MsgTxt ( + &Pgm *cat + ' ' *cat + &PgmLib *cat + ' ' *cat + &Mod *cat + ' ' *cat + &ModLib *cat + ' ' *cat + &SrcF *cat + ' ' *cat + &SrcFLib *cat + ' ' *cat + &SrcMbr *cat + ' ' *cat + &SrcChg *cat + &NL *cat + &nul + ) callprc 'printf' ( + &MsgTxt + ) + rtnval( &rc ) chgvar &lines ( &lines + 1 ) if ( &lines *gt 55 ) do callprc 'printf' ( &ff ) rtnval( &rc ) callprc 'printf' ( + &PagHdr + ) + rtnval( &rc ) chgvar &lines ( 3 ) enddo /* Decrement our loop counter and loop back if more... */ chgvar &offslst ( &offslst + &sizlste ) chgvar &NbrLE ( &NbrLE - 1 ) enddo End_Mod: /* Clear override and delete the *USRSPC... */ dltovr STDOUT lvl( *ACTGRPDFN ) call QUSDLTUS ( + &qusrspc + x'0000000000000000' + ) return endpgmAny OPM program will be ignored. Modules are listed whether the module was compiled and bound with others or the program was created straight from a single module.
Note that the code must be compiled as a module. The program is then created with CRTPGM with BNDDIR(QC2LE) and ACTGRP(*NEW). That brings the printf() API in and it closes the printer file when the *NEW activation group ends.
Tom