source: trunk/coreutils/src/cksum.c@ 2555

Last change on this file since 2555 was 2554, checked in by bird, 20 years ago

coretuils-5.94

File size: 9.5 KB
Line 
1/* cksum -- calculate and print POSIX checksums and sizes of files
2 Copyright (C) 92, 1995-2005 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18
19/* Written by Q. Frank Xia, [email protected].
20 Cosmetic changes and reorganization by David MacKenzie, [email protected].
21
22 Usage: cksum [file...]
23
24 The code segment between "#ifdef CRCTAB" and "#else" is the code
25 which calculates the "crctab". It is included for those who want
26 verify the correctness of the "crctab". To recreate the "crctab",
27 do something like the following:
28
29 cc -DCRCTAB -o crctab cksum.c
30 crctab > crctab.h
31
32 This software is compatible with neither the System V nor the BSD
33 `sum' program. It is supposed to conform to POSIX, except perhaps
34 for foreign language support. Any inconsistency with the standard
35 (other than foreign language support) is a bug. */
36
37#include <config.h>
38
39/* The official name of this program (e.g., no `g' prefix). */
40#define PROGRAM_NAME "cksum"
41
42#define AUTHORS "Q. Frank Xia"
43
44#include <stdio.h>
45#include <sys/types.h>
46#include "system.h"
47
48#if !defined UINT_FAST32_MAX && !defined uint_fast32_t
49# define uint_fast32_t unsigned int
50#endif
51
52#ifdef CRCTAB
53
54# define BIT(x) ((uint_fast32_t) 1 << (x))
55# define SBIT BIT (31)
56
57/* The generating polynomial is
58
59 32 26 23 22 16 12 11 10 8 7 5 4 2 1
60 G(X)=X + X + X + X + X + X + X + X + X + X + X + X + X + X + 1
61
62 The i bit in GEN is set if X^i is a summand of G(X) except X^32. */
63
64# define GEN (BIT (26) | BIT (23) | BIT (22) | BIT (16) | BIT (12) \
65 | BIT (11) | BIT (10) | BIT (8) | BIT (7) | BIT (5) \
66 | BIT (4) | BIT (2) | BIT (1) | BIT (0))
67
68static uint_fast32_t r[8];
69
70static void
71fill_r (void)
72{
73 int i;
74
75 r[0] = GEN;
76 for (i = 1; i < 8; i++)
77 r[i] = (r[i - 1] << 1) ^ ((r[i - 1] & SBIT) ? GEN : 0);
78}
79
80static uint_fast32_t
81crc_remainder (int m)
82{
83 uint_fast32_t rem = 0;
84 int i;
85
86 for (i = 0; i < 8; i++)
87 if (BIT (i) & m)
88 rem ^= r[i];
89
90 return rem & 0xFFFFFFFF; /* Make it run on 64-bit machine. */
91}
92
93int
94main (void)
95{
96 int i;
97
98 fill_r ();
99 printf ("static uint_fast32_t const crctab[256] =\n{\n 0x00000000");
100 for (i = 0; i < 51; i++)
101 {
102 printf (",\n 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x",
103 crc_remainder (i * 5 + 1), crc_remainder (i * 5 + 2),
104 crc_remainder (i * 5 + 3), crc_remainder (i * 5 + 4),
105 crc_remainder (i * 5 + 5));
106 }
107 printf ("\n};\n");
108 exit (EXIT_SUCCESS);
109}
110
111#else /* !CRCTAB */
112
113# include <getopt.h>
114# include "long-options.h"
115# include "error.h"
116# include "inttostr.h"
117
118/* Number of bytes to read at once. */
119# define BUFLEN (1 << 16)
120
121/* The name this program was run with. */
122char *program_name;
123
124static uint_fast32_t const crctab[256] =
125{
126 0x00000000,
127 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
128 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
129 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
130 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
131 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
132 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
133 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
134 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
135 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
136 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
137 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
138 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
139 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
140 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
141 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
142 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
143 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
144 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
145 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
146 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
147 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
148 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
149 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
150 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
151 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
152 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
153 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
154 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
155 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
156 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
157 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
158 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
159 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
160 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
161 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
162 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
163 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
164 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
165 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
166 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
167 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
168 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
169 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
170 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
171 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
172 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
173 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
174 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
175 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
176 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
177 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
178};
179
180/* Nonzero if any of the files read were the standard input. */
181static bool have_read_stdin;
182
183/* Calculate and print the checksum and length in bytes
184 of file FILE, or of the standard input if FILE is "-".
185 If PRINT_NAME is true, print FILE next to the checksum and size.
186 Return true if successful. */
187
188static bool
189cksum (const char *file, bool print_name)
190{
191 unsigned char buf[BUFLEN];
192 uint_fast32_t crc = 0;
193 uintmax_t length = 0;
194 size_t bytes_read;
195 FILE *fp;
196 char length_buf[INT_BUFSIZE_BOUND (uintmax_t)];
197 char const *hp;
198
199 if (STREQ (file, "-"))
200 {
201 fp = stdin;
202 have_read_stdin = true;
203 if (O_BINARY && ! isatty (STDIN_FILENO))
204 freopen (NULL, "rb", stdin);
205 }
206 else
207 {
208 fp = fopen (file, (O_BINARY ? "rb" : "r"));
209 if (fp == NULL)
210 {
211 error (0, errno, "%s", file);
212 return false;
213 }
214 }
215
216 while ((bytes_read = fread (buf, 1, BUFLEN, fp)) > 0)
217 {
218 unsigned char *cp = buf;
219
220 if (length + bytes_read < length)
221 error (EXIT_FAILURE, 0, _("%s: file too long"), file);
222 length += bytes_read;
223 while (bytes_read--)
224 crc = (crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
225 if (feof (fp))
226 break;
227 }
228
229 if (ferror (fp))
230 {
231 error (0, errno, "%s", file);
232 if (!STREQ (file, "-"))
233 fclose (fp);
234 return false;
235 }
236
237 if (!STREQ (file, "-") && fclose (fp) == EOF)
238 {
239 error (0, errno, "%s", file);
240 return false;
241 }
242
243 hp = umaxtostr (length, length_buf);
244
245 for (; length; length >>= 8)
246 crc = (crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF];
247
248 crc = ~crc & 0xFFFFFFFF;
249
250 if (print_name)
251 printf ("%u %s %s\n", (unsigned int) crc, hp, file);
252 else
253 printf ("%u %s\n", (unsigned int) crc, hp);
254
255 if (ferror (stdout))
256 error (EXIT_FAILURE, errno, "-: %s", _("write error"));
257
258 return true;
259}
260
261void
262usage (int status)
263{
264 if (status != EXIT_SUCCESS)
265 fprintf (stderr, _("Try `%s --help' for more information.\n"),
266 program_name);
267 else
268 {
269 printf (_("\
270Usage: %s [FILE]...\n\
271 or: %s [OPTION]\n\
272"),
273 program_name, program_name);
274 fputs (_("\
275Print CRC checksum and byte counts of each FILE.\n\
276\n\
277"), stdout);
278 fputs (HELP_OPTION_DESCRIPTION, stdout);
279 fputs (VERSION_OPTION_DESCRIPTION, stdout);
280 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
281 }
282 exit (status);
283}
284
285int
286main (int argc, char **argv)
287{
288 int i;
289 bool ok;
290
291 initialize_main (&argc, &argv);
292 program_name = argv[0];
293 setlocale (LC_ALL, "");
294 bindtextdomain (PACKAGE, LOCALEDIR);
295 textdomain (PACKAGE);
296
297 atexit (close_stdout);
298
299 parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, VERSION,
300 usage, AUTHORS, (char const *) NULL);
301 if (getopt_long (argc, argv, "", NULL, NULL) != -1)
302 usage (EXIT_FAILURE);
303
304 have_read_stdin = false;
305
306 if (optind == argc)
307 ok = cksum ("-", false);
308 else
309 {
310 ok = true;
311 for (i = optind; i < argc; i++)
312 ok &= cksum (argv[i], true);
313 }
314
315 if (have_read_stdin && fclose (stdin) == EOF)
316 error (EXIT_FAILURE, errno, "-");
317 exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
318}
319
320#endif /* !CRCTAB */
Note: See TracBrowser for help on using the repository browser.