$! VAXBCK.COM $! $! Backup a C system onto magtape, using the RMSBCK utility. $! It writes a backup command file to [-.COMMAND]BCK.COM and $! a restore command file to [-.COMMAND]RST.COM. It then $! initializes the magtape and executes the BACKUP command file. $! $! $ SET DEF [.command] $! $ @ VAXBCK out_tape bck_log rst_log $! $! bck_log and rst_log (yes/no) signal whether a "summary log" should be $! written (to the command output device) $! $ bck_disk := 'f$logical("SYS$DISK")' ! Input disk $ bck_dir := 'f$directory()' ! Current directory $ on control_y then goto fatal_exit $! $ if p1 .eqs. "" then inquire p1 "Output tape" $ if p2 .eqs. "" then - inquire p2 "Backup log? [yes/no] ( if none)" $ if p3 .eqs. "" then - inquire p3 "Restore log? [yes/no] ( if none)" $ bck_log = "" $ if p2 then bck_log := "/SL" $ rst_log = "" $ if p3 then rst_log := "/SL" $ temp_name := 'bck_disk''bck_dir'vaxbck.tmp ! Temp file name $ set default [-] ! Start one level up $! $! ** Generalized directory structure transversal algorithm. This $! ** section uses the directory utility to walk the directory structure, $! ** writing each directory specification to a temporary file, defined $! ** previously as local symbol "temp_name". $! $ direct/out='temp_name'/nohead/notrail/col=1 [...]*.dir; $! $! Read VAXBCK.TMP and write BACKUP and RESTOR command files. $! $ set default 'bck_dir' ! Return to [.command] $ open/write bck_file BCK.COM $ open/write rst_file RST.COM $! $! Pass 1, write directory creation stuff for RST.COM $! $ open/read temp_file 'temp_name' $ write bck_file "$ on error then continue" $ write rst_file "$ on error then continue" $ return := "loop1a" ! For get_next return $ loop1: ! For all entries ... $ goto get_next ! Get next file name $ loop1a: ! Return from get_next $ if "''bck_name'" .eqs. "" then goto loop1e ! Loop exit if no more $ write rst_file "$ create/direct ''bck_name'" ! Output command $ goto loop1 ! Continue loop $ loop1e: $! $! Pass 2, write backup/restore commands $! $ open/read temp_file 'temp_name' $ index = 0 $ write bck_file "$ mcr bck" $ write rst_file "$ mcr rst" $ return := "loop2a" ! For get_next return $ loop2: ! For all entries ... $ goto get_next ! Get next file name $ loop2a: ! Return from get_next $ if "''bck_name'" .eqs. "" then goto loop2e ! Exit if no more $ index = index + 1 $ out_name := "FILE''index'" $ bck_fullname := 'bck_disk''bck_name' $ write sys$output "''bck_fullname' will be written to ''p1'''out_name'" $ write bck_file "''p1'''out_name'.BCK''bck_log'=''bck_fullname'*.*" $ write rst_file "''bck_name'*.*/fr''rst_log'=mta0:''out_name'.BCK" $ goto loop2 ! Continue loop $ loop2e: $ write bck_file "$ exit" $ write rst_file "$ exit" $ delete 'temp_name';* $ close bck_file $ close rst_file $! $! Actually do the backup $! $ on error then continue $ dismount/nounload 'p1' $ on error then exit $ initialize/prot=(w=rwed,o=rwed,g=rwed,s=rwed)/den=1600 'p1' c $ mount 'p1' c $ create 'p1'README.NOW C distribution for VMS. To reload, copy RST.COM from this tape, then edit it to define the correct device/account to which the files are to be written. Then execute RST.COM and define the top-level directory as C:, define a BIN: directory, define the XCC and XAS commands and build the tools, using [.TOOLS]VTOOLS.COM, [.LEX]VLIBLX.COM and [.LEX]VMAKX.COM. This tape has the following contents: README.NOW This file KIT.DOC General installation guide RST.COM Model for restoring the rest of the files BCK.COM The command file used for backup and the RMSBCK container files of the format FILEnn.BCK. $ copy/log 'bck_dir'KIT.DOC 'p1' $ copy/log RST.COM 'p1' $ copy/log BCK.COM 'p1' $ bck_verify = 'f$verify()' $ set verify $ @ BCK.com $ if 'bck_verify' .eq. 0 then set noverify $ goto finis $ $ fatal_exit: $ write sys$error "CTRL/Y typed" $ close/error=fatal1 bck_file $ fatal1: close/error=fatal2 rst_file $ fatal2: close/error=fatal3 temp_file $ fatal3: $ finis: $ set default 'bck_dir' $ exit $! $! ** Subroutine get_name reads a line from the temporary file, parsing $! ** it and assigning the directory name indicated to "bck_name". $! ** At end of file or error (or a null directory), it closes the $! ** temporary file and sets "bck_name" to the null string. $! ** Usage: $! ** $! ** Open/read temp_name [file created by directory utility] $! ** return := sub_ret $! ** loop: ! For all entries, ... $! ** goto get_name ! Get next entry $! ** sub_ret: ! $! ** if "''bck_name'" .eqs."" then ! Exit if no more $! ** goto finished ! $! ** [Process this entry] ! Process this one and $! ** goto loop ! ... continue. $! ** finished: ! Loop exit $! $ get_next: $ read/end=get_done/error=get_done temp_file get_text $ dir_beg = 'f$locate("[", get_text)' $ if dir_beg .eq. 'f$length(get_text)' then goto get_done $ dir_end = 'f$locate("]", get_text)' $ dir_size = dir_end - dir_beg $ dir := "''f$extract(dir_beg, dir_size, get_text)'" $ name_beg = dir_end + 1 $ name_size = 'f$locate(".DIR;", get_text)' - name_beg $ name := "''f$extract(name_beg, name_size, get_text)'" $ bck_name := "''dir'.''name']" $ goto 'return' $ get_done: $ close temp_file $ bck_name := "" $ goto 'return' $!