* Copyright (c) 1985, 1987 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
"@(#) Copyright (c) 1985, 1987 Regents of the University of California.\n\
static char sccsid
[] = "@(#)tcopy.c 5.15 (Berkeley) 11/5/90";
#define MAXREC (64 * 1024)
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
;
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");