/* REXX */ /**********************************************************************/ /* zlsoffmt sample formatter for zlsof -json output */ /* lists file systems in use and the files that are in use */ /* */ /* Syntax: zlsoffmt [pathname] */ /* if pathname not given it uses stdin */ /* ex: format zlsof output: */ /* zlsof -json | zlsoffmt */ /* ex: format redirected zlsof output */ /* zlsof -json>out.json */ /* zlsoffmt out.json */ /* */ /* PROPERTY OF IBM */ /* COPYRIGHT IBM CORP. 2019 */ /* */ /* Bill Schoen 5/31/19 wjs@us.ibm.com */ /**********************************************************************/ signal on novalue /* initialize environment */ call initialize /* get json file name from the args */ parse arg jsonfile . if jsonfile='' then do parse source . . . . . . . rxenv . if rxenv<>'OMVS' then do call say 'specify input file' exit 1 end jsonfile='/dev/fd0' /* default to stdin if omvs environment */ end /* read the file to get the json string */ json=getjson(jsonfile) if length(json)<2 then exit 4 /* initialize a parse instance */ if jsonrqst("hwtjinit jtok") then exit /* parse the json string */ if jsonrqst('hwtjpars jtok json') then exit /* format the json string starting at the root */ root=0 tagresult='result' tagfiles='files' tagfilesystem='fileSystem' tagpathname='pathName' tagdiagname='diagName' taginum='inum' fslen=0 fsns.='' fsns=0 /* locate the result array of pids */ if jsonrqst('hwtjsrch jtok hwtj_searchtype_object tagresult root 0 ttok',1) then exit if jsonrqst('hwtjgnue jtok ttok pids') then exit do i=0 to pids-1 /* do for each pid returned */ /* locate the pid array entry object */ if jsonrqst('hwtjgaen jtok ttok i etok') then iterate /* locate the files array entry object for this pid */ if jsonrqst('hwtjsrch jtok hwtj_searchtype_object tagfiles etok 0 ftok') then iterate if jsonrqst('hwtjgnue jtok ftok files') then iterate do j=0 to files-1 /* do for each file in use by this pid */ /* locate the file object */ if jsonrqst('hwtjgaen jtok ftok j fetok') then iterate /* locate the file system name in the file object */ if jsonrqst('hwtjsrch jtok hwtj_searchtype_object tagfilesystem fetok 0 otok') then iterate if jsonrqst('hwtjgjst jtok otok type') then iterate if type<>'HWTJ_STRING_TYPE' then iterate /* remove any esc sequences in the file system name */ if jsonrqst('hwtjgval jtok otok fsn') then iterate if length(fsn)>fslen then fslen=length(fsn) /* remove any esc sequences in the file system name */ if jsonrqst('hwtjesct hwtj_decode fsn fsn') then iterate /* keep track of each file system name */ if fsns.fsn.!path.0='' then do fsns=fsns+1 fsns.fsns=fsn fsns.fsn.!path.0=0 end /* locate path name */ path='' if jsonrqst('hwtjsrch jtok hwtj_searchtype_object tagpathname fetok 0 otok') then iterate if jsonrqst('hwtjgjst jtok otok type') then iterate if type='HWTJ_STRING_TYPE' then do if jsonrqst('hwtjgval jtok otok path') then iterate end else do /* no path name, try the diagnostic name */ if jsonrqst('hwtjsrch jtok hwtj_searchtype_object tagdiagname fetok 0 otok') then iterate if jsonrqst('hwtjgjst jtok otok type') then iterate if type='HWTJ_STRING_TYPE' then do if jsonrqst('hwtjgval jtok otok path') then iterate end else /* still no name, use inode number */ do if jsonrqst('hwtjsrch jtok hwtj_searchtype_object taginum fetok 0 otok') then iterate if jsonrqst('hwtjgjst jtok otok type') then iterate if type='HWTJ_STRING_TYPE' then do if jsonrqst('hwtjgval jtok otok path') then iterate path='inode:'path end end end /* remove any esc sequences in the path name */ if jsonrqst('hwtjesct hwtj_decode path path') then iterate if path='' then iterate /* keep track of each path name for this file system */ if fsns.fsn.!path.path='' then /* first reference to path */ do /* keep path name */ fsns.fsn.!path.path=1 k=fsns.fsn.!path.0+1 fsns.fsn.!path.0=k fsns.fsn.!path.k=path end end end fsns.0=fsns do i=1 to fsns.0 fsn=fsns.i say fsn /* loop through path names for this file system */ do j=1 to fsns.fsn.!path.0 say ' ' fsns.fsn.!path.j end end /* terminate the parse instance */ if jsonrqst("hwtjterm jtok") then exit return 0 /**********************************************************************/ /* initialize basic environment initialization */ /**********************************************************************/ initialize: call syscalls 'ON' /* ensure region as large as we are permitted */ address syscall 'getrlimit (rlimit_as) as.' if as.1<>as.2 then do as.1=as.2 address syscall 'setrlimit (rlimit_as) as.' end /* define the host command environment */ call hwtcalls "ON" return /**********************************************************************/ /* getjson read the file to get the json string */ /**********************************************************************/ getjson: procedure expose (syscall_constants) parse arg jsonfile address syscall 'open (jsonfile)' o_rdonly fd=retval if fd=-1 then do say 'cannot read' jsonfile exit 0 end json='' do until retval<1 address syscall 'read (fd) buf 4096' json=json || buf end address syscall 'close (fd)' return json /**********************************************************************/ /* jsonrqst build and format the hwtjson call */ /* and check for service call errors */ /* first word is the service name */ /* remainder are the argument variable names without */ /* the returncode and diag. as first and last */ /* returncode and diag get added and checked */ /* returns: 0 = ok 1 = error */ /**********************************************************************/ jsonrqst: parse arg jcmd jcmdstr @diag.='' jrc=0 address hwtjson jcmd 'jrc' jcmdstr '@diag.' hcrc=rc if hcrc=0 & jrc=0 then return 0 if hcrc<>0 then do call say '>>' jcmd "failed, rc="hcrc return 1 end call say '>>' jcmd jcmdstr call say '>>' "retcode="jrc d2x(jrc)'x' call say '>>' "reason="@diag.HWTJ_REASONCODE call say '>>' "desc="@diag.HWTJ_REASONDESC return 1 /*****************************************/ /* say utility */ /*****************************************/ say: say arg(1) return