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