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