/* This REXX exec replaces the function of OSTAPE ASSEMBLE for loading the Kermit distribution tape onto a IBM VM system. Calling format is OSTAPE All files on the tape that begin with the file_name_prefix will be loaded to the filemode pointed to by the residence_disk. The default for the file_name_prefix is AA, so you will get all the general help files on the tape. The default for the residence_disk is whatever file_mode this exec was executed from. I reccomend that you put it on a disk -other- than your a-disk, so that your private files do not get mixed in with the KERMIT distribution. You will get some messages that look like errors, but they're usually not. I elected not to supress them, so that you wouldn't be left in "limbo" if something happened to go wrong. Here is a console log of a sample run: ostape xx f OSTAPE 2: will load all KERMIT files beginning with XX to disk F DMSERS002E File OSTAPE $$TEMP$$ A1 not found OSTAPE 2: bypassed OSTAPE.ASSEMBLE OSTAPE 2: bypassed AAAREAD.ME OSTAPE 2: bypassed AAAUPD.HLP . . . OSTAPE 2: bypassed XKAAAA.HLP OSTAPE 2: bypassed XKM936.HLP OSTAPE 2: bypassed XKMAAA.HLP OSTAPE 2: loading XXU.C as XXU C DMSCPY721I Copy OSTAPE $$TEMP$$ A1 to XXU C F1 (old file) DMSSTT002E File OSTAPE $$TEMP$$ not found OSTAPE 2: loaded 1 files OSTAPE 2: tape was left at physical file 1555 Ready; T=27.16/36.90 15:44:09 Another Typical Example: You just got in a new KERMIT tape, you want to load its documentation to your D-disk, and you want to load the latest TSO KERMIT to your E-disk. You would enter the following commands: OSTAPE AA D OSTAPE IKT E ---------------------------------------------------------------------- While this REXX implementation has the disadvantage of requiring VM/CMS release 4 or above, it has the distinct advantages of maintainability, readability and portability to other REXX systems with minor changes. The only system dependencies here are in the PARSE SOURCE, FILEDEF and MOVEFILE statements. Especially good things: 1) This exec takes pains to use only characters that will translate cleanly from EBCDIC to ASCII to EBCDIC, so that the many translations that the KERMIT distribution goes through will not cause any failures. This means that some of the code is less elegant than the ideal, because REXX's "OR" operator (the vertical bar) fails this test. So, I have to write certain compound conditions as multiple IF's. Another character that I can't use is the standard IBM "NOT" operator. REXX conveniently supports "slash =" (/=), meaning "NOT EQUAL" as a rough equivalent. Implementation restrictions: 1) This exec expects the files on the tape to be sorted in ascending order by the first 2 characters of their file name. 2) The KERMIT distribution tapes are mostly sorted, the exception being that the OSTAPE files (like this one) are at the beginning. So, if you use this exec to load the OSTAPE files, then you will get messages that most of the other (until the P's) files on the tape were bypassed. This is annoying, but harmless. 3) This exec uses several methods of end-of-tape detection. The one that is really used now (Dec-90) is the "missing-file" method in the routine load-a-file. A consequence of this is the message: DMSSTT002E File OSTAPE $$TEMP$$ not found when you hit end-of-tape. This is annoying, but harmless. The other methods may work in the future, depending on how the distribution tapes are formatted, and wether MOVEFILE ever passes a return code to RC. To find them all, look for all occurances of "eof". 4) This exec loads each file from the tape to the disk that it runs from. It then decides if the file is a label or a data file. If it is a data file, and it is one the user asked for, it is copied to its final destination. It would be possible to not load all the files to disk, but the more complex logic seems hardly worth the trouble. V2 20-Dec-90 Bob Meizlik - add distinction between eof and finished V1 19-Dec-90 Bob Meizlik, Pan American World Airways - original coding */ version = 2 parse upper source . . exec_name exec_type exec_mode . parse upper arg file_name_prefix residence_disk . call init call position_tape call load_files call clean_up exit load_files: do i = 1 by 1 call load_a_file if eof then leave if finished then leave if 1 /= this_file_is_label then do if file_wanted then do call copy_file files_loaded = files_loaded + 1 end else do say exec_name version': bypassed' name end end end return copy_file: say exec_name version': loading' name 'as' tape_fn tape_ft 'copy' temp_file_name tape_fn tape_ft residence_disk '(TYPE' return load_a_file: tape_pos = tape_pos + 1 'erase' temp_file_name /* required for end-of-tape detection */ if next_file_is_label then do 'FILEDEF INMOVE TAP1 (RECFM F LRECL 80 BLOCK 80' 'FILEDEF OUTMOVE DISK' temp_file_name '(RECFM VB LRECL 80' 'MOVEFILE INMOVE OUTMOVE' If rc = 3 then do /* this doesn't work under vm/xa sp 2.1 */ eof = 1 /* but, may work under future versions */ leave end this_file_is_label = 1 call analyze_label end else do 'FILEDEF INMOVE TAP1 (RECFM VB LRECL 80 BLOCK 16000' 'FILEDEF OUTMOVE DISK' temp_file_name '(RECFM VB LRECL 80' 'MOVEFILE INMOVE OUTMOVE' If rc = 3 then do eof = 1 leave end this_file_is_label = 0 next_file_is_label = 1 /* always a label after a data file */ end return analyze_label: do al = 1 by 1 'EXECIO 1 DISKR' temp_file_name al '(VAR TEMP' if rc /= 0, /* no label must be end-of-tape */ & al = 1 then do eof = 1 leave end if rc /= 0 then do /* no more label left */ leave end parse var temp label_type +4 . select when label_type = 'VOL1' then parse var temp +4 volser +6 when label_type = 'HDR1' then do next_file_is_label = 0 parse var temp +4 name +17 . parse var name tape_fn '.' tape_ft . if abbrev(name, file_name_prefix) then file_wanted = 1 else file_wanted = 0 if left(name, length(file_name_prefix)) > file_name_prefix, & tape_fn /= 'OSTAPE' then do finished = 1 leave end end when label_type = 'HDR2' then do next_file_is_label = 0 parse var temp +4 recfm +1 blksize +5 lrecl +4 . end when label_type = 'EOF1' then do next_file_is_label = 1 parse var temp +4 . end when label_type = 'EOF2' then do next_file_is_label = 1 parse var temp +4 . end when label_type = 'EOV1' then do next_file_is_label = 1 parse var temp +4 . eof = 1 end otherwise do say exec_name version': invalid label type found=' label_type exit 16 end end end return position_tape: 'tape rew' /* beginning of tape */ return init: if file_name_prefix = '' then file_name_prefix = 'AA' if residence_disk = '' then residence_disk = exec_mode say exec_name version': will load all KERMIT files beginning with', file_name_prefix 'to disk' residence_disk temp_file_name = exec_name '$$TEMP$$' exec_mode eof = 0 files_loaded = 0 file_wanted = 0 finished = 0 tape_error = 0 tape_pos = 0 this_file_is_label = 1 /* the first file is always a label */ next_file_is_label = 1 /* the first file is always a label */ return halt: clean_up: say exec_name version': loaded' files_loaded 'files' say exec_name version': tape was left at physical file' tape_pos return