Joined: 10 Oct 2003 Posts: 315 Topics: 49 Location: Germany
Posted: Thu Jun 05, 2014 7:58 am Post subject: Read PDS directory including "last modified" data
Hi *,
I'm trying to read the directory of a PDS (or PDSE) dataset using PL/1 (or Cobol).
This works for membernames, the structure for a PDS directory is documented for exemple here: OSDFSMS: Using Data Sets, SC26-7410-05.
My problem is now the "last modified" date (like ISPF output). Which bytes are the relevant bytes in the PDS directory records ? How to interpret this bytes?
There are some solutions in the internet available using REXX and the LMMFIND and ZLM4DATE command. But this doesn't help.
I need to do this task in a PL/1 and/or Cobol program.
So can anybody give me some advise, about the relevant bytes and the interpretation of the bytes ?
Joined: 10 Oct 2003 Posts: 315 Topics: 49 Location: Germany
Posted: Tue Jun 10, 2014 3:03 am Post subject:
ironponygrl,
well I'm, sorry. It is a PL/1 solution, not COBOL.
But here is the coding (only the main parts of it ....), may be, it's helpful for anybody.
The complete routine "ReadPDSDirectory" is a submodule with a callback option to provide each entry of the PDS Directory to the calling (main-) routine.
This is the datastructure which provides information for each entry.
Code:
DEFINE STRUCTURE
1 tPDSEntry
, 2 Name UNAL CHAR(8) /* Name of Member */
, 2 Modified UNAL CHAR(26) /* YYYY-MM-DD-SS.MM.SS.NNNNN */
, 2 User UNAL CHAR(8) /* User */
;
In the JCL of the calling main program the PDS files is defined as follows (or do a dynamic definition of the DD Name).
The coding in the main program calls the ReadPDSDirectory module and provides the callback entry which should be called for each PDS Directory entry from the ReadPDSDirectory submodule.
PERFORM 2000-MAIN-PROCESS UNTIL S-EOF-DIRECTORY = 'Y'
PERFORM 3000-WRAPUP
GOBACK
.
1000-INITIALIZATION.
**************************************************************
* THIS PARAGRAPH OPENS INPUT AND OUTPUT FILES AND DOES THE *
* PRIME READ. *
**************************************************************
OPEN INPUT PDS-DATASET.
PERFORM 2500-READ-DIRECTORY
.
2000-MAIN-PROCESS.
*************************************************************
* THIS PARAGRAPH PERFORMS THE MAIN LOGIC OF READING THE PDS *
* DIRECTORY AND EXTRACTING THE USER DATA. *
*************************************************************
MOVE 1 TO WS-OFFSET
PERFORM UNTIL PDS-DIR-LEN - WS-OFFSET < 11
OR PDS-DIR-REC(WS-OFFSET:1) = HIGH-VALUES
PERFORM 2100-PROCESS-MEMBER-DATA
INITIALIZE WS-TTR
MOVE WS-PDS-INDC TO WS-TTR (2:1)
DIVIDE WS-TTR-NUMERIC BY 32 GIVING WS-TRASH
REMAINDER WS-HALF-WORDS
COMPUTE WS-OFFSET = WS-OFFSET + 12 +
WS-HALF-WORDS * 2
END-PERFORM
PERFORM 2500-READ-DIRECTORY
.
2100-PROCESS-MEMBER-DATA.
*************************************************************
* THIS PARAGRAPH PROCESS THE MEMBER DATA. *
*************************************************************
MOVE SPACES TO WS-PDS-DIRECTORY
MOVE PDS-DIR-REC (WS-OFFSET:39)
TO WS-PDS-DIRECTORY
DISPLAY 'MEMBER NAME : ' WS-PDS-MEMBER-NAME
IF WS-PDS-INDC = X'00'
DISPLAY 'NO STATS EXIST FOR MEMBER : '
WS-PDS-MEMBER-NAME
ELSE
PERFORM 2200-CONVERT-DATES
PERFORM 2400-CONVERT-MODIFIED-TIME
DISPLAY 'INITIAL LINES : ' WS-PDS-INITIAL-LINES
DISPLAY 'CURRENT LINES : ' WS-PDS-CURRENT-LINES
DISPLAY 'MODIFIED LINES : ' WS-PDS-MODIFIED-LINES
DISPLAY 'USER ID : ' WS-PDS-USERID
END-IF
DISPLAY '*****************************************'
.
2200-CONVERT-DATES.
*************************************************************
* THIS PARAGRAPH CONVERTS THE CREATE AND MODIFIED DATES TO *
* READABLE FORMAT. *
*************************************************************
MOVE X'000C' TO WS-CHAR-PACKED
MOVE WS-PDS-CREATE-CENTURY TO WS-CHAR-PACKED-BYTE1
MOVE WS-PDS-CREATE-JDATE TO WS-PACKED-DATE
PERFORM 2300-CONV-JDATE-TO-GREGDATE
DISPLAY 'CREATE DATE : '
WS-GREGORIAN-DATE(1:4)
'-'
WS-GREGORIAN-DATE(5:2)
'-'
WS-GREGORIAN-DATE(7:2)
MOVE X'000C' TO WS-CHAR-PACKED
MOVE WS-PDS-MODIFIED-CENTURY TO WS-CHAR-PACKED-BYTE1
MOVE WS-PDS-MODIFIED-JDATE TO WS-PACKED-DATE
PERFORM 2300-CONV-JDATE-TO-GREGDATE
DISPLAY 'MODIFIED DATE : '
WS-GREGORIAN-DATE(1:4)
'-'
WS-GREGORIAN-DATE(5:2)
'-'
WS-GREGORIAN-DATE(7:2)
.
2300-CONV-JDATE-TO-GREGDATE.
*************************************************************
* THIS PARAGRAPH CONVERTS THE INPUT JULIAN DATE TO GREGORIAN*
* DATE. *
*************************************************************
COMPUTE WS-CENTURY = WS-PACKED / 10 + 19
COMPUTE WS-GREGORIAN-DATE = FUNCTION DATE-OF-INTEGER
(FUNCTION INTEGER-OF-DAY
(WS-JULIAN-DATE))
.
2400-CONVERT-MODIFIED-TIME.
*************************************************************
* THIS PARAGRAPH CONVERTS THE MODIFIED TIME TO READABLE *
* FORMAT. *
*************************************************************
MOVE X'000C' TO WS-CHAR-PACKED
MOVE WS-PDS-MODIFIED-HOURS TO WS-CHAR-PACKED-BYTE1
COMPUTE WS-MODIFIED-HH = WS-PACKED / 10
MOVE X'000C' TO WS-CHAR-PACKED
MOVE WS-PDS-MODIFIED-MINUTES TO WS-CHAR-PACKED-BYTE1
COMPUTE WS-MODIFIED-MM = WS-PACKED / 10
MOVE X'000C' TO WS-CHAR-PACKED
MOVE WS-PDS-MODIFIED-SECONDS TO WS-CHAR-PACKED-BYTE1
COMPUTE WS-MODIFIED-SS = WS-PACKED / 10
DISPLAY 'MODIFIED TIME : ' WS-MODIFIED-TIME
.
2500-READ-DIRECTORY.
*************************************************************
* THIS PARAGRAPH READS THE PDS DIRECTORY *
*************************************************************
READ PDS-DATASET
AT END
MOVE 'Y' TO S-EOF-DIRECTORY
END-READ
.
3000-WRAPUP.
*************************************************************
* THIS PARAGRAPH CLOSES THE INPUT & OUTPUT FILES *
***************************************************************
CLOSE PDS-DATASET
.
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
Posted: Tue Jun 10, 2014 6:35 pm Post subject:
bauer wrote:
The complete routine "ReadPDSDirectory" is a submodule with a callback option to provide each entry of the PDS Directory to the calling (main-) routine.
This is the datastructure which provides information for each entry.
bauer,
I don't have much experience with PLI, so I may be I am missing something.
1. Your PDS directory need to RECFM=U instead of RECFM=F
2. Does your program handle members WITHOUT stats? _________________ Kolusu
www.linkedin.com/in/kolusu
I always thought that RECFM=U was required for reading a PDS directory. I recently discovered that RECFM works equally. Others have always used RECFM=F and were surprised that RECFM=U worked As important is the LRECL, which everyone agrees is 256.
Joined: 10 Oct 2003 Posts: 315 Topics: 49 Location: Germany
Posted: Wed Jun 11, 2014 2:44 am Post subject:
kolusu,
according your questions:
1) see line DCL PDS FILE RECORD SEQUENTIAL INPUT ENV(U) ; in the PL/1 coding. Here is RECFM = U But, yes you are right, the JCL provides a different RECFM parameter.
2) yes, this is handled. See code line IF SUBSTR(ISPFStatisticsEntry.Misc,1,3) = '404040'X , according the IBM dokumentation: If this bytes are Blank => statistics data available, otherwise not available.
Remark: My here provided coding are only the most important lines. The real coding contains some additional logic for wildcardsearch, descision for reading SSI Data in case of loadmodule libs (type of libaray is evaluated).
I'm pretty sure that it makes no difference whether RECFM=F or RECFM=U in the JCL or records are Fixed or Undefined in the program. They can even be mixed.
The index consists of individual records each of 256 bytes. Whether F or U, the results (256 bytes of data for every read) are the same. Both F and U work, even in a mixture.
If the index records were blocked, it would be a different thing.
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
Posted: Wed Jun 11, 2014 11:04 am Post subject:
ironponygrl wrote:
thanks fellows, that's awesome. now I can see it clearly and if i ever need to do that, it's here for all perpetuity.
It doesn't hurt to have a copy of it now as I lost a good part of my solutions due to server crash and I had to use a backup which was more than a year old.
William Collins wrote:
I always thought that RECFM=U was required for reading a PDS directory. I recently discovered that RECFM works equally. Others have always used RECFM=F and were surprised that RECFM=U worked As important is the LRECL, which everyone agrees is 256.
William,
There are 2 things
1. JCL override of RECFM=U
2. RECORDING MODE in the Program in FILE SECTION.
It works only if you had
1.If your JCL has RECFM=U and if your Program had RECORDING MODE IS F
2.If your JCL has RECFM=F and if your Program had RECORDING MODE IS U
It fails if you had RECFM=F and the Program ALSO had RECORDING MODE IS F
So if you have in the program defined as
Code:
FD PDS-DATASET
RECORDING MODE IS U
RECORD CONTAINS 256 CHARACTERS
LABEL RECORDS ARE STANDARD.
It doesn't matter what RECFM you use in the JCL
bauer wrote:
So my understanding:
I should add your evaluation of the single byte (your field WS-PDS-INDC, my field Entry.INDIC), if statistics data bytes are in general available.
You should add my evaluation, if the statistics bytes have a really filled content.
bauer
bauer,
Unless I am gravely mistaken, the SUBSTR(ISPFStatisticsEntry.Misc,1,3) check is for EXTENDED statistics and NOT for the regular stats. With extended member statistics ISPF allows to store more than 65,535 lines. That is the reason as to why the field in extended stats are of 4 bytes instead of 2 bytes. _________________ Kolusu
www.linkedin.com/in/kolusu
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum