* Copyright (c) 1985, 1987 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1985, 1987 Regents of the University of California.\n\
static char sccsid
[] = "@(#)tcopy.c 5.11 (Berkeley) %G%";
#define MAXREC (64 * 1024)
#define DEFTAPE "/dev/rmt0"
int filen
, guesslen
, maxblk
= MAXREC
;
long lastrec
, record
, size
, tsize
;
extern int optind
, errno
;
register int lastnread
, nread
, nw
, inp
, outp
;
enum {READ
, VERIFY
, COPY
, COPYVERIFY
} op
= READ
;
int ch
, needeof
, intr(), (*oldsig
)();
char *buff
, *inf
, *getspace();
while ((ch
= getopt(argc
, argv
, "cs:v")) != EOF
)
fprintf(stderr
, "tcopy: illegal block size\n");
if ((outp
= open(argv
[1], op
== VERIFY
? O_RDONLY
: O_RDWR
,
if ((inp
= open(inf
, O_RDONLY
, 0)) < 0) {
if ((oldsig
= signal(SIGINT
, SIG_IGN
)) != SIG_IGN
)
(void) signal(SIGINT
, intr
);
for (lastnread
= NOCOUNT
;;) {
if ((nread
= read(inp
, buff
, maxblk
)) == -1) {
while (errno
== EINVAL
&& (maxblk
-= 1024)) {
nread
= read(inp
, buff
, maxblk
);
fprintf(stderr
, "read error, file %d, record %ld: ",
} else if (nread
!= lastnread
) {
if (lastnread
!= 0 && lastnread
!= NOCOUNT
) {
if (lastrec
== 0 && nread
== 0)
printf("%ld records\n", record
);
else if (record
- lastrec
> 1)
printf("records %ld to %ld\n",
printf("record %ld\n", lastrec
);
printf("file %d: block size %d: ",
if (op
== COPY
|| op
== COPYVERIFY
) {
nw
= write(outp
, buff
, nread
);
"write error, file %d, record %ld: ",
"write (%d) != read (%d)\n",
fprintf(stderr
, "copy aborted\n");
if (lastnread
<= 0 && lastnread
!= NOCOUNT
) {
printf("file %d: eof after %ld records: %ld bytes\n",
size
= record
= lastrec
= 0;
printf("total length: %ld bytes\n", tsize
);
(void)signal(SIGINT
, oldsig
);
if (op
== COPY
|| op
== COPYVERIFY
) {
register int eot
, inmaxblk
, inn
, outmaxblk
, outn
;
inmaxblk
= outmaxblk
= maxblk
;
for (eot
= 0;; guesslen
= 0) {
if ((inn
= read(inp
, inb
, inmaxblk
)) == -1) {
while (errno
== EINVAL
&& (inmaxblk
-= 1024)) {
inn
= read(inp
, inb
, inmaxblk
);
perror("tcopy: read error");
r1
: if ((outn
= read(outp
, outb
, outmaxblk
)) == -1) {
while (errno
== EINVAL
&& (outmaxblk
-= 1024)) {
outn
= read(outp
, outb
, outmaxblk
);
perror("tcopy: read error");
printf("tcopy: tapes have different block sizes; %d != %d.\n", inn
, outn
);
printf("tcopy: tapes are identical.\n");
if (bcmp(inb
, outb
, inn
)) {
printf("tcopy: tapes have different data.\n");
if (record
- lastrec
> 1)
printf("records %ld to %ld\n", lastrec
, record
);
printf("record %ld\n", lastrec
);
printf("interrupt at file %d: record %ld\n", filen
, record
);
printf("total length: %ld bytes\n", tsize
+ size
);
if ((bp
= malloc((u_int
)blk
)) == NULL
) {
fprintf(stderr
, "tcopy: no memory\n");
op
.mt_count
= (daddr_t
)1;
if (ioctl(fd
, MTIOCTOP
, (char *)&op
) < 0) {
perror("tcopy: tape op");
fprintf(stderr
, "usage: tcopy [-cv] [-s maxblk] src [dest]\n");