Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting a list of Datasets from Masks

642 views
Skip to first unread message

Lizette Koehler

unread,
May 9, 2013, 1:38:16 PM5/9/13
to
I know there are a couple of ways to do this. Since I have not been successful in the last month, I thought I would ask for some suggestions.

I want to create a REXX/ISPF app that will take in a LIST of Datasets that can be masked

A.B.C
A.**.C
A%%.*.D

And so forth.

I then want to get the list of all datasets under the masks to
1) Determine if they are online or Migrated (DSN and VOLSER will be sufficient)
2) Collect the info on them for space (maybe more stats later, but for now, DSN, Tracks Allocated/Tracks Used
3) Then tally the space from both Online and Migrated files.
4) Present the summary screen with the space allocated/used in both Trks/MBs

Simple - Yeah? I have been using the CSI (Catalog Search Interface) for Rexx and just have not figured it out. I need something simple.

So now I am thinking of trying the LM* functions in ISPF to do something like 3.4.

If you have any thoughts or suggestions, I would be very grateful. I am not the strongest coder on the planet and I need to write this so someone with even less skills than my self can maintain it. Otherwise I will keep rambling down the LM* path for a while.

Thanks

Lizette

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX

Barry Schwarz

unread,
May 9, 2013, 3:14:32 PM5/9/13
to
On 9 May 2013 10:38:16 -0700, star...@mindspring.com (Lizette
Koehler) wrote:

>I know there are a couple of ways to do this. Since I have not been successful in the last month, I thought I would ask for some suggestions.

Someone may post a home grown REXX that does most of what you want (or
point to the CBT tape), but otherwise to provide meaningful help we
need to see what you tried and a description of how it didn't work..

>I want to create a REXX/ISPF app that will take in a LIST of Datasets that can be masked

Is the REXX going to receive the list or will it receive the mask and
generate the list?

>A.B.C
>A.**.C
>A%%.*.D
>
>And so forth.
>
>I then want to get the list of all datasets under the masks to
>1) Determine if they are online or Migrated (DSN and VOLSER will be sufficient)

What migration tool are you using? IBM's HSM leaves the DSN in the
normal catalog search order. CA's ASM2 deletes the catalog entry and
stores the equivalent of catalog and CDS data in its IPC. I'm not
familiar with what the FDR product does.

>2) Collect the info on them for space (maybe more stats later, but for now, DSN, Tracks Allocated/Tracks Used

It's a little tough to get allocation data for a migrated dataset.

>3) Then tally the space from both Online and Migrated files.
>4) Present the summary screen with the space allocated/used in both Trks/MBs

What is your plan here? Will you build a table and use TBDISP? Or
build a temporary dataset and use BRIF/BROWSE?

>Simple - Yeah? I have been using the CSI (Catalog Search Interface) for Rexx and just have not figured it out. I need something simple.

There is a sample using CSI from REXX in one of the SAMPLIB datasets.
Look for IGGCSIRX.

>So now I am thinking of trying the LM* functions in ISPF to do something like 3.4.

I think you can limit yourself to the LMD* services. In particular,
example 3 for LMDLIST seems to come close to what you want.

>If you have any thoughts or suggestions, I would be very grateful. I am not the strongest coder on the planet and I need to write this so someone with even less skills than my self can maintain it. Otherwise I will keep rambling down the LM* path for a while.

--
Remove del for email

James Campbell

unread,
May 11, 2013, 3:27:35 AM5/11/13
to
CSI should give you dataset name information - ENTNAME/ENTYPE (to see if it is a cluster,
gdg base etc); VOLSER (which is MIGRAT for a migrated object), remember this is is an
array if there are multiple volumes

You then can use LISTDSI to get space usage. It will also tell you if it is a migrated dataset.
For VSAM clusters you can also get space information using CSI types XHARBA, XHURBA
etc

HLIST will give space usage for migrated ones - but not track information. Note that the
output from HLIST must go to a dataset - you cannot intercept the terminal output form (well,
you could if you use TSO Session Manager - but who does).

Yes, simple in a conceptual sense.

Possibly someone can give you fully developed code? Do any of the CBT tape things help -
www.cbttape.org.

James Campbell

Lizette Koehler

unread,
May 11, 2013, 9:54:29 AM5/11/13
to
James,

Thanks. I have 4 fully working examples of CSI. But I find the
documentation on usage a bit underwhelming.

After looking at CSI vs. LMDINIT, I find that for my purpose, the LMDINIT
function will be easier for someone else to support after I get done with
it.


Lizette

Lindy Mayfield

unread,
May 24, 2013, 7:13:51 AM5/24/13
to
Hi Lizette, Group,

If you don't already have it to look at, there is a wonderful exec called XDELETE that uses the CSI interface, and IMO it is a great example of those calls.

The author is our dear Gilbert Saint-flour.

I keep a copy here.
http://lilliana.eu/downloads/xdelete.rexx.txt

HTH!
Lindy

Marc Irvin

unread,
May 24, 2013, 11:24:13 AM5/24/13
to
Lizette,

I used to do similar things to what you describe. You have a mine field of gotchas to navigate, so it sound to me like you've got a long way to go -- happy coding and debugging.

First there's just listing the file. I thinks the acronym was SMS, system managed storage. You really need to contend with 5 plus file systems to fully do the job. USS, QSAM, VSAM, LMF, and finally SMS variables. For example, I could not really get anywhere until I had programs that told if a dataset was migrated or not, that told if VSAM or not, told if RECFM=U or not, if cataloged or not, or if RACF protected or not.

My REXXLA code links (ZipLink) have bit the dust, but all the code I share are in my files folder at my Yahoo Groups site titled Buddy_Rex; the link is: http://tech.groups.yahoo.com/group/Buddy_Rex. If that that seems a bit much, I am in the process of launching a new home for my REXX tools; that link is http://marcirvin.com/rexxsc. The subfolder for TSO stuff is a work in process.


The in code doc for a program named SYSX.REXX(DSNNAMES)
SAY 'REXXNAME: DSNNAMES'
SAY ''
SAY 'FUNCTION: Used IP DSN to pass HOST list of dataset names.'
SAY ''
SAY "ENRTYFMT: DSNNAMES 'HQ.*' <*Resp> <*EXplicit> < *VSam >"
SAY " <*Quiet>"
SAY " <*Loud>"
SAY " <*Test>"
SAY " <*Sort>"
SAY " <*HSTAT>"
SAY " <*BAKDT>"
SAY ''
SAY " *Resp Means return list via the return code parameter. "
SAY " *Loud Means to write a list of the files to the console. "
SAY " *Sort Means sort file names list if HSTAT and BAKDT opts off."
SAY " *HSTAT MEANS TO RETURN THE QUALIFIERS CATALOG INFORMATION."
SAY " *BAKDT MEANS TO RETURN THE DATE DATASET WAS LAST BACKED UP."
SAY " *VSam MEANS TO RETURN LIST OF VSAM FILES. "
SAY " rc=04 Means no file names matched the input file name mask."
say ''

Here is another snippet just to demonstrate some of the hurdles / complexity I dealt with back in the day. There should be short cuts since I wrote this back in the nineties.
SYSX.REXX(LISTDSNS)
/* AN MVI EXEC */
SYS=ADDRESS()
IF SYS = 'TSO' | SYS = 'MVS' | SYS = 'ISREDIT' THEN TSO = 1; ELSE TSO = 0
IF SYS = 'DOS' | SYS = 'KEDIT' | SYS = 'CMD' THEN DOS = 1; ELSE DOS = 0
IF SYS = 'CMS' | SYS = 'XEDIT' | SYS = 'REXX' THEN CMS = 1; ELSE CMS = 0
...
...
BEGIN:
IF DATATYPE(RIGHT(USERID(),1)) = 'NUM'
THEN !USERID = LEFT(USERID(),LENGTH(USERID())-1)
ELSE !USERID = USERID()
"STATE '"!USERID".REXX'"
IF RC ^= 0 THEN DO
"DSNALLOC '"!USERID".REXX' *OPDIR(18)"
IF RC ^= 0 THEN SIGNAL ERR040
END
PARSE VAR ARGSTRING DSNS DSN .
IF LEFT(DSNS,1) = "'" & DSN = '' THEN DO
DSN = DSNS; DSNS = '*'
END
IF DSNS = '' THEN DSNS = '*' /* DEFAULT TO LISTING ENTIRE LIST OF DSNS */
IF DSN = '' THEN DSN = "REXX"
IF POS('(',DSN) > 0 THEN SIGNAL ERR060
IF LEFT(DSN,1) ^= "'" THEN DSN = "'"!USERID"."DSN"'"
GETFILES(DSN)
PICKDSNS()
IF DSNS.0 = 0 THEN SIGNAL ERR028
IF XEXEC
THEN DO
DSNS.0 = DSNS.0 - 6
WRITEMEM("'"!USERID".REXX(CMS)'")
END
ELSE DO N = 1 FOR DSNS.0
SAY DSNS.N
END
IF XEDIT THEN "IEDIT '"!USERID".REXX(CMS)'"
EXIT:
EXIT 000
...
...
GETFILES: PROCEDURE EXPOSE IDSN IDSNFND DSNS. DSNS !USERID
/* ONLY ENTER THIS LOGIC IF INPUT FILE NAME IS A PDS */
PARSE ARG DSN .
IF DSN = '' THEN !X = !USERID
X = OUTTRAP("DSNS.")
"LISTCAT LEVEL("DSN") NAMES"
X = OUTTRAP("OFF")
IDSNFND = 0
DO N = 1 FOR DSNS.0 /* STRIP OFF GARBAGE BEFORE MEM LIST */
IF WORD(DSNS.N,1) ^= 'NONVSAM'
THEN DSNS.N = ''
ELSE DSNS.N = "'"STRIP(WORD(DSNS.N,3))"'"
IF DSNS.N = IDSN THEN IDSNFND = 1
END
X = 0 /* GET RID OF SUPERFLUOUS ENTRIES */
DO N = 1 FOR DSNS.0
IF DSNS.N ^= ''
THEN DO
X = X + 1
DSNS.X = STRIP(DSNS.N)
RC = LISTDSI(DSNS.N)
FMTS.X = LEFT(SYSUNITS,3)'/'RIGHT(SYSUSED,5,'0'),
RIGHT(SYSLRECL,5,'0')'/'RIGHT(SYSBLKSIZE,5,'0'),
LEFT(SYSRECFM,3) LEFT(SYSREFDATE,8) '00:00' LEFT(SYSDSORG,2),
LEFT(SYSVOLUME,6)
END
END
DSNS.0 = X
GETFILEX:
RETURN 'NOP'
PICKMEMS: /* SELECT ALL MEMBERS THAT HAVE THE DESIRED PREFIX. */
IMEM = TRANSLATE(STRIP(IMEM))
X = POS('*',IMEM)
Y = POS('%',IMEM)
L = LENGTH(IMEM)
IF X = L
THEN DO N = 1 FOR MEMS.0 /* SET NULL VALS IF NO MATCH */
IF X = 1 THEN ITERATE
IF X - 1 > LENGTH(MEMS.N) THEN DO
MEMS.N = ''
ITERATE
END
IF POSCOMPR(LEFT(IMEM,X-1),LEFT(MEMS.N,X-1)) THEN MEMS.N = ''
END
IF X > 1 & X < L /* ENTER HERE WHEN STAR(*) IS IN MIDDLE */
THEN DO N = 1 FOR MEMS.0 /* SET NULL VALS IF NO MATCH */
IF POSCOMPR(LEFT(IMEM,X-1),LEFT(MEMS.N,X-1))
THEN DO
MEMS.N = ''
ITERATE N
END
IF POSCOMPR(RIGHT(IMEM,X-L),RIGHT(MEMS.N,X-L))
THEN DO
MEMS.N = ''
ITERATE N
END
END
IF X = 1
THEN DO N = 1 FOR MEMS.0 /* SET NULL VALS IF NO MATCH */
IF POSCOMPR(RIGHT(IMEM,L-1),RIGHT(MEMS.N,L-1)) THEN MEMS.N = ''
END
IF X = 0 & Y = 0
THEN DO
MEMS.0 = 1 /* USE THE MEMBER NAME PROVIDED. */
IF IMEMFND THEN MEMS.1 = IMEM; ELSE SIGNAL ERR030
END
MEMSLIST: /* GET RID OF THE JUNK IN THE MEMS. LIST. */
X = 0; PFX = ''; SFX = ''
IF FTYPE THEN FT = DSN; ELSE FT = ''
IF FNAME THEN FT = ''
IF XEXEC THEN PFX = ' &1 &2'
IF XDATE THEN PARSE VAR DSN "'" XDSN "'" .
Z = MEMS.0 + 1
MEMS.Z = '' /* SET THE EOF */
DO N = 1 FOR MEMS.0
IF MEMS.N ^= ''
THEN DO
X = X + 1
IF XDATE THEN DO
"DSNSTATS '"XDSN"("MEMS.N")' *STACK *QUIET"
IF RC ^= 0 THEN SIGNAL ERR090
PULL SFX
END
MEMS.X = PFX STRIP(MEMS.N) FT SFX
END
END
MEMS.0 = X
RETURN 'NOP'
PICKDSNS: /*SELECT ALL DATASET NAMES THAT HAVE THE DESIRED PREFIX.*/
DSNS = TRANSLATE(STRIP(DSNS))
X = POS('*',DSNS)
Y = POS('%',DSNS)
L = LENGTH(DSNS)
IF X = L
THEN DO N = 1 FOR DSNS.0 /* SET NULL VALS IF NO MATCH */
IF X = 1 THEN ITERATE
IF X - 1 > LENGTH(DSNS.N) THEN DO
DSNS.N = ''
ITERATE
END
IF POSCOMPR(LEFT(DSNS,X-1),LEFT(DSNS.N,X-1)) THEN DSNS.N = ''
END
IF X > 1 & X < L /* ENTER HERE WHEN STAR(*) IS IN MIDDLE */
THEN DO N = 1 FOR DSNS.0 /* SET NULL VALS IF NO MATCH */
IF POSCOMPR(LEFT(DSNS,X-1),LEFT(DSNS.N,X-1))
THEN DO
DSNS.N = ''
ITERATE N
END
IF POSCOMPR(RIGHT(DSNS,X-L),RIGHT(DSNS.N,X-L))
THEN DO
DSNS.N = ''
ITERATE N
END
END
IF X = 1
THEN DO N = 1 FOR DSNS.0 /* SET NULL VALS IF NO MATCH */
IF POSCOMPR(RIGHT(DSNS,L-1),RIGHT(DSNS.N,L-1)) THEN DSNS.N = ''
END
IF X = 0 & Y = 0
THEN DO
DSNS.0 = 1 /* USE THE DATASET NAME PROVIDED. */
IF IDSNFND THEN DSNS.1 = DSNS; ELSE SIGNAL ERR032
END
...
...
DOC:
/*BEGTYPE
REXXNAME: LISTDSNS
FUNCTION: BARELY SIMULATE CMS LISTDSNS COMMAND IN TSO/ISPF.
HOWTORUN: POSSIBLY... LISTDSNS * TDMVS.MIRVI
EXAMPLES:
ENDTYPE*/
IF CMS THEN 'REXSAYIT LISTDSNS EXEC * /*BEGTYPE ENDTYPE*/'
IF TSO THEN "REXSAYIT $DSN 'MIRVI.REXX(LISTDSNS)' SYSEXEC /*BEGTYPE ENDTYPE*/"
EXIT 000
...
...
ERR028:
SAY 'LISTDSNS - NO MEMBERS FOUND IN '''DSN''' USING MEM('IMEM').'
EXIT 028
ERR060:
SAY 'LISTDSNS - THE MEMBER NAME MAY NOT BE SPECIFIED IN THE DSN FIELD.'
EXIT 060
ERR070:
SAY 'LISTDSNS - UNABLE TO ALLOCATE DATASET('DSNMEM').'
EXIT 070
ERR080:
SAY 'LISTDSNS - UNABLE TO WRITE TO DATASET('DSNMEM').'
EXIT 080
ERR090:
SAY 'LISTDSNS - "DSNSTATS" PROBLEM WITH MEMBER ('MEMS.N') IN DSN='XDSN'.'
EXIT 090


Marc Vincent Irvin

bill.ko...@gmail.com

unread,
Mar 25, 2014, 12:00:45 AM3/25/14
to
LM* Functions Are Useful...

DSNPAT = "OPER.*.*.*.G*.T*"; DSNAME = "";
"ISPEXEC LMDINIT LISTID(LID) LEVEL("DSNPAT")";
"ISPEXEC LMDLIST LISTID("LID") OPTION(LIST) DATASET(DSNAME) STATS(YES)"; LMDRC = RC;

DO UNTIL LMDRC > 0;
SAY DSNAME;
"ISPEXEC LMDLIST LISTID("LID") OPTION(LIST) DATASET(DSNAME)STATS(YES)";
LMDRC = RC;
END;
0 new messages