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