MODULE XBACK ( IDENT = 'X00.13' %TITLE 'XPO$BACKUP - XPORT File Backup' %BLISS32( ,ADDRESSING_MODE( EXTERNAL=LONG_RELATIVE ) ) %BLISS36( ,ENTRY( XPO$BACKUP ),OTS='' ) ) = BEGIN ! ! COPYRIGHT (c) 1980 BY ! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ! ! 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: BLISS Library ! ! ABSTRACT: ! ! This module is the XPORT file backup module. ! ! ENVIRONMENT: User mode - multiple host operating/file systems ! ! AUTHOR: Ward Clark, CREATION DATE: 21 February 1979 ! !-- ! ! TABLE OF CONTENTS: ! FORWARD ROUTINE XPO$BACKUP; ! XPORT file backup routine ! ! INCLUDE FILES: ! LIBRARY 'XPORT' ; ! Public XPORT control block and macro definitions LIBRARY 'XPOSYS' ; ! Internal XPORT macro definitions $XPO_SYS_TEST( $TOPS10, $TOPS20, $VMS, $11M, $RSTS, $RT11 ) ! ! MACROS: ! %IF $TOPS10 OR $RSTS %THEN MACRO default_spec = '*:[*]*' %; %FI %IF $TOPS20 %THEN MACRO default_spec = '*:<*>*' %; %FI %IF $RT11 %THEN MACRO default_spec = '*:*' %; %FI ! ! EQUATED SYMBOLS: ! LITERAL version_backup = $VMS OR $11M; ! Backup-by-version-number indicator ! ! PSECT DECLARATIONS: ! $XPO_PSECTS ! Declare XPORT PSECT names and attributes ! ! OWN STORAGE: ! ! ! EXTERNAL REFERENCES: ! GLOBAL ROUTINE XPO$BACKUP( iob, success_action, failure_action ) = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine performs XPORT file backup processing. ! ! FORMAL PARAMETERS: ! ! iob - address of IOB ! success_action - address of success action routine ! failure_action - address of failure action routine ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! None ! ! COMPLETION CODES: (also returned in IOB$G_COMP_CODE) ! ! XPO$_NORMAL - file successfully backed up ! ! XPO$_BAD_IOB - invalid IOB ! ( IOB$G_2ND_CODE = XPO$_BAD_LENGTH - invalid length ) ! XPO$_BAD_IO_OPT - invalid I/O option (REMEMBER) ! XPO$_BAD_TYPE - invalid backup file extension ! (IOB$G_2ND_CODE = XPO$_CONFLICT - fields other than file type specified ! or completion code from $XPO_PARSE_SPEC) ! XPO$_BAD_RSLT - invalid old or new file-spec ! (IOB$G_2ND_CODE = XPO$_MISSING - old or new file-spec missing ! or XPO$_NO_BACKUP - terminal or temporary file cannot be backed up ! or XPO$_BAD_TYPE - original file has backup extension ! or XPO$_BAD_VER ($VMS or $11M) - invalid version ! or completion code from $XPO_PARSE_SPEC) ! XPO$_FREE_MEM - error deallocating IOB-related memory ! (IOB$G_2ND_CODE = $XPO_FREE_MEM completion code) ! XPO$_NO_DELETE - previous backup file cannot be deleted ! (IOB$G_2ND_CODE = completion code from $XPO_NO_DELETE) ! XPO$_NOT_CLOSED - old and/or new file is not closed ! XPO$_RENAME_NEW - new file cannot be renamed ! (IOB$G_2ND_CODE = completion code from $XPO_RENAME) ! failure completion codes from XPO$RMS_CLEANUP (VMS) ! XPO$_RENAME_OLD - old file cannot be renamed ! (IOB$G_2ND_CODE = completion code from $XPO_RENAME) ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN MAP iob : REF $XPO_IOB(); ! Redefine the IOB parameter. BIND old_iob = .iob : $XPO_IOB(), ! Rename the old file IOB parameter new_iob = .old_iob[IOB$A_ASSOC_IOB] : ! and declare the new file IOB. $XPO_IOB(), old_resultant = old_iob[IOB$T_RESULTANT] : ! Declare the old and new resultant file-specs. $STR_DESCRIPTOR(), new_resultant = new_iob[IOB$T_RESULTANT] : $STR_DESCRIPTOR(); LOCAL %IF NOT version_backup %THEN dummy_parse : $XPO_SPEC_BLOCK, ! File extension parse block %FI dummy_iob : $XPO_IOB(); ! Dummy IOB for file renaming ! ! XPORT routine initialization. ! $XPO_MAIN_BEGIN( IO ) ! Define the MAIN_BLOCK code block ! and validate the caller's IOB. $XPO_IOB_INIT( IOB = dummy_iob, ! Initialize the dummy IOB, OPTION = OUTPUT ); ! forcing output file-spec resolution on $XPO_DELETE. ! ! Check the IOB for invalid or conflicting information. ! ! Return an error code if the IOB is invalid ! for one of the following reasons: IF NOT .old_iob[IOB$V_CLOSED] OR ! both IOB's have not been explicitly closed NOT .new_iob[IOB$V_CLOSED] THEN $XPO_QUIT( NOT_CLOSED ); IF .old_resultant[STR$H_LENGTH] LEQ 0 OR ! one of the IOBs does not have a resultant file-spec .new_resultant[STR$H_LENGTH] LEQ 0 THEN $XPO_QUIT( BAD_RSLT, MISSING ); IF .old_iob[IOB$V_TERMINAL] OR ! the old file is a terminal .old_iob[IOB$V_TEMPORARY] ! the old file is a temporary file, THEN $XPO_QUIT( BAD_RSLT, NO_BACKUP ); IF .iob[IOB$V_REMEMBER] ! OPTION=REMEMBER was specified THEN $XPO_QUIT( BAD_IO_OPT ); %IF NOT version_backup %THEN ! ! Verify that the backup file extension is valid. ! $XPO_IF_NOT( $XPO_PARSE_SPEC( ! Parse the backup file type. FILE_SPEC = .old_iob[IOB$A_BACK_TYPE], SPEC_BLOCK = dummy_parse, FAILURE = 0 ) ) THEN $XPO_QUIT( BAD_TYPE, (.$XPO_STATUS) ); ! If the backup extension file-spec includes IF .dummy_parse[XPO$H_NODE] NEQ 0 OR ! a node name, .dummy_parse[XPO$H_DEVICE] NEQ 0 OR ! a device name, .dummy_parse[XPO$H_DIRECT] NEQ 0 OR ! a directory specification, .dummy_parse[XPO$H_FILE_NAME] NEQ 0 OR ! a file name .dummy_parse[XPO$H_FILE_VER] NEQ 0 OR ! or a file version number .dummy_parse[XPO$H_FILE_TYPE] LSS 2 ! or no file extension was specified, THEN ! $XPO_QUIT( BAD_TYPE ); ! return an error code to the caller. ! ! Validate the file type of the old file. ! $XPO_IF_NOT( $XPO_PARSE_SPEC( ! Parse the old file's resultant file-spec. FILE_SPEC = old_iob[IOB$T_RESULTANT], SPEC_BLOCK = dummy_parse, FAILURE = 0 ) ) THEN $XPO_QUIT( BAD_RSLT, (.$XPO_STATUS) ); IF $STR_EQL( STRING1 = .old_iob[IOB$A_BACK_TYPE], ! Verify that the file type of the old file is STRING2 = dummy_parse[XPO$T_FILE_TYPE], ! not the backup file type. FAILURE = 0 ) THEN $XPO_QUIT( BAD_RSLT, BAD_TYPE ); ! ! Delete a previous backup file, if one exists. ! IF NOT $XPO_DELETE( IOB = dummy_iob, FILE_SPEC = .old_iob[IOB$A_BACK_TYPE], DEFAULT = default_spec, RELATED = old_iob[IOB$T_RESULTANT], FAILURE = 0 ) THEN IF .dummy_iob[IOB$G_COMP_CODE] NEQ XPO$_NO_FILE ! If an existing backup file cannot be deleted, THEN ! $XPO_QUIT( NO_DELETE, ! return error codes to the caller. (.dummy_iob[IOB$G_COMP_CODE]) ); ! ! Reinitialize the dummy_iob ! $XPO_IOB_INIT( IOB = dummy_iob ); ! ! Rename the original file to make it a backup file. ! IF NOT $XPO_RENAME( IOB = dummy_iob, FILE_SPEC = old_iob[IOB$T_RESULTANT], NEW_SPEC = .old_iob[IOB$A_BACK_TYPE], NEW_DEFAULT = default_spec, NEW_RELATED = old_iob[IOB$T_RESULTANT], FAILURE = 0 ) THEN $XPO_QUIT( RENAME_OLD, (.dummy_iob[IOB$G_COMP_CODE]) ); %FI ! ! Rename the new file to be the same as the original file. ! %IF $VMS OR $11M %THEN ! *** $VMS = TEMPORARY RMS KLUDGE *** BEGIN LOCAL version_pointer; version_pointer = ! Find the beginning of the version number field. CH$FIND_CH( .old_resultant[STR$H_LENGTH], .old_resultant[STR$A_POINTER], %C';' ); IF CH$FAIL( .version_pointer ) THEN $XPO_QUIT( BAD_RSLT, BAD_VER ); IF NOT $XPO_RENAME( IOB = dummy_iob, FILE_SPEC = new_iob[IOB$T_RESULTANT], NEW_SPEC = (CH$DIFF(.version_pointer, .old_iob[$SUB_FIELD(IOB$T_RESULTANT,STR$A_POINTER)]), .old_iob[$SUB_FIELD(IOB$T_RESULTANT,STR$A_POINTER)]), FAILURE = 0 ) THEN $XPO_QUIT( RENAME_NEW, (.dummy_iob[IOB$G_COMP_CODE]) ); END; %ELSE IF NOT $XPO_RENAME( IOB = dummy_iob, FILE_SPEC = new_iob[IOB$T_RESULTANT], NEW_SPEC = old_iob[IOB$T_RESULTANT], OPTIONS = MAX_VERSION, FAILURE = 0 ) THEN $XPO_QUIT( RENAME_NEW, (.dummy_iob[IOB$G_COMP_CODE]) ); %FI ! ! Reset the old and new IOBs after a successful backup. ! $XPO_ZAP_IOB( old_iob ); ! Reset the old file IOB $XPO_ZAP_IOB( new_iob ); ! and the new file IOB. $XPO_QUIT( NORMAL ); ! Return a success code to the caller. ! ! End of MAIN_BLOCK code block. ! $XPO_MAIN_END; ! Terminate MAIN_BLOCK. ! ! Cleanup dynamic memory. ! $XPO_ZAP_IOB( dummy_iob ); ! Reset the local dummy IOB. ! ! Call an appropriate action routine. ! $XPO_ACTION_RTN( .iob ); ! Call a success or failure action routine. ! ! Cleanup the IOBs after a file backup failure. ! IF NOT .old_iob[IOB$G_COMP_CODE] ! If the file backup failed, THEN ! BEGIN ! $XPO_ZAP_IOB( old_iob ); ! cleanup the old file IOB $XPO_ZAP_IOB( new_iob ); ! and the new file IOB. END; ! ! Return to the caller. ! RETURN .iob[IOB$G_COMP_CODE] ! Return the IOB completion code to the caller. END; ! End of XPO$BACKUP routine END ELUDOM