aboutsummaryrefslogtreecommitdiff
path: root/noao/imred/vtel/tcopy.x
blob: 427095635a2ac896bd59f275066d4aee92ccf912 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
include <error.h>
include <fset.h>
include <printf.h>
include <mach.h>
include	"vt.h"

define	SZ_VTRECFD	5120		# length, in chars, of full disk recs
define	YABUF		20000			# Yet Another BUFfer
define	SWAP		{temp=$1;$1=$2;$2=temp}
define	MAX_RANGES	100

# TCOPY -- This is an asynchronous tape to tape copy routine.  It considers
# the input and output to be streaming devices. 
# The user specifies which files on tape s/he wants and a root name for the
# output file names.

procedure t_tcopy()

char	inputfile[SZ_FNAME]
char	files[SZ_LINE]
char	outputfile[SZ_FNAME]

char	tapename[SZ_FNAME]
int	filerange[2 * MAX_RANGES + 1]
int	nfiles, filenumber, numrecords, whichfile
bool	verbose 

int	decode_ranges(), mtfile()
int	get_next_number(), tapecopy(), mtneedfileno()
bool	clgetb()
errchk	tapecopy

begin
	call fseti (STDOUT, F_FLUSHNL, YES)

        # Get input file(s).
        call clgstr ("inputfile", inputfile, SZ_FNAME)
	if (mtfile (inputfile) == NO || mtneedfileno (inputfile) == NO) {
	    call strcpy ("1", files, SZ_LINE)
        } else {
	    call clgstr ("files", files, SZ_LINE)
	}

        if (decode_ranges (files, filerange, MAX_RANGES, nfiles) == ERR)
	    call error (0, "Illegal file number list.")

	# Get the output file from the cl.
	call clgstr ("outputfile", outputfile, SZ_FNAME)

	# See if the output is mag tape, if not, error.
	if (mtfile (outputfile) == NO)
	    call error (1, "Outputfile should be magnetic tape.")

	# If no tape file number is given, then ask whether the tape
	# is blank or contains data.  If blank then start at [1], else
	# start at [EOT].

	if (mtneedfileno(outputfile) == YES)
	    if (!clgetb ("new_tape"))
		call mtfname (outputfile, EOT, outputfile, SZ_FNAME)
	    else
		call mtfname (outputfile, 1, outputfile, SZ_FNAME)

	# Get verbose flag.
	verbose = clgetb ("verbose")

        # Loop over files
	whichfile = 1
	filenumber = 0
        while (get_next_number (filerange, filenumber) != EOF) {

	    # Assemble the appropriate tape file name.
	    if (mtneedfileno (inputfile) == NO)
		call strcpy (inputfile, tapename, SZ_FNAME)
	    else
		call mtfname (inputfile, filenumber, tapename, SZ_FNAME)

	    if (whichfile > 1) {
	        # Assemble the appropriate output file name.
		call mtfname (outputfile, EOT, outputfile, SZ_FNAME)
	    }

	    if (verbose) {
		call printf ("reading %s, writing %s\n")
    		    call pargstr(tapename)
    		    call pargstr(outputfile)
	    }

	    iferr {
	        numrecords = tapecopy (tapename, outputfile)
	    } then {
		call eprintf ("Error copying file: %s\n")
		    call pargstr (tapename)
		call erract (EA_WARN)
		next
	    } else if (numrecords == 0) {
	        call printf ("Tape at EOT\n")
		break
	    }
	    whichfile = whichfile + 1

        }  # End while.
end


# TAPECOPY -- This is the actual tape to tape copy routine.

int procedure tapecopy (infile, outfile)

char	infile[SZ_FNAME]
char	outfile[SZ_FNAME]

pointer	bufa, bufb, temp
int	bufsz, numrecords
int	nbytes, lastnbytes, in, out
int	fstati(), mtopen(), awaitb()
errchk	mtopen, areadb, awriteb, awaitb

begin
	# Open input file, see if it has anything in it.  If not, return.
	in = mtopen (infile, READ_ONLY, 0)

	bufsz = fstati (in, F_MAXBUFSIZE)	# Maximum output buffer size.
	if (bufsz == 0)				# If no max, set a max.
	    bufsz = YABUF

	call malloc (bufa, bufsz, TY_CHAR) 	# Allocate output buffer.
	call malloc (bufb, bufsz, TY_CHAR)	# Other output buffer

	call areadb (in, Memc[bufa], bufsz, 0)
	nbytes = awaitb (in)
	if (nbytes == EOF) {
	    call close (in)
	    call mfree (bufa, TY_CHAR)
	    call mfree (bufb, TY_CHAR)
	    return (EOF)
	}

	# Open the output file.
	out = mtopen (outfile, WRITE_ONLY, 0)

	lastnbytes = 0				# Last record size memory.
	numrecords = 0				# Number of records read.

	if (nbytes > 0) {
	    if (nbytes > SZ_VTRECFD*SZB_SHORT &&
		nbytes < SZ_VTRECFD*SZB_SHORT+600)
		nbytes = SZ_VTRECFD*SZB_SHORT
	    call awriteb (out, Memc[bufa], nbytes, 0)
	    call areadb (in, Memc[bufb], bufsz, 0)
	    numrecords = numrecords + 1
	}

	SWAP (bufa, bufb)

	# Main Loop.
	repeat {
	    if (awaitb (out) != nbytes) {
		call printf ("Write error, record = %d.\n")
		    call pargi (numrecords+1)
	    }

	    nbytes = awaitb (in)
	    if (nbytes == ERR) {
		call printf ("Read error, record = %d.\n")
		    call pargi (numrecords+1)
		nbytes = lastnbytes
	    }
	    lastnbytes = nbytes

	    if (nbytes > 0) {
		if (nbytes > SZ_VTRECFD*SZB_SHORT &&
		    nbytes < SZ_VTRECFD*SZB_SHORT+600)
		    nbytes = SZ_VTRECFD*SZB_SHORT
	        call awriteb (out, Memc[bufa], nbytes, 0)
	        call areadb (in, Memc[bufb], bufsz, 0)
	        numrecords = numrecords + 1
	    }

	    SWAP (bufa, bufb)

	} until (nbytes == 0)	# all done

	call mfree (bufa, TY_CHAR)
	call mfree (bufb, TY_CHAR)
	call close (in)
	call close (out)

	return (numrecords)
end