mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-26 07:55:01 +00:00
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
This commit is contained in:
parent
2038017be6
commit
4b9c5aabdd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=46203
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user