diff options
author | Rodney W. Grimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
---|---|---|
committer | Rodney W. Grimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
commit | 9b50d9027575220cb6dd09b3e62f03f511e908b8 (patch) | |
tree | defc987843071f19a5891a97145437d43cba2af8 /usr.bin/tcopy | |
parent | efd31c5952bb9bb2485c109382100127424f8611 (diff) | |
download | src-9b50d9027575220cb6dd09b3e62f03f511e908b8.tar.gz src-9b50d9027575220cb6dd09b3e62f03f511e908b8.zip |
Notes
Diffstat (limited to 'usr.bin/tcopy')
-rw-r--r-- | usr.bin/tcopy/Makefile | 5 | ||||
-rw-r--r-- | usr.bin/tcopy/pathnames.h | 36 | ||||
-rw-r--r-- | usr.bin/tcopy/tcopy.1 | 89 | ||||
-rw-r--r-- | usr.bin/tcopy/tcopy.c | 332 |
4 files changed, 462 insertions, 0 deletions
diff --git a/usr.bin/tcopy/Makefile b/usr.bin/tcopy/Makefile new file mode 100644 index 000000000000..5a42f6db77bd --- /dev/null +++ b/usr.bin/tcopy/Makefile @@ -0,0 +1,5 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= tcopy + +.include <bsd.prog.mk> diff --git a/usr.bin/tcopy/pathnames.h b/usr.bin/tcopy/pathnames.h new file mode 100644 index 000000000000..ddf42867586e --- /dev/null +++ b/usr.bin/tcopy/pathnames.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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 + * SUCH DAMAGE. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 + */ + +#define _PATH_DEFTAPE "/dev/rmt0" diff --git a/usr.bin/tcopy/tcopy.1 b/usr.bin/tcopy/tcopy.1 new file mode 100644 index 000000000000..d5554cd3b42d --- /dev/null +++ b/usr.bin/tcopy/tcopy.1 @@ -0,0 +1,89 @@ +.\" Copyright (c) 1985, 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 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 +.\" SUCH DAMAGE. +.\" +.\" @(#)tcopy.1 8.2 (Berkeley) 4/17/94 +.\" +.Dd April 17, 1994 +.Dt TCOPY 1 +.Os BSD 4.3 +.Sh NAME +.Nm tcopy +.Nd copy and/or verify mag tapes +.Sh SYNOPSIS +.Nm tcopy +.Op Fl cvx +.Op Fl s Ar maxblk +.Oo Ar src Op Ar dest +.Oc +.Sh DESCRIPTION +.Nm Tcopy +is designed to copy magnetic tapes. The only assumption made +about the tape is that there are two tape marks at the end. +.Nm Tcopy +with only a source tape +.Pf ( Ar rmt0 +by default) specified will print +information about the sizes of records and tape files. If a destination +is specified a copy will be made of the source tape. The blocking on the +destination tape will be identical to that used on the source tape. Copying +a tape will yield the same output as if just printing the sizes. +.Pp +Options: +.Bl -tag -width s_maxblk +.It Fl c +Copy +.Ar src +to +.Ar dest +and then verify that the two tapes are identical. +.It Fl s Ar maxblk +Specify a maximum block size, +.Ar maxblk . +.It Fl v +Given the two tapes, +.ar src +and +.Ar dest +verify that they are identical. +.It Fl x +Output all informational messages to the standard error. +This option is useful when +.Ar dest +is +.Pa /dev/stdout . +.El +.Sh SEE ALSO +.Xr mtio 4 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 . diff --git a/usr.bin/tcopy/tcopy.c b/usr.bin/tcopy/tcopy.c new file mode 100644 index 000000000000..e7174990ac7c --- /dev/null +++ b/usr.bin/tcopy/tcopy.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 1985, 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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 + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1985, 1987, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)tcopy.c 8.2 (Berkeley) 4/17/94"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/mtio.h> + +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "pathnames.h" + +#define MAXREC (64 * 1024) +#define NOCOUNT (-2) + +int filen, guesslen, maxblk = MAXREC; +long lastrec, record, size, tsize; +FILE *msg = stdout; + +void *getspace __P((int)); +void intr __P((int)); +void usage __P((void)); +void verify __P((int, int, char *)); +void writeop __P((int, int)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + register int lastnread, nread, nw, inp, outp; + enum {READ, VERIFY, COPY, COPYVERIFY} op = READ; + sig_t oldsig; + int ch, needeof; + char *buff, *inf; + + guesslen = 1; + while ((ch = getopt(argc, argv, "cs:vx")) != EOF) + switch((char)ch) { + case 'c': + op = COPYVERIFY; + break; + case 's': + maxblk = atoi(optarg); + if (maxblk <= 0) { + fprintf(stderr, "tcopy: illegal block size\n"); + usage(); + } + guesslen = 0; + break; + case 'v': + op = VERIFY; + break; + case 'x': + msg = stderr; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + switch(argc) { + case 0: + if (op != READ) + usage(); + inf = _PATH_DEFTAPE; + break; + case 1: + if (op != READ) + usage(); + inf = argv[0]; + break; + case 2: + if (op == READ) + op = COPY; + inf = argv[0]; + if ((outp = open(argv[1], op == VERIFY ? O_RDONLY : + op == COPY ? O_WRONLY : O_RDWR, DEFFILEMODE)) < 0) { + perror(argv[1]); + exit(3); + } + break; + default: + usage(); + } + + if ((inp = open(inf, O_RDONLY, 0)) < 0) { + perror(inf); + exit(1); + } + + buff = getspace(maxblk); + + if (op == VERIFY) { + verify(inp, outp, buff); + exit(0); + } + + if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN) + (void) signal(SIGINT, intr); + + needeof = 0; + for (lastnread = NOCOUNT;;) { + if ((nread = read(inp, buff, maxblk)) == -1) { + while (errno == EINVAL && (maxblk -= 1024)) { + nread = read(inp, buff, maxblk); + if (nread >= 0) + goto r1; + } + fprintf(stderr, "read error, file %d, record %ld: ", + filen, record); + perror(""); + exit(1); + } else if (nread != lastnread) { + if (lastnread != 0 && lastnread != NOCOUNT) { + if (lastrec == 0 && nread == 0) + fprintf(msg, "%ld records\n", record); + else if (record - lastrec > 1) + fprintf(msg, "records %ld to %ld\n", + lastrec, record); + else + fprintf(msg, "record %ld\n", lastrec); + } + if (nread != 0) + fprintf(msg, "file %d: block size %d: ", + filen, nread); + (void) fflush(stdout); + lastrec = record; + } +r1: guesslen = 0; + if (nread > 0) { + if (op == COPY || op == COPYVERIFY) { + if (needeof) { + writeop(outp, MTWEOF); + needeof = 0; + } + nw = write(outp, buff, nread); + if (nw != nread) { + fprintf(stderr, + "write error, file %d, record %ld: ", + filen, record); + if (nw == -1) + perror(""); + else + fprintf(stderr, + "write (%d) != read (%d)\n", + nw, nread); + fprintf(stderr, "copy aborted\n"); + exit(5); + } + } + size += nread; + record++; + } else { + if (lastnread <= 0 && lastnread != NOCOUNT) { + fprintf(msg, "eot\n"); + break; + } + fprintf(msg, + "file %d: eof after %ld records: %ld bytes\n", + filen, record, size); + needeof = 1; + filen++; + tsize += size; + size = record = lastrec = 0; + lastnread = 0; + } + lastnread = nread; + } + fprintf(msg, "total length: %ld 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); + verify(inp, outp, buff); + } + } + exit(0); +} + +void +verify(inp, outp, outb) + register int inp, outp; + register char *outb; +{ + register int eot, inmaxblk, inn, outmaxblk, outn; + register char *inb; + + inb = getspace(maxblk); + inmaxblk = outmaxblk = maxblk; + for (eot = 0;; guesslen = 0) { + if ((inn = read(inp, inb, inmaxblk)) == -1) { + if (guesslen) + while (errno == EINVAL && (inmaxblk -= 1024)) { + inn = read(inp, inb, inmaxblk); + if (inn >= 0) + goto r1; + } + perror("tcopy: read error"); + break; + } +r1: if ((outn = read(outp, outb, outmaxblk)) == -1) { + if (guesslen) + while (errno == EINVAL && (outmaxblk -= 1024)) { + outn = read(outp, outb, outmaxblk); + if (outn >= 0) + goto r2; + } + perror("tcopy: read error"); + break; + } +r2: if (inn != outn) { + fprintf(msg, + "%s: tapes have different block sizes; %d != %d.\n", + "tcopy", inn, outn); + break; + } + if (!inn) { + if (eot++) { + fprintf(msg, "tcopy: tapes are identical.\n"); + return; + } + } else { + if (bcmp(inb, outb, inn)) { + fprintf(msg, + "tcopy: tapes have different data.\n"); + break; + } + eot = 0; + } + } + exit(1); +} + +void +intr(signo) + int signo; +{ + if (record) + if (record - lastrec > 1) + fprintf(msg, "records %ld to %ld\n", lastrec, record); + else + fprintf(msg, "record %ld\n", lastrec); + fprintf(msg, "interrupt at file %d: record %ld\n", filen, record); + fprintf(msg, "total length: %ld bytes\n", tsize + size); + exit(1); +} + +void * +getspace(blk) + int blk; +{ + void *bp; + + if ((bp = malloc((size_t)blk)) == NULL) { + fprintf(stderr, "tcopy: no memory\n"); + exit(11); + } + return (bp); +} + +void +writeop(fd, type) + int fd, type; +{ + struct mtop op; + + op.mt_op = type; + op.mt_count = (daddr_t)1; + if (ioctl(fd, MTIOCTOP, (char *)&op) < 0) { + perror("tcopy: tape op"); + exit(6); + } +} + +void +usage() +{ + fprintf(stderr, "usage: tcopy [-cvx] [-s maxblk] src [dest]\n"); + exit(1); +} |