|
|
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.