summaryrefslogtreecommitdiffstats
path: root/usr.bin/tcopy
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1999-04-30 13:13:32 +0000
committerphk <phk@FreeBSD.org>1999-04-30 13:13:32 +0000
commitca402ccf60ff298de9082838079fbbea0c315f01 (patch)
tree966de84d1239eda328387c22dc2096862aa6a585 /usr.bin/tcopy
parent6f402caa86e0c6c0c2fc853ea9f38902b9f85f30 (diff)
downloadFreeBSD-src-ca402ccf60ff298de9082838079fbbea0c315f01.zip
FreeBSD-src-ca402ccf60ff298de9082838079fbbea0c315f01.tar.gz
Tcopy uses 32 bit unsigned to accumulate a count of bytes read/written.
That doesn't work well for tapes over 4G. I use tcopy a lot to write images of a tape to tape as tape to tape copying is terribly slow. Slower than it should be. Quickly found out tcopy can not rewind a file when doing copy/verify. PR: 11386 Submitted by: David Kelly dkelly@hiwaay.net Reviewed by: phk
Diffstat (limited to 'usr.bin/tcopy')
-rw-r--r--usr.bin/tcopy/tcopy.116
-rw-r--r--usr.bin/tcopy/tcopy.c50
2 files changed, 51 insertions, 15 deletions
diff --git a/usr.bin/tcopy/tcopy.1 b/usr.bin/tcopy/tcopy.1
index 32cf748..d201073 100644
--- a/usr.bin/tcopy/tcopy.1
+++ b/usr.bin/tcopy/tcopy.1
@@ -87,3 +87,19 @@ The
.Nm
command appeared in
.Bx 4.3 .
+.Sh BUGS
+Writting an image of a tape to a file does not preserve much more than
+the raw data. Block size(s) and tape EOF marks are lost which would
+otherwise be preserved in a tape-to-tape copy.
+
+EOD is determined by two sequential EOF marks with no data between.
+There are old systems which typically wrote three EOF's between tape
+files.
+.Xr tcopy 1
+will erroneously stop copying early in this case.
+
+When using the copy/verify option \-c
+.Xr tcopy 1
+does not rewind the tapes prior to start. A rewind is performed
+after writing prior to the verification stage. If one doesn't start
+at BOT then the comparison may not be of the intended data.
diff --git a/usr.bin/tcopy/tcopy.c b/usr.bin/tcopy/tcopy.c
index a3a40ad..b004868 100644
--- a/usr.bin/tcopy/tcopy.c
+++ b/usr.bin/tcopy/tcopy.c
@@ -42,7 +42,7 @@ static const char copyright[] =
static char sccsid[] = "@(#)tcopy.c 8.2 (Berkeley) 4/17/94";
#endif
static const char rcsid[] =
- "$Id$";
+ "$Id: tcopy.c,v 1.4 1997/08/14 06:41:00 charnier Exp $";
#endif /* not lint */
#include <sys/types.h>
@@ -65,7 +65,7 @@ static const char rcsid[] =
#define NOCOUNT (-2)
int filen, guesslen, maxblk = MAXREC;
-u_long lastrec, record, size, tsize;
+u_int64_t lastrec, record, size, tsize;
FILE *msg = stdout;
void *getspace __P((int));
@@ -73,6 +73,7 @@ void intr __P((int));
static void usage __P((void));
void verify __P((int, int, char *));
void writeop __P((int, int));
+void rewind_tape(int);
int
main(argc, argv)
@@ -156,16 +157,16 @@ main(argc, argv)
if (nread >= 0)
goto r1;
}
- err(1, "read error, file %d, record %ld", filen, record);
+ err(1, "read error, file %d, record %qu", filen, record);
} else if (nread != lastnread) {
if (lastnread != 0 && lastnread != NOCOUNT) {
if (lastrec == 0 && nread == 0)
- fprintf(msg, "%ld records\n", record);
+ fprintf(msg, "%qu records\n", record);
else if (record - lastrec > 1)
- fprintf(msg, "records %ld to %ld\n",
+ fprintf(msg, "records %qu to %qu\n",
lastrec, record);
else
- fprintf(msg, "record %ld\n", lastrec);
+ fprintf(msg, "record %qu\n", lastrec);
}
if (nread != 0)
fprintf(msg, "file %d: block size %d: ",
@@ -183,9 +184,9 @@ r1: guesslen = 0;
nw = write(outp, buff, nread);
if (nw != nread) {
if (nw == -1) {
- warn("write error, file %d, record %ld", filen, record);
+ warn("write error, file %d, record %qu", filen, record);
} else {
- warnx("write error, file %d, record %ld", filen, record);
+ warnx("write error, file %d, record %qu", filen, record);
warnx("write (%d) != read (%d)", nw, nread);
}
errx(5, "copy aborted");
@@ -199,7 +200,7 @@ r1: guesslen = 0;
break;
}
fprintf(msg,
- "file %d: eof after %lu records: %lu bytes\n",
+ "file %d: eof after %qu records: %qu bytes\n",
filen, record, size);
needeof = 1;
filen++;
@@ -209,14 +210,14 @@ r1: guesslen = 0;
}
lastnread = nread;
}
- fprintf(msg, "total length: %lu bytes\n", tsize);
+ fprintf(msg, "total length: %qu bytes\n", tsize);
(void)signal(SIGINT, oldsig);
if (op == COPY || op == COPYVERIFY) {
writeop(outp, MTWEOF);
writeop(outp, MTWEOF);
if (op == COPYVERIFY) {
- writeop(outp, MTREW);
- writeop(inp, MTREW);
+ rewind_tape(outp);
+ rewind_tape(inp);
verify(inp, outp, buff);
}
}
@@ -283,10 +284,10 @@ intr(signo)
{
if (record)
if (record - lastrec > 1)
- fprintf(msg, "records %ld to %ld\n", lastrec, record);
+ fprintf(msg, "records %qu to %qu\n", lastrec, record);
else
- fprintf(msg, "record %ld\n", lastrec);
- fprintf(msg, "interrupt at file %d: record %ld\n", filen, record);
+ fprintf(msg, "record %qu\n", lastrec);
+ fprintf(msg, "interrupt at file %d: record %qu\n", filen, record);
fprintf(msg, "total length: %ld bytes\n", tsize + size);
exit(1);
}
@@ -320,3 +321,22 @@ usage()
fprintf(stderr, "usage: tcopy [-cvx] [-s maxblk] [src [dest]]\n");
exit(1);
}
+
+void
+rewind_tape(int fd)
+{
+ struct stat sp;
+
+ if(fstat(fd, &sp))
+ errx(12, "fstat in rewind");
+
+ /*
+ * don't want to do tape ioctl on regular files:
+ */
+ if( S_ISREG(sp.st_mode) ) {
+ if( lseek(fd, 0, SEEK_SET) == -1 )
+ errx(13, "lseek");
+ } else
+ /* assume its a tape */
+ writeop(fd, MTREW);
+}
OpenPOWER on IntegriCloud