diff options
author | phk <phk@FreeBSD.org> | 1999-04-30 13:13:32 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1999-04-30 13:13:32 +0000 |
commit | ca402ccf60ff298de9082838079fbbea0c315f01 (patch) | |
tree | 966de84d1239eda328387c22dc2096862aa6a585 /usr.bin/tcopy | |
parent | 6f402caa86e0c6c0c2fc853ea9f38902b9f85f30 (diff) | |
download | FreeBSD-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.1 | 16 | ||||
-rw-r--r-- | usr.bin/tcopy/tcopy.c | 50 |
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); +} |