Annotation of 43BSDReno/usr.bin/tcopy/tcopy.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.