|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985, 1987 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1985, 1987 Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)tcopy.c 5.14 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: #include <sys/types.h> ! 31: #include <sys/signal.h> ! 32: #include <sys/file.h> ! 33: #include <sys/ioctl.h> ! 34: #include <sys/mtio.h> ! 35: #include <sys/errno.h> ! 36: #include <stdio.h> ! 37: #include "pathnames.h" ! 38: ! 39: #define MAXREC (64 * 1024) ! 40: #define NOCOUNT (-2) ! 41: ! 42: int filen, guesslen, maxblk = MAXREC; ! 43: long lastrec, record, size, tsize; ! 44: ! 45: main(argc, argv) ! 46: int argc; ! 47: char **argv; ! 48: { ! 49: extern char *optarg; ! 50: extern int optind, errno; ! 51: register int lastnread, nread, nw, inp, outp; ! 52: enum {READ, VERIFY, COPY, COPYVERIFY} op = READ; ! 53: sig_t oldsig; ! 54: int ch, needeof; ! 55: char *buff, *inf, *getspace(); ! 56: void intr(); ! 57: ! 58: guesslen = 1; ! 59: while ((ch = getopt(argc, argv, "cs:v")) != EOF) ! 60: switch((char)ch) { ! 61: case 'c': ! 62: op = COPYVERIFY; ! 63: break; ! 64: case 's': ! 65: maxblk = atoi(optarg); ! 66: if (maxblk <= 0) { ! 67: fprintf(stderr, "tcopy: illegal block size\n"); ! 68: usage(); ! 69: } ! 70: guesslen = 0; ! 71: break; ! 72: case 'v': ! 73: op = VERIFY; ! 74: break; ! 75: case '?': ! 76: default: ! 77: usage(); ! 78: } ! 79: argc -= optind; ! 80: argv += optind; ! 81: ! 82: switch(argc) { ! 83: case 0: ! 84: if (op != READ) ! 85: usage(); ! 86: inf = _PATH_DEFTAPE; ! 87: break; ! 88: case 1: ! 89: if (op != READ) ! 90: usage(); ! 91: inf = argv[0]; ! 92: break; ! 93: case 2: ! 94: if (op == READ) ! 95: op = COPY; ! 96: inf = argv[0]; ! 97: if ((outp = open(argv[1], op == VERIFY ? O_RDONLY : O_RDWR, ! 98: 0666)) < 0) { ! 99: perror(argv[1]); ! 100: exit(3); ! 101: } ! 102: break; ! 103: default: ! 104: usage(); ! 105: } ! 106: ! 107: if ((inp = open(inf, O_RDONLY, 0)) < 0) { ! 108: perror(inf); ! 109: exit(1); ! 110: } ! 111: ! 112: buff = getspace(maxblk); ! 113: ! 114: if (op == VERIFY) { ! 115: verify(inp, outp, buff); ! 116: exit(0); ! 117: } ! 118: ! 119: if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN) ! 120: (void) signal(SIGINT, intr); ! 121: ! 122: needeof = 0; ! 123: for (lastnread = NOCOUNT;;) { ! 124: if ((nread = read(inp, buff, maxblk)) == -1) { ! 125: while (errno == EINVAL && (maxblk -= 1024)) { ! 126: nread = read(inp, buff, maxblk); ! 127: if (nread >= 0) ! 128: goto r1; ! 129: } ! 130: fprintf(stderr, "read error, file %d, record %ld: ", ! 131: filen, record); ! 132: perror(""); ! 133: exit(1); ! 134: } else if (nread != lastnread) { ! 135: if (lastnread != 0 && lastnread != NOCOUNT) { ! 136: if (lastrec == 0 && nread == 0) ! 137: printf("%ld records\n", record); ! 138: else if (record - lastrec > 1) ! 139: printf("records %ld to %ld\n", ! 140: lastrec, record); ! 141: else ! 142: printf("record %ld\n", lastrec); ! 143: } ! 144: if (nread != 0) ! 145: printf("file %d: block size %d: ", ! 146: filen, nread); ! 147: (void) fflush(stdout); ! 148: lastrec = record; ! 149: } ! 150: r1: guesslen = 0; ! 151: if (nread > 0) { ! 152: if (op >= COPY) { ! 153: if (needeof) { ! 154: writeop(outp, MTWEOF); ! 155: needeof = 0; ! 156: } ! 157: nw = write(outp, buff, nread); ! 158: if (nw != nread) { ! 159: fprintf(stderr, ! 160: "write error, file %d, record %ld: ", ! 161: filen, record); ! 162: if (nw == -1) ! 163: perror(""); ! 164: else ! 165: fprintf(stderr, ! 166: "write (%d) != read (%d)\n", ! 167: nw, nread); ! 168: fprintf(stderr, "copy aborted\n"); ! 169: exit(5); ! 170: } ! 171: } ! 172: size += nread; ! 173: record++; ! 174: } else { ! 175: if (lastnread <= 0 && lastnread != NOCOUNT) { ! 176: printf("eot\n"); ! 177: break; ! 178: } ! 179: printf("file %d: eof after %ld records: %ld bytes\n", ! 180: filen, record, size); ! 181: needeof = 1; ! 182: filen++; ! 183: tsize += size; ! 184: size = record = lastrec = 0; ! 185: lastnread = 0; ! 186: } ! 187: lastnread = nread; ! 188: } ! 189: printf("total length: %ld bytes\n", tsize); ! 190: (void)signal(SIGINT, oldsig); ! 191: if (op >= COPY) { ! 192: writeop(outp, MTWEOF); ! 193: writeop(outp, MTWEOF); ! 194: if (op == COPYVERIFY) { ! 195: writeop(outp, MTREW); ! 196: writeop(inp, MTREW); ! 197: verify(inp, outp, buff); ! 198: } ! 199: } ! 200: exit(0); ! 201: } ! 202: ! 203: verify(inp, outp, outb) ! 204: register int inp, outp; ! 205: register char *outb; ! 206: { ! 207: extern int errno; ! 208: register int eot, inmaxblk, inn, outmaxblk, outn; ! 209: register char *inb; ! 210: char *getspace(); ! 211: ! 212: inb = getspace(maxblk); ! 213: inmaxblk = outmaxblk = maxblk; ! 214: for (eot = 0;; guesslen = 0) { ! 215: if ((inn = read(inp, inb, inmaxblk)) == -1) { ! 216: if (guesslen) ! 217: while (errno == EINVAL && (inmaxblk -= 1024)) { ! 218: inn = read(inp, inb, inmaxblk); ! 219: if (inn >= 0) ! 220: goto r1; ! 221: } ! 222: perror("tcopy: read error"); ! 223: break; ! 224: } ! 225: r1: if ((outn = read(outp, outb, outmaxblk)) == -1) { ! 226: if (guesslen) ! 227: while (errno == EINVAL && (outmaxblk -= 1024)) { ! 228: outn = read(outp, outb, outmaxblk); ! 229: if (outn >= 0) ! 230: goto r2; ! 231: } ! 232: perror("tcopy: read error"); ! 233: break; ! 234: } ! 235: r2: if (inn != outn) { ! 236: printf("tcopy: tapes have different block sizes; %d != %d.\n", inn, outn); ! 237: break; ! 238: } ! 239: if (!inn) { ! 240: if (eot++) { ! 241: printf("tcopy: tapes are identical.\n"); ! 242: return; ! 243: } ! 244: } else { ! 245: if (bcmp(inb, outb, inn)) { ! 246: printf("tcopy: tapes have different data.\n"); ! 247: break; ! 248: } ! 249: eot = 0; ! 250: } ! 251: } ! 252: exit(1); ! 253: } ! 254: ! 255: void ! 256: intr() ! 257: { ! 258: if (record) ! 259: if (record - lastrec > 1) ! 260: printf("records %ld to %ld\n", lastrec, record); ! 261: else ! 262: printf("record %ld\n", lastrec); ! 263: printf("interrupt at file %d: record %ld\n", filen, record); ! 264: printf("total length: %ld bytes\n", tsize + size); ! 265: exit(1); ! 266: } ! 267: ! 268: char * ! 269: getspace(blk) ! 270: int blk; ! 271: { ! 272: char *bp, *malloc(); ! 273: ! 274: if ((bp = malloc((u_int)blk)) == NULL) { ! 275: fprintf(stderr, "tcopy: no memory\n"); ! 276: exit(11); ! 277: } ! 278: return(bp); ! 279: } ! 280: ! 281: writeop(fd, type) ! 282: int fd, type; ! 283: { ! 284: struct mtop op; ! 285: ! 286: op.mt_op = type; ! 287: op.mt_count = (daddr_t)1; ! 288: if (ioctl(fd, MTIOCTOP, (char *)&op) < 0) { ! 289: perror("tcopy: tape op"); ! 290: exit(6); ! 291: } ! 292: } ! 293: ! 294: usage() ! 295: { ! 296: fprintf(stderr, "usage: tcopy [-cv] [-s maxblk] src [dest]\n"); ! 297: exit(1); ! 298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.