ramin@rtgvax.UUCP (Pantagruel) (08/26/86)
Dammit dammit dammit! I should've asked for it while it was flying past... I did see the request a few months back for a program to read TAR format tapes from VMS, but thought "oh well... who needs that." Well if anyone has one, I sure would appreciate getting a copy of it... Our unix tape drive is about to be shipped to the funny farm and the vms machines are getting all the new model ones... I looked in mod.sources listings but alas... I'll also check the decus tapes, but I doubt I'll have much luck. Thanks much... ramin -- =--------------------------------------=-------------------------------------= : alias: ramin firoozye' : USps: Systems Control Inc. : : uucp: ...!shasta \ : 1801 Page Mill Road : : ...!lll-lcc \ : Palo Alto, CA 94303 : : ...!ihnp4 \...!rtgvax!ramin : ^G: (415) 494-1165 x-1777 : =--------------------------------------=-------------------------------------=
bhoward@funvax.UUCP (Bruce Howard) (08/28/86)
> Dammit dammit dammit! > > I should've asked for it while it was flying past... I did see the > request a few months back for a program to read TAR format tapes from > VMS, but thought "oh well... who needs that." > > Well if anyone has one, I sure would appreciate getting a copy of > it... Our unix tape drive is about to be shipped to the funny farm and > the vms machines are getting all the new model ones... I looked in > mod.sources listings but alas... I'll also check the decus tapes, but > I doubt I'll have much luck. Gosh! And I thought we were the only people in the world with a screwball set up -- we have a network of VAXen that speak Internet and DECnet to each other. The only available tape drive unfortunately lies on the downstairs VAX 8600. In the long term, the BEST solution will be to obtain a TK50 or TU80? (something like that) tape drive. Anyways, please credit most of the following solution to Chris Lent at ...philabs!phri!cooper!chris. This method has been successfully used to read in our Berkeley distribution tapes. Additionally, I have managed to write what appear to be UNIX format tapes though I have not been able to test them on a tape drive attached to a UNIX host. First you must have an fdl file created that describes the file we are pulling off the UNIX format tape. I have not had the time nor the desire to fully understand its format but it seems to simply say that whatever it is we pull off the tape should be placed in a sequential file with no strange attributes: --- cut here --- IDENT "16-NOV-1985 09:34:31 VAX/VMS ANALYZE/RMS_FILE Utility" SYSTEM SOURCE VAX/VMS FILE ALLOCATION 13 BEST_TRY_CONTIGUOUS no CLUSTER_SIZE 1 CONTIGUOUS no EXTENSION 0 GLOBAL_BUFFER_COUNT 0 NAME "dua2:[bhoward.vms]tar.exe" ORGANIZATION sequential OWNER [647,24] PROTECTION (system:RWED, owner:RWED, group:RE, world:RE) RECORD BLOCK_SPAN yes CARRIAGE_CONTROL none FORMAT fixed SIZE 10240 --- cut here --- The owner field should be defined to be the UIC of the account which happens to be reading in the file. I don't think that which is defined in the NAME field is important, but you can experiment or look it up in the VMS docs. For purposes of this explanation, I shall assume you have typed this into a file named tarcvt.fdl Once you have this fdl typed in, the following steps will read a file off of the UNIX tape into a VMS file which can then be transported to UNIX via ethernet or kermit. $ mount mua0: /foreign/block=10240 (mua0: happens to be the name of our primary tape drive. 10240 is the block size on our berkeley tapes. Set as is appropriate for your tape.) $ convert /fdl=tarcvt.fdl mua0: nameoftarfile (this reads in the first file on the tape into a file on vms named nameoftarfile) $ dismount mua0: Sometimes, as in the case of the berkeley distribution, you have multiple files on a tape. One of ours had three sections. You can use the set mag command to move between files. For example, we wanted to pull off the ingress database which I believe was the third file of one tape. To do this we typed: $ mount mua0: /foreign/block=10240 $ set mag /skip=files:2 $ convert /fdl=tarcvt.fdl mua0: ingres.tar $ dismount mua0: Also useful, is set mag /rewind which rewinds without dismounting the tape. To write a tape file is almost the same as reading. You just switch the order around on the files, that is: $ mount mua0: /foreign/block=10240 $ convert /fdl=tarcvt.fdl usrbackup.tar mua0: $ convert /fdl=tarcvt.fdl srcbackup.dump mua0: $ dismount mua0: which places two files onto the tape. I have NOT confirmed that these tapes are readable by UNIX hosts. Here are a few tricks I've developed to read tar files across DECnet. For example, to pull off a directory name ./etc/getty from a tar file that has been placed onto VMS, from UNIX type: % dcp -i mother/bhoward::'[.archive]src.tar' - | tar -xvf - ./etc/getty Password for mother/bhoward::? (type password) (watch it verbosely untar) This can also be done with the cpio and dump commands though I don't believe it works with dump in interactive mode. I think this is slightly incomplete, but it should get you started. I plan of writing a more complete paper on these and other techniques our unique (silly) hardware situation has forced us to develop. Please feel free to ask me questions via mail. Cheers! Bruce -- --------------------------------- ...decvax!ittatc!funvax!bhoward Bruce Howard @ Fairfield University ...ihnp4!itivax!funvax!bhoward Located in Scenic Fairfield, CT 06430 ---------------------------------
ramin@rtgvax.UUCP (09/07/86)
Well... my recent inquiry about TAR programs in VMS garnished me
the following responses... The last two have actual programs
that were enclosed and I have included them verbatim (though
it seems they are closely related... but I thought I'd throw them
both in anyway...) I also have another FORTRAN one here that someone at
a sister company wrote. I haven't included it since I don't know
if he wants it distributed...
I have not fully tested any of them. But since this machine is
shortly due to go off the net I figured I should send it out
before they pull the plug...(:-( Barring circumstances I should be
back on the net via another system in about a month and I might
fix up the programs to allow subdirectory creations, etc...)
Again, thanks to all who responded.
P.S. John Gilmore (hoptoad!gnu) has also offered a copy of a C TAR program
he has... Hopefully I'll get it soon enough... If someone needs to
try it out they could contact him directly if I'm not around...
ramin
***************************************************************************
From: H}vard Eidnes <lll-lcc!caip!seismo!mcvax!vax.runit.unit.uninett!H_Eidnes>
I saw your recent request for some TAR program on VMS. It just
happens that a friend of mine recently wrote such a program.
The program is written in VMS Pascal. It has mainly been used
to read TAR tapes down to TAR files on disk to be transferred
to a Unix system to be unpacked. We've used Kermit to transfer
from our VMS computer to a MicroVAX II (without 1/2" tape), and
that has worked, but is slow, eg. it took 12hrs transferring
TeX, but it worked...
The Pascal program is capable of just extracting a part of a tape
by giving it a starting and ending filename prefix. It also has
routines to do actual extraction on VMS, but we haven't used these
routines much. NB: the program only handles TAR files blocked 20.
I will be happy to send you the program if you want it.
***************************************************************************
From: lll-lcc!caip!uw-beaver!uw-june!gordon (Gordon Davisson)
Here's a program that does what you want. It did get into a recent decus
tape (VAX85C?), but that version happens to not work. Use this instead.
--
Human: Gordon Davisson
ARPA: gordon@uw-june.ARPA
UUCP: {ihnp4,decvax,tektronix}!uw-beaver!uw-june!gordon
Bitnet: gordon@uwaphast
ATT: (206) 527-0832
USnail: 5008 12th NE, Seattle, WA, 98105
--------------- cut here, then run the file (with an @) ---------------
$!
$ write sys$output "creating CVT.FOR"
$ create CVT.FOR
$ deck
c
c this subroutine converts a complete filespec (directory+file) name from
c unix format to VMS
c
subroutine cvt_dir_uv( unix, vms, vlen )
parameter reserved = 10
character*(*) unix, vms
integer*2 vlen, i, j
vms( 1:1 ) = '['
vlen = 1
i = 1
if ( unix( 1:1 ) .eq. '/' ) i = 2
j = index( unix( i: ), '/' )
do while ( j .ne. 0 )
vms( vlen+1:vlen+1 ) = '.'
call cvt_string_uv( unix( i : i+j-2 ), vms( vlen+2: ), k )
i = i + j
j = index( unix( i: ), '/' )
vlen = vlen + k + 1
if ( vlen + reserved .gt. len( vms )) then
vlen = len( vms ) - reserved
if ( vms( vlen:vlen ) .eq. '.' ) vlen = vlen - 1
do while ( j .ne. 0 )
i = i + j
j = index( unix( i: ), '/' )
end do
end if
end do
if ( vlen .eq. 1 ) then
vlen = 0
else
vlen = vlen + 1
vms( vlen:vlen ) = ']'
end if
call cvt_file_uv( unix( i: ), vms( vlen+1: ), k )
vlen = vlen + k
return
end
c
c this subroutine converts an individual file name from unix format to VMS
c
subroutine cvt_file_uv( unix, vms, vlen )
parameter mlen1 = 64, mlen2 = 64
c parameter mlen1 = 9, mlen2 = 3 ! for version 3 and before
character*(*) unix, vms
integer*2 vlen, i, j
i = index( unix, '.' )
if ( i .eq. 0 ) i = len( unix ) + 1
call cvt_string_uv( unix( :i-1 ), vms, j )
if ( j .gt. mlen1 ) j = mlen1
vlen = j + 1
if ( vlen .gt. len( vms )) vlen = len( vms )
vms( vlen:vlen ) = '.'
if ( i .ge. len( unix )) return
call cvt_string_uv( unix( i+1: ), vms( vlen+1: ), j )
if ( j .gt. mlen2 ) j = mlen2
vlen = vlen + j
return
end
c
c this subroutine converts a string to characters that can appear in
c VMS filenames
c
c if you're using a version 3 or pervious VMS system, you'll have to
c rewrite this to avoid _ and $.
c
subroutine cvt_string_uv( unix, vms, vlen )
character*(*) unix, vms, c*1
integer*2 vlen, i
vms = unix
vlen = min( len( unix ), len( vms ))
do i = 1, vlen
c = vms( i:i )
if ( 'A' .le. c .and. c .le. 'Z' .or.
- '0' .le. c .and. c .le. '9' .or.
- c .eq. '_' .or. c .eq. '$' ) then
continue
else if ( 'a' .le. c .and. c .le. 'z' ) then
vms( i:i ) = char( ichar( c ) - 32 )
else if ( c .eq. '-' ) then
vms( i:i ) = '_'
else
vms( i:i ) = '$'
end if
end do
return
end
c
c this souroutine converts an octal digit to a 3-character protection mask
c
subroutine cvt_prot( c, out )
character c*1, out*3, mask( 8 )*3
data mask / '---', '--x', '-w-', '-wx',
- 'r--', 'r-x', 'rw-', 'rwx' /
out = mask( ichar( c ) - ichar( '0' ) + 1 )
return
end
$ eod
$!
$ write sys$output "creating TAPEIO.DCK"
$ create TAPEIO.DCK
$ deck
c
c parameters:
c blocklen is the size of the units tar works with
c saveblocks is the number of blocks into the file saved for a second chance
c maxrecl is the maximum length of record a text can have
c maxblockfactor is the maximum blocking factor this program can deal with
c
parameter blocklen = 512, saveblocks = 5, maxrecl = 512,
- maxblockfactor = 20
c secondary parameters calculated from those above
parameter recblocks = 2 + maxrecl/blocklen,
- maxblocks = maxblockfactor + saveblocks + recblocks,
- maxlen = blocklen*maxblocks
c these are numbers for fortran units to be used for various files
parameter inunit = 1, outunit = 2, listunit = 3, nameunit = 4
c
c variables:
c
c i/o control stuff
integer*2 channel
logical*1 tape_file
c this is the buffer records get read into
character buffer*( maxlen ), block( maxblocks )*( blocklen )
equivalence ( buffer, block )
c control info for the buffer
integer*2 using, using2, curr
logical*1 eof
common /commonbuf/ buffer
common /commonints/ using, using2, curr, eof, tape_file, channel
$ eod
$!
$ write sys$output "creating TAPEIO.FOR"
$ create TAPEIO.FOR
$ deck
c
c this routine accesses, checks, and rewinds the specified tape (or file,
c if tape_file is true.
c
subroutine open_tape( name )
include 'tapeio.dck/list'
include '($iodef)/nolist'
include '($dvidef)/nolist'
include '($devdef)/nolist'
character*(*) name
integer*2 iosb( 2 ), devreq_w( 2 )
integer*4 stat, devreq( 4 ), devchar, sys$assign, sys$qiow,
- sys$getdvi
equivalence ( devreq, devreq_w )
data devreq_w, devreq( 3 ), devreq( 4 )
- / 4, dvi$_devchar, 0, 0 /
if ( tape_file ) then
stat = sys$assign( name, channel,, )
if ( .not. stat ) goto 900
devreq( 2 ) = %loc( devchar )
stat = sys$getdvi( , %val( channel ),, devreq, iosb,,, )
if ( .not. stat ) goto 900
stat = iosb( 1 )
if ( .not. stat ) goto 900
if ( .not. btest( devchar, dev$v_avl )) goto 910
if ( .not. btest( devchar, dev$v_for )) goto 920
stat = sys$qiow( , %val( channel ), %val( io$_rewind ),
- iosb,,,,,,,, )
if ( .not. stat ) goto 930
stat = iosb( 1 )
if ( .not. stat ) goto 930
else
open( inunit, err=950, name=name,
- type='old', readonly )
end if
return
c
c fatal errors
c
900 type *, 'Error accessing tape, ', name
call exit( stat )
910 type *, 'Tape offline or not available.'
call exit
920 type *, 'Tape must be mounted /foreign.'
call exit
930 type *, 'Error rewinding tape.'
call exit( stat )
950 type *, 'Error opening input file, ', name
call exit
end
c
c this routine makes sure the next block is available, reading it from
c tape if necessary.
c
subroutine next_block
include 'tapeio.dck'
include '($iodef)/nolist'
integer*2 blen, u, i, iosb( 4 )
integer*4 stat, sys$qiow
data curr, blen / 0, 0 /
eof = .false.
curr = curr + 1
if ( curr .le. blen / blocklen ) return
if ( using2 .le. 0 ) then
u = using
else if ( using .le. 0 ) then
u = using2
else
u = min( using, using2 )
end if
if ( u .gt. blen / blocklen ) then
type *, 'Internal error. Call the debugger.'
call exit
else if ( u .gt. 1 ) then
buffer( 1 : blen - blocklen*(u-1)) =
- buffer( 1+blocklen*(u-1) : blen )
blen = blen - blocklen*(u-1)
curr = curr - u + 1
using = using - u + 1
using2 = using2 - u + 1
else if ( u .lt. 1 ) then
blen = 0
curr = 1
end if
do while ( curr .gt. blen / blocklen )
if ( tape_file ) then
stat = sys$qiow( , %val( channel ), %val( io$_readlblk ),
- iosb,,, %ref( buffer( blen+1: )), %val( maxlen-blen )
- ,,,, )
if ( .not. stat ) then
type *, 'Error reading from tape'
call exit( stat )
else if ( .not. iosb( 1 )) then
type *, 'Error reading from tape'
call exit( iosb( 1 ))
else if ( iosb( 2 ) .eq. 0 ) then
goto 99
endif
blen = blen + iosb( 2 )
else
read( inunit, 10, end=99 ) i, buffer( blen+1: )
10 format( q, a )
blen = blen + i
end if
if ( blen .gt. maxlen ) then
type *, 'Blocking factor too large.'
call exit
end if
end do
return
99 curr = curr - 1
eof = .true.
return
end
$ eod
$!
$ write sys$output "creating TAR.CLD"
$ create TAR.CLD
$ deck
!**************************************TAR**************************************
define verb TAR
image drc0:[gordon.decus.tar]TAR
parameter P1 , label=TAPE , prompt="Tape drive"
value (required,type=$infile)
qualifier FILE
qualifier EXTRACT
qualifier BINARY
qualifier INQUIRE
qualifier SECOND_CHANCE
default
qualifier NAMES
value (default="sys$output:",type=$outfile)
qualifier LIST
value (default="sys$output:",type=$outfile)
qualifier VERBOSE
qualifier FLATTEN
default
$ eod
$!
$ write sys$output "creating TAR.FOR"
$ create TAR.FOR
$ deck
c
c This is tar for VMS, by Gordon Davisson (gordon@uw-june). It is
c not based on any liscenced software, and is completely in the
c public domain.
c
c Version 1.0, Gordon Davisson, July 24 1985
c revised by G.D. July 29 1985 to use io$_rewind right and not abuse rms$_eof
c revised by G.D. Oct 17 1985 to make sure tape is mounted
c
program tar
parameter bell = char( 7 ), lf = char( 10 )
external cli$_present, cli$_negated, cli$_locpres, cli$_locneg,
- cli$_absent, cli$_defaulted, cli$_normal,
- cli$_comma, cli$_concat
include 'tapeio.dck/list'
character fname*100, out*128, pstr*9, prot*3, link*1, tmp*1
integer*2 i, j, start, finish, flen, olen, files,
- stuff1, stuff2, stuff3, iosb( 2 )
integer*4 size, blocks, time, stat,
- cli$get_value, cli$present, sys$assign, sys$qiow
logical*1 listing, naming, extracting, binary, inquiring,
- verbose, second_chance, flatten, absent
absent( stat ) = ( stat .eq. %loc( cli$_absent ) .or.
- stat .eq. %loc( cli$_negated ))
c
c parse command line
c
c file -- read from normal file, not a tape
stat = cli$present( 'file' )
if ( absent( stat )) then
tape_file = .true.
else if ( .not. stat ) then
goto 900
else
tape_file = .false.
end if
c p1 -- tape drive name
stat = cli$get_value( 'tape', fname, flen )
if ( .not. stat ) goto 900
call open_tape( fname( :flen ))
c p2 -- files to extract/list/whatever. NOT IMPLEMENTED
c files = 0
c stat = cli$get_value( 'match', fname, flen )
c do while ( .not. absent( stat ))
c if ( .not. stat ) goto 900
c type *, 'File selector: ', fname( :flen )
c files = files + 1
c stat = cli$get_value( 'match', fname, flen )
c end do
c extract -- copy files to disk
stat = cli$present( 'extract' )
if ( absent( stat )) then
extracting = .false.
else if ( .not. stat ) then
goto 900
else
extracting = .true.
end if
c binary -- copy to disk in block mode
stat = cli$present( 'binary' )
if ( absent( stat )) then
binary = .false.
else if ( .not. stat ) then
goto 900
else
binary = .true.
end if
c inquire -- ask what to do to each file
stat = cli$present( 'inquire' )
if ( absent( stat )) then
inquiring = .false.
else if ( .not. stat ) then
goto 900
else
inquiring = .true.
end if
c second_chance -- try to recognize binary files and save them as such
stat = cli$present( 'second_chance' )
if ( absent( stat )) then
second_chance = .false.
else if ( .not. stat ) then
goto 900
else
second_chance = .true.
end if
c list -- list files on tape
stat = cli$get_value( 'list', fname, flen )
if ( absent( stat )) then
listing = .false.
else if ( .not. stat ) then
goto 900
else
open( listunit, err=920, name=fname( :flen ), type='new',
- defaultfile='tar.lis', carriagecontrol='list' )
listing = .true.
end if
c verbose -- make a verbose list
stat = cli$present( 'verbose' )
if ( absent( stat )) then
verbose = .false.
else if ( .not. stat ) then
goto 900
else
verbose = .true.
end if
c flatten -- extract all files to the current directory
stat = cli$present( 'flatten' )
if ( absent( stat )) then
flatten = .false.
else if ( .not. stat ) then
goto 900
else
flatten = .true.
end if
c names -- make a list of what unix filenames mapped to what VMS filenames
stat = cli$get_value( 'names', fname, flen )
if ( absent( stat )) then
naming = .false.
else if ( .not. stat ) then
goto 900
else
open( nameunit, err=930, name=fname( :flen ), type='new',
- defaultfile='tar.nam', carriagecontrol='list' )
naming = .true.
end if
c
c file loop: executed for each file in the archive
c
do while ( .true. )
10 using = 0
using2 = 0
call next_block
if ( eof .or. block( curr ) (1:1) .eq. char( 0 )) goto 899
c start parsing out a file entry -- parse the header
read( block( curr ), 1001 ) fname, prot, stuff1, stuff2,
- size, time, stuff3, link
1001 format( a100, 3x, a3, 2x, 2(o6,2x), 2(o11,1x), o6, 2x, a1 )
blocks = ( size + blocklen - 1 ) / blocklen
flen = index( fname, char( 0 )) - 1
if ( flen .lt. 0 ) flen = len( fname )
c add it to the list
if ( listing .and. verbose ) then
call cvt_prot( prot( 1:1 ), pstr( 1:3 ))
call cvt_prot( prot( 2:2 ), pstr( 4:6 ))
call cvt_prot( prot( 3:3 ), pstr( 7:9 ))
write( listunit, 2001 ) pstr, stuff1, stuff2, size,
- time, fname( :flen )
2001 format( a9, i3, '/', i3, i7, i11, 1x, a )
else if ( listing ) then
write( listunit, 2002 ) fname( :flen )
2002 format( a )
end if
c ignore links
if ( link .eq. '1' ) goto 10
c skip if not extracting
if ( .not. extracting ) goto 40
c figure out what to do with the file
if ( inquiring ) then
call lib$get_input( tmp, fname( :flen ) // ': [ynbtq]' )
do while ( index( ' yYnNbBtTqQ', tmp ) .eq. 0 )
call lib$get_input( tmp,
- bell // fname( :flen ) // ': [ynbtq]' )
end do
call str$upcase( tmp, tmp )
if ( tmp .eq. 'Q' ) goto 899
else
tmp = 'Y'
end if
if ( tmp .eq. 'Y' .or. tmp .eq. ' ' ) then
tmp = 'T'
if ( binary ) tmp = 'B'
else if ( tmp .eq. 'N' ) then
goto 40
end if
c parse file name
call cvt_dir_uv( fname( :flen ), out, olen )
if ( flatten ) then
i = index( out( :olen ), ']' )
out = out( i+1:olen )
olen = olen - i
end if
if ( tmp .eq. 'B' ) goto 30
c create a text file
20 open( outunit, name=out( :olen ), type='new', recl=maxrecl,
- defaultfile='.', carriagecontrol='list', err=38 )
if ( size .le. 0 ) then
close( outunit )
goto 99
end if
c copy the file to disk
if ( second_chance ) using2 = curr
call next_block
blocks = blocks - 1
start = 1
do while ( size .gt. 0 )
using = curr
finish = index( block( curr ) ( start: ), lf )
do while ( finish .eq. 0 .and. blocks .gt. 0 .and.
- curr - using + 1 .lt. recblocks )
call next_block
blocks = blocks - 1
if ( eof ) goto 990
finish = index( block( curr ), lf )
end do
if ( finish .eq. 0 ) finish = 2 * blocklen + 1
if ( using .eq. curr ) finish = finish + start - 1
i = start + blocklen * (using-1)
j = finish + blocklen * (curr-1)
start = finish + 1
size = size - j + i - 1
if ( size .lt. 0 ) then
j = j + size
size = 0
end if
if ( using2 .ne. 0 .and. j - i .gt. maxrecl ) then
type *, 'Giving ', fname( :flen ), ' a second chance...'
blocks = blocks + curr - using2
curr = using2
using = 0
using2 = 0
close( outunit, dispose='delete' )
goto 30
end if
write( outunit, 2005, err=39, iostat=stat )
- buffer( i : j-1 )
2005 format( a )
if ( curr - using2 .ge. saveblocks ) using2 = 0
end do
close( outunit )
goto 99
c create a binary file
30 using = 0
using2 = 0
open( outunit, name=out( :olen ), type='new',
- recl=blocklen, recordtype='fixed', defaultfile='.',
- carriagecontrol='none', err=39 )
do while ( blocks .gt. 0 )
call next_block
blocks = blocks - 1
write( outunit, 3001, err=39, iostat=stat ) block( curr )
3001 format( a )
end do
close( outunit )
goto 99
c got an error creating the file: skip it.
38 type *, 'Error creating ', out( :olen ), ' skipping...'
goto 40
c got an error writing the file: skip the rest of it.
39 type *, 'Error writing ', out( :olen ), ' skipping...'
close( outunit, dispose='delete' )
c skip the file
40 using = 0
using2 = 0
do i = 1, blocks
call next_block
if ( eof ) goto 990
end do
goto 10
c successfully copied file to disk: enter it in the names file
99 if ( naming ) write( nameunit, 2000 ) out( :olen ),
- fname( :flen )
2000 format( a, ' -> ', a )
end do
c end of tape: close it and exit!
899 close( inunit )
call exit
c
c fatal errors
c
900 type *, 'Error parsing command line'
call exit
920 type *, 'Error opening listing file, ', fname( :flen )
call exit
930 type *, 'Error opening names file, ', fname( :flen )
call exit
990 type *, 'Premature end of tape while reading ', fname( :flen )
call exit
end
$ eod
$!
$ write sys$output "creating TAR.HLP"
$ create TAR.HLP
$ deck
1 TAR
Invokes the tape archive reader to read unix-format tapes.
Format:
TAR tape-name[:]
2 Parameter
tape-name[:]
Specifies the device name of the tape drive the archive is mounted on.
The archive must be mounted foreign.
If the /FILE qualifier is specified, this parameter is interpreted as
the file name for the archive.
2 Command_Qualifiers
/BINARY
Specifies that the files extracted should be put into fixed-length-512-
byte-record files and that no interpretation should be preformed on
the contents.
/EXTRACT
Specifies that the files in the archive should be copied into the
directory, or subdirectories (depending on the /FLATTEN qualifier).
/FILE
Specifies that, instead of a tape, the archive is contained in a normal
file.
/FLATTEN (D)
Specifies that files extracted from the archive should be put in the
default directory even when the files would normally be put in
subdirectories.
This qualifier is on by default because the program is incapable of
creating subdirectories to put the extracted files in, so unless they
exist already, /NOFLATTEN in a pure loss.
/INQUIRE
Tells the program to ask the user what to do with each file it has been
told to extract. The program prompts with the filename followed by a
list of options. The options are:
y - extract the file normally
n - skip the file
t - extract the file in text (not binary) mode
b - extract the file in binary mode
q - exit the program
The y option is equivalent t or b depending on whether the /BINARY
qualifier was given.
/LIST
/LIST=filename (default = sys$output:)
Tells the program to create a list of all of the files on the tape.
If the /VERBOSE qualifier is also specified, the list contains more
than just the file names.
/NAMES
/NAMES=filename (default = sys$output:)
If files are extracted, the program creates a file giving the names
of the files on the tape and the VMS filenames they were mapped into
when extracted.
/SECOND_CHANCE (D)
This specifies that if a file is being extracted in text mode, and
a line longer then 512 bytes in encountered sufficiently near the
beginning of the file, it should be re-extracted in binary mode.
If negated, files with long lines are discarded in text mode.
/VERBOSE
This specifies that lists should contain more information than just
the filename.
2 Bugs
Here's a list of some of the more noticable bugs and deficiencies:
- It can't write tar tapes.
- It can't operate on only some of the files on a tape.
- Verbose listings contain the date in seconds since 1970 or