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