***********************************************************************
* Licensed Material - Property of IBM                                 *
* 5639-B92 , 5648-A25 , 5688-197 , 5639-D65 , 5688-235                *
* (C) Copyright IBM Corp., 1997, 1998                                 *
* All rights reserved.                                                *
* US Government Users Restricted Rights - Use, duplication or         *
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.   *
***********************************************************************
         SPACE
***********************************************************************
*                                                                     *
* Name: IGYFSAVE                                                      *
*                                                                     *
* Attributes:                                                         *
*                                                                     *
*   Addressing mode (AMODE) - 31                                      *
*   Residency mode (RMODE)  - 24 this is due to having data control   *
*     blocks that must reside below 16 megabytes                      *
*   Not reusable                                                      *
*   Not reentrant                                                     *
*   Requires for assembly an assembler that supports the 31 bit       *
*     addressing instructions, such as the H assembler or the         *
*     IBM High Level Assembler                                        *
*   Should be link edited by itself with IGYFSAVE as the entry point  *
*                                                                     *
* Function:                                                           *
*                                                                     *
*   To copy the temporary file created by the LPEX save into the      *
*   permanent file.  IGYFSAVE insures that the temporary file has     *
*   the correct data set characteristics (RECFM and LRECL), number    *
*   of records and timestamp record as specified by the input.        *
*   IGYFSAVE is intended to be called by the IGYFMSAV REXX procedure  *
*   located in the SIGYCLST data set.                                 *
*                                                                     *
* Processing:                                                         *
*                                                                     *
*   - perform standard linkage (save caller registers, etc.)          *
*   - insure input parameters are correct                             *
*   - GETMAIN main memory to hold all the temporary file records      *
*   - Zero count of records read, open the temporary file and         *
*     insure it has the expected characteristics (RECFM and LRECL)    *
*   - read all the temporary file records into main memory (does      *
*     not read beyond the expected number of records)                 *
*   - close the temporary file                                        *
*   - check that the number of records read matchs the expected       *
*     number of records                                               *
*   - check that the timestamp record (if present) matches the        *
*     expected timestamp                                              *
*   - open the permanent file                                         *
*   - write the read records to the permanent file (except for        *
*     the timestamp record)                                           *
*   - close the permanent file                                        *
*   - FREEMAIN main memory                                            *
*   - set return code register 15                                     *
*   - restore caller save area and registers and return to caller     *
*                                                                     *
*   Note that control flows strictly from top to bottom except for    *
*   the loop to read records (label LOOP) and the loop to write       *
*   records (label OLOOP).                                            *
*                                                                     *
* Register Usage:                                                     *
*                                                                     *
*    6 - number of records read                                       *
*    7 - for input the location where to save the next record, for    *
*        output the location of the next record to be written         *
*    8 - location of the last record read (before it was saved)       *
*   10 - location where the last record read was saved                *
*   11 - based register to DCB addressibility for IHADCB DSECT        *
*   12 - base register for IGYFSAVE addressibility                    *
*   13 - address of standard register save area                       *
*                                                                     *
* System Macros Used:                                                 *
*                                                                     *
*   GETMAIN - get main memory                                         *
*   FREEMAIN - free main memory                                       *
*   OPEN - open the temporary or permanent file                       *
*   CLOSE - close the temporary or permanent file                     *
*   GET - read a record from the temporary file                       *
*   PUT - write a record to the permanent file                        *
*                                                                     *
* Input:                                                              *
*                                                                     *
*   Register 1 points to a one word parameter list that points        *
*   to the standard JCL PARM= parameters, namely a halfword           *
*   containing the length of the following parameters followed by     *
*   the parameters of the form:                                       *
*                                                                     *
*   RR.LLLLL.NNNNNNNN.TTTTTTTTTTTT                                    *
*                                                                     *
*   where:                                                            *
*                                                                     *
*   RR - the expected record format (RECFM) or the temporary file.    *
*        This must be FB or VB.                                       *
*                                                                     *
*   LLLLL - the expected logical record length of the temporary       *
*           file.                                                     *
*                                                                     *
*   NNNNNNNN - the expected number of records in the temporary file.  *
*                                                                     *
*   TTTTTTTTTTTT - the expected timestamp value in the timestamp      *
*                  record.                                            *
*                                                                     *
*   Note: a timestamp record is created as the last record (and       *
*   included in the count of expected number of records) if either    *
*   the RECFM=FB and the LRECL is at least 12 or the RECFM=VB         *
*   and the LRECL is at least 16.                                     *
*                                                                     *
*   Register 13 points to the callers register save area              *
*   Register 14 points to the address in the caller where to          *
*     return control                                                  *
*   Register 15 points to the IGYFSAVE entry point (the start         *
*     of the CSECT)                                                   *
*                                                                     *
* Data Sets:                                                          *
*                                                                     *
*   IGYFSAVI - identfies the temporary file.                          *
*                                                                     *
*   IGYFSAVO - identfies the permanent file which should be a member  *
*              of a PDS or PDSE.                                      *
*                                                                     *
* Return codes: (note: the actual return code in register 15 is       *
*   increased by 100 to allow the caller to distiguish return codes   *
*   from IGYFSAVE versus return code from the TSO CALL command used   *
*   to invoke IGYFSAVE)                                               *
*                                                                     *
*   16 - the length of the parameters was not at least 30.            *
*                                                                     *
*   20 - the parameters were invalid: RR not FB or VB, LLLLL was      *
*        zero or NNNNNN was zero but a timstamp record should be      *
*        present, LLLLL wwas not all digits or NNNNNN was not all     *
*        digits.                                                      *
*                                                                     *
*   24 - the amount of storage to hold all the records is greater     *
*        than or equal to 2 gigabytes or storage could not            *
*        be obtained to hold all records (GETMAIN failed).            *
*                                                                     *
*   28 - the temporary file does not have the expected RECFM or       *
*        LRECL.  This can be caused by using an incorrect version     *
*        of the NFS client.                                           *
*                                                                     *
*   32 - the temporary file does not have the expected number of      *
*        records.  This can be caused by the file system (NFS or      *
*        SdU) failing to write all of the data to the temporary       *
*        file.                                                        *
*                                                                     *
*   36 - the temporary file timestamp records does not have the       *
*        expected timestamp.  This can be caused by the file system   *
*        (NFS or SdU) failing to write all of the data to the         *
*        temporary file.                                              *
*                                                                     *
*   40 - could not open either the temporary file (IGYFSAVI) or       *
*        the permanent file (IGYFSAVO).  This is probably due to      *
*        the caller failing to allocate the file.                     *
*                                                                     *
* Error exits: If IGYFSAVE abends due to lack space on the permanent  *
*   file and that file is a member of a PDS or PDSE, then the         *
*   original contents of the member are presered by the system.       *
*                                                                     *
***********************************************************************
         EJECT
IGYFSAVE AMODE 31
IGYFSAVE CSECT
***********************************************************************
*                                                                     *
* Perform standard linkage (save caller registers, etc.)              *
*                                                                     *
***********************************************************************
         STM   14,12,12(13)
         LR    12,15
         USING IGYFSAVE,12
         USING IHADCB,11
         ST    13,SAVE+4
         LA    15,SAVE
         ST    15,8(0,13)
         LR    13,15
***********************************************************************
*                                                                     *
* Insure input parameters are correct                                 *
*                                                                     *
***********************************************************************
         L     2,0(0,1)
         LH    3,0(0,2)
         C     3,LENPARMS
         BNL   OKPARML
         LA    0,16
         ST    0,RCODE
         B     EXIT
OKPARML  DS    0H
         MVC   PARMS(EPARMS-PARMS),2(2)
         CLC   RECFM,RECFMFB
         BE    OKRECFM
         CLC   RECFM,RECFMVB
         BE    OKRECFM
         LA    0,20
         ST    0,RCODE
         B     EXIT
OKRECFM  DS    0H
         TRT   LRECLC,DIGITS
         BZ    LRECLN
         LA    0,20
         ST    0,RCODE
         B     EXIT
LRECLN   DS    0H
         PACK  DBLWORD,LRECLC
         CVB   0,DBLWORD
         LTR   0,0
         BP    OKLRECL
         LA    0,20
         ST    0,RCODE
         B     EXIT
OKLRECL  DS    0H
         ST    0,LRECL
         TRT   NUMRECC,DIGITS
         BZ    NUMRECN
         LA    0,20
         ST    0,RCODE
         B     EXIT
NUMRECN  DS    0H
         PACK  DBLWORD,NUMRECC
         CVB   0,DBLWORD
         L     1,LRECL
         CLC   RECFM,RECFMFB
         BNE   TIMVB
         C     1,F12
         BL    OKNUMREC
         B     TESTNUM
TIMVB    DS    0H
         C     1,F16
         BL    OKNUMREC
TESTNUM  DS    0H
         LTR   0,0
         BP    OKNUMREC
         LA    0,20
         ST    0,RCODE
         B     EXIT
OKNUMREC DS    0H
         ST    0,NUMREC
         L     1,LRECL
         M     0,NUMREC
         LTR   0,0
         BZ    OKLEN1
         LA    0,24
         ST    0,RCODE
         B     EXIT
OKLEN1   DS    0H
         ST    1,FULLWORD
         TM    FULLWORD,B'10000000'
         BZ    OKLEN2
         LA    0,24
         ST    0,RCODE
         B     EXIT
OKLEN2   DS    0H
***********************************************************************
*                                                                     *
* GETMAIN main memory to hold all the temporary file records          *
*                                                                     *
***********************************************************************
         LR    3,1
         A     3,F7
         SRL   3,3
         SLL   3,3
         ST    3,STORLEN
         GETMAIN RC,LV=(3),LOC=ANY
         LTR   15,15
         BZ    OKGETM
         LA    0,24
         ST    0,RCODE
         B     EXIT
OKGETM   DS    0H
         ST    1,STORADDR
         LR    7,1
***********************************************************************
*                                                                     *
* Zero count of records read, open the temporary file and             *
* insure it has the expected characteristics (RECFM and LRECL)        *
*                                                                     *
***********************************************************************
         SR    6,6
         OPEN  (TEMPFILE,(INPUT)),MODE=31
         LA    11,TEMPFILE
         TM    DCBOFLGS,DCBOFOPN
         BO    OKOPENT
         LA    0,40
         ST    0,RCODE
         B     EXIT
OKOPENT  DS    0H
         LH    4,DCBLRECL
         C     4,LRECL
         BE    OKLRECLF
         LA    0,28
         ST    0,RCODE
         CLOSE (TEMPFILE),MODE=31
         B     EXIT
OKLRECLF DS    0H
         TM    DCBRECFM,DCBRECBR
         BNO   BADRECFM
         CLC   RECFM,RECFMFB
         BNE   TRYVB
         TM    DCBRECFM,DCBRECF
         BNO   BADRECFM
         TM    DCBRECFM,DCBRECV
         BNZ   BADRECFM
         B     OKRECFMF
TRYVB    DS    0H
         TM    DCBRECFM,DCBRECF
         BNZ   BADRECFM
         TM    DCBRECFM,DCBRECV
         BNO   BADRECFM
         B     OKRECFMF
BADRECFM DS    0H
         LA    0,28
         ST    0,RCODE
         CLOSE (TEMPFILE),MODE=31
         B     EXIT
OKRECFMF DS    0H
***********************************************************************
*                                                                     *
* Read all the temporary file records into main memory (does          *
* not read beyond the expected number of records)                     *
*                                                                     *
***********************************************************************
LOOP     DS    0H
         GET   TEMPFILE
         LR    8,1
         LA    6,1(0,6)
         C     6,NUMREC
         BNH   OKREC
         LA    0,32
         ST    0,RCODE
         CLOSE (TEMPFILE),MODE=31
         B     EXIT
OKREC    DS    0H
         LR    10,7
         CLC   RECFM,RECFMFB
         BNE   MOVEVB
         LR    2,7
         L     3,LRECL
         LR    4,8
         LR    5,3
         MVCL  2,4
         A     7,LRECL
         B     ELOOP
MOVEVB   DS    0H
         LR    2,7
         LH    3,0(0,8)
         LR    4,8
         LR    5,3
         LR    9,5
         MVCL  2,4
         AR    7,9
ELOOP    DS    0H
         B     LOOP
***********************************************************************
*                                                                     *
* Close the temporary file                                            *
*                                                                     *
***********************************************************************
ENDFILE  DS    0H
         CLOSE (TEMPFILE),MODE=31
***********************************************************************
*                                                                     *
* Check that the number of records read matchs the expected           *
* number of records                                                   *
*                                                                     *
***********************************************************************
         C     6,NUMREC
         BE    TESTTIME
         LA    0,32
         ST    0,RCODE
         B     EXIT
***********************************************************************
*                                                                     *
* Check that the timestamp record (if present) matches the            *
* expected timestamp                                                  *
*                                                                     *
***********************************************************************
TESTTIME DS    0H
         CLC   RECFM,RECFMFB
         BNE   TIMEVB
         L     0,LRECL
         C     0,F12
         BL    NOTIME
         CLC   TIMESTMP,0(10)
         BE    UPDATE
         LA    0,36
         ST    0,RCODE
         B     EXIT
TIMEVB   DS    0H
         L     0,LRECL
         C     0,F16
         BL    NOTIME
         CLC   TIMESTMP,4(10)
         BE    UPDATE
         LA    0,36
         ST    0,RCODE
         B     EXIT
NOTIME   MVI   USETIME,C'N'
UPDATE   DS    0H
***********************************************************************
*                                                                     *
* Open the permanent file                                             *
*                                                                     *
***********************************************************************
         OPEN  (PERMFILE,(OUTPUT)),MODE=31
         LA    11,PERMFILE
         TM    DCBOFLGS,DCBOFOPN
         BO    OKOPENP
         LA    0,40
         ST    0,RCODE
         B     EXIT
OKOPENP  DS    0H
         L     7,STORADDR
         SR    6,6
***********************************************************************
*                                                                     *
* Write the read records to the permanent file (except for            *
* the timestamp record)                                               *
*                                                                     *
***********************************************************************
OLOOP    DS    0H
         LA    6,1(0,6)
         CLI   USETIME,C'N'
         BE    USEALL
         C     6,NUMREC
         BNL   ENDOUT
         B     PUTREC
USEALL   DS    0H
         C     6,NUMREC
         BH    ENDOUT
PUTREC   DS    0H
         PUT   PERMFILE,(7)
         CLC   RECFM,RECFMFB
         BNE   NEXTVB
         A     7,LRECL
         B     EOLOOP
NEXTVB   DS    0H
         AH    7,0(0,7)
EOLOOP   DS    0H
         B     OLOOP
ENDOUT   DS    0H
***********************************************************************
*                                                                     *
* Close the permanent file                                            *
*                                                                     *
***********************************************************************
         CLOSE (PERMFILE),MODE=31
         SR    0,0
         ST    0,RCODE
EXIT     DS    0H
***********************************************************************
*                                                                     *
* FREEMAIN main memory                                                *
*                                                                     *
***********************************************************************
         L     2,STORADDR
         LTR   2,2
         BZ    NOFREE
         L     3,STORLEN
         FREEMAIN RC,LV=(3),A=(2)
NOFREE   DS    0H
***********************************************************************
*                                                                     *
* Set return code register 15                                         *
*                                                                     *
***********************************************************************
         L     15,RCODE
         LA    15,100(0,15)
***********************************************************************
*                                                                     *
* Restore caller save area and registers and return to caller         *
*                                                                     *
***********************************************************************
         L     13,SAVE+4
         L     14,12(0,13)
         LM    0,12,20(13)
         BR    14
         EJECT
***********************************************************************
*                                                                     *
* Variables                                                           *
*                                                                     *
***********************************************************************
SAVE     DS    18F
DBLWORD  DS    D
FULLWORD DS    F
RCODE    DC    F'44'              Should never end up with a 44
STORLEN  DC    F'0'
STORADDR DC    A(0)
LRECL    DS    F
NUMREC   DS    F
PARMS    DS    0C
RECFM    DS    CL2
         DS    C
LRECLC   DS    CL5
         DS    C
NUMRECC  DS    CL8
         DS    C
TIMESTMP DS    CL12
EPARMS   DS    0C
USETIME  DC    C'Y'
         EJECT
***********************************************************************
*                                                                     *
* Constants                                                           *
*                                                                     *
***********************************************************************
F7       DC    F'7'
F12      DC    F'12'
F16      DC    F'16'
LENPARMS DC    A(EPARMS-PARMS)
RECFMFB  DC    CL2'FB'
RECFMVB  DC    CL2'VB'
DIGITS   DS    0C                 TRT table to determine digits 0-9
         DC    240AL1(1)
         DC    10AL1(0)
         DC    6AL1(1)
         EJECT
***********************************************************************
*                                                                     *
* Data Control Blocks (DCB) for I/O                                   *
*                                                                     *
***********************************************************************
TEMPFILE DCB   DDNAME=IGYFSAVI,DSORG=PS,MACRF=GL,EODAD=ENDFILE
PERMFILE DCB   DDNAME=IGYFSAVO,DSORG=PS,MACRF=PM
         DCBD DSORG=PS,DEVD=DA
         END
