/* cksum -- calculate and print POSIX checksums and sizes of files This is the cksum utility
Copyright (C) 1992-2018 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */ The GNUv3 license
/* Written by Q. Frank Xia, qx@math.columbia.edu.
Cosmetic changes and reorganization by David MacKenzie, djm@gnu.ai.mit.edu.
Usage: cksum [file...]
The code segment between "#ifdef CRCTAB" and "#else" is the code
which calculates the "crctab". It is included for those who want
verify the correctness of the "crctab". To recreate the "crctab",
do something like the following:
cc -DCRCTAB -o crctab cksum.c
crctab > crctab.h
This software is compatible with neither the System V nor the BSD
'sum' program. It is supposed to conform to POSIX, except perhaps
for foreign language support. Any inconsistency with the standard
(other than foreign language support) is a bug. */
#include <config.h> Provides system specific information
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "cksum" Line 38
#define AUTHORS proper_name ("Q. Frank Xia") Line 40
#include <stdio.h> Provides standard I/O capability
#include <sys/types.h> Provides system data types
#include <stdint.h> ...!includes auto-comment...
#include "system.h" ...!includes auto-comment...
#include "fadvise.h" ...!includes auto-comment...
#include "xbinary-io.h" ...!includes auto-comment...
#ifdef CRCTAB Line 49
# define BIT(x) ((uint_fast32_t) 1 << (x)) Line 51
# define SBIT BIT (31) Line 52
/* The generating polynomial is
32 26 23 22 16 12 11 10 8 7 5 4 2 1
G(X)=X + X + X + X + X + X + X + X + X + X + X + X + X + X + 1
The i bit in GEN is set if X^i is a summand of G(X) except X^32. */
# define GEN (BIT (26) | BIT (23) | BIT (22) | BIT (16) | BIT (12) \ Line 61
| BIT (11) | BIT (10) | BIT (8) | BIT (7) | BIT (5) \ Line 62
| BIT (4) | BIT (2) | BIT (1) | BIT (0)) Line 63
static uint_fast32_t r[8]; Line 65
static void Line 67
fill_r (void) Line 68
{
r[0] = GEN; Line 70
for (int i = 1; i < 8; i++) Line 71
r[i] = (r[i - 1] << 1) ^ ((r[i - 1] & SBIT) ? GEN : 0); Line 72
} Block 1
static uint_fast32_t Line 75
crc_remainder (int m) Line 76
{
uint_fast32_t rem = 0; Line 78
for (int i = 0; i < 8; i++) Line 80
if (BIT (i) & m) Line 81
rem ^= r[i]; Line 82
return rem & 0xFFFFFFFF; /* Make it run on 64-bit machine. */ Line 84
} Block 2
int
main (void) Line 88
{
fill_r (); Line 90
printf ("static uint_fast32_t const crctab[256] =\n{\n 0x00000000"); Line 91
for (int i = 0; i < 51; i++) Line 92
{
printf (",\n 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x", Line 94
crc_remainder (i * 5 + 1), crc_remainder (i * 5 + 2), Line 95
crc_remainder (i * 5 + 3), crc_remainder (i * 5 + 4), Line 96
crc_remainder (i * 5 + 5)); Line 97
}
printf ("\n};\n"); Line 99
return EXIT_SUCCESS; Line 100
} Block 3
#else /* !CRCTAB */ Line 103
# include <getopt.h> ...!includes auto-comment...
# include "long-options.h" ...!includes auto-comment...
# include "die.h" ...!includes auto-comment...
# include "error.h" ...!includes auto-comment...
static struct option const long_options[] = Line 110
{
{NULL, 0, NULL, 0} Line 112
}; Block 4
/* Number of bytes to read at once. */
# define BUFLEN (1 << 16) Line 116
static uint_fast32_t const crctab[256] = Line 118
{
0x00000000, Line 120
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, Line 121
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, Line 122
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, Line 123
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, Line 124
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, Line 125
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, Line 126
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, Line 127
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, Line 128
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, Line 129
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, Line 130
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, Line 131
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, Line 132
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, Line 133
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, Line 134
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, Line 135
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, Line 136
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, Line 137
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, Line 138
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, Line 139
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, Line 140
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, Line 141
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, Line 142
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, Line 143
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, Line 144
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, Line 145
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, Line 146
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, Line 147
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, Line 148
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, Line 149
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, Line 150
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, Line 151
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, Line 152
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, Line 153
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, Line 154
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, Line 155
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, Line 156
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, Line 157
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, Line 158
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, Line 159
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, Line 160
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, Line 161
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, Line 162
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, Line 163
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, Line 164
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, Line 165
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, Line 166
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, Line 167
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, Line 168
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, Line 169
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, Line 170
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 Line 171
}; Block 5
/* Nonzero if any of the files read were the standard input. */
static bool have_read_stdin; Line 175
/* Calculate and print the checksum and length in bytes
of file FILE, or of the standard input if FILE is "-".
If PRINT_NAME is true, print FILE next to the checksum and size.
Return true if successful. */
static bool Line 182
cksum (const char *file, bool print_name) Line 183
{
unsigned char buf[BUFLEN]; Line 185
uint_fast32_t crc = 0; Line 186
uintmax_t length = 0; Line 187
size_t bytes_read; Line 188
FILE *fp; Line 189
char length_buf[INT_BUFSIZE_BOUND (uintmax_t)]; Line 190
char const *hp; Line 191
if (STREQ (file, "-")) Line 193
{
fp = stdin; Line 195
have_read_stdin = true; Line 196
xset_binary_mode (STDIN_FILENO, O_BINARY); Line 197
}
else Line 199
{
fp = fopen (file, (O_BINARY ? "rb" : "r")); Line 201...!syscalls auto-comment...
if (fp == NULL) Line 202
{
error (0, errno, "%s", quotef (file)); Line 204
return false; Line 205
}
}
fadvise (fp, FADVISE_SEQUENTIAL); Line 209...!syscalls auto-comment...
while ((bytes_read = fread (buf, 1, BUFLEN, fp)) > 0) Line 211...!syscalls auto-comment...
{
unsigned char *cp = buf; Line 213
if (length + bytes_read < length) Line 215
die (EXIT_FAILURE, 0, _("%s: file too long"), quotef (file)); Line 216
length += bytes_read; Line 217
while (bytes_read--) Line 218
crc = (crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF]; Line 219
if (feof (fp)) Line 220
break; Line 221
}
if (ferror (fp)) Line 224
{
error (0, errno, "%s", quotef (file)); Line 226
if (!STREQ (file, "-")) Line 227
fclose (fp); Line 228...!syscalls auto-comment...
return false; Line 229
}
if (!STREQ (file, "-") && fclose (fp) == EOF) Line 232...!syscalls auto-comment...
{
error (0, errno, "%s", quotef (file)); Line 234
return false; Line 235
}
hp = umaxtostr (length, length_buf); Line 238
for (; length; length >>= 8) Line 240
crc = (crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF]; Line 241
crc = ~crc & 0xFFFFFFFF; Line 243
if (print_name) Line 245
printf ("%u %s %s\n", (unsigned int) crc, hp, file); Line 246
else Line 247
printf ("%u %s\n", (unsigned int) crc, hp); Line 248
if (ferror (stdout)) Line 250
die (EXIT_FAILURE, errno, "-: %s", _("write error")); Line 251
return true; Line 253
} Block 6
void Line 256
usage (int status) Line 257
{
if (status != EXIT_SUCCESS) Line 259
emit_try_help (); ...!common auto-comment...
else Line 261
{
printf (_("\ Line 263
Usage: %s [FILE]...\n\ Line 264
or: %s [OPTION]\n\ Line 265
"), Line 266
program_name, program_name); Line 267
fputs (_("\ Line 268
Print CRC checksum and byte counts of each FILE.\n\ Line 269
\n\
"), stdout); Line 271
fputs (HELP_OPTION_DESCRIPTION, stdout); Line 272
fputs (VERSION_OPTION_DESCRIPTION, stdout); Line 273
emit_ancillary_info (PROGRAM_NAME); Line 274
}
exit (status); Line 276
} Block 7
int
main (int argc, char **argv) Line 280
{
int i; Line 282
bool ok; Line 283
initialize_main (&argc, &argv); VMS-specific entry point handling wildcard expansion
set_program_name (argv[0]); Retains program name and discards path
setlocale (LC_ALL, ""); Sets up internationalization (i18n)
bindtextdomain (PACKAGE, LOCALEDIR); Assigns i18n directorySets text domain for _() [gettext()] function
textdomain (PACKAGE); Sets text domain for _() [gettext()] function
atexit (close_stdout); Close stdout on exit (see gnulib)
/* Line buffer stdout to ensure lines are written atomically and immediately
so that processes running in parallel do not intersperse their output. */
setvbuf (stdout, NULL, _IOLBF, 0); Line 295
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, Version, ...!common auto-comment...
usage, AUTHORS, (char const *) NULL); Line 298
if (getopt_long (argc, argv, "", long_options, NULL) != -1) Line 299
usage (EXIT_FAILURE); Line 300
have_read_stdin = false; Line 302
if (optind == argc) Line 304
ok = cksum ("-", false); Line 305
else Line 306
{
ok = true; Line 308
for (i = optind; i < argc; i++) Line 309
ok &= cksum (argv[i], true); Line 310
}
if (have_read_stdin && fclose (stdin) == EOF) Line 313...!syscalls auto-comment...
die (EXIT_FAILURE, errno, "-"); Line 314
return ok ? EXIT_SUCCESS : EXIT_FAILURE; Line 315
} Block 8
#endif /* !CRCTAB */ Line 318