124973Sbloom /* 2*30870Skarels * Copyright (c) 1985, 1987 Regents of the University of California. 324973Sbloom * All rights reserved. The Berkeley software License Agreement 424973Sbloom * specifies the terms and conditions for redistribution. 524973Sbloom */ 624973Sbloom 724973Sbloom #ifndef lint 824973Sbloom char copyright[] = 9*30870Skarels "@(#) Copyright (c) 1985, 1987 Regents of the University of California.\n\ 1024973Sbloom All rights reserved.\n"; 1124973Sbloom #endif not lint 1224973Sbloom 1324973Sbloom #ifndef lint 14*30870Skarels static char sccsid[] = "@(#)tcopy.c 5.4 (Berkeley) 04/09/87"; 1524973Sbloom #endif not lint 1624973Sbloom 1724973Sbloom #include <stdio.h> 1825590Sbloom #include <signal.h> 1924973Sbloom #include <sys/file.h> 2024973Sbloom #include <sys/types.h> 2124973Sbloom #include <sys/ioctl.h> 2224973Sbloom #include <sys/mtio.h> 2324973Sbloom 24*30870Skarels #define MAXREC (64 * 1024) 25*30870Skarels #define NOCOUNT (-2) 26*30870Skarels #undef DEFTAPE 27*30870Skarels #define DEFTAPE "/dev/rmt0" 2824973Sbloom 29*30870Skarels char *buff; 30*30870Skarels char *inf = DEFTAPE; 31*30870Skarels int maxblk = MAXREC; 32*30870Skarels int filen; 33*30870Skarels long record, lastrec; 34*30870Skarels int intr(); 35*30870Skarels long itol(); 36*30870Skarels char *malloc(); 37*30870Skarels long size, tsize; 38*30870Skarels int nfile; 39*30870Skarels int lastread; 40*30870Skarels int copy; 4124973Sbloom 4224973Sbloom main(argc, argv) 4324973Sbloom char **argv; 4424973Sbloom { 45*30870Skarels register nread, nw, inp, outp; 4624973Sbloom struct mtop op; 47*30870Skarels int needeof = 0, guesslen = 1; 4824973Sbloom 49*30870Skarels while (argc > 1 && *argv[1] == '-') { 50*30870Skarels switch (*++argv[1]) { 51*30870Skarels case 's': 52*30870Skarels if (argc < 3) 53*30870Skarels goto usage; 54*30870Skarels maxblk = atoi(argv[2]); 55*30870Skarels if (maxblk <= 0) { 56*30870Skarels fprintf(stderr, "illegal block size\n"); 57*30870Skarels goto usage; 58*30870Skarels } 59*30870Skarels argc--; 60*30870Skarels argv++; 61*30870Skarels guesslen = 0; 62*30870Skarels break; 63*30870Skarels } 64*30870Skarels argc--; 65*30870Skarels argv++; 66*30870Skarels } 67*30870Skarels if (argc < 1 || argc > 3) { 68*30870Skarels usage: 69*30870Skarels fprintf(stderr, "Usage: tcopy [-s maxblk] src [dest]\n"); 7024973Sbloom exit(1); 7124973Sbloom } 72*30870Skarels if (argc > 1) 73*30870Skarels inf = argv[1]; 74*30870Skarels if ((inp = open(inf, O_RDONLY, 0)) < 0) { 75*30870Skarels perror(inf); 76*30870Skarels exit(1); 77*30870Skarels } 7825590Sbloom if (argc == 3) { 7925590Sbloom copy = 1; 80*30870Skarels if ((outp = open(argv[2], O_WRONLY, 0666)) < 0) { 81*30870Skarels perror(argv[2]); 8225590Sbloom exit(3); 8325590Sbloom } 8424973Sbloom } 8525590Sbloom if (signal(SIGINT, SIG_IGN) != SIG_IGN) 86*30870Skarels (void) signal(SIGINT, intr); 87*30870Skarels buff = malloc(maxblk); 88*30870Skarels if (buff == NULL) { 89*30870Skarels fprintf("tcopy: no memory\n"); 90*30870Skarels exit(11); 91*30870Skarels } 92*30870Skarels lastread = NOCOUNT; 9324973Sbloom for (;;) { 94*30870Skarels nread = read(inp, buff, maxblk); 95*30870Skarels if (nread == -1) { 96*30870Skarels if (guesslen && maxblk > MAXREC / 2) { 97*30870Skarels maxblk -= 1024; 98*30870Skarels continue; 99*30870Skarels } 100*30870Skarels fprintf(stderr, "read error, file %d, record %d: ", 101*30870Skarels filen, record); 102*30870Skarels perror(""); 103*30870Skarels } else if (nread != lastread) { 104*30870Skarels if (lastread != 0 && lastread != NOCOUNT) { 105*30870Skarels if (lastrec == 0 && nread == 0) 106*30870Skarels printf("%d records\n", record); 107*30870Skarels else if (record - lastrec > 1) 108*30870Skarels printf("records %ld to %ld\n", 109*30870Skarels lastrec, record); 110*30870Skarels else 111*30870Skarels printf("record %ld\n", lastrec); 112*30870Skarels } 113*30870Skarels if (nread != 0) 114*30870Skarels printf("file %d: block size %d: ", 115*30870Skarels filen, nread); 116*30870Skarels fflush(stdout); 117*30870Skarels lastrec = record; 11824973Sbloom } 119*30870Skarels guesslen = 0; 120*30870Skarels if (nread > 0) { 121*30870Skarels if (copy) { 122*30870Skarels if (needeof) { 123*30870Skarels op.mt_op = MTWEOF; 124*30870Skarels op.mt_count = (daddr_t) 1; 125*30870Skarels if (ioctl(outp, MTIOCTOP, (char *)&op) < 0) { 126*30870Skarels perror("write tape mark"); 127*30870Skarels exit(6); 128*30870Skarels } 129*30870Skarels needeof = 0; 130*30870Skarels } 131*30870Skarels nw = write(outp, buff, nread); 132*30870Skarels if (nw != nread) { 133*30870Skarels fprintf(stderr, 134*30870Skarels "write error, file %d, record %d: ", 135*30870Skarels filen, record); 136*30870Skarels if (nw == -1) 137*30870Skarels perror(""); 138*30870Skarels else 139*30870Skarels fprintf(stderr, 140*30870Skarels "write (%d) != read (%d)\n", 141*30870Skarels nw, nread); 142*30870Skarels fprintf(stderr, "copy aborted\n"); 143*30870Skarels exit(5); 144*30870Skarels } 145*30870Skarels } 146*30870Skarels size += nread; 147*30870Skarels record++; 148*30870Skarels } else { 149*30870Skarels if (lastread <= 0 && lastread != NOCOUNT) { 15024973Sbloom printf("eot\n"); 15124973Sbloom break; 15224973Sbloom } 15324973Sbloom printf("file %d: eof after %ld records: %ld bytes\n", 154*30870Skarels filen, record, size); 155*30870Skarels needeof = 1; 15624973Sbloom filen++; 15724973Sbloom tsize += size; 158*30870Skarels record = 0; 159*30870Skarels lastrec = 0; 160*30870Skarels lastread = 0; 16124973Sbloom size = 0; 16224973Sbloom if (nfile && filen > nfile) 16324973Sbloom break; 16424973Sbloom } 165*30870Skarels lastread = nread; 16624973Sbloom } 16725590Sbloom if (copy) 16825590Sbloom (void) close(outp); 16924973Sbloom printf("total length: %ld bytes\n", tsize); 17024973Sbloom } 17124973Sbloom 172*30870Skarels intr() 17324973Sbloom { 174*30870Skarels if (record) 175*30870Skarels if (record - lastrec > 1) 176*30870Skarels printf("records %ld to %ld\n", lastrec, record); 17724973Sbloom else 178*30870Skarels printf("record %ld\n", lastrec); 179*30870Skarels printf("interrupt at file %d: record %ld\n", filen, record); 18024973Sbloom printf("total length: %ld bytes\n", tsize+size); 18124973Sbloom exit(1); 18224973Sbloom } 183