/* 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