1: /* 2: * @(#)makesimtape.c 2.1 (2.11BSD) 1998/12/31 3: * Hacked 'maketape.c' to write a file in a format suitable for 4: * use with Bob Supnik's PDP-11 simulator (V2.3) emulated tape 5: * driver. 6: * 7: * NOTE: a PDP-11 has to flip the shorts within the long when writing out 8: * the record size. Seems a PDP-11 is neither a little-endian 9: * machine nor a big-endian one. 10: */ 11: 12: #include <stdio.h> 13: #include <errno.h> 14: #include <fcntl.h> 15: #include <stdlib.h> 16: #include <sys/types.h> 17: #include <sys/stat.h> 18: #include <sys/uio.h> 19: 20: #define MAXB 30 21: 22: char buf[MAXB * 512]; 23: char name[50]; 24: long recsz, flipped, trl(); 25: int blksz; 26: int mt, fd, cnt; 27: struct iovec iovec[3]; 28: struct iovec tmark[2]; 29: void usage(); 30: 31: main(argc, argv) 32: int argc; 33: char *argv[]; 34: { 35: int i, j = 0, k = 0; 36: long zero = 0; 37: register char *outfile = NULL, *infile = NULL; 38: FILE *mf; 39: struct stat st; 40: 41: while ((i = getopt(argc, argv, "i:o:")) != EOF) 42: { 43: switch (i) 44: { 45: case 'o': 46: outfile = optarg; 47: break; 48: case 'i': 49: infile = optarg; 50: break; 51: default: 52: usage(); 53: /* NOTREACHED */ 54: } 55: } 56: if (!outfile || !infile) 57: usage(); 58: /* NOTREACHED */ 59: /* 60: * Stat the outfile and make sure it either 1) Does not exist, or 61: * 2) Exists but is a regular file. 62: */ 63: if (stat(outfile, &st) != -1 && !(S_ISREG(st.st_mode))) 64: errx(1, "outfile must either not exist or be a regular file"); 65: /* NOTREACHED */ 66: 67: mt = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0600); 68: if (mt < 0) 69: err(1, "Can not create %s", outfile); 70: /* NOTREACHED */ 71: 72: mf = fopen(infile, "r"); 73: if (!mf) 74: err(1, "Can not open %s", infile); 75: /* NOTREACHED*/ 76: 77: tmark[0].iov_len = sizeof (long); 78: tmark[0].iov_base = (char *)&zero; 79: 80: while (1) 81: { 82: if ((i = fscanf(mf, "%s %d", name, &blksz))== EOF) 83: exit(0); 84: if (i != 2) { 85: fprintf(stderr,"Help! Scanf didn't read 2 things (%d)\n", i); 86: exit(1); 87: } 88: if (blksz <= 0 || blksz > MAXB) 89: { 90: fprintf(stderr, "Block size %u is invalid\n", blksz); 91: exit(1); 92: } 93: recsz = blksz * 512; /* convert to bytes */ 94: iovec[0].iov_len = sizeof (recsz); 95: #ifdef pdp11 96: iovec[0].iov_base = (char *)&flipped; 97: #else 98: iovec[0].iov_base = (char *)&recsz; 99: #endif 100: iovec[1].iov_len = (int)recsz; 101: iovec[1].iov_base = buf; 102: iovec[2].iov_len = iovec[0].iov_len; 103: iovec[2].iov_base = iovec[0].iov_base; 104: 105: if (strcmp(name, "*") == 0) 106: { 107: if (writev(mt, tmark, 1) < 0) 108: warn(1, "writev of pseudo tapemark failed"); 109: k++; 110: continue; 111: } 112: fd = open(name, 0); 113: if (fd < 0) 114: err(1, "Can't open %s for reading", name); 115: /* NOTREACHED */ 116: printf("%s: block %d, file %d\n", name, j, k); 117: 118: /* 119: * we pad the last record with nulls 120: * (instead of the bell std. of padding with trash). 121: * this allows you to access text files on the 122: * tape without garbage at the end of the file. 123: * (note that there is no record length associated 124: * with tape files) 125: */ 126: 127: while ((cnt=read(fd, buf, (int)recsz)) == (int)recsz) 128: { 129: j++; 130: #ifdef pdp11 131: flipped = trl(recsz); 132: #endif 133: if (writev(mt, iovec, 3) < 0) 134: err(1, "writev #1"); 135: /* NOTREACHED */ 136: } 137: if (cnt > 0) 138: { 139: j++; 140: bzero(buf + cnt, (int)recsz - cnt); 141: #ifdef pdp11 142: flipped = trl(recsz); 143: #endif 144: if (writev(mt, iovec, 3) < 0) 145: err(1, "writev #2"); 146: /* NOTREACHED */ 147: } 148: close(fd); 149: } 150: /* 151: * Write two tape marks to simulate EOT 152: */ 153: writev(mt, tmark, 1); 154: writev(mt, tmark, 1); 155: } 156: 157: long 158: trl(l) 159: long l; 160: { 161: union { 162: long l; 163: short s[2]; 164: } foo; 165: register short x; 166: 167: foo.l = l; 168: x = foo.s[0]; 169: foo.s[0] = foo.s[1]; 170: foo.s[1] = x; 171: return(foo.l); 172: } 173: 174: void 175: usage() 176: { 177: fprintf(stderr, "usage: makesimtape -o outfilefile -i inputfile\n"); 178: exit(1); 179: }