[net.sources] Basic programs to read TAR tapes

minow (07/25/82)

-h- rdmt.bas	Sat Jul 24 23:16:31 1982	RDMT.BAS;4
1	extend
2	! &
	! Read a Unix tar magtape onto a RSTS disk.  One file only.	&
	! Author: Martin Minow.						&
	! &
	! Edit lines 20 and 30 to change the names of the input and	&
	! output devices.						&
	! &

20	open "dk:tartap.dat" for output as file 2
30	open "mt0:" for input as file 1, recordsize 10320%
100	i% = magtape(3%, 0%, 1%)		! Rewind
1000	on error goto 19000			! Trap all errors
1010	while 1%
1020		get #1%\ i% = recount		! Read one block
1040		put #2%+swap%(1%), count i%	! Write the block
1990	next
19000	if err = 11% then print "Normal ending at EOF" else on error goto 0
19010	close 2%
32767	end
-h- untar.bas	Sat Jul 24 23:16:31 1982	UNTAR.BAS;9
1	extend
2	! &
	! UNTAR.BAS							&
	! &
	! Author: Jim Burrows and Martin Minow
	! &
	! Decompile Unix tar tapes on RSTS/E.  The file has previously	&
	! been copied onto a disk using RDMT.BAS			&
	! &
	! You should assume that you will have to modify this program	&
	! to suit your specific needs.					&
	! &

10	On error goto 19000		! Common error handler		&
\	LF

minow (07/25/82)

-h- rdmt.bas	Sat Jul 24 23:16:31 1982	RDMT.BAS;4
1	extend
2	! &
	! Read a Unix tar magtape onto a RSTS disk.  One file only.	&
	! Author: Martin Minow.						&
	! &
	! Edit lines 20 and 30 to change the names of the input and	&
	! output devices.						&
	! &

20	open "dk:tartap.dat" for output as file 2
30	open "mt0:" for input as file 1, recordsize 10320%
100	i% = magtape(3%, 0%, 1%)		! Rewind
1000	on error goto 19000			! Trap all errors
1010	while 1%
1020		get #1%\ i% = recount		! Read one block
1040		put #2%+swap%(1%), count i%	! Write the block
1990	next
19000	if err = 11% then print "Normal ending at EOF" else on error goto 0
19010	close 2%
32767	end
-h- untar.bas	Sat Jul 24 23:16:31 1982	UNTAR.BAS;9
1	extend
2	! &
	! UNTAR.BAS							&
	! &
	! Author: Jim Burrows and Martin Minow
	! &
	! Decompile Unix tar tapes on RSTS/E.  The file has previously	&
	! been copied onto a disk using RDMT.BAS			&
	! &
	! You should assume that you will have to modify this program	&
	! to suit your specific needs.					&
	! &

10	On error goto 19000		! Common error handler		&
\	LF$ = chr$(10%)			! Line feed			&

100	input "Input device (and file) <DK:tartap.dat>: "; InDev$	&
\	InDev$ = cvt$$(InDev$, -1%)					&
\	InDev$ = "DK:tartap.dat" if InDev$ = ""				&
\	Rsize% = 512%							&
\	IsTape% = 0%			! Direct from tape don't work	&
\	open InDev$ for input as file #1%, recordsize Rsize%		&
		! InDev$ contains a block-by-block copy of the TAR tape	&

110	input "Log file <SY:FILES.LST>"; LogFile$			&
\	LogFile$ = cvt$$(LogFile$, -1%)					&
\	LogFile$ = "SY:FILES.LST" if LogFile$ = ""			&
\	open LogFile$ for output as file #3%				&
		! LogFile will contain a log of the unTAR process

120	input "Output header <DSKZ:>"; OutHead$				&
\	OutHead$ = cvt$$(OutHead$, -1%)					&
\	OutHead$ = "DSKZ:" if OutHead$ = ""				&
		! Output file header

200	if IsTape% then		! This should be copied to RDMT.BAS	&
		if Fngetyesno%("Rewind", "Yes") then			&
			q% = magtape(3%, 0%, 1%)

210	if IsTape% then		! This should be copied to RDMT.BAS	&
		input "Skip N files before reading <0>: "; Fskip%	&
\		for i% = 1% to Fskip%					&
\		    q% = 1%						&
\		    while q% <> 0%					&
\			q% = magtape(4%, 32767%, 1%)			&
\			q% = (magtape(7%, 0%, 2%) and 128%) = 0%	&
\		    next						&
\		next i%							&

220	IsAscii% = Fngetyesno%("Convert \n to <CR><LF>", "Yes")

1000	until 0%			! For all blocks in the file,	&
					! Get the file header and	&
					! Process the file		&
\		get #1%			! Read header record 		&
\		field #1%,		! Parse the record buffer:	&
			100% as UnixFilNam$,	! Path name		&
			24% as Junk$,		! Ignored		&
			8% as BlkCnt$,		! Blocks of data	&
			3% as BytCnt$		! Bytes in last block	&
\		UnixFilNam$,FilNam$=UnixFilNam$+'' ! Grab file name	&
\		BlkCnt$=cvt$$(blkcnt$,-1%)	! Squeeze out blanks	&
\		BlkCnt$='0'			! and get the true	&
			if BlkCnt$ = ''		! block count		&
\		BytCnt$=cvt$$(Bytcnt$,-1%)	! Do the same for the	&
\		BytCnt$='0'			! bytes left in the	&
			if BytCnt$ = ''		! last block.		&
\		q%=instr(1%,FilNam$,'/')	! Remove path names	&
\		while q%			! All of them		&
\			FilNam$=right(FilNam$,q%+1%)	! Remove path	&
\			q%=instr(1%,FilNam$,'/')	! More?		&
\		next				! Loop			&
\		q%=instr(1%,filnam$,'_')	! Squeeze "foo_bar" to	&
\		While q%			! "foobar"		&
\			FilNam$=left(Filnam$,q%-1%)+right(filnam$,q%+1%) &
\			q%=instr(1%,filnam$,'_') ! look for another '_'	&
\		next				! for all '_'		&
\		OutFile$ = OutHead$ + FilNam$	! Output file name	&
\		BytCnt%=Fnb%(BytCnt$, 8%)	! convert oct->int for 	&
\		BlkCnt%=Fnb%(BlkCnt$, 8%)	! block and byte counts	&
\		goto 8000 if (BlkCnt% = 0% and BytCnt% = 0%)		&
\		print '"'; UnixFilNam$; '"';				&
			BlkCnt%; " blocks, "; BytCnt%; " bytes in last"	& 
			! Do all setup for the next file.

1100		For Blk%=1% to BlkCnt%		! Copy all the blocks	&
\			Get #1%			! From channel one	&
\			InCount% = recount	! How many bytes	&
\			GoSub 10000		! This will open a file	&
\			GoSub 11000		! This writes record	&
\		next blk%			! Do all blocks		&
\		If (BytCnt%) then		! If stuff in a final	&
			get #1%			! block, get it and	&
\			InCount% = recount	! How many bytes	&
\			InCount% = BytCnt% if BytCnt% < InCount%	&
\			GoSub 10000		! (maybe open file)	&
\			GoSub 11000		! And output it		&

1200		Close #2%			! Outfile finished	&
\		print "File finished"

8000	next					! For entire Archive	&

9000	Close #3%				! Logfile finished	&
\	goto 32767				! Exit program.		&

10000	return					! Exit if channel 2 is	&
		if (Bufsiz(2%) <> 0%)		! already open		&
\	Open OutFile$ for input as file #2%	! See if it's there	&
\	Print OutFile$; " already exists!"				&
\	Close #2%							&
\	Input "new File name? "; OutFile$				&
\	Goto 10000							&

10100	Open OutFile$ for output as file #2%				&
\	Print #3%, UnixFilNam$; "==>"; OutFile$				&

10200	return								&

10300	Print OutFile$; " is illegal"					&
	\ Input "new File name? "; OutFile$				&
	\ Goto 10000							&



11000	If not IsAscii% then						&
		put #2% + Swap%(1%), count InCount%	! Binary	&
\		return							&

11010	i% = 0%								&
\	While i% < InCount%						&
\		field #1%, i% as A$, InCount% - i% as A$		&
\		j% = instr(1%, A$, LF$)					&
\		if (j% = 0%) then					&
			print #2%, A$;		! Finish this block	&
\			i% = InCount%		! Exit next time	&
\			goto 11080		! Continue		&

11020		field #1%, i% as A$, j%-1% as A$			&
\		print #2%, A$			! Line + <CR><LF>	&
\		i% = i% + j%			! Step over newline	&

11080	next					! For the record	&

11090	return

19000	resume 10100 if (erl = 10000 and err=5%)! Can't find file	&
	\ resume 10300 if (erl = 10000)		! Bad file name		&
	\ resume 9000 if (erl = 1000 and err = 11%)	! Normal	&

19100	print "Failed at block "; Blk%

19999	on error goto 0				! Crash on fatal errors	&

24000	def fngetyesno%(prompt$, default$)	! Prompt and get truth	&
\	q% = 0%								&
\	until (q% = 1% or q% = 5%)					&
\		print prompt$; "(Y/N) <"; default$; ">";		&
\		input line q$						&
\		q$ = cvt$$(q$, -1%)					&
\		q$ = cvt$$(default$, -1%) if q$ = ""			&
\		q% = instr(1%, "YES NO", q$)				&
\	next								&
\	fngetyesno% = (q% = 1%)						&
\	fnend

25550	def fnb%(s$,b%)				! BASE B% TO INTEGER	&
\	q=0 &
\	for q.ndx%=1% to len(s$) &
\		q=b%*q+instr(1%, &
			"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", &
			left(s$,1%))-1% &
\		s$=right(s$,2%) &
\	next q.ndx% &
\	q=q-65536. if q>32767. &
\	fnb%=q &
\	fnend &

32767	end
-h- vrdmt.bas	Sat Jul 24 23:16:31 1982	VRDMT.BAS;2
1	extend
2	! &
	! Read a Unix tar magtape onto a VMS disk.  One file only.	&
	! Author: Martin Minow						&
	! &

10	print "Input from <mta0:> ";\ input line x$\ x$ = cvt$$(x$, -1%)
12	x$ = "mta0:" if x$ = ""
14	print "Don't forget to mount/foreign/blocksize=10240 "; x$
20	open "tartap.dat" for output as file 2,		&
		access write,				&
		organization virtual,			&
		recordsize 512%
30	open x$ for input as file 1,			&
		access read,				&
		organization undefined,			&
		recordsize 32766%
100	i% = magtape(3%, 0%, 1%)		! Rewind
1000	on error goto 19000
1005	counter% = 0%
1007	field #2%, 512% as outbuffer$
1010	while 1%
1015		on error goto 19000
1020		get #1\ inputcount% = recount
1050		counter% = counter% + 1%
1060		print "record"; counter%; inputcount%; " bytes"
2000		place% = 0%
2010		while place% < inputcount%
2020			field #1%, place% as q$, 512% as q$
2030			lset outbuffer$ = q$
2040			put #2%, count 512%
2050			outcount% = outcount% + 1%
2060			print " "; outcount%;
2070			place% = place% + 512%
2080		next
2090		print
9990	next
19000	if err = 11% then resume 19800
19005	recordcount% = recount
19010	print "Fatal error "; err; " after reading "; counter%; " records."
19015	print "recount = "; recordcount%
19020	print "eof forced after reading "; counter%; " records"\ resume 19900
19800	print "Normal completion after reading "; counter%; " records."
19900	close 2%
32767	end
-h- vuntar.bas	Sat Jul 24 23:16:31 1982	VUNTAR.BAS;9
1	extend
2	! &
	! VUNTAR.BAS							&
	! &
	! Author: Jim Burrows and Martin Minow
	! &
	! Decompile Unix tar tapes on VAX/VMS.  The file has previously	&
	! been copied onto a disk using VRDMT.BAS			&
	! &
	! You should assume that you will have to modify this program	&
	! to suit your specific needs.					&
	! &

10	On error goto 19000		! Common error handler		&
\	LF$ = chr$(10%)			! Line feed			&

100	input "Input device (and file) <tartap.dat>: "; InDev$		&
\	InDev$ = cvt$$(InDev$, -1%)					&
\	InDev$ = "tartap.dat" if InDev$ = ""				&
\	Rsize% = 512%							&
\	IsTape% = 0%			! Direct from tape don't work	&
\	open InDev$ for input as file #1%,				&
		organization virtual,					&
		recordsize Rsize%					&
		! InDev$ contains a block-by-block copy of the TAR tape	&

110	input "Log file <files.lst>"; LogFile$				&
\	LogFile$ = cvt$$(LogFile$, -1%)					&
\	LogFile$ = "files.lst" if LogFile$ = ""				&
\	open LogFile$ for output as file #3%				& 
		! LogFile will contain a log of the unTAR process

120	input "Output header <none>"; OutHead$				&
\	OutHead$ = cvt$$(OutHead$, -1%)					&
		! Output file header

200	if IsTape% then		! This should be copied to RDMT.BAS	&
		if Fngetyesno%("Rewind", "Yes") then			&
			q% = magtape(3%, 0%, 1%)

210	if IsTape% then		! This should be copied to RDMT.BAS	&
		input "Skip N files before reading <0>: "; Fskip%	&
\		for i% = 1% to Fskip%					&
\		    q% = 1%						&
\		    while q% <> 0%					&
\			q% = magtape(4%, 32767%, 1%)			&
\			q% = (magtape(7%, 0%, 2%) and 128%) = 0%	&
\		    next						&
\		next i%							&

220	IsAscii% = Fngetyesno%("Convert \n to <CR><LF>", "Yes")

1000	until 0%			! For all blocks in the file,	&
					! Get the file header and	&
					! Process the file		&
\		get #1%			! Read header record 		&
\		field #1%,		! Parse the record buffer:	&
			100% as UnixFilNam$,	! Path name		&
			24% as Junk$,		! Ignored		&
			8% as BlkCnt$,		! Blocks of data	&
			3% as BytCnt$		! Bytes in last block	&
\		UnixFilNam$,FilNam$=UnixFilNam$+'' ! Grab file name	&
\		BlkCnt$ = cvt$$(blkcnt$,-1%)	! Squeeze out blanks	&
\		BlkCnt$ = '0'			! and get the true	&
			if BlkCnt$ = ''		! block count		&
\		BytCnt$ = cvt$$(Bytcnt$,-1%)	! Do the same for the	&
\		BytCnt$ = '0'			! bytes left in the	&
			if BytCnt$ = ''		! last block.		&
\		q% = instr(1%, FilNam$, '/')	! Remove path names	&
\		while q%			! All of them		&
\			FilNam$ = right(FilNam$, q%+1%)	! Remove path	&
\			q% = instr(1%, FilNam$, '/')	! More?		&
\		next				! Loop			&
\		q% = instr(1%,filnam$,'_')	! Squeeze "foo_bar" to	&
\		While q%			! "foobar"		&
\			FilNam$ = left(Filnam$,q%-1%)+right(filnam$,q%+1%) &
\			q%  =instr(1%,filnam$,'_') ! another '_' ?	&
\		next				! for all '_'		&
\		OutFile$ = OutHead$ + FilNam$	! Output file name	&
\		BytCnt% = Fnb%(BytCnt$, 8%)	! convert oct->int for 	&
\		BlkCnt% = Fnb%(BlkCnt$, 8%)	! block and byte counts	&
\		goto 8000 if (BlkCnt% = 0% and BytCnt% = 0%)		&
\		print '"'; UnixFilNam$; '"';				&
			BlkCnt%; " blocks, "; BytCnt%; " bytes in last"	& 

1100		For Blk%=1% to BlkCnt%		! Copy all the blocks	&
\			Get #1%			! From channel one	&
\			InCount% = recount	! How many bytes	&
\			GoSub 10000		! This will open a file	&
\			GoSub 11000		! This writes record	&
\		next blk%			! Do all blocks		&
\		If (BytCnt%) then		! If stuff in a final	&
			get #1%			! block, get it and	&
\			InCount% = recount	! How many bytes	&
\			InCount% = BytCnt% if BytCnt% < InCount%	&
\			GoSub 10000		! (maybe open file)	&
\			GoSub 11000		! And output it		&

1200		Close #2%			! Outfile finished	&
\		print "File finished"

8000	next					! For entire Archive	&

9000	Close #3%				! Logfile finished	&
\	goto 32767				! Exit program.		&

10000	return					! Exit if channel 2 is	&
		if (Bufsiz(2%) <> 0%)		! already open		&
\	Open OutFile$ for input as file #2%	! See if it's there	&
\	Print OutFile$; " already exists!"				&
\	Close #2%							&
\	Input "new File name? "; OutFile$				&
\	Goto 10000							&

10100	if IsAscii%	then Open OutFile$ for output as file #2%,	&
				organization sequential variable,	&
				recordsize 520%				&
			else Open OutFile$ for output as file #2%,	&
				organization virtual,			&
				recordsize 512%				&
\	Print #3%, UnixFilNam$; "==>"; OutFile$				&

10200	return								&

10300	Print OutFile$; " is illegal"					&
	\ Input "new File name? "; OutFile$				&
	\ Goto 10000							&


11000	If not IsAscii% then						&
		put #2% + Swap%(1%), count InCount%	! Binary	&
\		return							&

11010	i% = 0%								&
\	While i% < InCount%						&
\		field #1%, i% as A$, InCount% - i% as A$		&
\		j% = instr(1%, A$, LF$)					&
\		if (j% = 0%) then					&
			print #2%, A$;		! Finish this block	&
\			i% = InCount%		! Exit next time	&
\			goto 11080		! Continue		&

11020		field #1%, i% as A$, j%-1% as A$			&
\		print #2%, A$			! Line + <CR><LF>	&
\		i% = i% + j%			! Step over newline	&

11080	next					! For the record	&

11090	return

19000	resume 10100 if (erl = 10000 and err=5%)! Can't find file	&
	\ resume 10300 if (erl = 10000)		! Bad file name		&
	\ resume 9000 if (erl = 1000 and err = 11%)	! Normal	&

19100	print "Failed with error"; err; "at block"; Blk%		&
	\ close #3%				! Close log file	&

19999	on error goto 0				! Crash on fatal errors	&

24000	def fngetyesno%(prompt$, default$)	! Prompt and get truth	&
\	q% = 0%								&
\	until (q% = 1% or q% = 5%)					&
\		print prompt$; "(Y/N) <"; default$; ">";		&
\		input line q$						&
\		q$ = cvt$$(q$, -1%)					&
\		q$ = cvt$$(default$, -1%) if q$ = ""			&
\		q% = instr(1%, "YES NO", q$)				&
\	next								&
\	fngetyesno% = (q% = 1%)						&
\	fnend

25550	def fnb%(s$,b%)				! BASE B% TO INTEGER	&
\	q=0 &
\	for q.ndx%=1% to len(s$) &
\		q=b%*q+instr(1%, &
			"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", &
			left(s$,1%))-1% &
\		s$=right(s$,2%) &
\	next q.ndx% &
\	q=q-65536. if q>32767. &
\	fnb%=q &
\	fnend &

32767	end