/* REXX DSVCSI Catalog Search Interface A fast way to get complex catalog searches done. Use '(routine name) ?' for HELP-text. Written by someone at IBM probably Modification History 20160307 fxc cleaned up grungy IBM coding; added basic tracing capability 20230426 fxc message if nothing found 20230511 fxc remove some dead code 20240308 fxc chg dollar-sign to @ everywhere; 20250717 fxc correct HELP_text; 20250918 fxc SPACEOUT; 20250925 fxc chg setting of sw. to sw.0; */ arg argline /* pro-forma quick-start */ parse source sys_id how_invokt exec_name DD_nm DS_nm, as_invokt cmd_env addr_spc usr_tokn parse value "0" with, sw. helpmsg address TSO arg parms "((" opts /* split parms and opts */ opts = Strip( opts,'T','5d'x ) /* trim trailing bananas */ parse var opts "TRACE" tv . /* is trace requested? */ parse value tv "N" with tv . /* TRACE defaults to Normal */ rc = Trace( "O" ); rc = Trace( tv ) /* trace off, trace on? */ sw.0nested = sysvar( "SYSNEST" ) = "YES" sw.0inispf = sysvar( "SYSISPF" ) = "ACTIVE" if parms = "?" then call HELP /* ...and don't come back */ upper parms @@msg = msg( 'off' ) if parms = '' then parms = sysvar( "sysuid" ) parms = Strip( parms ) origparm = parms /* save for later */ if Pos( "*",parms ) = 0 then parms = parms".**" csikey = parms count = 0 /* set counter for dataset entry */ /********************************************************************/ /* */ /* name: iggcsirx */ /*description: this rexx exec is used to call the catalog */ /* search interface. */ /* input: filter key */ /* output: data sets names and volumes */ /* */ /********************************************************************/ /********************************************************************/ /* */ /* initialize the parm list */ /* */ /********************************************************************/ modrsnrc = Left( ' ',4 ) /* clear module/return/reason */ csifiltk = Left( csikey,44 ) /* move filter key into list */ csicatnm = Left( ' ',44 ) /* clear catalog name */ csiresnm = Left( ' ',44 ) /* clear resume name */ csidtyps = Left( ' ',16 ) /* clear entry types */ csicldi = "Y" /* indicate data and index */ csiresum = Left( ' ',1 ) /* clear resume flag */ csis1cat = Left( ' ',1 ) /* indicate search > 1 catalogs*/ csiresrv = Left( ' ',1 ) /* clear reserve character */ csinumen = '0001'x /* init number of fields */ csifld1 = Left( 'SECFLAGS',8 ) /* put here for test */ /********************************************************************/ /* */ /* build the selection criteria fields part of parameter list */ /* */ /********************************************************************/ csifield = csifiltk || csicatnm || csiresnm || csidtyps ||, csicldi || csiresum || csis1cat || csiresrv, || csinumen || csifld1 /********************************************************************/ /* */ /* initialize and build work are output part of parameter list */ /* */ /********************************************************************/ rc = Trace( "O" ) /* avoid 20 pages of echo */ worklen = 64000 dwork = '0000FA00'x || copies('00'x,worklen-4) /* */ /* worklen = 1024 */ /* dwork = '00000400'x || copies('00'x,worklen-4) */ rc = Trace( tv ) /********************************************************************/ /* */ /* initialize work variables */ /* */ /********************************************************************/ resume = 'Y' catnamet = Left( ' ',44 ) dnamet = Left( ' ',44 ) if sw.0nested then nop else "NEWSTACK" /********************************************************************/ /* */ /* set up loop for resume (if a resume is necessary) */ /* */ /********************************************************************/ do while resume = 'Y' /********************************************************************/ /* */ /* issue link to catalog generic filter interface */ /* */ /********************************************************************/ address linkpgm 'iggcsi00 modrsnrc csifield dwork' resume = substr( csifield,150,1 ) /* get resume flag for next loop from csiresum */ usedlen = c2d( substr( dwork,9,4 ) ) /* get amt of work area used */ fld_no = c2d( substr( dwork,13,2 ) ) - 1 /* get number of fields */ pos1 = 15 /* starting position */ /********************************************************************/ /* */ /* process data returned in work area */ /* */ /********************************************************************/ do while pos1 < usedlen /* do until all data is processed*/ if substr( dwork,pos1+1,1 ) = '0' /* if catalog, prt catalog head*/ then do pos1 = pos1 + 50 end /* 0 = catalog */ dname = substr( dwork,pos1+2,44 ) /* get entry name */ /********************************************************************/ /* */ /* assign entry type name */ /* */ /********************************************************************/ tmptyp = substr( dwork,pos1+1,1 ) select when tmptyp = 'C' then dtype = 'CLUSTER ' when tmptyp = 'D' then dtype = 'DATA ' when tmptyp = 'I' then dtype = 'INDEX ' when tmptyp = 'A' then dtype = 'NONVSAM ' when tmptyp = 'H' then dtype = 'GDS ' when tmptyp = 'B' then dtype = 'GDG ' when tmptyp = 'R' then dtype = 'PATH ' when tmptyp = 'G' then dtype = 'AIX ' when tmptyp = 'X' then dtype = 'ALIAS ' when tmptyp = 'U' then dtype = 'UCAT ' otherwise dtype = '' end /* select */ /********************************************************************/ /* */ /* have name and type, get field info */ /* */ /********************************************************************/ pos1 = pos1 + 46 pos_tmp = pos1 + 2 /* point to field length strings - 2 */ /* get length of each field */ do i = 1 to fld_no fld_len.i = c2d( substr( dwork,pos_tmp+2,2 ) ) pos_tmp = pos_tmp + 2 end /* fld_no */ /* get field data */ pos_tmp = pos1 + 4 + (fld_no * 2) /* point to data string */ /* field 1 - secflags */ sec_typ = ' ' if numvol_devtyp = 0 then nop sec_typ = c2x( substr( dwork,pos_tmp,1 ) ) if dnamet ^= dname &, /* if resume, name may already */ dtype ^= '' then /* printed */ do /* if not, print it */ count = count + 1 queue Left( dtype,8 ) dname dnamet = dname end /********************************************************************/ /* */ /* get position of next entry */ /* */ /********************************************************************/ pos1 = pos1 + c2d( substr( dwork,pos1,2 ) ) end /* end of do while pos1 < usedlen */ end /* end of do while resume = 'y' */ if count = 0 then , /* nothing queued */ queue "No data found for" origparm @z = msg( @@msg ) /* reset MSG setting */ if sw.0nested then return else do do queued() parse pull line; say line end /* queued */ end exit /*@ DSVCSI */ /* . ----------------------------------------------------------------- */ HELP: /*@ */ address TSO;"CLEAR" if helpmsg <> "" then say helpmsg ex_nam = Left( exec_name,8 ) /* predictable size */ say " " say " "ex_nam" is the driver for the Catalog Search Interface, a very " say " high-efficiency catalog search to be used in place of TSO " say " functions such as LISTCAT, etc. " say " " say " Syntax: "ex_nam" target " say " " say " target is a string representing the entities to be " say " searched-for. It may be generic. " say " " "NEWSTACK"; pull ; "CLEAR" ; "DELSTACK" say " " say " Debugging tools provided include: " say " " say " TRACE tv: will use value following TRACE to place the execution in" say " REXX TRACE Mode. " say " " say " " say " Debugging tools can be accessed in the following manner: " say " " say " TSO "ex_nam" parameters (( debug-options " say " " say " For example: " say " " say " TSO "ex_nam" (( trace ?r " if sysvar( "SYSISPF" ) = "ACTIVE" then, address ISPEXEC "CONTROL DISPLAY REFRESH" exit /*@ HELP */