124973Sbloom /* 230870Skarels * Copyright (c) 1985, 1987 Regents of the University of California. 3*32759Sbostic * All rights reserved. 4*32759Sbostic * 5*32759Sbostic * Redistribution and use in source and binary forms are permitted 6*32759Sbostic * provided that this notice is preserved and that due credit is given 7*32759Sbostic * to the University of California at Berkeley. The name of the University 8*32759Sbostic * may not be used to endorse or promote products derived from this 9*32759Sbostic * software without specific written prior permission. This software 10*32759Sbostic * is provided ``as is'' without express or implied warranty. 1124973Sbloom */ 1224973Sbloom 1324973Sbloom #ifndef lint 1424973Sbloom char copyright[] = 1530870Skarels "@(#) Copyright (c) 1985, 1987 Regents of the University of California.\n\ 1624973Sbloom All rights reserved.\n"; 17*32759Sbostic #endif /* not lint */ 1824973Sbloom 1924973Sbloom #ifndef lint 20*32759Sbostic static char sccsid[] = "@(#)tcopy.c 5.6 (Berkeley) 12/04/87"; 21*32759Sbostic #endif /* not lint */ 2224973Sbloom 2324973Sbloom #include <stdio.h> 2425590Sbloom #include <signal.h> 2524973Sbloom #include <sys/file.h> 2624973Sbloom #include <sys/types.h> 2724973Sbloom #include <sys/ioctl.h> 2824973Sbloom #include <sys/mtio.h> 2930873Skarels #include <sys/errno.h> 3024973Sbloom 3130870Skarels #define MAXREC (64 * 1024) 3230870Skarels #define NOCOUNT (-2) 3330870Skarels #undef DEFTAPE 3430870Skarels #define DEFTAPE "/dev/rmt0" 3524973Sbloom 3630870Skarels char *buff; 3730870Skarels char *inf = DEFTAPE; 3830870Skarels int maxblk = MAXREC; 3930870Skarels int filen; 4030870Skarels long record, lastrec; 4130870Skarels int intr(); 4230870Skarels char *malloc(); 4330870Skarels long size, tsize; 4430870Skarels int nfile; 4530870Skarels int lastread; 4630870Skarels int copy; 4730873Skarels extern int errno; 4824973Sbloom 4924973Sbloom main(argc, argv) 50*32759Sbostic int argc; 51*32759Sbostic char **argv; 5224973Sbloom { 5330870Skarels register nread, nw, inp, outp; 5424973Sbloom struct mtop op; 5530870Skarels int needeof = 0, guesslen = 1; 5624973Sbloom 5730870Skarels while (argc > 1 && *argv[1] == '-') { 5830870Skarels switch (*++argv[1]) { 5930870Skarels case 's': 6030870Skarels if (argc < 3) 6130870Skarels goto usage; 6230870Skarels maxblk = atoi(argv[2]); 6330870Skarels if (maxblk <= 0) { 6430870Skarels fprintf(stderr, "illegal block size\n"); 6530870Skarels goto usage; 6630870Skarels } 6730870Skarels argc--; 6830870Skarels argv++; 6930870Skarels guesslen = 0; 7030870Skarels break; 7130870Skarels } 7230870Skarels argc--; 7330870Skarels argv++; 7430870Skarels } 7530870Skarels if (argc < 1 || argc > 3) { 7630870Skarels usage: 7730870Skarels fprintf(stderr, "Usage: tcopy [-s maxblk] src [dest]\n"); 7824973Sbloom exit(1); 7924973Sbloom } 8030870Skarels if (argc > 1) 8130870Skarels inf = argv[1]; 8230870Skarels if ((inp = open(inf, O_RDONLY, 0)) < 0) { 8330870Skarels perror(inf); 8430870Skarels exit(1); 8530870Skarels } 8625590Sbloom if (argc == 3) { 8725590Sbloom copy = 1; 8830870Skarels if ((outp = open(argv[2], O_WRONLY, 0666)) < 0) { 8930870Skarels perror(argv[2]); 9025590Sbloom exit(3); 9125590Sbloom } 9224973Sbloom } 9325590Sbloom if (signal(SIGINT, SIG_IGN) != SIG_IGN) 9430870Skarels (void) signal(SIGINT, intr); 95*32759Sbostic buff = malloc((u_int)maxblk); 9630870Skarels if (buff == NULL) { 97*32759Sbostic fprintf(stderr, "tcopy: no memory\n"); 9830870Skarels exit(11); 9930870Skarels } 10030870Skarels lastread = NOCOUNT; 10124973Sbloom for (;;) { 10230870Skarels nread = read(inp, buff, maxblk); 10330870Skarels if (nread == -1) { 10430873Skarels if (errno == EINVAL && guesslen && 10530873Skarels maxblk > MAXREC / 2) { 10630870Skarels maxblk -= 1024; 10730870Skarels continue; 10830870Skarels } 109*32759Sbostic fprintf(stderr, "read error, file %d, record %ld: ", 11030870Skarels filen, record); 11130870Skarels perror(""); 11230870Skarels } else if (nread != lastread) { 11330870Skarels if (lastread != 0 && lastread != NOCOUNT) { 11430870Skarels if (lastrec == 0 && nread == 0) 115*32759Sbostic printf("%ld records\n", record); 11630870Skarels else if (record - lastrec > 1) 11730870Skarels printf("records %ld to %ld\n", 11830870Skarels lastrec, record); 11930870Skarels else 12030870Skarels printf("record %ld\n", lastrec); 12130870Skarels } 12230870Skarels if (nread != 0) 12330870Skarels printf("file %d: block size %d: ", 12430870Skarels filen, nread); 125*32759Sbostic (void) fflush(stdout); 12630870Skarels lastrec = record; 12724973Sbloom } 12830870Skarels guesslen = 0; 12930870Skarels if (nread > 0) { 13030870Skarels if (copy) { 13130870Skarels if (needeof) { 13230870Skarels op.mt_op = MTWEOF; 13330870Skarels op.mt_count = (daddr_t) 1; 13430870Skarels if (ioctl(outp, MTIOCTOP, (char *)&op) < 0) { 13530870Skarels perror("write tape mark"); 13630870Skarels exit(6); 13730870Skarels } 13830870Skarels needeof = 0; 13930870Skarels } 14030870Skarels nw = write(outp, buff, nread); 14130870Skarels if (nw != nread) { 14230870Skarels fprintf(stderr, 143*32759Sbostic "write error, file %d, record %ld: ", 14430870Skarels filen, record); 14530870Skarels if (nw == -1) 14630870Skarels perror(""); 14730870Skarels else 14830870Skarels fprintf(stderr, 14930870Skarels "write (%d) != read (%d)\n", 15030870Skarels nw, nread); 15130870Skarels fprintf(stderr, "copy aborted\n"); 15230870Skarels exit(5); 15330870Skarels } 15430870Skarels } 15530870Skarels size += nread; 15630870Skarels record++; 15730870Skarels } else { 15830870Skarels if (lastread <= 0 && lastread != NOCOUNT) { 15924973Sbloom printf("eot\n"); 16024973Sbloom break; 16124973Sbloom } 16224973Sbloom printf("file %d: eof after %ld records: %ld bytes\n", 16330870Skarels filen, record, size); 16430870Skarels needeof = 1; 16524973Sbloom filen++; 16624973Sbloom tsize += size; 16730870Skarels record = 0; 16830870Skarels lastrec = 0; 16930870Skarels lastread = 0; 17024973Sbloom size = 0; 17124973Sbloom if (nfile && filen > nfile) 17224973Sbloom break; 17324973Sbloom } 17430870Skarels lastread = nread; 17524973Sbloom } 17625590Sbloom if (copy) 17725590Sbloom (void) close(outp); 17824973Sbloom printf("total length: %ld bytes\n", tsize); 17924973Sbloom } 18024973Sbloom 18130870Skarels intr() 18224973Sbloom { 18330870Skarels if (record) 18430870Skarels if (record - lastrec > 1) 18530870Skarels printf("records %ld to %ld\n", lastrec, record); 18624973Sbloom else 18730870Skarels printf("record %ld\n", lastrec); 18830870Skarels printf("interrupt at file %d: record %ld\n", filen, record); 18924973Sbloom printf("total length: %ld bytes\n", tsize+size); 19024973Sbloom exit(1); 19124973Sbloom } 192