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