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