124973Sbloom /* 230870Skarels * 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[] = 930870Skarels "@(#) 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*30873Skarels static char sccsid[] = "@(#)tcopy.c 5.5 (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> 23*30873Skarels #include <sys/errno.h> 2424973Sbloom 2530870Skarels #define MAXREC (64 * 1024) 2630870Skarels #define NOCOUNT (-2) 2730870Skarels #undef DEFTAPE 2830870Skarels #define DEFTAPE "/dev/rmt0" 2924973Sbloom 3030870Skarels char *buff; 3130870Skarels char *inf = DEFTAPE; 3230870Skarels int maxblk = MAXREC; 3330870Skarels int filen; 3430870Skarels long record, lastrec; 3530870Skarels int intr(); 3630870Skarels long itol(); 3730870Skarels char *malloc(); 3830870Skarels long size, tsize; 3930870Skarels int nfile; 4030870Skarels int lastread; 4130870Skarels int copy; 42*30873Skarels extern int errno; 4324973Sbloom 4424973Sbloom main(argc, argv) 4524973Sbloom char **argv; 4624973Sbloom { 4730870Skarels register nread, nw, inp, outp; 4824973Sbloom struct mtop op; 4930870Skarels int needeof = 0, guesslen = 1; 5024973Sbloom 5130870Skarels while (argc > 1 && *argv[1] == '-') { 5230870Skarels switch (*++argv[1]) { 5330870Skarels case 's': 5430870Skarels if (argc < 3) 5530870Skarels goto usage; 5630870Skarels maxblk = atoi(argv[2]); 5730870Skarels if (maxblk <= 0) { 5830870Skarels fprintf(stderr, "illegal block size\n"); 5930870Skarels goto usage; 6030870Skarels } 6130870Skarels argc--; 6230870Skarels argv++; 6330870Skarels guesslen = 0; 6430870Skarels break; 6530870Skarels } 6630870Skarels argc--; 6730870Skarels argv++; 6830870Skarels } 6930870Skarels if (argc < 1 || argc > 3) { 7030870Skarels usage: 7130870Skarels fprintf(stderr, "Usage: tcopy [-s maxblk] src [dest]\n"); 7224973Sbloom exit(1); 7324973Sbloom } 7430870Skarels if (argc > 1) 7530870Skarels inf = argv[1]; 7630870Skarels if ((inp = open(inf, O_RDONLY, 0)) < 0) { 7730870Skarels perror(inf); 7830870Skarels exit(1); 7930870Skarels } 8025590Sbloom if (argc == 3) { 8125590Sbloom copy = 1; 8230870Skarels if ((outp = open(argv[2], O_WRONLY, 0666)) < 0) { 8330870Skarels perror(argv[2]); 8425590Sbloom exit(3); 8525590Sbloom } 8624973Sbloom } 8725590Sbloom if (signal(SIGINT, SIG_IGN) != SIG_IGN) 8830870Skarels (void) signal(SIGINT, intr); 8930870Skarels buff = malloc(maxblk); 9030870Skarels if (buff == NULL) { 9130870Skarels fprintf("tcopy: no memory\n"); 9230870Skarels exit(11); 9330870Skarels } 9430870Skarels lastread = NOCOUNT; 9524973Sbloom for (;;) { 9630870Skarels nread = read(inp, buff, maxblk); 9730870Skarels if (nread == -1) { 98*30873Skarels if (errno == EINVAL && guesslen && 99*30873Skarels maxblk > MAXREC / 2) { 10030870Skarels maxblk -= 1024; 10130870Skarels continue; 10230870Skarels } 10330870Skarels fprintf(stderr, "read error, file %d, record %d: ", 10430870Skarels filen, record); 10530870Skarels perror(""); 10630870Skarels } else if (nread != lastread) { 10730870Skarels if (lastread != 0 && lastread != NOCOUNT) { 10830870Skarels if (lastrec == 0 && nread == 0) 10930870Skarels printf("%d records\n", record); 11030870Skarels else if (record - lastrec > 1) 11130870Skarels printf("records %ld to %ld\n", 11230870Skarels lastrec, record); 11330870Skarels else 11430870Skarels printf("record %ld\n", lastrec); 11530870Skarels } 11630870Skarels if (nread != 0) 11730870Skarels printf("file %d: block size %d: ", 11830870Skarels filen, nread); 11930870Skarels fflush(stdout); 12030870Skarels lastrec = record; 12124973Sbloom } 12230870Skarels guesslen = 0; 12330870Skarels if (nread > 0) { 12430870Skarels if (copy) { 12530870Skarels if (needeof) { 12630870Skarels op.mt_op = MTWEOF; 12730870Skarels op.mt_count = (daddr_t) 1; 12830870Skarels if (ioctl(outp, MTIOCTOP, (char *)&op) < 0) { 12930870Skarels perror("write tape mark"); 13030870Skarels exit(6); 13130870Skarels } 13230870Skarels needeof = 0; 13330870Skarels } 13430870Skarels nw = write(outp, buff, nread); 13530870Skarels if (nw != nread) { 13630870Skarels fprintf(stderr, 13730870Skarels "write error, file %d, record %d: ", 13830870Skarels filen, record); 13930870Skarels if (nw == -1) 14030870Skarels perror(""); 14130870Skarels else 14230870Skarels fprintf(stderr, 14330870Skarels "write (%d) != read (%d)\n", 14430870Skarels nw, nread); 14530870Skarels fprintf(stderr, "copy aborted\n"); 14630870Skarels exit(5); 14730870Skarels } 14830870Skarels } 14930870Skarels size += nread; 15030870Skarels record++; 15130870Skarels } else { 15230870Skarels if (lastread <= 0 && lastread != NOCOUNT) { 15324973Sbloom printf("eot\n"); 15424973Sbloom break; 15524973Sbloom } 15624973Sbloom printf("file %d: eof after %ld records: %ld bytes\n", 15730870Skarels filen, record, size); 15830870Skarels needeof = 1; 15924973Sbloom filen++; 16024973Sbloom tsize += size; 16130870Skarels record = 0; 16230870Skarels lastrec = 0; 16330870Skarels lastread = 0; 16424973Sbloom size = 0; 16524973Sbloom if (nfile && filen > nfile) 16624973Sbloom break; 16724973Sbloom } 16830870Skarels lastread = nread; 16924973Sbloom } 17025590Sbloom if (copy) 17125590Sbloom (void) close(outp); 17224973Sbloom printf("total length: %ld bytes\n", tsize); 17324973Sbloom } 17424973Sbloom 17530870Skarels intr() 17624973Sbloom { 17730870Skarels if (record) 17830870Skarels if (record - lastrec > 1) 17930870Skarels printf("records %ld to %ld\n", lastrec, record); 18024973Sbloom else 18130870Skarels printf("record %ld\n", lastrec); 18230870Skarels printf("interrupt at file %d: record %ld\n", filen, record); 18324973Sbloom printf("total length: %ld bytes\n", tsize+size); 18424973Sbloom exit(1); 18524973Sbloom } 186