1 /* $NetBSD: tcopy.c,v 1.15 2008/07/21 14:19:26 lukem Exp $ */
4 * Copyright (c) 1985, 1987, 1993, 1995
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1985, 1987, 1993\
35 The Regents of the University of California. All rights reserved.");
40 static char sccsid
[] = "@(#)tcopy.c 8.3 (Berkeley) 1/23/95";
42 __RCSID("$NetBSD: tcopy.c,v 1.15 2008/07/21 14:19:26 lukem Exp $");
45 #include <sys/types.h>
47 #include <sys/ioctl.h>
61 #define MAXREC (64 * 1024)
64 int filen
, guesslen
, maxblk
= MAXREC
;
69 void *getspace
__P((int));
71 int main
__P((int, char **));
72 void usage
__P((void));
73 void verify
__P((int, int, char *));
74 void writeop
__P((int, int));
81 int ch
, needeof
, nw
, inp
, outp
;
82 ssize_t lastnread
, nread
;
83 enum {READ
, VERIFY
, COPY
, COPYVERIFY
} op
= READ
;
91 while ((ch
= getopt(argc
, argv
, "cs:vx")) != -1)
97 maxblk
= atoi(optarg
);
99 warnx("illegal block size");
132 if ((outp
= open(argv
[1], op
== VERIFY
? O_RDONLY
:
133 op
== COPY
? O_WRONLY
: O_RDWR
, DEFFILEMODE
)) < 0) {
134 err(3, "%s", argv
[1]);
141 if ((inp
= open(inf
, O_RDONLY
, 0)) < 0)
144 buff
= getspace(maxblk
);
147 verify(inp
, outp
, buff
);
151 if ((oldsig
= signal(SIGINT
, SIG_IGN
)) != SIG_IGN
)
152 (void) signal(SIGINT
, intr
);
155 for (lastnread
= NOCOUNT
;;) {
156 if ((nread
= read(inp
, buff
, maxblk
)) == -1) {
157 while (errno
== EINVAL
&& (maxblk
-= 1024)) {
158 nread
= read(inp
, buff
, maxblk
);
162 err(1, "read error, file %d, record %ld",
164 } else if (nread
!= lastnread
) {
165 if (lastnread
!= 0 && lastnread
!= NOCOUNT
) {
166 if (lastrec
== 0 && nread
== 0)
167 fprintf(msg
, "%ld records\n", record
);
168 else if (record
- lastrec
> 1)
169 fprintf(msg
, "records %ld to %ld\n",
172 fprintf(msg
, "record %ld\n", lastrec
);
175 fprintf(msg
, "file %d: block size %ld: ",
177 (void) fflush(stdout
);
182 if (op
== COPY
|| op
== COPYVERIFY
) {
184 writeop(outp
, MTWEOF
);
187 nw
= write(outp
, buff
, nread
);
191 "write error, file %d, record %ld: ",
195 ": %s", strerror(error
));
198 "write (%d) != read (%ld)\n",
200 fprintf(stderr
, "copy aborted\n");
207 if (lastnread
<= 0 && lastnread
!= NOCOUNT
) {
208 fprintf(msg
, "eot\n");
212 "file %d: eof after %ld records: %lld bytes\n",
213 filen
, record
, (long long)size
);
217 size
= record
= lastrec
= 0;
222 fprintf(msg
, "total length: %lld bytes\n", (long long)tsize
);
223 (void)signal(SIGINT
, oldsig
);
224 if (op
== COPY
|| op
== COPYVERIFY
) {
225 writeop(outp
, MTWEOF
);
226 writeop(outp
, MTWEOF
);
227 if (op
== COPYVERIFY
) {
228 writeop(outp
, MTREW
);
230 verify(inp
, outp
, buff
);
237 verify(inp
, outp
, outb
)
241 int eot
, inmaxblk
, inn
, outmaxblk
, outn
;
244 inb
= getspace(maxblk
);
245 inmaxblk
= outmaxblk
= maxblk
;
246 for (eot
= 0;; guesslen
= 0) {
247 if ((inn
= read(inp
, inb
, inmaxblk
)) == -1) {
249 while (errno
== EINVAL
&& (inmaxblk
-= 1024)) {
250 inn
= read(inp
, inb
, inmaxblk
);
257 r1
: if ((outn
= read(outp
, outb
, outmaxblk
)) == -1) {
259 while (errno
== EINVAL
&& (outmaxblk
-= 1024)) {
260 outn
= read(outp
, outb
, outmaxblk
);
267 r2
: if (inn
!= outn
) {
269 "%s: tapes have different block sizes; %d != %d.\n",
275 fprintf(msg
, "%s: tapes are identical.\n",
281 if (memcmp(inb
, outb
, inn
)) {
283 "%s: tapes have different data.\n",
299 if (record
- lastrec
> 1)
300 fprintf(msg
, "records %ld to %ld\n", lastrec
, record
);
302 fprintf(msg
, "record %ld\n", lastrec
);
304 fprintf(msg
, "interrupt at file %d: record %ld\n", filen
, record
);
305 fprintf(msg
, "total length: %lld bytes\n", (long long)(tsize
+ size
));
306 (void)raise_default_signal(signo
);
316 if ((bp
= malloc((size_t)blk
)) == NULL
)
317 errx(11, "no memory");
329 op
.mt_count
= (daddr_t
)1;
330 if (ioctl(fd
, MTIOCTOP
, (char *)&op
) < 0)
338 fprintf(stderr
, "usage: tcopy [-cvx] [-s maxblk] src [dest]\n");