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