/* Compute checksums of files or strings.                                       This is the md5sum utility
   Copyright (C) 1995-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 Ulrich Drepper <drepper@gnu.ai.mit.edu>.  */                      
                                                                                
#include <config.h>                                                             Provides system specific information
                                                                                
#include <getopt.h>                                                             ...!includes auto-comment...
#include <sys/types.h>                                                          Provides system data types
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "argmatch.h"                                                           ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "xdectoint.h"                                                          ...!includes auto-comment...
#include "xstrtol.h"                                                            ...!includes auto-comment...
                                                                                
#if HASH_ALGO_BLAKE2                                                            Line 30
# include "blake2/b2sum.h"                                                      Line 31
#endif                                                                          Line 32
#if HASH_ALGO_MD5                                                               Line 33
# include "md5.h"                                                               ...!includes auto-comment...
#endif                                                                          Line 35
#if HASH_ALGO_SHA1                                                              Line 36
# include "sha1.h"                                                              Line 37
#endif                                                                          Line 38
#if HASH_ALGO_SHA256 || HASH_ALGO_SHA224                                        Line 39
# include "sha256.h"                                                            Line 40
#endif                                                                          Line 41
#if HASH_ALGO_SHA512 || HASH_ALGO_SHA384                                        Line 42
# include "sha512.h"                                                            Line 43
#endif                                                                          Line 44
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "fadvise.h"                                                            ...!includes auto-comment...
#include "stdio--.h"                                                            ...!includes auto-comment...
#include "xbinary-io.h"                                                         ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#if HASH_ALGO_MD5                                                               Line 52
# define PROGRAM_NAME "md5sum"                                                  Line 53
# define DIGEST_TYPE_STRING "MD5"                                               Line 54
# define DIGEST_STREAM md5_stream                                               Line 55
# define DIGEST_BITS 128                                                        Line 56
# define DIGEST_REFERENCE "RFC 1321"                                            Line 57
# define DIGEST_ALIGN 4                                                         Line 58
#elif HASH_ALGO_BLAKE2                                                          Line 59
# define PROGRAM_NAME "b2sum"                                                   Line 60
# define DIGEST_TYPE_STRING "BLAKE2"                                            Line 61
# define DIGEST_STREAM blake2fns[b2_algorithm]                                  Line 62
# define DIGEST_BITS 512                                                        Line 63
# define DIGEST_REFERENCE "RFC 7693"                                            Line 64
# define DIGEST_ALIGN 8                                                         Line 65
#elif HASH_ALGO_SHA1                                                            Line 66
# define PROGRAM_NAME "sha1sum"                                                 Line 67
# define DIGEST_TYPE_STRING "SHA1"                                              Line 68
# define DIGEST_STREAM sha1_stream                                              Line 69
# define DIGEST_BITS 160                                                        Line 70
# define DIGEST_REFERENCE "FIPS-180-1"                                          Line 71
# define DIGEST_ALIGN 4                                                         Line 72
#elif HASH_ALGO_SHA256                                                          Line 73
# define PROGRAM_NAME "sha256sum"                                               Line 74
# define DIGEST_TYPE_STRING "SHA256"                                            Line 75
# define DIGEST_STREAM sha256_stream                                            Line 76
# define DIGEST_BITS 256                                                        Line 77
# define DIGEST_REFERENCE "FIPS-180-2"                                          Line 78
# define DIGEST_ALIGN 4                                                         Line 79
#elif HASH_ALGO_SHA224                                                          Line 80
# define PROGRAM_NAME "sha224sum"                                               Line 81
# define DIGEST_TYPE_STRING "SHA224"                                            Line 82
# define DIGEST_STREAM sha224_stream                                            Line 83
# define DIGEST_BITS 224                                                        Line 84
# define DIGEST_REFERENCE "RFC 3874"                                            Line 85
# define DIGEST_ALIGN 4                                                         Line 86
#elif HASH_ALGO_SHA512                                                          Line 87
# define PROGRAM_NAME "sha512sum"                                               Line 88
# define DIGEST_TYPE_STRING "SHA512"                                            Line 89
# define DIGEST_STREAM sha512_stream                                            Line 90
# define DIGEST_BITS 512                                                        Line 91
# define DIGEST_REFERENCE "FIPS-180-2"                                          Line 92
# define DIGEST_ALIGN 8                                                         Line 93
#elif HASH_ALGO_SHA384                                                          Line 94
# define PROGRAM_NAME "sha384sum"                                               Line 95
# define DIGEST_TYPE_STRING "SHA384"                                            Line 96
# define DIGEST_STREAM sha384_stream                                            Line 97
# define DIGEST_BITS 384                                                        Line 98
# define DIGEST_REFERENCE "FIPS-180-2"                                          Line 99
# define DIGEST_ALIGN 8                                                         Line 100
#else                                                                           Line 101
# error "Can't decide which hash algorithm to compile."                         Line 102
#endif                                                                          Line 103
                                                                                
#if HASH_ALGO_BLAKE2                                                            Line 105
# define AUTHORS \                                                              Line 106
  proper_name ("Padraig Brady"), \                                              Line 107
  proper_name ("Samuel Neves")                                                  Line 108
#else                                                                           Line 109
# define AUTHORS \                                                              Line 110
  proper_name ("Ulrich Drepper"), \                                             Line 111
  proper_name ("Scott Miller"), \                                               Line 112
  proper_name ("David Madore")                                                  Line 113
# define DIGEST_HEX_BYTES (DIGEST_BITS / 4)                                     Line 114
#endif                                                                          Line 115
#define DIGEST_BIN_BYTES (DIGEST_BITS / 8)                                      Line 116
                                                                                
                                                                                
/* The minimum length of a valid digest line.  This length does                 
   not include any newline character at the end of a line.  */                  
#if HASH_ALGO_BLAKE2                                                            Line 121
# define MIN_DIGEST_LINE_LENGTH 3 /* With -l 8.  */                             Line 122
#else                                                                           Line 123
# define MIN_DIGEST_LINE_LENGTH \                                               Line 124
   (DIGEST_HEX_BYTES /* length of hexadecimal message digest */ \               Line 125
    + 1 /* blank */ \                                                           Line 126
    + 1 /* minimum filename length */ )                                         Line 127
#endif                                                                          Line 128
                                                                                
/* True if any of the files read were the standard input. */                    
static bool have_read_stdin;                                                    Line 131
                                                                                
/* The minimum length of a valid checksum line for the selected algorithm.  */  
static size_t min_digest_line_length;                                           Line 134
                                                                                
/* Set to the length of a digest hex string for the selected algorithm.  */     
static size_t digest_hex_bytes;                                                 Line 137
                                                                                
/* With --check, don't generate any output.                                     
   The exit code indicates success or failure.  */                              
static bool status_only = false;                                                Line 141
                                                                                
/* With --check, print a message to standard error warning about each           
   improperly formatted checksum line.  */                                      
static bool warn = false;                                                       Line 145
                                                                                
/* With --check, ignore missing files.  */                                      
static bool ignore_missing = false;                                             Line 148
                                                                                
/* With --check, suppress the "OK" printed for each verified file.  */          
static bool quiet = false;                                                      Line 151
                                                                                
/* With --check, exit with a non-zero return code if any line is                
   improperly formatted. */                                                     
static bool strict = false;                                                     Line 155
                                                                                
/* Whether a BSD reversed format checksum is detected.  */                      
static int bsd_reversed = -1;                                                   Line 158
                                                                                
/* line delimiter.  */                                                          
static unsigned char delim = '\n';                                              Line 161
                                                                                
#if HASH_ALGO_BLAKE2                                                            Line 163
static char const *const algorithm_in_string[] =                                Line 164
{                                                                               
  "blake2b", NULL                                                               Line 166
};                                                                              Block 1
static char const *const algorithm_out_string[] =                               Line 168
{                                                                               
  "BLAKE2b", NULL                                                               Line 170
};                                                                              Block 2
enum Algorithm                                                                  Line 172
{                                                                               
  BLAKE2b                                                                       Line 174
};                                                                              Block 3
verify (ARRAY_CARDINALITY (algorithm_in_string) == 2);                          Line 176
verify (ARRAY_CARDINALITY (algorithm_out_string) == 2);                         Line 177
                                                                                
static enum Algorithm b2_algorithm;                                             Line 179
static uintmax_t b2_length;                                                     Line 180
static blake2fn blake2fns[]=                                                    Line 181
{                                                                               
  blake2b_stream                                                                Line 183
};                                                                              Block 4
static uintmax_t blake2_max_len[]=                                              Line 185
{                                                                               
  BLAKE2B_OUTBYTES                                                              Line 187
};                                                                              Block 5
#endif /* HASH_ALGO_BLAKE2 */                                                   Line 189
                                                                                
/* For long options that have no equivalent short option, use a                 
   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */      
enum                                                                            Line 193
{                                                                               
  IGNORE_MISSING_OPTION = CHAR_MAX + 1,                                         Line 195
  STATUS_OPTION,                                                                Line 196
  QUIET_OPTION,                                                                 Line 197
  STRICT_OPTION,                                                                Line 198
  TAG_OPTION                                                                    Line 199
};                                                                              Block 6
                                                                                
static struct option const long_options[] =                                     Line 202
{                                                                               
#if HASH_ALGO_BLAKE2                                                            Line 204
  { "length", required_argument, NULL, 'l'},                                    Line 205
#endif                                                                          Line 206
  { "binary", no_argument, NULL, 'b' },                                         Line 207
  { "check", no_argument, NULL, 'c' },                                          Line 208
  { "ignore-missing", no_argument, NULL, IGNORE_MISSING_OPTION},                Line 209
  { "quiet", no_argument, NULL, QUIET_OPTION },                                 Line 210
  { "status", no_argument, NULL, STATUS_OPTION },                               Line 211
  { "text", no_argument, NULL, 't' },                                           Line 212
  { "warn", no_argument, NULL, 'w' },                                           Line 213
  { "strict", no_argument, NULL, STRICT_OPTION },                               Line 214
  { "tag", no_argument, NULL, TAG_OPTION },                                     Line 215
  { "zero", no_argument, NULL, 'z' },                                           Line 216
  { GETOPT_HELP_OPTION_DECL },                                                  Line 217
  { GETOPT_VERSION_OPTION_DECL },                                               Line 218
  { NULL, 0, NULL, 0 }                                                          Line 219
};                                                                              Block 7
                                                                                
void                                                                            Line 222
usage (int status)                                                              Line 223
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 225
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 227
    {                                                                           
      printf (_("\                                                              Line 229
Usage: %s [OPTION]... [FILE]...\n\                                              Line 230
Print or check %s (%d-bit) checksums.\n\                                        Line 231
"),                                                                             Line 232
              program_name,                                                     Line 233
              DIGEST_TYPE_STRING,                                               Line 234
              DIGEST_BITS);                                                     Line 235
                                                                                
      emit_stdin_note ();                                                       ...!common auto-comment...
      if (O_BINARY)                                                             Line 238
        fputs (_("\                                                             Line 239
\n\                                                                             
  -b, --binary         read in binary mode (default unless reading tty stdin)\n\Line 241
"), stdout);                                                                    Line 242
      else                                                                      Line 243
        fputs (_("\                                                             Line 244
\n\                                                                             
  -b, --binary         read in binary mode\n\                                   Line 246
"), stdout);                                                                    Line 247
                                                                                
      printf (_("\                                                              Line 249
  -c, --check          read %s sums from the FILEs and check them\n"),          Line 250
              DIGEST_TYPE_STRING);                                              Line 251
#if HASH_ALGO_BLAKE2                                                            Line 252
        fputs (_("\                                                             Line 253
  -l, --length         digest length in bits; must not exceed the maximum for\n\Line 254
                       the blake2 algorithm and must be a multiple of 8\n\      Line 255
"), stdout);                                                                    Line 256
#endif                                                                          Line 257
      fputs (_("\                                                               Line 258
      --tag            create a BSD-style checksum\n\                           Line 259
"), stdout);                                                                    Line 260
      if (O_BINARY)                                                             Line 261
        fputs (_("\                                                             Line 262
  -t, --text           read in text mode (default if reading tty stdin)\n\      Line 263
"), stdout);                                                                    Line 264
      else                                                                      Line 265
        fputs (_("\                                                             Line 266
  -t, --text           read in text mode (default)\n\                           Line 267
"), stdout);                                                                    Line 268
      fputs (_("\                                                               Line 269
  -z, --zero           end each output line with NUL, not newline,\n\           Line 270
                       and disable file name escaping\n\                        Line 271
"), stdout);                                                                    Line 272
      fputs (_("\                                                               Line 273
\n\                                                                             
The following five options are useful only when verifying checksums:\n\         Line 275
      --ignore-missing  don't fail or report status for missing files\n\        Line 276
      --quiet          don't print OK for each successfully verified file\n\    Line 277
      --status         don't output anything, status code shows success\n\      Line 278
      --strict         exit non-zero for improperly formatted checksum lines\n\ Line 279
  -w, --warn           warn about improperly formatted checksum lines\n\        Line 280
\n\                                                                             
"), stdout);                                                                    Line 282
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 283
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 284
      printf (_("\                                                              Line 285
\n\                                                                             
The sums are computed as described in %s.  When checking, the input\n\          Line 287
should be a former output of this program.  The default mode is to print a\n\   Line 288
line with checksum, a space, a character indicating input mode ('*' for binary,\Line 289
\n' ' for text or where binary is insignificant), and name for each FILE.\n"),  Line 290
              DIGEST_REFERENCE);                                                Line 291
      emit_ancillary_info (PROGRAM_NAME);                                       Line 292
    }                                                                           
                                                                                
  exit (status);                                                                Line 295
}                                                                               Block 8
                                                                                
#define ISWHITE(c) ((c) == ' ' || (c) == '\t')                                  Line 298
                                                                                
/* Given a file name, S of length S_LEN, that is not NUL-terminated,            
   modify it in place, performing the equivalent of this sed substitution:      
   's/\\n/\n/g;s/\\\\/\\/g' i.e., replacing each "\\n" string with a newline    
   and each "\\\\" with a single backslash, NUL-terminate it and return S.      
   If S is not a valid escaped file name, i.e., if it ends with an odd number   
   of backslashes or if it contains a backslash followed by anything other      
   than "n" or another backslash, return NULL.  */                              
                                                                                
static char *                                                                   Line 308
filename_unescape (char *s, size_t s_len)                                       Line 309
{                                                                               
  char *dst = s;                                                                Line 311
                                                                                
  for (size_t i = 0; i < s_len; i++)                                            Line 313
    {                                                                           
      switch (s[i])                                                             Line 315
        {                                                                       
        case '\\':                                                              Line 317
          if (i == s_len - 1)                                                   Line 318
            {                                                                   
              /* File name ends with an unescaped backslash: invalid.  */       
              return NULL;                                                      Line 321
            }                                                                   
          ++i;                                                                  Line 323
          switch (s[i])                                                         Line 324
            {                                                                   
            case 'n':                                                           Line 326
              *dst++ = '\n';                                                    Line 327
              break;                                                            Line 328
            case '\\':                                                          Line 329
              *dst++ = '\\';                                                    Line 330
              break;                                                            Line 331
            default:                                                            Line 332
              /* Only '\' or 'n' may follow a backslash.  */                    
              return NULL;                                                      Line 334
            }                                                                   
          break;                                                                Line 336
                                                                                
        case '\0':                                                              Line 338
          /* The file name may not contain a NUL.  */                           
          return NULL;                                                          Line 340
                                                                                
        default:                                                                Line 342
          *dst++ = s[i];                                                        Line 343
          break;                                                                Line 344
        }                                                                       
    }                                                                           
  if (dst < s + s_len)                                                          Line 347
    *dst = '\0';                                                                Line 348
                                                                                
  return s;                                                                     Line 350
}                                                                               Block 9
                                                                                
/* Return true if S is a NUL-terminated string of DIGEST_HEX_BYTES hex digits.  
   Otherwise, return false.  */                                                 
static bool _GL_ATTRIBUTE_PURE                                                  Line 355
hex_digits (unsigned char const *s)                                             Line 356
{                                                                               
  for (unsigned int i = 0; i < digest_hex_bytes; i++)                           Line 358
    {                                                                           
      if (!isxdigit (*s))                                                       Line 360
        return false;                                                           Line 361
      ++s;                                                                      Line 362
    }                                                                           
  return *s == '\0';                                                            Line 364
}                                                                               Block 10
                                                                                
/* Split the checksum string S (of length S_LEN) from a BSD 'md5' or            
   'sha1' command into two parts: a hexadecimal digest, and the file            
   name.  S is modified.  Return true if successful.  */                        
                                                                                
static bool                                                                     Line 371
bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest,                 Line 372
             char **file_name, bool escaped_filename)                           Line 373
{                                                                               
  size_t i;                                                                     Line 375
                                                                                
  if (s_len == 0)                                                               Line 377
    return false;                                                               Line 378
                                                                                
  /* Find end of filename.  */                                                  
  i = s_len - 1;                                                                Line 381
  while (i && s[i] != ')')                                                      Line 382
    i--;                                                                        Line 383
                                                                                
  if (s[i] != ')')                                                              Line 385
    return false;                                                               Line 386
                                                                                
  *file_name = s;                                                               Line 388
                                                                                
  if (escaped_filename && filename_unescape (s, i) == NULL)                     Line 390
    return false;                                                               Line 391
                                                                                
  s[i++] = '\0';                                                                Line 393
                                                                                
  while (ISWHITE (s[i]))                                                        Line 395
    i++;                                                                        Line 396
                                                                                
  if (s[i] != '=')                                                              Line 398
    return false;                                                               Line 399
                                                                                
  i++;                                                                          Line 401
                                                                                
  while (ISWHITE (s[i]))                                                        Line 403
    i++;                                                                        Line 404
                                                                                
  *hex_digest = (unsigned char *) &s[i];                                        Line 406
                                                                                
  return hex_digits (*hex_digest);                                              Line 408
}                                                                               Block 11
                                                                                
/* Split the string S (of length S_LEN) into three parts:                       
   a hexadecimal digest, binary flag, and the file name.                        
   S is modified.  Return true if successful.  */                               
                                                                                
static bool                                                                     Line 415
split_3 (char *s, size_t s_len,                                                 Line 416
         unsigned char **hex_digest, int *binary, char **file_name)             Line 417
{                                                                               
  bool escaped_filename = false;                                                Line 419
  size_t algo_name_len;                                                         Line 420
                                                                                
  size_t i = 0;                                                                 Line 422
  while (ISWHITE (s[i]))                                                        Line 423
    ++i;                                                                        Line 424
                                                                                
  if (s[i] == '\\')                                                             Line 426
    {                                                                           
      ++i;                                                                      Line 428
      escaped_filename = true;                                                  Line 429
    }                                                                           
                                                                                
  /* Check for BSD-style checksum line. */                                      
                                                                                
  algo_name_len = strlen (DIGEST_TYPE_STRING);                                  Line 434
  if (STREQ_LEN (s + i, DIGEST_TYPE_STRING, algo_name_len))                     Line 435
    {                                                                           
      i += algo_name_len;                                                       Line 437
#if HASH_ALGO_BLAKE2                                                            Line 438
      /* Terminate and match algorithm name.  */                                
      char const *algo_name = &s[i - algo_name_len];                            Line 440
      /* Skip algorithm variants.  */                                           
      while (s[i] && ! ISWHITE (s[i]) && s[i] != '-' && s[i] != '(')            Line 442
        ++i;                                                                    Line 443
      bool length_specified = s[i] == '-';                                      Line 444
      bool openssl_format = s[i] == '('; /* and no length_specified */          Line 445
      s[i++] = '\0';                                                            Line 446
      ptrdiff_t algo = argmatch (algo_name, algorithm_out_string, NULL, 0);     Line 447
      if (algo < 0)                                                             Line 448
        return false;                                                           Line 449
      else                                                                      Line 450
        b2_algorithm = algo;                                                    Line 451
      if (openssl_format)                                                       Line 452
        s[--i] = '(';                                                           Line 453
                                                                                
      if (length_specified)                                                     Line 455
        {                                                                       
          unsigned long int tmp_ulong;                                          Line 457
          if (xstrtoul (s + i, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK         Line 458
              && 0 < tmp_ulong && tmp_ulong <= blake2_max_len[b2_algorithm] * 8 Line 459
              && tmp_ulong % 8 == 0)                                            Line 460
            b2_length = tmp_ulong;                                              Line 461
          else                                                                  Line 462
            return false;                                                       Line 463
                                                                                
          while (ISDIGIT (s[i]))                                                Line 465
            ++i;                                                                Line 466
        }                                                                       
      else                                                                      Line 468
        b2_length = blake2_max_len[b2_algorithm] * 8;                           Line 469
                                                                                
      digest_hex_bytes = b2_length / 4;                                         Line 471
#endif                                                                          Line 472
      if (s[i] == ' ')                                                          Line 473
        ++i;                                                                    Line 474
      if (s[i] == '(')                                                          Line 475
        {                                                                       
          ++i;                                                                  Line 477
          *binary = 0;                                                          Line 478
          return bsd_split_3 (s + i, s_len - i,                                 Line 479
                              hex_digest, file_name, escaped_filename);         Line 480
        }                                                                       
      return false;                                                             Line 482
    }                                                                           
                                                                                
  /* Ignore this line if it is too short.                                       
     Each line must have at least 'min_digest_line_length - 1' (or one more, if 
     the first is a backslash) more characters to contain correct message digest
     information.  */                                                           
  if (s_len - i < min_digest_line_length + (s[i] == '\\'))                      Line 489
    return false;                                                               Line 490
                                                                                
  *hex_digest = (unsigned char *) &s[i];                                        Line 492
                                                                                
#if HASH_ALGO_BLAKE2                                                            Line 494
  /* Auto determine length.  */                                                 
  unsigned char const *hp = *hex_digest;                                        Line 496
  digest_hex_bytes = 0;                                                         Line 497
  while (isxdigit (*hp++))                                                      Line 498
    digest_hex_bytes++;                                                         Line 499
  if (digest_hex_bytes < 2 || digest_hex_bytes % 2                              Line 500
      || blake2_max_len[b2_algorithm] * 2 < digest_hex_bytes)                   Line 501
    return false;                                                               Line 502
  b2_length = digest_hex_bytes * 4;                                             Line 503
#endif                                                                          Line 504
                                                                                
  /* The first field has to be the n-character hexadecimal                      
     representation of the message digest.  If it is not followed               
     immediately by a white space it's an error.  */                            
  i += digest_hex_bytes;                                                        Line 509
  if (!ISWHITE (s[i]))                                                          Line 510
    return false;                                                               Line 511
                                                                                
  s[i++] = '\0';                                                                Line 513
                                                                                
  if (! hex_digits (*hex_digest))                                               Line 515
    return false;                                                               Line 516
                                                                                
  /* If "bsd reversed" format detected.  */                                     
  if ((s_len - i == 1) || (s[i] != ' ' && s[i] != '*'))                         Line 519
    {                                                                           
      /* Don't allow mixing bsd and standard formats,                           
         to minimize security issues with attackers                             
         renaming files with leading spaces.                                    
         This assumes that with bsd format checksums                            
         that the first file name does not have                                 
         a leading ' ' or '*'.  */                                              
      if (bsd_reversed == 0)                                                    Line 527
        return false;                                                           Line 528
      bsd_reversed = 1;                                                         Line 529
    }                                                                           
  else if (bsd_reversed != 1)                                                   Line 531
    {                                                                           
      bsd_reversed = 0;                                                         Line 533
      *binary = (s[i++] == '*');                                                Line 534
    }                                                                           
                                                                                
  /* All characters between the type indicator and end of line are              
     significant -- that includes leading and trailing white space.  */         
  *file_name = &s[i];                                                           Line 539
                                                                                
  if (escaped_filename)                                                         Line 541
    return filename_unescape (&s[i], s_len - i) != NULL;                        Line 542
                                                                                
  return true;                                                                  Line 544
}                                                                               Block 12
                                                                                
/* If ESCAPE is true, then translate each NEWLINE byte to the string, "\\n",    
   and each backslash to "\\\\".  */                                            
static void                                                                     Line 549
print_filename (char const *file, bool escape)                                  Line 550
{                                                                               
  if (! escape)                                                                 Line 552
    {                                                                           
      fputs (file, stdout);                                                     Line 554
      return;                                                                   Line 555
    }                                                                           
                                                                                
  while (*file)                                                                 Line 558
    {                                                                           
      switch (*file)                                                            Line 560
        {                                                                       
        case '\n':                                                              Line 562
          fputs ("\\n", stdout);                                                Line 563
          break;                                                                Line 564
                                                                                
        case '\\':                                                              Line 566
          fputs ("\\\\", stdout);                                               Line 567
          break;                                                                Line 568
                                                                                
        default:                                                                Line 570
          putchar (*file);                                                      Line 571
          break;                                                                Line 572
        }                                                                       
      file++;                                                                   Line 574
    }                                                                           
}                                                                               Block 13
                                                                                
/* An interface to the function, DIGEST_STREAM.                                 
   Operate on FILENAME (it may be "-").                                         
                                                                                
   *BINARY indicates whether the file is binary.  BINARY < 0 means it           
   depends on whether binary mode makes any difference and the file is          
   a terminal; in that case, clear *BINARY if the file was treated as           
   text because it was a terminal.                                              
                                                                                
   Put the checksum in *BIN_RESULT, which must be properly aligned.             
   Put true in *MISSING if the file can't be opened due to ENOENT.              
   Return true if successful.  */                                               
                                                                                
static bool                                                                     Line 590
digest_file (const char *filename, int *binary, unsigned char *bin_result,      Line 591
             bool *missing)                                                     Line 592
{                                                                               
  FILE *fp;                                                                     Line 594
  int err;                                                                      Line 595
  bool is_stdin = STREQ (filename, "-");                                        Line 596
                                                                                
  *missing = false;                                                             Line 598
                                                                                
  if (is_stdin)                                                                 Line 600
    {                                                                           
      have_read_stdin = true;                                                   Line 602
      fp = stdin;                                                               Line 603
      if (O_BINARY && *binary)                                                  Line 604
        {                                                                       
          if (*binary < 0)                                                      Line 606
            *binary = ! isatty (STDIN_FILENO);                                  Line 607
          if (*binary)                                                          Line 608
            xset_binary_mode (STDIN_FILENO, O_BINARY);                          Line 609
        }                                                                       
    }                                                                           
  else                                                                          Line 612
    {                                                                           
      fp = fopen (filename, (O_BINARY && *binary ? "rb" : "r"));                Line 614...!syscalls auto-comment...
      if (fp == NULL)                                                           Line 615
        {                                                                       
          if (ignore_missing && errno == ENOENT)                                Line 617
            {                                                                   
              *missing = true;                                                  Line 619
              return true;                                                      Line 620
            }                                                                   
          error (0, errno, "%s", quotef (filename));                            Line 622
          return false;                                                         Line 623
        }                                                                       
    }                                                                           
                                                                                
  fadvise (fp, FADVISE_SEQUENTIAL);                                             Line 627...!syscalls auto-comment...
                                                                                
#if HASH_ALGO_BLAKE2                                                            Line 629
  err = DIGEST_STREAM (fp, bin_result, b2_length / 8);                          Line 630
#else                                                                           Line 631
  err = DIGEST_STREAM (fp, bin_result);                                         Line 632
#endif                                                                          Line 633
  if (err)                                                                      Line 634
    {                                                                           
      error (0, errno, "%s", quotef (filename));                                Line 636
      if (fp != stdin)                                                          Line 637
        fclose (fp);                                                            Line 638...!syscalls auto-comment...
      return false;                                                             Line 639
    }                                                                           
                                                                                
  if (!is_stdin && fclose (fp) != 0)                                            Line 642...!syscalls auto-comment...
    {                                                                           
      error (0, errno, "%s", quotef (filename));                                Line 644
      return false;                                                             Line 645
    }                                                                           
                                                                                
  return true;                                                                  Line 648
}                                                                               Block 14
                                                                                
static bool                                                                     Line 651
digest_check (const char *checkfile_name)                                       Line 652
{                                                                               
  FILE *checkfile_stream;                                                       Line 654
  uintmax_t n_misformatted_lines = 0;                                           Line 655
  uintmax_t n_improperly_formatted_lines = 0;                                   Line 656
  uintmax_t n_mismatched_checksums = 0;                                         Line 657
  uintmax_t n_open_or_read_failures = 0;                                        Line 658
  bool properly_formatted_lines = false;                                        Line 659
  bool matched_checksums = false;                                               Line 660
  unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];          Line 661
  /* Make sure bin_buffer is properly aligned. */                               
  unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN);   Line 663
  uintmax_t line_number;                                                        Line 664
  char *line;                                                                   Line 665
  size_t line_chars_allocated;                                                  Line 666
  bool is_stdin = STREQ (checkfile_name, "-");                                  Line 667
                                                                                
  if (is_stdin)                                                                 Line 669
    {                                                                           
      have_read_stdin = true;                                                   Line 671
      checkfile_name = _("standard input");                                     Line 672
      checkfile_stream = stdin;                                                 Line 673
    }                                                                           
  else                                                                          Line 675
    {                                                                           
      checkfile_stream = fopen (checkfile_name, "r");                           Line 677...!syscalls auto-comment...
      if (checkfile_stream == NULL)                                             Line 678
        {                                                                       
          error (0, errno, "%s", quotef (checkfile_name));                      Line 680
          return false;                                                         Line 681
        }                                                                       
    }                                                                           
                                                                                
  line_number = 0;                                                              Line 685
  line = NULL;                                                                  Line 686
  line_chars_allocated = 0;                                                     Line 687
  do                                                                            
    {                                                                           
      char *filename IF_LINT ( = NULL);                                         Line 690
      int binary;                                                               Line 691
      unsigned char *hex_digest IF_LINT ( = NULL);                              Line 692
      ssize_t line_length;                                                      Line 693
                                                                                
      ++line_number;                                                            Line 695
      if (line_number == 0)                                                     Line 696
        die (EXIT_FAILURE, 0, _("%s: too many checksum lines"),                 Line 697
             quotef (checkfile_name));                                          Line 698
                                                                                
      line_length = getline (&line, &line_chars_allocated, checkfile_stream);   Line 700
      if (line_length <= 0)                                                     Line 701
        break;                                                                  Line 702
                                                                                
      /* Ignore comment lines, which begin with a '#' character.  */            
      if (line[0] == '#')                                                       Line 705
        continue;                                                               Line 706
                                                                                
      /* Remove any trailing newline.  */                                       
      if (line[line_length - 1] == '\n')                                        Line 709
        line[--line_length] = '\0';                                             Line 710
                                                                                
      if (! (split_3 (line, line_length, &hex_digest, &binary, &filename)       Line 712
             && ! (is_stdin && STREQ (filename, "-"))))                         Line 713
        {                                                                       
          ++n_misformatted_lines;                                               Line 715
                                                                                
          if (warn)                                                             Line 717
            {                                                                   
              error (0, 0,                                                      Line 719
                     _("%s: %" PRIuMAX                                          Line 720
                       ": improperly formatted %s checksum line"),              Line 721
                     quotef (checkfile_name), line_number,                      Line 722
                     DIGEST_TYPE_STRING);                                       Line 723
            }                                                                   
                                                                                
          ++n_improperly_formatted_lines;                                       Line 726
        }                                                                       
      else                                                                      Line 728
        {                                                                       
          static const char bin2hex[] = { '0', '1', '2', '3',                   Line 730
                                          '4', '5', '6', '7',                   Line 731
                                          '8', '9', 'a', 'b',                   Line 732
                                          'c', 'd', 'e', 'f' };                 Line 733
          bool ok;                                                              Line 734
          bool missing;                                                         Line 735
          /* Only escape in the edge case producing multiple lines,             
             to ease automatic processing of status output.  */                 
          bool needs_escape = ! status_only && strchr (filename, '\n');         Line 738
                                                                                
          properly_formatted_lines = true;                                      Line 740
                                                                                
          ok = digest_file (filename, &binary, bin_buffer, &missing);           Line 742
                                                                                
          if (!ok)                                                              Line 744
            {                                                                   
              ++n_open_or_read_failures;                                        Line 746
              if (!status_only)                                                 Line 747
                {                                                               
                  if (needs_escape)                                             Line 749
                    putchar ('\\');                                             Line 750
                  print_filename (filename, needs_escape);                      Line 751
                  printf (": %s\n", _("FAILED open or read"));                  Line 752
                }                                                               
            }                                                                   
          else if (ignore_missing && missing)                                   Line 755
            {                                                                   
              /* Ignore missing files with --ignore-missing.  */                
              ;                                                                 
            }                                                                   
          else                                                                  Line 760
            {                                                                   
              size_t digest_bin_bytes = digest_hex_bytes / 2;                   Line 762
              size_t cnt;                                                       Line 763
                                                                                
              /* Compare generated binary number with text representation       
                 in check file.  Ignore case of hex digits.  */                 
              for (cnt = 0; cnt < digest_bin_bytes; ++cnt)                      Line 767
                {                                                               
                  if (tolower (hex_digest[2 * cnt])                             Line 769
                      != bin2hex[bin_buffer[cnt] >> 4]                          Line 770
                      || (tolower (hex_digest[2 * cnt + 1])                     Line 771
                          != (bin2hex[bin_buffer[cnt] & 0xf])))                 Line 772
                    break;                                                      Line 773
                }                                                               
              if (cnt != digest_bin_bytes)                                      Line 775
                ++n_mismatched_checksums;                                       Line 776
              else                                                              Line 777
                matched_checksums = true;                                       Line 778
                                                                                
              if (!status_only)                                                 Line 780
                {                                                               
                  if (cnt != digest_bin_bytes || ! quiet)                       Line 782
                    {                                                           
                      if (needs_escape)                                         Line 784
                        putchar ('\\');                                         Line 785
                      print_filename (filename, needs_escape);                  Line 786
                    }                                                           
                                                                                
                  if (cnt != digest_bin_bytes)                                  Line 789
                    printf (": %s\n", _("FAILED"));                             Line 790
                  else if (!quiet)                                              Line 791
                    printf (": %s\n", _("OK"));                                 Line 792
                }                                                               
            }                                                                   
        }                                                                       
    }                                                                           
  while (!feof (checkfile_stream) && !ferror (checkfile_stream));               Line 797
                                                                                
  free (line);                                                                  Line 799
                                                                                
  if (ferror (checkfile_stream))                                                Line 801
    {                                                                           
      error (0, 0, _("%s: read error"), quotef (checkfile_name));               Line 803
      return false;                                                             Line 804
    }                                                                           
                                                                                
  if (!is_stdin && fclose (checkfile_stream) != 0)                              Line 807...!syscalls auto-comment...
    {                                                                           
      error (0, errno, "%s", quotef (checkfile_name));                          Line 809
      return false;                                                             Line 810
    }                                                                           
                                                                                
  if (! properly_formatted_lines)                                               Line 813
    {                                                                           
      /* Warn if no tests are found.  */                                        
      error (0, 0, _("%s: no properly formatted %s checksum lines found"),      Line 816
             quotef (checkfile_name), DIGEST_TYPE_STRING);                      Line 817
    }                                                                           
  else                                                                          Line 819
    {                                                                           
      if (!status_only)                                                         Line 821
        {                                                                       
          if (n_misformatted_lines != 0)                                        Line 823
            error (0, 0,                                                        Line 824
                   (ngettext                                                    Line 825
                    ("WARNING: %" PRIuMAX " line is improperly formatted",      Line 826
                     "WARNING: %" PRIuMAX " lines are improperly formatted",    Line 827
                     select_plural (n_misformatted_lines))),                    Line 828
                   n_misformatted_lines);                                       Line 829
                                                                                
          if (n_open_or_read_failures != 0)                                     Line 831
            error (0, 0,                                                        Line 832
                   (ngettext                                                    Line 833
                    ("WARNING: %" PRIuMAX " listed file could not be read",     Line 834
                     "WARNING: %" PRIuMAX " listed files could not be read",    Line 835
                     select_plural (n_open_or_read_failures))),                 Line 836
                   n_open_or_read_failures);                                    Line 837
                                                                                
          if (n_mismatched_checksums != 0)                                      Line 839
            error (0, 0,                                                        Line 840
                   (ngettext                                                    Line 841
                    ("WARNING: %" PRIuMAX " computed checksum did NOT match",   Line 842
                     "WARNING: %" PRIuMAX " computed checksums did NOT match",  Line 843
                     select_plural (n_mismatched_checksums))),                  Line 844
                   n_mismatched_checksums);                                     Line 845
                                                                                
          if (ignore_missing && ! matched_checksums)                            Line 847
            error (0, 0, _("%s: no file was verified"),                         Line 848
                   quotef (checkfile_name));                                    Line 849
        }                                                                       
    }                                                                           
                                                                                
  return (properly_formatted_lines                                              Line 853
          && matched_checksums                                                  Line 854
          && n_mismatched_checksums == 0                                        Line 855
          && n_open_or_read_failures == 0                                       Line 856
          && (!strict || n_improperly_formatted_lines == 0));                   Line 857
}                                                                               Block 15
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 861
{                                                                               
  unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];          Line 863
  /* Make sure bin_buffer is properly aligned. */                               
  unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN);   Line 865
  bool do_check = false;                                                        Line 866
  int opt;                                                                      Line 867
  bool ok = true;                                                               Line 868
  int binary = -1;                                                              Line 869
  bool prefix_tag = false;                                                      Line 870
                                                                                
  /* Setting values of global variables.  */                                    
  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 883
                                                                                
#if HASH_ALGO_BLAKE2                                                            Line 885
  const char* short_opts = "l:bctwz";                                           Line 886
  const char* b2_length_str = "";                                               Line 887
#else                                                                           Line 888
  const char* short_opts = "bctwz";                                             Line 889
#endif                                                                          Line 890
                                                                                
  while ((opt = getopt_long (argc, argv, short_opts, long_options, NULL)) != -1)Line 892
    switch (opt)                                                                Line 893
      {                                                                         
#if HASH_ALGO_BLAKE2                                                            Line 895
      case 'l':                                                                 Line 896
        b2_length = xdectoumax (optarg, 0, UINTMAX_MAX, "",                     Line 897
                                _("invalid length"), 0);                        Line 898
        b2_length_str = optarg;                                                 Line 899
        if (b2_length % 8 != 0)                                                 Line 900
          {                                                                     
            error (0, 0, _("invalid length: %s"), quote (b2_length_str));       Line 902
            die (EXIT_FAILURE, 0, _("length is not a multiple of 8"));          Line 903
          }                                                                     
        break;                                                                  Line 905
#endif                                                                          Line 906
      case 'b':                                                                 Line 907
        binary = 1;                                                             Line 908
        break;                                                                  Line 909
      case 'c':                                                                 Line 910
        do_check = true;                                                        Line 911
        break;                                                                  Line 912
      case STATUS_OPTION:                                                       Line 913
        status_only = true;                                                     Line 914
        warn = false;                                                           Line 915
        quiet = false;                                                          Line 916
        break;                                                                  Line 917
      case 't':                                                                 Line 918
        binary = 0;                                                             Line 919
        break;                                                                  Line 920
      case 'w':                                                                 Line 921
        status_only = false;                                                    Line 922
        warn = true;                                                            Line 923
        quiet = false;                                                          Line 924
        break;                                                                  Line 925
      case IGNORE_MISSING_OPTION:                                               Line 926
        ignore_missing = true;                                                  Line 927
        break;                                                                  Line 928
      case QUIET_OPTION:                                                        Line 929
        status_only = false;                                                    Line 930
        warn = false;                                                           Line 931
        quiet = true;                                                           Line 932
        break;                                                                  Line 933
      case STRICT_OPTION:                                                       Line 934
        strict = true;                                                          Line 935
        break;                                                                  Line 936
      case TAG_OPTION:                                                          Line 937
        prefix_tag = true;                                                      Line 938
        binary = 1;                                                             Line 939
        break;                                                                  Line 940
      case 'z':                                                                 Line 941
        delim = '\0';                                                           Line 942
        break;                                                                  Line 943
      case_GETOPT_HELP_CHAR;                                                    Line 944
      case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                         Line 945
      default:                                                                  Line 946
        usage (EXIT_FAILURE);                                                   Line 947
      }                                                                         
                                                                                
  min_digest_line_length = MIN_DIGEST_LINE_LENGTH;                              Line 950
#if HASH_ALGO_BLAKE2                                                            Line 951
  if (b2_length > blake2_max_len[b2_algorithm] * 8)                             Line 952
    {                                                                           
      error (0, 0, _("invalid length: %s"), quote (b2_length_str));             Line 954
      die (EXIT_FAILURE, 0,                                                     Line 955
           _("maximum digest length for %s is %"PRIuMAX" bits"),                Line 956
           quote (algorithm_in_string[b2_algorithm]),                           Line 957
           blake2_max_len[b2_algorithm] * 8);                                   Line 958
    }                                                                           
  if (b2_length == 0 && ! do_check)                                             Line 960
    b2_length = blake2_max_len[b2_algorithm] * 8;                               Line 961
  digest_hex_bytes = b2_length / 4;                                             Line 962
#else                                                                           Line 963
  digest_hex_bytes = DIGEST_HEX_BYTES;                                          Line 964
#endif                                                                          Line 965
                                                                                
  if (prefix_tag && !binary)                                                    Line 967
   {                                                                            
     /* This could be supported in a backwards compatible way                   
        by prefixing the output line with a space in text mode.                 
        However that's invasive enough that it was agreed to                    
        not support this mode with --tag, as --text use cases                   
        are adequately supported by the default output format.  */              
     error (0, 0, _("--tag does not support --text mode"));                     Line 974
     usage (EXIT_FAILURE);                                                      Line 975
   }                                                                            
                                                                                
  if (delim != '\n' && do_check)                                                Line 978
    {                                                                           
      error (0, 0, _("the --zero option is not supported when "                 Line 980
                     "verifying checksums"));                                   Line 981
      usage (EXIT_FAILURE);                                                     Line 982
    }                                                                           
                                                                                
  if (prefix_tag && do_check)                                                   Line 985
    {                                                                           
      error (0, 0, _("the --tag option is meaningless when "                    Line 987
                     "verifying checksums"));                                   Line 988
      usage (EXIT_FAILURE);                                                     Line 989
    }                                                                           
                                                                                
  if (0 <= binary && do_check)                                                  Line 992
    {                                                                           
      error (0, 0, _("the --binary and --text options are meaningless when "    Line 994
                     "verifying checksums"));                                   Line 995
      usage (EXIT_FAILURE);                                                     Line 996
    }                                                                           
                                                                                
  if (ignore_missing && !do_check)                                              Line 999
    {                                                                           
      error (0, 0,                                                              Line 1001
             _("the --ignore-missing option is meaningful only when "           Line 1002
               "verifying checksums"));                                         Line 1003
      usage (EXIT_FAILURE);                                                     Line 1004
    }                                                                           
                                                                                
  if (status_only && !do_check)                                                 Line 1007
    {                                                                           
      error (0, 0,                                                              Line 1009
       _("the --status option is meaningful only when verifying checksums"));   Line 1010
      usage (EXIT_FAILURE);                                                     Line 1011
    }                                                                           
                                                                                
  if (warn && !do_check)                                                        Line 1014
    {                                                                           
      error (0, 0,                                                              Line 1016
       _("the --warn option is meaningful only when verifying checksums"));     Line 1017
      usage (EXIT_FAILURE);                                                     Line 1018
    }                                                                           
                                                                                
  if (quiet && !do_check)                                                       Line 1021
    {                                                                           
      error (0, 0,                                                              Line 1023
       _("the --quiet option is meaningful only when verifying checksums"));    Line 1024
      usage (EXIT_FAILURE);                                                     Line 1025
    }                                                                           
                                                                                
  if (strict & !do_check)                                                       Line 1028
   {                                                                            
     error (0, 0,                                                               Line 1030
        _("the --strict option is meaningful only when verifying checksums"));  Line 1031
     usage (EXIT_FAILURE);                                                      Line 1032
   }                                                                            
                                                                                
  if (!O_BINARY && binary < 0)                                                  Line 1035
    binary = 0;                                                                 Line 1036
                                                                                
  char **operand_lim = argv + argc;                                             Line 1038
  if (optind == argc)                                                           Line 1039
    *operand_lim++ = bad_cast ("-");                                            Line 1040
                                                                                
  for (char **operandp = argv + optind; operandp < operand_lim; operandp++)     Line 1042
    {                                                                           
      char *file = *operandp;                                                   Line 1044
                                                                                
      if (do_check)                                                             Line 1046
        ok &= digest_check (file);                                              Line 1047
      else                                                                      Line 1048
        {                                                                       
          int file_is_binary = binary;                                          Line 1050
          bool missing;                                                         Line 1051
                                                                                
          if (! digest_file (file, &file_is_binary, bin_buffer, &missing))      Line 1053
            ok = false;                                                         Line 1054
          else                                                                  Line 1055
            {                                                                   
              /* We don't really need to escape, and hence detect, the '\\'     
                 char, and not doing so should be both forwards and backwards   
                 compatible, since only escaped lines would have a '\\' char at 
                 the start.  However just in case users are directly comparing  
                 against old (hashed) outputs, in the presence of files         
                 containing '\\' characters, we decided to not simplify the     
                 output in this case.  */                                       
              bool needs_escape = (strchr (file, '\\') || strchr (file, '\n'))  Line 1064
                                  && delim == '\n';                             Line 1065
                                                                                
              if (prefix_tag)                                                   Line 1067
                {                                                               
                  if (needs_escape)                                             Line 1069
                    putchar ('\\');                                             Line 1070
                                                                                
#if HASH_ALGO_BLAKE2                                                            Line 1072
                  fputs (algorithm_out_string[b2_algorithm], stdout);           Line 1073
                  if (b2_length < blake2_max_len[b2_algorithm] * 8)             Line 1074
                    printf ("-%"PRIuMAX, b2_length);                            Line 1075
#else                                                                           Line 1076
                  fputs (DIGEST_TYPE_STRING, stdout);                           Line 1077
#endif                                                                          Line 1078
                  fputs (" (", stdout);                                         Line 1079
                  print_filename (file, needs_escape);                          Line 1080
                  fputs (") = ", stdout);                                       Line 1081
                }                                                               
                                                                                
              /* Output a leading backslash if the file name contains           
                 a newline or backslash.  */                                    
              if (!prefix_tag && needs_escape)                                  Line 1086
                putchar ('\\');                                                 Line 1087
                                                                                
              for (size_t i = 0; i < (digest_hex_bytes / 2); ++i)               Line 1089
                printf ("%02x", bin_buffer[i]);                                 Line 1090
                                                                                
              if (!prefix_tag)                                                  Line 1092
                {                                                               
                  putchar (' ');                                                Line 1094
                                                                                
                  putchar (file_is_binary ? '*' : ' ');                         Line 1096
                                                                                
                  print_filename (file, needs_escape);                          Line 1098
                }                                                               
                                                                                
              putchar (delim);                                                  Line 1101
            }                                                                   
        }                                                                       
    }                                                                           
                                                                                
  if (have_read_stdin && fclose (stdin) == EOF)                                 Line 1106...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, _("standard input"));                             Line 1107
                                                                                
  return ok ? EXIT_SUCCESS : EXIT_FAILURE;                                      Line 1109
}                                                                               Block 16