Google
 

Trailing-Edge - PDP-10 Archives - BB-L054E-RK - apxchk.b36
There is 1 other file named apxchk.b36 in the archive. Click here to see a list.
MODULE APXCHK (
		LANGUAGE(BLISS36),
		ENTRY (
			INS_INIT_FILES,
			RES_INIT_FILES,
			BACKUP,
			REPLACE,
			REVERT,
			BCHECK,
			ICHECK,
			RCHECK,
			SCHECK,
			CK_BATCH
				)
		) =
BEGIN

!
!                   COPYRIGHT (c) 1980, 1982 BY
!           Digital Equipment Corporation, Maynard, MA.
!
!   This software is furnished under a license and may be  used
!   and  copied  only  in  accordance  with  the  terms of such
!   license and with  the  inclusion  of  the  above  copyright
!   notice.   This software or any other copies thereof may not
!   be provided  or  otherwise  made  available  to  any  other
!   person.   No  title  to  and  ownership  of the software is
!   hereby transferred.
!
!   The information in  this  software  is  subject  to  change
!   without  notice and should not be construed as a commitment
!   by Digital Equipment Corporation.
!
!   Digital  assumes  no  responsibility   for   the   use   or
!   reliability  of  its  software  on  equipment  which is not
!   supplied by Digital.
!

!++
! FACILITY:
!
!   Autopatch Exec File Verification Support Routines
!
! ABSTRACT:
!
!
!
!
! ENVIRONMENT: TOPS-20 / TOPS-10
!
! AUTHOR: Donald R. Brandt, CREATION DATE: 13 May 1980
!
! MODIFIED BY:
!
!	Revision history follows
!
!--

!
! Edit History for APXCHK
!

!070 by ESB on 15-Jun-82
!	Define logical names for the product before processing the batch
!	communication file.
!
!071 by ESB on 23-Jun-82
!	In BCHECK and SCHECK, don't give an error if the BLD file does
!	not exist.
!
!110 by RBW on 22-Aug-83
!	In BCHECK, don't abort if utility files are protected.  Also
!	eliminated multply defined symbol errors for $CHLFD, $CHCRT, $CHFFD.

GLOBAL BIND EDTCHK = %O'107' ;		! Edit level of this module
!
! TABLE OF CONTENTS:
!

FORWARD ROUTINE

    INS_INIT_FILES,			!Init files for INSTALL
    RES_INIT_FILES,			!Init files for RESTORE
    BACKUP,				!Backup a product
    REPLACE,				!Replace a product
    REVERT,				!Restore a product
    BCHECK,				!BUILD process checking
    ICHECK,				!INSTALL process checking
    RCHECK,				!RESTORE process checking
    SCHECK,				!SELECT process checking
    CK_BATCH,				!Check status of batch job
    UPDATE ;				!Update descriptors after batch

!
! INCLUDE FILES:
!

LIBRARY 'BLI:TENDEF'	;		!PDP-10 Definitions
UNDECLARE			![106]	 Undeclare multiply defined symbols
    $CHLFD,
    $CHCRT,
    $CHFFD		;
LIBRARY 'BLI:MONSYM'	;		!TOPS-20 Monitor Symbols
LIBRARY 'APEX'		;		!APEX definitions
LIBRARY 'BLSPAR'	;		!BLISS parser macros
LIBRARY 'DEBUG'		;		!Debugging macros

!
! EXTERNAL REFERENCES:
!

GLOBAL BIND EDTAPX = APEX_EDT ;		! Edit level of APEX.R36


!
!  The BLISS interface routines to the GALAXY library
!   These are defined in BLSGLX.B36
!

EXTERNAL ROUTINE $K_SOUT ;		!String output routine
EXTERNAL ROUTINE $M_GMEM ;		!Memory allocation routine
EXTERNAL ROUTINE $FMT$NUM ;		!Format a number
 
!
!  APEX support routines
!
 
EXTERNAL ROUTINE CLOSE ;		!Close a file
EXTERNAL ROUTINE CK_FILE ;		!Check validity of a file
EXTERNAL ROUTINE PCK_FILE;	![106]	 Tolerate protection violation
EXTERNAL ROUTINE CKW_FILE ;		!Check writeability of a file
EXTERNAL ROUTINE SCK_FILE ;		!Silently check file
EXTERNAL ROUTINE FILE_COPY ;		!Make a copy of a file
EXTERNAL ROUTINE GET_BYTES ;		!Get bytes from a file
EXTERNAL ROUTINE OPEN_I ;		!Open a file for input
EXTERNAL ROUTINE UPD_FILE ;		!Update a file version and cksum

EXTERNAL ROUTINE GET_VALUE ;		!Get item value from TBLUK table
EXTERNAL ROUTINE T_LOOKUP ;		!Lookup entry in a table
EXTERNAL ROUTINE A_LOOKUP ;		!Lookup address in a table
EXTERNAL ROUTINE A_ENTER ;		!Enter address/value in a table
EXTERNAL ROUTINE CHANGE_PS ;		!Change patch status
EXTERNAL ROUTINE DEF_LN ;		![070] Define logical names
GLOBAL ROUTINE INS_INIT_FILES(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   Here to initialize the files with the proper  status  prior
!   to INSTALL processing.
!
!   The following files are initialized:
!
!	libraries
!	component output files
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 for the product to be INSTALLed
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!   Changes FILE_STATUS field in file descriptor.
!
! ROUTINE VALUE:
!
!	Always returns TRUE.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Begin ROUTINE INS_INIT_FILES

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','INS_INIT_FILES') ;
 
    CK_DATATYPE(product,PRODUCT) ;
!
! Init library files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	file =	.lib[LIB_FILE] ;
	CK_DATATYPE(file,FILE) ;
	file[FILE_STATUS] = fs_ini ;
	END ;
!
! Now init component output files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    CK_DATATYPE(file,FILE) ;
	    file[FILE_STATUS] = fs_ini ;
	    END ;
	END ;

    true
    END ;				!End of INS_INIT_FILES
GLOBAL ROUTINE RES_INIT_FILES(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   Here to initialize the files with the proper  status  prior
!   to RESTORE processing.
!
!   The following files are initialized:
!
!	libraries
!	component output files
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 for the product to be RESTOREd
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!   Changes FILE_STATUS field in file descriptor.
!
! ROUTINE VALUE:
!
!	Always returns TRUE.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Begin ROUTINE RES_INIT_FILES

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','RES_INIT_FILES') ;
 
    CK_DATATYPE(product,PRODUCT) ;
!
! Init library files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	file =	.lib[LIB_FILE] ;
	CK_DATATYPE(file,FILE) ;
	file[FILE_STATUS] = fs_rei ;
	END ;
!
! Now init component output files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    CK_DATATYPE(file,FILE) ;
	    file[FILE_STATUS] = fs_rei ;
	    END ;
	END ;

    true
    END ;				!End of RES_INIT_FILES
GLOBAL ROUTINE BACKUP(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   Here to perform the backup cycle  for  INSTALL  processing.
!   During  backup  processing,  backup  copies  of the current
!   system files are generated.  The file descriptors  of  each
!   file  specify  the  names  and  logical directories for the
!   "current" and "backup" copies.
!
!   The following files are backed up:
!
!	libraries
!	component output files
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 for the product to be backed up
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if no errors.
!	Returns FALSE if all files are not successfully backed up.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Beginning ROUTINE BACKUP

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn,
	value ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','BACKUP') ;
 
    CK_DATATYPE(product,PRODUCT) ;
    value = true ;
!
! Backup library files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	file =	.lib[LIB_FILE] ;
	CK_DATATYPE(file,FILE) ;
	IF ((.file[FILE_STATUS] EQL fs_ini) OR
	    (.file[FILE_STATUS] EQL fs_rrc))
	THEN
	    BEGIN
	    IF FILE_COPY(.file,.file[FILE_BACKUP])
	    THEN
		file[FILE_STATUS] = fs_ibc
	    ELSE
		value	= false ;
	    END ;
	END ;
!
! Now backup component output files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    CK_DATATYPE(file,FILE) ;
	    IF ((.file[FILE_STATUS] EQL fs_ini) OR
		(.file[FILE_STATUS] EQL fs_rrc))
	    THEN
		BEGIN
		IF FILE_COPY(.file,.file[FILE_BACKUP])
		THEN
		    file[FILE_STATUS] = fs_ibc
		ELSE
		    value = false ;
		END ;
	    END ;
	END ;

    .value
    END ;				!End of BACKUP
GLOBAL ROUTINE REPLACE(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   Here  to  perform the replace cycle for INSTALL processing.
!   During replace processing, current copies of  system  files
!   are  replaced with new copies.  That is, the current copies
!   are superseded.  The file descriptors of each file  specify
!   the  names  and  logical  directories for the "current" and
!   "new" copies.
!
!   The following files are replaced:
!
!	libraries
!	component output files
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 for the product to be backed up
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if no errors.
!	Returns FALSE if all files are not successfully replaced.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Beginning ROUTINE REPLACE

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn,
	value ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','REPLACE') ;
 
    CK_DATATYPE(product,PRODUCT) ;
    value = true ;
!
! Replace library files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	file =	.lib[LIB_FILE] ;
	CK_DATATYPE(file,FILE) ;
	IF .file[FILE_STATUS] EQL fs_ibc
	THEN
	    IF FILE_COPY(.file[FILE_NEWEST],.file)
	    THEN
		file[FILE_STATUS] = fs_irc
	    ELSE
		value = false ;
	END ;
!
! Now replace component output files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    CK_DATATYPE(file,FILE) ;
	    IF .file[FILE_STATUS] EQL fs_ibc
	    THEN
		IF FILE_COPY(.file[FILE_NEWEST],.file)
		THEN
		    file[FILE_STATUS] = fs_irc
		ELSE
		    value = false ;
	    END ;
	END ;

    .value
    END ;				!End of REPLACE
GLOBAL ROUTINE REVERT(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   Here  to  perform  the revert cycle for RESTORE processing.
!   During revert processing, current copies  of  system  files
!   are  restored  from  backup  copies.   That is, the current
!   copies are superseded.  The file descriptors of  each  file
!   specify the names and logical directories for the "current"
!   and "backup" copies.
!
!   The following files are restored:
!
!	libraries
!	component output files
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 for the product to be backed up
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if no errors.
!	Returns FALSE if all files are not successfully restored.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Beginning ROUTINE REVERT

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn,
	value ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','REVERT') ;
 
    CK_DATATYPE(product,PRODUCT) ;
    value = true ;
!
! Restore library files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	file =	.lib[LIB_FILE] ;
	CK_DATATYPE(file,FILE) ;
	IF ((.file[FILE_STATUS] EQL fs_rei) OR
	    (.file[FILE_STATUS] EQL fs_irc))
	THEN
	    BEGIN
	    IF FILE_COPY(.file[FILE_BACKUP],.file)
	    THEN
		file[FILE_STATUS] = fs_rrc
	    ELSE
		value	= false ;
	    END ;
	END ;
!
! Now restore component output files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    CK_DATATYPE(file,FILE) ;
	    IF ((.file[FILE_STATUS] EQL fs_rei) OR
		(.file[FILE_STATUS] EQL fs_irc))
	    THEN
		BEGIN
		IF FILE_COPY(.file[FILE_BACKUP],.file)
		THEN
		    file[FILE_STATUS] = fs_rrc
		ELSE
		    value = false ;
		END ;
	    END ;
	END ;

    .value
    END ;				!End of REVERT
GLOBAL ROUTINE BCHECK(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   This function checks all the required files to see  if  the
!   product can be patched and rebuilt with the associated .CTL
!   file.  It fails if any of the following are invalid.
!
!	patch and build file
!	patch command file
!	utilities
!	current copies of libraries
!	patch files
!	component build files
!	component input files
!
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 to be checked
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if no errors.
!	Returns FALSE if operation not completed successfully.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Beginning ROUTINE BCHECK

    LOCAL
	component:	REF COMPONENT$$,
	edit:		REF EDIT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	patch:		REF PATCH$$,
	n,
	nn,
	val,
	value ;
    MAP
	product:	REF PRODUCT$$ ;
    OWN
	tab:		REF TABLE$$ INITIAL(0) ;
 
    $TRACE('Beginning','BCHECK') ;
 
    CK_DATATYPE(product,PRODUCT) ;
    value = true ;
!
! Setup a table to keep track of patch files checked
!  (avoids duplicate error messages when CK_FILE fails)
!
    IF .tab EQL 0
    THEN
	tab = GET_TABLE(10)
    ELSE
	PURGE_TABLE(tab) ;
!
! Check patch and build file and patch command file
!
    value = .value AND CK_FILE(.product[PROD_CTL_FILE]) ;
    value = .value AND CK_FILE(.product[PROD_PCF_FILE]) ;
!
! Check current copies of library files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	value = .value AND CK_FILE(.lib[LIB_FILE])
	END ;
!
! Check copies of component build files and component input files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
![071] Don't care if the BLD file isn't there.
	%( value = .value AND )% SCK_FILE(.component[COMP_BLD]) ;	![071]
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_INP_LIST],file) EQL true DO
	    BEGIN
	    value = .value AND CK_FILE(.file)
	    END ;
	END ;
!
! Check utility files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_UTL_LIST],file) EQL true DO
	BEGIN
	value = .value AND PCK_FILE(.file)	![106] Tolerate protect. fault.
	END ;
!
! Check patch files for all selected patches to this product
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_SP_LIST],patch) EQL true DO
	BEGIN
	CK_DATATYPE(patch,PATCH) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.patch[PAT_EDIT_LIST],edit) EQL true DO
	    BEGIN
	    CK_DATATYPE(edit,EDIT) ;
	    IF NOT A_LOOKUP(.tab,.edit[EDIT_FILE],val)
	    THEN
		BEGIN
		A_ENTER(.tab,.edit[EDIT_FILE],0) ;
		value = .value AND CK_FILE(.edit[EDIT_FILE])
		END ;
	    END ;
	END ;

    .value
    END ;				!End of BCHECK
GLOBAL ROUTINE ICHECK(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   This function checks the minimal components of a product to
!   see  if  the  product  can be installed.  It checks the new
!   and current copies of:
!
!	libraries
!	component output files
!
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 to be checked
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if no errors.
!	Returns FALSE if any files are invalid.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Beginning ROUTINE ICHECK

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn,
	value ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','ICHECK') ;
 
    CK_DATATYPE(product,PRODUCT) ;
    value = true ;
!
! Check current and newest copies of library files
! Check current copy for reading (to do backup) as well as create
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	file = .lib[LIB_FILE] ;
	CK_DATATYPE(file,FILE) ;
	value = .value AND CK_FILE(.file) ;
	value = .value AND CKW_FILE(.file) ;
	value = .value AND CK_FILE(.file[FILE_NEWEST])
	END ;
!
! Now check current and newest copies of component output files
! Check current copy for reading (to do backup) as well as create
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    CK_DATATYPE(file,FILE) ;
	    value = .value AND CK_FILE(.file) ;
	    value = .value AND CKW_FILE(.file) ;
	    value = .value AND CK_FILE(.file[FILE_NEWEST])
	    END ;
	END ;

    .value
    END ;				!End of ICHECK
GLOBAL ROUTINE RCHECK(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   This function checks the minimal components of a product to
!   see  if  the product can be restored.  It checks the backup
!   copies of:
!
!	libraries
!	component output files
!
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 to be checked
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if no errors.
!	Returns FALSE if any files are invalid.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Beginning ROUTINE RCHECK

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn,
	value ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','RCHECK') ;
 
    CK_DATATYPE(product,PRODUCT) ;
    value = true ;
!
! Check backup copies of library files
! Check current copy for create privs
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	file = .lib[LIB_FILE] ;
	CK_DATATYPE(file,FILE) ;
	value = .value AND CKW_FILE(.file) ;
	value = .value AND CK_FILE(.file[FILE_BACKUP])
	END ;
!
! Now check backup copies of component output files
! Check current copy for create privs
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    CK_DATATYPE(file,FILE) ;
	    value = .value AND CKW_FILE(.file) ;
	    value = .value AND CK_FILE(.file[FILE_BACKUP])
	    END ;
	END ;

    .value
    END ;				!End of RCHECK
GLOBAL ROUTINE SCHECK(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   This function checks the minimal components of a product to
!   see  if  the  product can be selected for autopatching.  It
!   fails if the current copies of any  of  the  following  are
!   invalid:
!
!	patch and build file
!	libraries
!	component build files
!	component output files
!
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 to be checked
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if no errors.
!	Returns FALSE if any files are invalid.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Beginning ROUTINE SCHECK

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn,
	value ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','SCHECK') ;
 
    CK_DATATYPE(product,PRODUCT) ;
    value = true ;
!
! Check patch and build file
!
    value = .value AND CK_FILE(.product[PROD_CTL_FILE]) ;
!
! Check current copies of library files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	value = .value AND CK_FILE(.lib[LIB_FILE])
	END ;
!
! Check copies of component build files and component output files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
![071] Don't care if BLD file not there.
	%( value = .value AND )% SCK_FILE(.component[COMP_BLD]) ;	![071]
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    value = .value AND CK_FILE(.file)
	    END ;
	END ;

    .value
    END ;				!End of SCHECK
GLOBAL ROUTINE CK_BATCH(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   The batch communications file can be deleted  after  it  is
!   read  AND  the  database  has  been checkpointed.  Since no
!   checkpointing is done in this  routine,  the  file  is  not
!   deleted  here.  It is deleted at the beginning of the batch
!   stream as well as during SETUP processing.
!
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 to be checked
!
! IMPLICIT INPUTS:
!
!   Logical name PAT: must be defined.
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if batch communication file was processed.
!	Returns FALSE if no batch communication file processed.
!
! SIDE EFFECTS:
!
!   If a batch communication file is processed, the  status  of
!   all  effected patches will be changed, and the checksums of
!   all new libraries and component outputs  will  be  computed
!   and stored in the FILE$$ descriptors.
!
!--

    BEGIN				!Beginning ROUTINE CK_BATCH

    LITERAL
	$$BAD	= 1,
	$$GOOD	= 2 ;
    OWN
	msgtab:		$KEYTAB((
				(BAD,$$BAD),
				(GOOD,$$GOOD)
				)),
	msg_tab:	DTABLE$$(msgtab) ;

    LITERAL
	byte_size = 36 ;		! Byte size of file
    LOCAL
	count,				! Header record word
	file:		REF FILE$$,
	message,			! 1 word message buffer
	status ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','CK_BATCH') ;
 
    CK_DATATYPE(product,PRODUCT) ;

    SELECTONE .product[PROD_STATUS] OF
	SET
	[prod_state_rbb, prod_state_bfq]: true ;

	[OTHERWISE]: RETURN false ;
	TES ;

    file = .product[PROD_BCF_FILE] ;
    IF NOT SCK_FILE(.file)
    THEN
	RETURN false ;

    TTY((cr_LF,'[Checking results of batch job to rebuild '),
      .product[PROD_NAME],(']')) ;

    DEF_LN(.product) ;				![070] Define logical names

    OPEN_I(.file,byte_size) ;
    GET_BYTES(.file,1,count) ;
    GET_BYTES(.file,.count,message) ;
    CLOSE(.file) ;

    IF NOT T_LOOKUP(msg_tab,message,status)
    THEN
	RETURN $ERROR(W$CPF,*,.product[PROD_NAME]) ;

    SELECTONE .status OF
	SET
	[$$GOOD]:
	    BEGIN
	    product[PROD_STATUS] = prod_state_bjs ;
	    IF UPDATE(.product)
	    THEN
		TTY((cr_lf,'  [Completed successfully]'))
	    ELSE
		$ERROR(W$FAM,*) ;
	    END ;

	[$$BAD]:
	    BEGIN
	    product[PROD_STATUS] = prod_state_bjf ;
	    TTY((cr_lf,'  [Did not complete successfully]')) ;
	    END ;

	[OTHERWISE]:  false ;
	TES ;

    true

    END ;				!End of CK_BATCH
ROUTINE UPDATE(product) =

!++
!
! FUNCTIONAL DESCRIPTION:
!
!   This  function  updates  the status of all patches that are
!   now applied to the new  libraries.   It  also  updates  the
!   FILE$$  descriptors to reflect the new version and checksum
!   of the files that were patched and rebuilt during the batch
!   job for the product.  Files affected are:
!
!	newest copies of libraries
!	newest copies of component output files
!
!
! FORMAL PARAMETERS:
!
!	product:
!		the address of the product descriptor (PRODUCT$$)
!		 to be updated
!
! IMPLICIT INPUTS:
!
!	None
!
! IMPLICIT OUTPUTS:
!
!	None
!
! ROUTINE VALUE:
!
!	Returns TRUE if no errors.
!	Returns FALSE if any file could not be accessed for updating.
!
! SIDE EFFECTS:
!
!	None
!
!--

    BEGIN				!Beginning ROUTINE UPDATE

    LOCAL
	component:	REF COMPONENT$$,
	file:		REF FILE$$,
	lib:		REF LIBRARY$$,
	n,
	nn,
	value ;
    MAP
	product:	REF PRODUCT$$ ;
 
    $TRACE('Beginning','UPDATE') ;
 
    CK_DATATYPE(product,PRODUCT) ;
    value = true ;
!
! Update status of all effected patches
!
    CHANGE_PS(.product,ps_sel,ps_app) ;
!
! Update newest copies of library files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_LIB_LIST],lib) EQL true DO
	BEGIN
	CK_DATATYPE(lib,LIBRARY) ;
	file = .lib[LIB_FILE] ;
	CK_DATATYPE(file,FILE) ;
	value = .value AND UPD_FILE(.file[FILE_NEWEST])
	END ;
!
! Now update newest copies of component output files
!
    n = 0 ;
    WHILE
    GET_VALUE((n=.n+1),.product[PROD_COMP_LIST],component) EQL true DO
	BEGIN
	CK_DATATYPE(component,COMPONENT) ;
	nn = 0 ;
	WHILE
	GET_VALUE((nn=.nn+1),.component[COMP_OUT_LIST],file) EQL true DO
	    BEGIN
	    CK_DATATYPE(file,FILE) ;
	    value = .value AND UPD_FILE(.file[FILE_NEWEST])
	    END ;
	END ;

    .value
    END ;				!End of UPDATE


END

ELUDOM