Search code examples
cobolzos

PDS member list associated with DDNAME


How to get member list of a PDS(using a DD Name specified in a batch job) using a COBOL? It is possible to dynamically process PDS(es) specified using a DDNAME. So Getting a list of PDS(es) for a given DDNAME and processing a specified member name is possible using TCB.

But how to get member list of PDS using COBOL? I Know this can be easily implemented using REXX. But I need it in COBOL or directly callable from COBOL.


Solution

  • If you specify this, with a simple SELECT (include FILE STATUS, of course), you will be able to read a PDS directory.

       FD  INPUT-FILE 
           RECORDING MODE IS U 
           LABEL RECORDS ARE STANDARD. 
       01  INPUT-RECORD. 
           05  FILLER PIC X(256). 
    

    In the JCL you specify the DDName like this:

    //ffffffff DD DISP=OLD,DSN=yourpdsname,
    //            RECFM=U,LRECL=256
    

    You can also change the RECORDING MODE to F in the COBOL program and the RECFM to F in the JCL. Either will work (U(ndefined) or F(ixed)).

    Then you just treat the directory as a normal file.

    However, there are multiple entries per directory block, and you'll need to understand those to be able to use the data.

    Here's a program originally from about 1982. At some point I changed what was originally a GO TO loop to be an inline PERFORM and made other changes for what was then available as new under IBM's VS COBOL II, to the 1985 COBOL Standard.

    EXPANDED-DIRECTORY is a copybook which I've pasted-in for you.

    You CALL the program with the input record, as defined above, and the EXPANDED-DIRECTORY.

    Then, after each CALL, you have access to the members from the current block (if there are any).

       ID DIVISION. 
       PROGRAM-ID. OCDIRBLK. 
       DATA DIVISION. 
       WORKING-STORAGE SECTION. 
       01  LENGTH-UP-DIRECTORY          BINARY PIC 9(4). 
       01  LENGTH-OF-USER-DATA          BINARY PIC 9(4). 
       01  DIRECTORY-DATA-LENGTH        BINARY PIC 9(4). 
       01  HIGH-ORDER-BIT-VALUE         BINARY PIC 9(4) VALUE 128.
       01  BIT-ONE-VALUE                BINARY PIC 9(4) VALUE 64. 
       01  BIT-TWO-VALUE                BINARY PIC 9(4) VALUE 32. 
       01  USER-DATA-LENGTH             BINARY PIC 9(4). 
           88  NO-USER-HALFWORDS               VALUE ZERO. 
           88  SOME-USER-HALFWORDS             VALUE 1 THRU 31. 
           88  MEMBER-HAS-ONE-POINTER          VALUE 32 THRU 63. 
           88  MEMBER-HAS-TWO-POINTERS         VALUE 64 THRU 127. 
           88  MEMBER-IS-AN-ALIAS              VALUE 128 THRU 255.
       01  FILLER REDEFINES USER-DATA-LENGTH. 
           05  FILLER                          PIC X. 
           05  USER-DATA-BYTE                  PIC X. 
       LINKAGE SECTION. 
       01  INPUT-DIRECTORY. 
           05  I-D-LENGTH               BINARY PIC 9(4). 
               88  I-D-NO-MEMBERS              VALUE ZERO. 
           05  FILLER OCCURS 0 TO 252 TIMES 
               DEPENDING ON LENGTH-UP-DIRECTORY 
                                               PIC X. 
           05  I-D-MEMBER-NAME                 PIC X(8). 
               88 I-D-END-OF-BLOCK             VALUE HIGH-VALUES. 
           05  I-D-TRACK-ADDRESS               PIC XXX. 
           05  I-D-INDICATOR                   PIC X. 
           05  I-D-USER-DATA. 
               10  FILLER 
                   OCCURS 0 TO 62 TIMES 
                   DEPENDING ON 
                   LENGTH-OF-USER-DATA. 
                   15  FILLER                  PIC X. 
       01  EXPANDED-DIRECTORY. 
           05  E-D-NUMBER-OF-ENTRIES    BINARY PIC 9(4). 
           05  FILLER OCCURS 22 TIMES. 
               10  E-D-MEMBER-NAME             PIC X(8). 
               10  E-D-TRACK-ADDRESS           PIC X(3). 
               10  E-D-INDICATOR               PIC X(1). 
               10  E-D-ALIAS-FLAG              PIC X. 
                   88  E-D-ALIAS               VALUE "Y". 
                   88  E-D-ALIAS-NOT           VALUE "N". 
               10  E-D-NO-OF-POINTERS          PIC 9. 
               10  E-D-USER-DATA               PIC X(62). 
       PROCEDURE DIVISION               USING 
                                              INPUT-DIRECTORY 
                                              EXPANDED-DIRECTORY 
                                              . 
    
           IF I-D-NO-MEMBERS 
               MOVE ZERO                TO DIRECTORY-DATA-LENGTH 
           ELSE 
               SUBTRACT +2              FROM I-D-LENGTH 
                 GIVING                 DIRECTORY-DATA-LENGTH 
           END-IF 
    
           MOVE ZERO                    TO E-D-NUMBER-OF-ENTRIES 
                                           LENGTH-UP-DIRECTORY 
           PERFORM UNTIL ( LENGTH-UP-DIRECTORY 
                 NOT LESS THAN DIRECTORY-DATA-LENGTH ) 
                     OR ( I-D-END-OF-BLOCK ) 
               ADD 1                    TO E-D-NUMBER-OF-ENTRIES 
               MOVE I-D-MEMBER-NAME     TO E-D-MEMBER-NAME 
                                            ( E-D-NUMBER-OF-ENTRIES ) 
               MOVE I-D-TRACK-ADDRESS   TO E-D-TRACK-ADDRESS 
                                            ( E-D-NUMBER-OF-ENTRIES ) 
               MOVE I-D-INDICATOR       TO E-D-INDICATOR 
                                            ( E-D-NUMBER-OF-ENTRIES ) 
                                               USER-DATA-BYTE 
               MOVE ZERO                TO E-D-NO-OF-POINTERS 
                                            ( E-D-NUMBER-OF-ENTRIES ) 
               IF MEMBER-IS-AN-ALIAS 
                   SET E-D-ALIAS ( E-D-NUMBER-OF-ENTRIES ) 
                                        TO TRUE 
                   SUBTRACT HIGH-ORDER-BIT-VALUE 
                                        FROM USER-DATA-LENGTH 
               ELSE 
                   SET E-D-ALIAS-NOT ( E-D-NUMBER-OF-ENTRIES ) 
                                        TO TRUE 
               END-IF 
               IF MEMBER-HAS-TWO-POINTERS 
                   MOVE 2               TO E-D-NO-OF-POINTERS 
                                            ( E-D-NUMBER-OF-ENTRIES )
                   SUBTRACT BIT-ONE-VALUE 
                                        FROM USER-DATA-LENGTH 
               END-IF 
               IF MEMBER-HAS-ONE-POINTER 
                   ADD 1                TO E-D-NO-OF-POINTERS 
                                            ( E-D-NUMBER-OF-ENTRIES )
                   SUBTRACT BIT-TWO-VALUE 
                                        FROM USER-DATA-LENGTH 
               END-IF 
               IF SOME-USER-HALFWORDS 
                   MULTIPLY USER-DATA-LENGTH BY 2 
                    GIVING              LENGTH-OF-USER-DATA 
                   MOVE I-D-USER-DATA   TO E-D-USER-DATA 
                                            ( E-D-NUMBER-OF-ENTRIES )
                   ADD LENGTH-OF-USER-DATA TO LENGTH-UP-DIRECTORY 
               ELSE 
                   MOVE SPACE           TO E-D-USER-DATA 
                                            ( E-D-NUMBER-OF-ENTRIES )
                   MOVE ZERO            TO LENGTH-OF-USER-DATA 
               END-IF 
               ADD 12                   TO LENGTH-UP-DIRECTORY 
           END-PERFORM 
           GOBACK 
           . 
    

    Here's an example of a program reading a PDS/PDSE directory, and using OCDIRBLK as a contained/nested/embedded program.

       IDENTIFICATION DIVISION. 
       PROGRAM-ID. STOB30. 
       ENVIRONMENT DIVISION. 
       INPUT-OUTPUT SECTION. 
       FILE-CONTROL. 
    
            SELECT INPUT-FILE ASSIGN TO PDSIND 
               FILE STATUS IS W-PDSIND-FILE-STATUS. 
    
       DATA DIVISION. 
       FILE SECTION. 
       FD         INPUT-FILE 
           RECORDING MODE IS U 
           RECORD IS VARYING FROM 1 TO 256 DEPENDING ON 
           W-RECORD-LENGTH 
           LABEL RECORDS ARE STANDARD. 
       01  INPUT-RECORD. 
           05  FILLER PIC X(252). 
       WORKING-STORAGE SECTION. 
       01  W-THIS-PROGRAM                      PIC X(9) VALUE 
                                                         "STOB30".
       01  W-WHEN-COMPILED                     PIC X(8)BX(8). 
       01  W-RECORD-LENGTH              BINARY PIC 9(8). 
       01  W-PDSIND-FILE-STATUS                PIC XX. 
           88  W-PDSIND-FILE-STATUS-OK         VALUE ZERO "10". 
           88  W-END-OF-INPUT-PDSIND           VALUE "10". 
       01  EXPANDED-DIRECTORY. 
           05  E-D-NUMBER-OF-ENTRIES    BINARY PIC 9(4). 
           05  FILLER 
               OCCURS 22 TIMES 
               INDEXED BY E-D-IND. 
               10  E-D-MEMBER-NAME             PIC X(8). 
               10  E-D-TRACK-ADDRESS           PIC X(3). 
               10  E-D-INDICATOR               PIC X(1). 
               10  E-D-ALIAS-FLAG              PIC X. 
                   88  E-D-ALIAS               VALUE "Y". 
                   88  E-D-ALIAS-NOT           VALUE "N". 
               10  E-D-NO-OF-POINTERS          PIC 9. 
               10  E-D-USER-DATA               PIC X(62). 
       PROCEDURE DIVISION. 
           PERFORM                      00-START-UP 
           PERFORM                      10-INTIAL-FILE-PROCESSING 
           PERFORM UNTIL W-END-OF-INPUT-PDSIND 
               CALL "OCDIRBLK"          USING INPUT-RECORD 
                                              EXPANDED-DIRECTORY 
               SET E-D-IND              TO 1 
               PERFORM E-D-NUMBER-OF-ENTRIES TIMES 
                  DISPLAY 
                          E-D-MEMBER-NAME ( E-D-IND ) 
                  SET E-D-IND           UP BY 1 
               END-PERFORM 
               PERFORM                  99A-READ-INPUT-FILE 
           END-PERFORM 
           PERFORM                      30-FINALISE-INPUT-PROCESSING
           GOBACK 
           . 
       00-START-UP. 
           MOVE WHEN-COMPILED           TO W-WHEN-COMPILED 
           DISPLAY 
                   W-THIS-PROGRAM 
                   " COMPILED ON " 
                   W-WHEN-COMPILED 
           . 
       10-INTIAL-FILE-PROCESSING. 
           OPEN INPUT INPUT-FILE 
           IF NOT W-PDSIND-FILE-STATUS-OK 
               DISPLAY W-THIS-PROGRAM " DODGY PDSIND OPEN STATUS " 
                       ">" W-PDSIND-FILE-STATUS "<" 
               CALL "BBDUMP" 
           END-IF 
    
           PERFORM                      10A-PRIMING-READ 
           . 
       10A-PRIMING-READ. 
           PERFORM                      99A-READ-INPUT-FILE 
           . 
       30-FINALISE-INPUT-PROCESSING. 
           CLOSE INPUT-FILE 
           IF NOT W-PDSIND-FILE-STATUS-OK 
               DISPLAY W-THIS-PROGRAM " DODGY PDSIND CLOSE STATUS "
                       ">" W-PDSIND-FILE-STATUS "<" 
               CALL "BBDUMP" 
           END-IF 
           . 
       99A-READ-INPUT-FILE. 
           IF  W-END-OF-INPUT-PDSIND 
                DISPLAY "YOIKS" 
           END-IF 
           READ INPUT-FILE 
           IF NOT W-PDSIND-FILE-STATUS-OK 
               DISPLAY W-THIS-PROGRAM " DODGY PDSIND READ " 
                       ">" W-PDSIND-FILE-STATUS "<" 
               CALL "BBDUMP" 
           END-IF 
           . 
       IDENTIFICATION DIVISION. 
       PROGRAM-ID. OCDIRBLK. 
       DATA DIVISION. 
       WORKING-STORAGE SECTION. 
       01  LENGTH-UP-DIRECTORY          BINARY PIC 9(4). 
       01  LENGTH-OF-USER-DATA          BINARY PIC 9(4). 
       01  DIRECTORY-DATA-LENGTH        BINARY PIC 9(4). 
       01  HIGH-ORDER-BIT-VALUE         BINARY PIC 9(4) VALUE 128. 
       01  BIT-ONE-VALUE                BINARY PIC 9(4) VALUE 64. 
       01  BIT-TWO-VALUE                BINARY PIC 9(4) VALUE 32. 
       01  USER-DATA-LENGTH             BINARY PIC 9(4). 
           88  NO-USER-HALFWORDS               VALUE ZERO. 
           88  SOME-USER-HALFWORDS             VALUE 1 THRU 31. 
           88  MEMBER-HAS-ONE-POINTER          VALUE 32 THRU 63. 
           88  MEMBER-HAS-TWO-POINTERS         VALUE 64 THRU 127. 
           88  MEMBER-IS-AN-ALIAS              VALUE 128 THRU 255. 
       01  FILLER REDEFINES USER-DATA-LENGTH. 
           05  FILLER                          PIC X. 
           05  USER-DATA-BYTE                  PIC X. 
       LINKAGE SECTION. 
       01  INPUT-DIRECTORY. 
           05  I-D-LENGTH               BINARY PIC 9(4). 
               88  I-D-NO-MEMBERS              VALUE ZERO. 
           05  FILLER OCCURS 0 TO 252 TIMES 
               DEPENDING ON LENGTH-UP-DIRECTORY 
                                               PIC X. 
           05  I-D-MEMBER-NAME                 PIC X(8). 
               88 I-D-END-OF-BLOCK             VALUE HIGH-VALUES.
           05  I-D-TRACK-ADDRESS               PIC XXX. 
           05  I-D-INDICATOR                   PIC X. 
           05  I-D-USER-DATA. 
               10  FILLER 
                   OCCURS 0 TO 62 TIMES 
                   DEPENDING ON 
                   LENGTH-OF-USER-DATA. 
                   15  FILLER                  PIC X. 
       01  EXPANDED-DIRECTORY. 
           05  E-D-NUMBER-OF-ENTRIES    BINARY PIC 9(4). 
           05  FILLER OCCURS 22 TIMES. 
               10  E-D-MEMBER-NAME             PIC X(8). 
               10  E-D-TRACK-ADDRESS           PIC X(3). 
               10  E-D-INDICATOR               PIC X(1). 
               10  E-D-ALIAS-FLAG              PIC X. 
                   88  E-D-ALIAS               VALUE "Y". 
                   88  E-D-ALIAS-NOT           VALUE "N". 
               10  E-D-NO-OF-POINTERS          PIC 9. 
               10  E-D-USER-DATA               PIC X(62). 
       PROCEDURE DIVISION               USING 
                                              INPUT-DIRECTORY 
                                              EXPANDED-DIRECTORY 
                                              . 
    
           IF I-D-NO-MEMBERS 
               MOVE ZERO                TO DIRECTORY-DATA-LENGTH 
           ELSE 
               SUBTRACT +2              FROM I-D-LENGTH 
                 GIVING                 DIRECTORY-DATA-LENGTH 
           END-IF 
    
           MOVE ZERO                    TO E-D-NUMBER-OF-ENTRIES 
                                           LENGTH-UP-DIRECTORY 
           PERFORM UNTIL ( LENGTH-UP-DIRECTORY 
                 NOT LESS THAN DIRECTORY-DATA-LENGTH ) 
                     OR ( I-D-END-OF-BLOCK ) 
               ADD 1                    TO E-D-NUMBER-OF-ENTRIES 
               MOVE I-D-MEMBER-NAME     TO E-D-MEMBER-NAME 
                                            ( E-D-NUMBER-OF-ENTRIES )
               MOVE I-D-TRACK-ADDRESS   TO E-D-TRACK-ADDRESS 
                                            ( E-D-NUMBER-OF-ENTRIES )
               MOVE I-D-INDICATOR       TO E-D-INDICATOR 
                                            ( E-D-NUMBER-OF-ENTRIES )
                                               USER-DATA-BYTE 
               MOVE ZERO                TO E-D-NO-OF-POINTERS 
                                            ( E-D-NUMBER-OF-ENTRIES )
               IF MEMBER-IS-AN-ALIAS 
                   SET E-D-ALIAS ( E-D-NUMBER-OF-ENTRIES ) 
                                        TO TRUE 
                   SUBTRACT HIGH-ORDER-BIT-VALUE 
                                        FROM USER-DATA-LENGTH 
               ELSE 
                   SET E-D-ALIAS-NOT ( E-D-NUMBER-OF-ENTRIES ) 
                                        TO TRUE 
               END-IF 
               IF MEMBER-HAS-TWO-POINTERS 
                   MOVE 2               TO E-D-NO-OF-POINTERS 
                                            ( E-D-NUMBER-OF-ENTRIES )
                   SUBTRACT BIT-ONE-VALUE 
                                        FROM USER-DATA-LENGTH 
               END-IF 
               IF MEMBER-HAS-ONE-POINTER 
                   ADD 1                TO E-D-NO-OF-POINTERS 
                                            ( E-D-NUMBER-OF-ENTRIES )
                   SUBTRACT BIT-TWO-VALUE 
                                        FROM USER-DATA-LENGTH 
               END-IF 
               IF SOME-USER-HALFWORDS 
                   MULTIPLY USER-DATA-LENGTH BY 2 
                    GIVING              LENGTH-OF-USER-DATA 
                   MOVE I-D-USER-DATA   TO E-D-USER-DATA 
                                            ( E-D-NUMBER-OF-ENTRIES )
                   ADD LENGTH-OF-USER-DATA TO LENGTH-UP-DIRECTORY 
               ELSE 
                   MOVE SPACE           TO E-D-USER-DATA 
                                            ( E-D-NUMBER-OF-ENTRIES )
                   MOVE ZERO            TO LENGTH-OF-USER-DATA 
               END-IF 
               ADD 12                   TO LENGTH-UP-DIRECTORY 
           END-PERFORM 
           GOBACK 
           . 
       END PROGRAM OCDIRBLK. 
       END PROGRAM STOB30. 
    

    Here's an example of the JCL:

    //LISTDIR EXEC PGM=STOB30,TIME=(,2)
    //STEPLIB DD DSN=yours as necessary
    //SYSOUT DD SYSOUT=* for the DISPLAY output 
    //PDSIND DD DSN=your pds/pdse,
    // DISP=SHR,LRECL=256,RECFM=U
    

    Note, whilst setting up the JCL I didn't include the RECFM=U (by accident). Ran clean producing the correct results with a RECFM=FB,LRECL=80 PDS and a RECFM=U PDSE.

    This surprised me. Your mileage may vary.