annotate toys/cksum.c @ 543:60b97ba66a70

Extensive semi-gratuitous refactoring: factor out common code, handle euid!=uid and egid!=gid cases. (Note: test suite requires root access, possibly container support.)
author Rob Landley <rob@landley.net>
date Mon, 12 Mar 2012 23:00:28 -0500
parents 0cc0c0e879d1
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
1 /* vi: set sw=4 ts=4:
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
2 *
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
3 * cksum.c - produce crc32 checksum value for each input
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
4 *
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
5 * Copyright 2008 Rob Landley <rob@landley.net>
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
6 *
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
7 * See http://www.opengroup.org/onlinepubs/009695399/utilities/cksum.html
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
8
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
9 USE_CKSUM(NEWTOY(cksum, "IPLN", TOYFLAG_BIN))
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
10
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
11 config CKSUM
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
12 bool "cksum"
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
13 default y
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
14 help
447
0cc0c0e879d1 Correct cksum parameters and clarify -N option
Elie De Brauwer <eliedebrauwer@gmail.com>
parents: 338
diff changeset
15 usage: cksum [-IPLN] [file...]
336
0c816f5abe22 Add -F option to cksum.
Rob Landley <rob@landley.net>
parents: 333
diff changeset
16
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
17 For each file, output crc32 checksum value, length and name of file.
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
18 If no files listed, copy from stdin. Filename "-" is a synonym for stdin.
336
0c816f5abe22 Add -F option to cksum.
Rob Landley <rob@landley.net>
parents: 333
diff changeset
19
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
20 -L Little endian (defaults to big endian)
338
a4c26369ec43 Accidentally changed cksum behavior with the -P flag, toggle its meaning.
Rob Landley <rob@landley.net>
parents: 337
diff changeset
21 -P Pre-inversion
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
22 -I Skip post-inversion
447
0cc0c0e879d1 Correct cksum parameters and clarify -N option
Elie De Brauwer <eliedebrauwer@gmail.com>
parents: 338
diff changeset
23 -N Do not include length in CRC calculation
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
24 */
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
25
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
26 #include "toys.h"
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
27
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
28 DEFINE_GLOBALS(
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
29 unsigned crc_table[256];
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
30 )
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
31
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
32 #define TT this.cksum
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
33
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
34 static unsigned cksum_be(unsigned crc, unsigned char c)
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
35 {
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
36 return (crc<<8)^TT.crc_table[(crc>>24)^c];
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
37 }
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
38
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
39 static unsigned cksum_le(unsigned crc, unsigned char c)
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
40 {
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
41 return TT.crc_table[(crc^c)&0xff] ^ (crc>>8);
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
42 }
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
43
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
44 static void do_cksum(int fd, char *name)
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
45 {
338
a4c26369ec43 Accidentally changed cksum behavior with the -P flag, toggle its meaning.
Rob Landley <rob@landley.net>
parents: 337
diff changeset
46 unsigned crc = (toys.optflags&4) ? 0xffffffff : 0;
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
47 uint64_t llen = 0, llen2;
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
48 unsigned (*cksum)(unsigned crc, unsigned char c);
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
49
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
50
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
51 cksum = (toys.optflags&2) ? cksum_le : cksum_be;
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
52 // CRC the data
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
53
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
54 for (;;) {
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
55 int len, i;
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
56
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
57 len = read(fd, toybuf, sizeof(toybuf));
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
58 if (len<0) {
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
59 perror_msg("%s",name);
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
60 toys.exitval = EXIT_FAILURE;
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
61 }
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
62 if (len<1) break;
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
63
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
64 llen += len;
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
65 for (i=0; i<len; i++) crc=cksum(crc, toybuf[i]);
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
66 }
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
67
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
68 // CRC the length
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
69
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
70 llen2 = llen;
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
71 if (!(toys.optflags&1)) {
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
72 while (llen) {
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
73 crc = cksum(crc, llen);
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
74 llen >>= 8;
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
75 }
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
76 }
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
77
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
78 printf("%u %"PRIu64, (toys.optflags&8) ? crc : ~crc, llen2);
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
79 if (strcmp("-", name)) printf(" %s", name);
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
80 xputc('\n');
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
81 }
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
82
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
83 void cksum_main(void)
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
84 {
337
aaafa1ceaa91 Add -N, -I, -L, and -P options to cksum.
Rob Landley <rob@landley.net>
parents: 336
diff changeset
85 crc_init(TT.crc_table, toys.optflags&2);
333
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
86 loopfiles(toys.optargs, do_cksum);
d5d8f9a6e649 Add cksum.
Rob Landley <rob@landley.net>
parents:
diff changeset
87 }