1: #include <stdio.h> 2: #include <signal.h> 3: 4: #define BIG 32767 5: #define LCASE 01 6: #define UCASE 02 7: #define SWAB 04 8: #define NERR 010 9: #define SYNC 020 10: int cflag; 11: int fflag; 12: int skip; 13: int seekn; 14: int count; 15: int files = 1; 16: char *string; 17: char *ifile; 18: char *ofile; 19: char *ibuf; 20: char *obuf; 21: char *sbrk(); 22: int ibs = 512; 23: int obs = 512; 24: int bs; 25: int cbs; 26: int ibc; 27: int obc; 28: int cbc; 29: int nifr; 30: int nipr; 31: int nofr; 32: int nopr; 33: int ntrunc; 34: int ibf; 35: int obf; 36: char *op; 37: int nspace; 38: char etoa[] = { 39: 0000,0001,0002,0003,0234,0011,0206,0177, 40: 0227,0215,0216,0013,0014,0015,0016,0017, 41: 0020,0021,0022,0023,0235,0205,0010,0207, 42: 0030,0031,0222,0217,0034,0035,0036,0037, 43: 0200,0201,0202,0203,0204,0012,0027,0033, 44: 0210,0211,0212,0213,0214,0005,0006,0007, 45: 0220,0221,0026,0223,0224,0225,0226,0004, 46: 0230,0231,0232,0233,0024,0025,0236,0032, 47: 0040,0240,0241,0242,0243,0244,0245,0246, 48: 0247,0250,0133,0056,0074,0050,0053,0041, 49: 0046,0251,0252,0253,0254,0255,0256,0257, 50: 0260,0261,0135,0044,0052,0051,0073,0136, 51: 0055,0057,0262,0263,0264,0265,0266,0267, 52: 0270,0271,0174,0054,0045,0137,0076,0077, 53: 0272,0273,0274,0275,0276,0277,0300,0301, 54: 0302,0140,0072,0043,0100,0047,0075,0042, 55: 0303,0141,0142,0143,0144,0145,0146,0147, 56: 0150,0151,0304,0305,0306,0307,0310,0311, 57: 0312,0152,0153,0154,0155,0156,0157,0160, 58: 0161,0162,0313,0314,0315,0316,0317,0320, 59: 0321,0176,0163,0164,0165,0166,0167,0170, 60: 0171,0172,0322,0323,0324,0325,0326,0327, 61: 0330,0331,0332,0333,0334,0335,0336,0337, 62: 0340,0341,0342,0343,0344,0345,0346,0347, 63: 0173,0101,0102,0103,0104,0105,0106,0107, 64: 0110,0111,0350,0351,0352,0353,0354,0355, 65: 0175,0112,0113,0114,0115,0116,0117,0120, 66: 0121,0122,0356,0357,0360,0361,0362,0363, 67: 0134,0237,0123,0124,0125,0126,0127,0130, 68: 0131,0132,0364,0365,0366,0367,0370,0371, 69: 0060,0061,0062,0063,0064,0065,0066,0067, 70: 0070,0071,0372,0373,0374,0375,0376,0377, 71: }; 72: char atoe[] = { 73: 0000,0001,0002,0003,0067,0055,0056,0057, 74: 0026,0005,0045,0013,0014,0015,0016,0017, 75: 0020,0021,0022,0023,0074,0075,0062,0046, 76: 0030,0031,0077,0047,0034,0035,0036,0037, 77: 0100,0117,0177,0173,0133,0154,0120,0175, 78: 0115,0135,0134,0116,0153,0140,0113,0141, 79: 0360,0361,0362,0363,0364,0365,0366,0367, 80: 0370,0371,0172,0136,0114,0176,0156,0157, 81: 0174,0301,0302,0303,0304,0305,0306,0307, 82: 0310,0311,0321,0322,0323,0324,0325,0326, 83: 0327,0330,0331,0342,0343,0344,0345,0346, 84: 0347,0350,0351,0112,0340,0132,0137,0155, 85: 0171,0201,0202,0203,0204,0205,0206,0207, 86: 0210,0211,0221,0222,0223,0224,0225,0226, 87: 0227,0230,0231,0242,0243,0244,0245,0246, 88: 0247,0250,0251,0300,0152,0320,0241,0007, 89: 0040,0041,0042,0043,0044,0025,0006,0027, 90: 0050,0051,0052,0053,0054,0011,0012,0033, 91: 0060,0061,0032,0063,0064,0065,0066,0010, 92: 0070,0071,0072,0073,0004,0024,0076,0341, 93: 0101,0102,0103,0104,0105,0106,0107,0110, 94: 0111,0121,0122,0123,0124,0125,0126,0127, 95: 0130,0131,0142,0143,0144,0145,0146,0147, 96: 0150,0151,0160,0161,0162,0163,0164,0165, 97: 0166,0167,0170,0200,0212,0213,0214,0215, 98: 0216,0217,0220,0232,0233,0234,0235,0236, 99: 0237,0240,0252,0253,0254,0255,0256,0257, 100: 0260,0261,0262,0263,0264,0265,0266,0267, 101: 0270,0271,0272,0273,0274,0275,0276,0277, 102: 0312,0313,0314,0315,0316,0317,0332,0333, 103: 0334,0335,0336,0337,0352,0353,0354,0355, 104: 0356,0357,0372,0373,0374,0375,0376,0377, 105: }; 106: char atoibm[] = 107: { 108: 0000,0001,0002,0003,0067,0055,0056,0057, 109: 0026,0005,0045,0013,0014,0015,0016,0017, 110: 0020,0021,0022,0023,0074,0075,0062,0046, 111: 0030,0031,0077,0047,0034,0035,0036,0037, 112: 0100,0132,0177,0173,0133,0154,0120,0175, 113: 0115,0135,0134,0116,0153,0140,0113,0141, 114: 0360,0361,0362,0363,0364,0365,0366,0367, 115: 0370,0371,0172,0136,0114,0176,0156,0157, 116: 0174,0301,0302,0303,0304,0305,0306,0307, 117: 0310,0311,0321,0322,0323,0324,0325,0326, 118: 0327,0330,0331,0342,0343,0344,0345,0346, 119: 0347,0350,0351,0255,0340,0275,0137,0155, 120: 0171,0201,0202,0203,0204,0205,0206,0207, 121: 0210,0211,0221,0222,0223,0224,0225,0226, 122: 0227,0230,0231,0242,0243,0244,0245,0246, 123: 0247,0250,0251,0300,0117,0320,0241,0007, 124: 0040,0041,0042,0043,0044,0025,0006,0027, 125: 0050,0051,0052,0053,0054,0011,0012,0033, 126: 0060,0061,0032,0063,0064,0065,0066,0010, 127: 0070,0071,0072,0073,0004,0024,0076,0341, 128: 0101,0102,0103,0104,0105,0106,0107,0110, 129: 0111,0121,0122,0123,0124,0125,0126,0127, 130: 0130,0131,0142,0143,0144,0145,0146,0147, 131: 0150,0151,0160,0161,0162,0163,0164,0165, 132: 0166,0167,0170,0200,0212,0213,0214,0215, 133: 0216,0217,0220,0232,0233,0234,0235,0236, 134: 0237,0240,0252,0253,0254,0255,0256,0257, 135: 0260,0261,0262,0263,0264,0265,0266,0267, 136: 0270,0271,0272,0273,0274,0275,0276,0277, 137: 0312,0313,0314,0315,0316,0317,0332,0333, 138: 0334,0335,0336,0337,0352,0353,0354,0355, 139: 0356,0357,0372,0373,0374,0375,0376,0377, 140: }; 141: 142: 143: main(argc, argv) 144: int argc; 145: char **argv; 146: { 147: int (*conv)(); 148: register char *ip; 149: register c; 150: int ebcdic(), ibm(), ascii(), null(), cnull(), term(); 151: int a; 152: 153: conv = null; 154: for(c=1; c<argc; c++) { 155: string = argv[c]; 156: if(match("ibs=")) { 157: ibs = number(BIG); 158: continue; 159: } 160: if(match("obs=")) { 161: obs = number(BIG); 162: continue; 163: } 164: if(match("cbs=")) { 165: cbs = number(BIG); 166: continue; 167: } 168: if (match("bs=")) { 169: bs = number(BIG); 170: continue; 171: } 172: if(match("if=")) { 173: ifile = string; 174: continue; 175: } 176: if(match("of=")) { 177: ofile = string; 178: continue; 179: } 180: if(match("skip=")) { 181: skip = number(BIG); 182: continue; 183: } 184: if(match("seek=")) { 185: seekn = number(BIG); 186: continue; 187: } 188: if(match("count=")) { 189: count = number(BIG); 190: continue; 191: } 192: if(match("files=")) { 193: files = number(BIG); 194: continue; 195: } 196: if(match("conv=")) { 197: cloop: 198: if(match(",")) 199: goto cloop; 200: if(*string == '\0') 201: continue; 202: if(match("ebcdic")) { 203: conv = ebcdic; 204: goto cloop; 205: } 206: if(match("ibm")) { 207: conv = ibm; 208: goto cloop; 209: } 210: if(match("ascii")) { 211: conv = ascii; 212: goto cloop; 213: } 214: if(match("lcase")) { 215: cflag |= LCASE; 216: goto cloop; 217: } 218: if(match("ucase")) { 219: cflag |= UCASE; 220: goto cloop; 221: } 222: if(match("swab")) { 223: cflag |= SWAB; 224: goto cloop; 225: } 226: if(match("noerror")) { 227: cflag |= NERR; 228: goto cloop; 229: } 230: if(match("sync")) { 231: cflag |= SYNC; 232: goto cloop; 233: } 234: } 235: fprintf(stderr,"bad arg: %s\n", string); 236: exit(0); 237: } 238: if(conv == null && cflag&(LCASE|UCASE)) 239: conv = cnull; 240: if (ifile) 241: ibf = open(ifile, 0); 242: else 243: ibf = dup(0); 244: if(ibf < 0) { 245: fprintf(stderr,"cannot open: %s\n", ifile); 246: exit(0); 247: } 248: if (ofile) 249: obf = creat(ofile, 0666); 250: else 251: obf = dup(1); 252: if(obf < 0) { 253: fprintf(stderr,"cannot create: %s\n", ofile); 254: exit(0); 255: } 256: if (bs) { 257: ibs = obs = bs; 258: if (conv == null) 259: fflag++; 260: } 261: if(ibs == 0 || obs == 0) { 262: fprintf(stderr,"counts: cannot be zero\n"); 263: exit(0); 264: } 265: ibuf = sbrk(ibs); 266: if (fflag) 267: obuf = ibuf; 268: else 269: obuf = sbrk(obs); 270: sbrk(64); /* For good measure */ 271: if(ibuf == (char *)-1 || obuf == (char *)-1) { 272: fprintf(stderr, "not enough memory\n"); 273: exit(0); 274: } 275: ibc = 0; 276: obc = 0; 277: cbc = 0; 278: op = obuf; 279: 280: if (signal(SIGINT, SIG_IGN) != SIG_IGN) 281: signal(SIGINT, term); 282: while(skip) { 283: read(ibf, ibuf, ibs); 284: skip--; 285: } 286: while(seekn) { 287: lseek(obf, (long)obs, 1); 288: seekn--; 289: } 290: 291: loop: 292: if(ibc-- == 0) { 293: ibc = 0; 294: if(count==0 || nifr+nipr!=count) { 295: if(cflag&(NERR|SYNC)) 296: for(ip=ibuf+ibs; ip>ibuf;) 297: *--ip = 0; 298: ibc = read(ibf, ibuf, ibs); 299: } 300: if(ibc == -1) { 301: perror("read"); 302: if((cflag&NERR) == 0) { 303: flsh(); 304: term(); 305: } 306: ibc = 0; 307: for(c=0; c<ibs; c++) 308: if(ibuf[c] != 0) 309: ibc = c; 310: stats(); 311: } 312: if(ibc == 0 && --files<=0) { 313: flsh(); 314: term(); 315: } 316: if(ibc != ibs) { 317: nipr++; 318: if(cflag&SYNC) 319: ibc = ibs; 320: } else 321: nifr++; 322: ip = ibuf; 323: c = (ibc>>1) & ~1; 324: if(cflag&SWAB && c) 325: do { 326: a = *ip++; 327: ip[-1] = *ip; 328: *ip++ = a; 329: } while(--c); 330: ip = ibuf; 331: if (fflag) { 332: obc = ibc; 333: flsh(); 334: ibc = 0; 335: } 336: goto loop; 337: } 338: c = 0; 339: c |= *ip++; 340: c &= 0377; 341: (*conv)(c); 342: goto loop; 343: } 344: 345: flsh() 346: { 347: register c; 348: 349: if(obc) { 350: if(obc == obs) 351: nofr++; else 352: nopr++; 353: c = write(obf, obuf, obc); 354: if(c != obc) { 355: perror("write"); 356: term(); 357: } 358: obc = 0; 359: } 360: } 361: 362: match(s) 363: char *s; 364: { 365: register char *cs; 366: 367: cs = string; 368: while(*cs++ == *s) 369: if(*s++ == '\0') 370: goto true; 371: if(*s != '\0') 372: return(0); 373: 374: true: 375: cs--; 376: string = cs; 377: return(1); 378: } 379: 380: number(big) 381: { 382: register char *cs; 383: long n; 384: 385: cs = string; 386: n = 0; 387: while(*cs >= '0' && *cs <= '9') 388: n = n*10 + *cs++ - '0'; 389: for(;;) 390: switch(*cs++) { 391: 392: case 'k': 393: n *= 1024; 394: continue; 395: 396: case 'w': 397: n *= sizeof(int); 398: continue; 399: 400: case 'b': 401: n *= 512; 402: continue; 403: 404: case '*': 405: case 'x': 406: string = cs; 407: n *= number(BIG); 408: 409: case '\0': 410: if (n>=big || n<0) { 411: fprintf(stderr, "dd: argument %D out of range\n", n); 412: exit(1); 413: } 414: return(n); 415: } 416: /* never gets here */ 417: } 418: 419: cnull(cc) 420: { 421: register c; 422: 423: c = cc; 424: if(cflag&UCASE && c>='a' && c<='z') 425: c += 'A'-'a'; 426: if(cflag&LCASE && c>='A' && c<='Z') 427: c += 'a'-'A'; 428: null(c); 429: } 430: 431: null(c) 432: { 433: 434: *op = c; 435: op++; 436: if(++obc >= obs) { 437: flsh(); 438: op = obuf; 439: } 440: } 441: 442: ascii(cc) 443: { 444: register c; 445: 446: c = etoa[cc] & 0377; 447: if(cbs == 0) { 448: cnull(c); 449: return; 450: } 451: if(c == ' ') { 452: nspace++; 453: goto out; 454: } 455: while(nspace > 0) { 456: null(' '); 457: nspace--; 458: } 459: cnull(c); 460: 461: out: 462: if(++cbc >= cbs) { 463: null('\n'); 464: cbc = 0; 465: nspace = 0; 466: } 467: } 468: 469: ebcdic(cc) 470: { 471: register c; 472: 473: c = cc; 474: if(cflag&UCASE && c>='a' && c<='z') 475: c += 'A'-'a'; 476: if(cflag&LCASE && c>='A' && c<='Z') 477: c += 'a'-'A'; 478: c = atoe[c] & 0377; 479: if(cbs == 0) { 480: null(c); 481: return; 482: } 483: if(cc == '\n') { 484: while(cbc < cbs) { 485: null(atoe[' ']); 486: cbc++; 487: } 488: cbc = 0; 489: return; 490: } 491: if(cbc == cbs) 492: ntrunc++; 493: cbc++; 494: if(cbc <= cbs) 495: null(c); 496: } 497: 498: ibm(cc) 499: { 500: register c; 501: 502: c = cc; 503: if(cflag&UCASE && c>='a' && c<='z') 504: c += 'A'-'a'; 505: if(cflag&LCASE && c>='A' && c<='Z') 506: c += 'a'-'A'; 507: c = atoibm[c] & 0377; 508: if(cbs == 0) { 509: null(c); 510: return; 511: } 512: if(cc == '\n') { 513: while(cbc < cbs) { 514: null(atoibm[' ']); 515: cbc++; 516: } 517: cbc = 0; 518: return; 519: } 520: if(cbc == cbs) 521: ntrunc++; 522: cbc++; 523: if(cbc <= cbs) 524: null(c); 525: } 526: 527: term() 528: { 529: 530: stats(); 531: exit(0); 532: } 533: 534: stats() 535: { 536: 537: fprintf(stderr,"%u+%u records in\n", nifr, nipr); 538: fprintf(stderr,"%u+%u records out\n", nofr, nopr); 539: if(ntrunc) 540: fprintf(stderr,"%u truncated records\n", ntrunc); 541: }