xref: /inferno-os/appl/cmd/sum.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement Sum;
2
3include "sys.m";
4include "draw.m";
5include "crc.m";
6
7Sum : module
8{
9	init : fn(nil : ref Draw->Context, argv : list of string);
10};
11
12init(nil : ref Draw->Context, argv : list of string)
13{
14	sys := load Sys Sys->PATH;
15	stderr := sys->fildes(2);
16	crcm := load Crc Crc->PATH;
17	crcs := crcm->init(0, 0);
18	a := tl argv;
19	buf := array[Sys->ATOMICIO] of byte;
20	err := 0;
21	for ( ; a != nil; a = tl a) {
22		s := hd a;
23		(ok, d) := sys->stat(s);
24		if (ok < 0) {
25			sys->fprint(stderr, "sum: cannot get status of %s: %r\n", s);
26			err = 1;
27			continue;
28		}
29		if (d.mode & Sys->DMDIR)
30			continue;
31		fd := sys->open(s, Sys->OREAD);
32		if (fd == nil) {
33			sys->fprint(stderr, "sum: cannot open %s: %r\n", s);
34			err = 1;
35			continue;
36		}
37		crc := 0;
38		nbytes := big 0;
39		while((nr := sys->read(fd, buf, len buf)) > 0){
40			crc = crcm->crc(crcs, buf, nr);
41			nbytes += big nr;
42		}
43		if(nr < 0) {
44			sys->fprint(stderr, "sum: error reading %s: %r\n", s);
45			err = 1;
46		}
47		# encode the length but make n==0 not 0
48		l := int (nbytes & big 16rFFFFFFFF);
49		buf[0] = byte((l>>24)^16rCC);
50		buf[1] = byte((l>>16)^16r55);
51		buf[2] = byte((l>>8)^16rCC);
52		buf[3] = byte(l^16r55);
53		crc = crcm->crc(crcs, buf, 4);
54		sys->print("%.8ux %6bd %s\n", crc, nbytes, s);
55		crcm->reset(crcs);
56	}
57	if(err)
58		raise "fail:error";
59}
60