Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/dd.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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