1 /* 2 * Copyright (c) 1985, 1987 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 char copyright[] = 9 "@(#) Copyright (c) 1985, 1987 Regents of the University of California.\n\ 10 All rights reserved.\n"; 11 #endif not lint 12 13 #ifndef lint 14 static char sccsid[] = "@(#)tcopy.c 5.5 (Berkeley) 04/09/87"; 15 #endif not lint 16 17 #include <stdio.h> 18 #include <signal.h> 19 #include <sys/file.h> 20 #include <sys/types.h> 21 #include <sys/ioctl.h> 22 #include <sys/mtio.h> 23 #include <sys/errno.h> 24 25 #define MAXREC (64 * 1024) 26 #define NOCOUNT (-2) 27 #undef DEFTAPE 28 #define DEFTAPE "/dev/rmt0" 29 30 char *buff; 31 char *inf = DEFTAPE; 32 int maxblk = MAXREC; 33 int filen; 34 long record, lastrec; 35 int intr(); 36 long itol(); 37 char *malloc(); 38 long size, tsize; 39 int nfile; 40 int lastread; 41 int copy; 42 extern int errno; 43 44 main(argc, argv) 45 char **argv; 46 { 47 register nread, nw, inp, outp; 48 struct mtop op; 49 int needeof = 0, guesslen = 1; 50 51 while (argc > 1 && *argv[1] == '-') { 52 switch (*++argv[1]) { 53 case 's': 54 if (argc < 3) 55 goto usage; 56 maxblk = atoi(argv[2]); 57 if (maxblk <= 0) { 58 fprintf(stderr, "illegal block size\n"); 59 goto usage; 60 } 61 argc--; 62 argv++; 63 guesslen = 0; 64 break; 65 } 66 argc--; 67 argv++; 68 } 69 if (argc < 1 || argc > 3) { 70 usage: 71 fprintf(stderr, "Usage: tcopy [-s maxblk] src [dest]\n"); 72 exit(1); 73 } 74 if (argc > 1) 75 inf = argv[1]; 76 if ((inp = open(inf, O_RDONLY, 0)) < 0) { 77 perror(inf); 78 exit(1); 79 } 80 if (argc == 3) { 81 copy = 1; 82 if ((outp = open(argv[2], O_WRONLY, 0666)) < 0) { 83 perror(argv[2]); 84 exit(3); 85 } 86 } 87 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 88 (void) signal(SIGINT, intr); 89 buff = malloc(maxblk); 90 if (buff == NULL) { 91 fprintf("tcopy: no memory\n"); 92 exit(11); 93 } 94 lastread = NOCOUNT; 95 for (;;) { 96 nread = read(inp, buff, maxblk); 97 if (nread == -1) { 98 if (errno == EINVAL && guesslen && 99 maxblk > MAXREC / 2) { 100 maxblk -= 1024; 101 continue; 102 } 103 fprintf(stderr, "read error, file %d, record %d: ", 104 filen, record); 105 perror(""); 106 } else if (nread != lastread) { 107 if (lastread != 0 && lastread != NOCOUNT) { 108 if (lastrec == 0 && nread == 0) 109 printf("%d records\n", record); 110 else if (record - lastrec > 1) 111 printf("records %ld to %ld\n", 112 lastrec, record); 113 else 114 printf("record %ld\n", lastrec); 115 } 116 if (nread != 0) 117 printf("file %d: block size %d: ", 118 filen, nread); 119 fflush(stdout); 120 lastrec = record; 121 } 122 guesslen = 0; 123 if (nread > 0) { 124 if (copy) { 125 if (needeof) { 126 op.mt_op = MTWEOF; 127 op.mt_count = (daddr_t) 1; 128 if (ioctl(outp, MTIOCTOP, (char *)&op) < 0) { 129 perror("write tape mark"); 130 exit(6); 131 } 132 needeof = 0; 133 } 134 nw = write(outp, buff, nread); 135 if (nw != nread) { 136 fprintf(stderr, 137 "write error, file %d, record %d: ", 138 filen, record); 139 if (nw == -1) 140 perror(""); 141 else 142 fprintf(stderr, 143 "write (%d) != read (%d)\n", 144 nw, nread); 145 fprintf(stderr, "copy aborted\n"); 146 exit(5); 147 } 148 } 149 size += nread; 150 record++; 151 } else { 152 if (lastread <= 0 && lastread != NOCOUNT) { 153 printf("eot\n"); 154 break; 155 } 156 printf("file %d: eof after %ld records: %ld bytes\n", 157 filen, record, size); 158 needeof = 1; 159 filen++; 160 tsize += size; 161 record = 0; 162 lastrec = 0; 163 lastread = 0; 164 size = 0; 165 if (nfile && filen > nfile) 166 break; 167 } 168 lastread = nread; 169 } 170 if (copy) 171 (void) close(outp); 172 printf("total length: %ld bytes\n", tsize); 173 } 174 175 intr() 176 { 177 if (record) 178 if (record - lastrec > 1) 179 printf("records %ld to %ld\n", lastrec, record); 180 else 181 printf("record %ld\n", lastrec); 182 printf("interrupt at file %d: record %ld\n", filen, record); 183 printf("total length: %ld bytes\n", tsize+size); 184 exit(1); 185 } 186