1 /* Compute checksums of files or strings.
2 Copyright (C) 1995-2019 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>. */
22 #include <sys/types.h>
27 #include "xdectoint.h"
31 # include "blake2/b2sum.h"
39 #if HASH_ALGO_SHA256 || HASH_ALGO_SHA224
42 #if HASH_ALGO_SHA512 || HASH_ALGO_SHA384
49 #include "xbinary-io.h"
51 /* The official name of this program (e.g., no 'g' prefix). */
53 # define PROGRAM_NAME "md5sum"
54 # define DIGEST_TYPE_STRING "MD5"
55 # define DIGEST_STREAM md5_stream
56 # define DIGEST_BITS 128
57 # define DIGEST_REFERENCE "RFC 1321"
58 # define DIGEST_ALIGN 4
59 #elif HASH_ALGO_BLAKE2
60 # define PROGRAM_NAME "b2sum"
61 # define DIGEST_TYPE_STRING "BLAKE2"
62 # define DIGEST_STREAM blake2fns[b2_algorithm]
63 # define DIGEST_BITS 512
64 # define DIGEST_REFERENCE "RFC 7693"
65 # define DIGEST_ALIGN 8
67 # define PROGRAM_NAME "sha1sum"
68 # define DIGEST_TYPE_STRING "SHA1"
69 # define DIGEST_STREAM sha1_stream
70 # define DIGEST_BITS 160
71 # define DIGEST_REFERENCE "FIPS-180-1"
72 # define DIGEST_ALIGN 4
73 #elif HASH_ALGO_SHA256
74 # define PROGRAM_NAME "sha256sum"
75 # define DIGEST_TYPE_STRING "SHA256"
76 # define DIGEST_STREAM sha256_stream
77 # define DIGEST_BITS 256
78 # define DIGEST_REFERENCE "FIPS-180-2"
79 # define DIGEST_ALIGN 4
80 #elif HASH_ALGO_SHA224
81 # define PROGRAM_NAME "sha224sum"
82 # define DIGEST_TYPE_STRING "SHA224"
83 # define DIGEST_STREAM sha224_stream
84 # define DIGEST_BITS 224
85 # define DIGEST_REFERENCE "RFC 3874"
86 # define DIGEST_ALIGN 4
87 #elif HASH_ALGO_SHA512
88 # define PROGRAM_NAME "sha512sum"
89 # define DIGEST_TYPE_STRING "SHA512"
90 # define DIGEST_STREAM sha512_stream
91 # define DIGEST_BITS 512
92 # define DIGEST_REFERENCE "FIPS-180-2"
93 # define DIGEST_ALIGN 8
94 #elif HASH_ALGO_SHA384
95 # define PROGRAM_NAME "sha384sum"
96 # define DIGEST_TYPE_STRING "SHA384"
97 # define DIGEST_STREAM sha384_stream
98 # define DIGEST_BITS 384
99 # define DIGEST_REFERENCE "FIPS-180-2"
100 # define DIGEST_ALIGN 8
102 # error "Can't decide which hash algorithm to compile."
107 proper_name ("Padraig Brady"), \
108 proper_name ("Samuel Neves")
111 proper_name ("Ulrich Drepper"), \
112 proper_name ("Scott Miller"), \
113 proper_name ("David Madore")
114 # define DIGEST_HEX_BYTES (DIGEST_BITS / 4)
116 #define DIGEST_BIN_BYTES (DIGEST_BITS / 8)
119 /* The minimum length of a valid digest line. This length does
120 not include any newline character at the end of a line. */
122 # define MIN_DIGEST_LINE_LENGTH 3 /* With -l 8. */
124 # define MIN_DIGEST_LINE_LENGTH \
125 (DIGEST_HEX_BYTES /* length of hexadecimal message digest */ \
127 + 1 /* minimum filename length */ )
130 /* True if any of the files read were the standard input. */
131 static bool have_read_stdin
;
133 /* The minimum length of a valid checksum line for the selected algorithm. */
134 static size_t min_digest_line_length
;
136 /* Set to the length of a digest hex string for the selected algorithm. */
137 static size_t digest_hex_bytes
;
139 /* With --check, don't generate any output.
140 The exit code indicates success or failure. */
141 static bool status_only
= false;
143 /* With --check, print a message to standard error warning about each
144 improperly formatted checksum line. */
145 static bool warn
= false;
147 /* With --check, ignore missing files. */
148 static bool ignore_missing
= false;
150 /* With --check, suppress the "OK" printed for each verified file. */
151 static bool quiet
= false;
153 /* With --check, exit with a non-zero return code if any line is
154 improperly formatted. */
155 static bool strict
= false;
157 /* Whether a BSD reversed format checksum is detected. */
158 static int bsd_reversed
= -1;
160 /* line delimiter. */
161 static unsigned char delim
= '\n';
164 static char const *const algorithm_in_string
[] =
168 static char const *const algorithm_out_string
[] =
176 verify (ARRAY_CARDINALITY (algorithm_in_string
) == 2);
177 verify (ARRAY_CARDINALITY (algorithm_out_string
) == 2);
179 static enum Algorithm b2_algorithm
;
180 static uintmax_t b2_length
;
181 static blake2fn blake2fns
[]=
185 static uintmax_t blake2_max_len
[]=
189 #endif /* HASH_ALGO_BLAKE2 */
191 /* For long options that have no equivalent short option, use a
192 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
195 IGNORE_MISSING_OPTION
= CHAR_MAX
+ 1,
202 static struct option
const long_options
[] =
205 { "length", required_argument
, NULL
, 'l'},
207 { "binary", no_argument
, NULL
, 'b' },
208 { "check", no_argument
, NULL
, 'c' },
209 { "ignore-missing", no_argument
, NULL
, IGNORE_MISSING_OPTION
},
210 { "quiet", no_argument
, NULL
, QUIET_OPTION
},
211 { "status", no_argument
, NULL
, STATUS_OPTION
},
212 { "text", no_argument
, NULL
, 't' },
213 { "warn", no_argument
, NULL
, 'w' },
214 { "strict", no_argument
, NULL
, STRICT_OPTION
},
215 { "tag", no_argument
, NULL
, TAG_OPTION
},
216 { "zero", no_argument
, NULL
, 'z' },
217 { GETOPT_HELP_OPTION_DECL
},
218 { GETOPT_VERSION_OPTION_DECL
},
225 if (status
!= EXIT_SUCCESS
)
230 Usage: %s [OPTION]... [FILE]...\n\
231 Print or check %s (%d-bit) checksums.\n\
241 -b, --binary read in binary mode (default unless reading tty stdin)\n\
246 -b, --binary read in binary mode\n\
250 -c, --check read %s sums from the FILEs and check them\n"),
254 -l, --length digest length in bits; must not exceed the maximum for\n\
255 the blake2 algorithm and must be a multiple of 8\n\
259 --tag create a BSD-style checksum\n\
263 -t, --text read in text mode (default if reading tty stdin)\n\
267 -t, --text read in text mode (default)\n\
270 -z, --zero end each output line with NUL, not newline,\n\
271 and disable file name escaping\n\
275 The following five options are useful only when verifying checksums:\n\
276 --ignore-missing don't fail or report status for missing files\n\
277 --quiet don't print OK for each successfully verified file\n\
278 --status don't output anything, status code shows success\n\
279 --strict exit non-zero for improperly formatted checksum lines\n\
280 -w, --warn warn about improperly formatted checksum lines\n\
283 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
284 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
287 The sums are computed as described in %s. When checking, the input\n\
288 should be a former output of this program. The default mode is to print a\n\
289 line with checksum, a space, a character indicating input mode ('*' for binary,\
290 \n' ' for text or where binary is insignificant), and name for each FILE.\n\
292 Note: There is no difference between binary mode and text mode on GNU systems.\
295 emit_ancillary_info (PROGRAM_NAME
);
301 #define ISWHITE(c) ((c) == ' ' || (c) == '\t')
303 /* Given a file name, S of length S_LEN, that is not NUL-terminated,
304 modify it in place, performing the equivalent of this sed substitution:
305 's/\\n/\n/g;s/\\\\/\\/g' i.e., replacing each "\\n" string with a newline
306 and each "\\\\" with a single backslash, NUL-terminate it and return S.
307 If S is not a valid escaped file name, i.e., if it ends with an odd number
308 of backslashes or if it contains a backslash followed by anything other
309 than "n" or another backslash, return NULL. */
312 filename_unescape (char *s
, size_t s_len
)
316 for (size_t i
= 0; i
< s_len
; i
++)
323 /* File name ends with an unescaped backslash: invalid. */
336 /* Only '\' or 'n' may follow a backslash. */
342 /* The file name may not contain a NUL. */
356 /* Return true if S is a NUL-terminated string of DIGEST_HEX_BYTES hex digits.
357 Otherwise, return false. */
358 static bool _GL_ATTRIBUTE_PURE
359 hex_digits (unsigned char const *s
)
361 for (unsigned int i
= 0; i
< digest_hex_bytes
; i
++)
370 /* Split the checksum string S (of length S_LEN) from a BSD 'md5' or
371 'sha1' command into two parts: a hexadecimal digest, and the file
372 name. S is modified. Return true if successful. */
375 bsd_split_3 (char *s
, size_t s_len
, unsigned char **hex_digest
,
376 char **file_name
, bool escaped_filename
)
383 /* Find end of filename. */
385 while (i
&& s
[i
] != ')')
393 if (escaped_filename
&& filename_unescape (s
, i
) == NULL
)
398 while (ISWHITE (s
[i
]))
406 while (ISWHITE (s
[i
]))
409 *hex_digest
= (unsigned char *) &s
[i
];
411 return hex_digits (*hex_digest
);
414 /* Split the string S (of length S_LEN) into three parts:
415 a hexadecimal digest, binary flag, and the file name.
416 S is modified. Return true if successful. */
419 split_3 (char *s
, size_t s_len
,
420 unsigned char **hex_digest
, int *binary
, char **file_name
)
422 bool escaped_filename
= false;
423 size_t algo_name_len
;
426 while (ISWHITE (s
[i
]))
432 escaped_filename
= true;
435 /* Check for BSD-style checksum line. */
437 algo_name_len
= strlen (DIGEST_TYPE_STRING
);
438 if (STREQ_LEN (s
+ i
, DIGEST_TYPE_STRING
, algo_name_len
))
442 /* Terminate and match algorithm name. */
443 char const *algo_name
= &s
[i
- algo_name_len
];
444 /* Skip algorithm variants. */
445 while (s
[i
] && ! ISWHITE (s
[i
]) && s
[i
] != '-' && s
[i
] != '(')
447 bool length_specified
= s
[i
] == '-';
448 bool openssl_format
= s
[i
] == '('; /* and no length_specified */
450 ptrdiff_t algo
= argmatch (algo_name
, algorithm_out_string
, NULL
, 0);
457 b2_length
= blake2_max_len
[b2_algorithm
] * 8;
458 if (length_specified
)
462 if (! (xstrtoumax (s
+ i
, &siend
, 0, &length
, NULL
) == LONGINT_OK
463 && 0 < length
&& length
<= b2_length
471 digest_hex_bytes
= b2_length
/ 4;
479 return bsd_split_3 (s
+ i
, s_len
- i
,
480 hex_digest
, file_name
, escaped_filename
);
485 /* Ignore this line if it is too short.
486 Each line must have at least 'min_digest_line_length - 1' (or one more, if
487 the first is a backslash) more characters to contain correct message digest
489 if (s_len
- i
< min_digest_line_length
+ (s
[i
] == '\\'))
492 *hex_digest
= (unsigned char *) &s
[i
];
495 /* Auto determine length. */
496 unsigned char const *hp
= *hex_digest
;
497 digest_hex_bytes
= 0;
498 while (isxdigit (*hp
++))
500 if (digest_hex_bytes
< 2 || digest_hex_bytes
% 2
501 || blake2_max_len
[b2_algorithm
] * 2 < digest_hex_bytes
)
503 b2_length
= digest_hex_bytes
* 4;
506 /* The first field has to be the n-character hexadecimal
507 representation of the message digest. If it is not followed
508 immediately by a white space it's an error. */
509 i
+= digest_hex_bytes
;
515 if (! hex_digits (*hex_digest
))
518 /* If "bsd reversed" format detected. */
519 if ((s_len
- i
== 1) || (s
[i
] != ' ' && s
[i
] != '*'))
521 /* Don't allow mixing bsd and standard formats,
522 to minimize security issues with attackers
523 renaming files with leading spaces.
524 This assumes that with bsd format checksums
525 that the first file name does not have
526 a leading ' ' or '*'. */
527 if (bsd_reversed
== 0)
531 else if (bsd_reversed
!= 1)
534 *binary
= (s
[i
++] == '*');
537 /* All characters between the type indicator and end of line are
538 significant -- that includes leading and trailing white space. */
541 if (escaped_filename
)
542 return filename_unescape (&s
[i
], s_len
- i
) != NULL
;
547 /* If ESCAPE is true, then translate each NEWLINE byte to the string, "\\n",
548 and each backslash to "\\\\". */
550 print_filename (char const *file
, bool escape
)
554 fputs (file
, stdout
);
563 fputs ("\\n", stdout
);
567 fputs ("\\\\", stdout
);
578 /* An interface to the function, DIGEST_STREAM.
579 Operate on FILENAME (it may be "-").
581 *BINARY indicates whether the file is binary. BINARY < 0 means it
582 depends on whether binary mode makes any difference and the file is
583 a terminal; in that case, clear *BINARY if the file was treated as
584 text because it was a terminal.
586 Put the checksum in *BIN_RESULT, which must be properly aligned.
587 Put true in *MISSING if the file can't be opened due to ENOENT.
588 Return true if successful. */
591 digest_file (const char *filename
, int *binary
, unsigned char *bin_result
,
596 bool is_stdin
= STREQ (filename
, "-");
602 have_read_stdin
= true;
604 if (O_BINARY
&& *binary
)
607 *binary
= ! isatty (STDIN_FILENO
);
609 xset_binary_mode (STDIN_FILENO
, O_BINARY
);
614 fp
= fopen (filename
, (O_BINARY
&& *binary
? "rb" : "r"));
617 if (ignore_missing
&& errno
== ENOENT
)
622 error (0, errno
, "%s", quotef (filename
));
627 fadvise (fp
, FADVISE_SEQUENTIAL
);
630 err
= DIGEST_STREAM (fp
, bin_result
, b2_length
/ 8);
632 err
= DIGEST_STREAM (fp
, bin_result
);
636 error (0, errno
, "%s", quotef (filename
));
642 if (!is_stdin
&& fclose (fp
) != 0)
644 error (0, errno
, "%s", quotef (filename
));
652 digest_check (const char *checkfile_name
)
654 FILE *checkfile_stream
;
655 uintmax_t n_misformatted_lines
= 0;
656 uintmax_t n_improperly_formatted_lines
= 0;
657 uintmax_t n_mismatched_checksums
= 0;
658 uintmax_t n_open_or_read_failures
= 0;
659 bool properly_formatted_lines
= false;
660 bool matched_checksums
= false;
661 unsigned char bin_buffer_unaligned
[DIGEST_BIN_BYTES
+ DIGEST_ALIGN
];
662 /* Make sure bin_buffer is properly aligned. */
663 unsigned char *bin_buffer
= ptr_align (bin_buffer_unaligned
, DIGEST_ALIGN
);
664 uintmax_t line_number
;
666 size_t line_chars_allocated
;
667 bool is_stdin
= STREQ (checkfile_name
, "-");
671 have_read_stdin
= true;
672 checkfile_name
= _("standard input");
673 checkfile_stream
= stdin
;
677 checkfile_stream
= fopen (checkfile_name
, "r");
678 if (checkfile_stream
== NULL
)
680 error (0, errno
, "%s", quotef (checkfile_name
));
687 line_chars_allocated
= 0;
690 char *filename
IF_LINT ( = NULL
);
692 unsigned char *hex_digest
IF_LINT ( = NULL
);
696 if (line_number
== 0)
697 die (EXIT_FAILURE
, 0, _("%s: too many checksum lines"),
698 quotef (checkfile_name
));
700 line_length
= getline (&line
, &line_chars_allocated
, checkfile_stream
);
701 if (line_length
<= 0)
704 /* Ignore comment lines, which begin with a '#' character. */
708 /* Remove any trailing newline. */
709 if (line
[line_length
- 1] == '\n')
710 line
[--line_length
] = '\0';
712 if (! (split_3 (line
, line_length
, &hex_digest
, &binary
, &filename
)
713 && ! (is_stdin
&& STREQ (filename
, "-"))))
715 ++n_misformatted_lines
;
721 ": improperly formatted %s checksum line"),
722 quotef (checkfile_name
), line_number
,
726 ++n_improperly_formatted_lines
;
730 static const char bin2hex
[] = { '0', '1', '2', '3',
733 'c', 'd', 'e', 'f' };
736 /* Only escape in the edge case producing multiple lines,
737 to ease automatic processing of status output. */
738 bool needs_escape
= ! status_only
&& strchr (filename
, '\n');
740 properly_formatted_lines
= true;
742 ok
= digest_file (filename
, &binary
, bin_buffer
, &missing
);
746 ++n_open_or_read_failures
;
751 print_filename (filename
, needs_escape
);
752 printf (": %s\n", _("FAILED open or read"));
755 else if (ignore_missing
&& missing
)
757 /* Ignore missing files with --ignore-missing. */
762 size_t digest_bin_bytes
= digest_hex_bytes
/ 2;
765 /* Compare generated binary number with text representation
766 in check file. Ignore case of hex digits. */
767 for (cnt
= 0; cnt
< digest_bin_bytes
; ++cnt
)
769 if (tolower (hex_digest
[2 * cnt
])
770 != bin2hex
[bin_buffer
[cnt
] >> 4]
771 || (tolower (hex_digest
[2 * cnt
+ 1])
772 != (bin2hex
[bin_buffer
[cnt
] & 0xf])))
775 if (cnt
!= digest_bin_bytes
)
776 ++n_mismatched_checksums
;
778 matched_checksums
= true;
782 if (cnt
!= digest_bin_bytes
|| ! quiet
)
786 print_filename (filename
, needs_escape
);
789 if (cnt
!= digest_bin_bytes
)
790 printf (": %s\n", _("FAILED"));
792 printf (": %s\n", _("OK"));
797 while (!feof (checkfile_stream
) && !ferror (checkfile_stream
));
801 if (ferror (checkfile_stream
))
803 error (0, 0, _("%s: read error"), quotef (checkfile_name
));
807 if (!is_stdin
&& fclose (checkfile_stream
) != 0)
809 error (0, errno
, "%s", quotef (checkfile_name
));
813 if (! properly_formatted_lines
)
815 /* Warn if no tests are found. */
816 error (0, 0, _("%s: no properly formatted %s checksum lines found"),
817 quotef (checkfile_name
), DIGEST_TYPE_STRING
);
823 if (n_misformatted_lines
!= 0)
826 ("WARNING: %" PRIuMAX
" line is improperly formatted",
827 "WARNING: %" PRIuMAX
" lines are improperly formatted",
828 select_plural (n_misformatted_lines
))),
829 n_misformatted_lines
);
831 if (n_open_or_read_failures
!= 0)
834 ("WARNING: %" PRIuMAX
" listed file could not be read",
835 "WARNING: %" PRIuMAX
" listed files could not be read",
836 select_plural (n_open_or_read_failures
))),
837 n_open_or_read_failures
);
839 if (n_mismatched_checksums
!= 0)
842 ("WARNING: %" PRIuMAX
" computed checksum did NOT match",
843 "WARNING: %" PRIuMAX
" computed checksums did NOT match",
844 select_plural (n_mismatched_checksums
))),
845 n_mismatched_checksums
);
847 if (ignore_missing
&& ! matched_checksums
)
848 error (0, 0, _("%s: no file was verified"),
849 quotef (checkfile_name
));
853 return (properly_formatted_lines
855 && n_mismatched_checksums
== 0
856 && n_open_or_read_failures
== 0
857 && (!strict
|| n_improperly_formatted_lines
== 0));
861 main (int argc
, char **argv
)
863 unsigned char bin_buffer_unaligned
[DIGEST_BIN_BYTES
+ DIGEST_ALIGN
];
864 /* Make sure bin_buffer is properly aligned. */
865 unsigned char *bin_buffer
= ptr_align (bin_buffer_unaligned
, DIGEST_ALIGN
);
866 bool do_check
= false;
870 bool prefix_tag
= false;
872 /* Setting values of global variables. */
873 initialize_main (&argc
, &argv
);
874 set_program_name (argv
[0]);
875 setlocale (LC_ALL
, "");
876 bindtextdomain (PACKAGE
, LOCALEDIR
);
877 textdomain (PACKAGE
);
879 atexit (close_stdout
);
881 /* Line buffer stdout to ensure lines are written atomically and immediately
882 so that processes running in parallel do not intersperse their output. */
883 setvbuf (stdout
, NULL
, _IOLBF
, 0);
886 const char* short_opts
= "l:bctwz";
887 const char* b2_length_str
= "";
889 const char* short_opts
= "bctwz";
892 while ((opt
= getopt_long (argc
, argv
, short_opts
, long_options
, NULL
)) != -1)
897 b2_length
= xdectoumax (optarg
, 0, UINTMAX_MAX
, "",
898 _("invalid length"), 0);
899 b2_length_str
= optarg
;
900 if (b2_length
% 8 != 0)
902 error (0, 0, _("invalid length: %s"), quote (b2_length_str
));
903 die (EXIT_FAILURE
, 0, _("length is not a multiple of 8"));
926 case IGNORE_MISSING_OPTION
:
927 ignore_missing
= true;
944 case_GETOPT_HELP_CHAR
;
945 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
947 usage (EXIT_FAILURE
);
950 min_digest_line_length
= MIN_DIGEST_LINE_LENGTH
;
952 if (b2_length
> blake2_max_len
[b2_algorithm
] * 8)
954 error (0, 0, _("invalid length: %s"), quote (b2_length_str
));
955 die (EXIT_FAILURE
, 0,
956 _("maximum digest length for %s is %"PRIuMAX
" bits"),
957 quote (algorithm_in_string
[b2_algorithm
]),
958 blake2_max_len
[b2_algorithm
] * 8);
960 if (b2_length
== 0 && ! do_check
)
961 b2_length
= blake2_max_len
[b2_algorithm
] * 8;
962 digest_hex_bytes
= b2_length
/ 4;
964 digest_hex_bytes
= DIGEST_HEX_BYTES
;
967 if (prefix_tag
&& !binary
)
969 /* This could be supported in a backwards compatible way
970 by prefixing the output line with a space in text mode.
971 However that's invasive enough that it was agreed to
972 not support this mode with --tag, as --text use cases
973 are adequately supported by the default output format. */
974 error (0, 0, _("--tag does not support --text mode"));
975 usage (EXIT_FAILURE
);
978 if (delim
!= '\n' && do_check
)
980 error (0, 0, _("the --zero option is not supported when "
981 "verifying checksums"));
982 usage (EXIT_FAILURE
);
985 if (prefix_tag
&& do_check
)
987 error (0, 0, _("the --tag option is meaningless when "
988 "verifying checksums"));
989 usage (EXIT_FAILURE
);
992 if (0 <= binary
&& do_check
)
994 error (0, 0, _("the --binary and --text options are meaningless when "
995 "verifying checksums"));
996 usage (EXIT_FAILURE
);
999 if (ignore_missing
&& !do_check
)
1002 _("the --ignore-missing option is meaningful only when "
1003 "verifying checksums"));
1004 usage (EXIT_FAILURE
);
1007 if (status_only
&& !do_check
)
1010 _("the --status option is meaningful only when verifying checksums"));
1011 usage (EXIT_FAILURE
);
1014 if (warn
&& !do_check
)
1017 _("the --warn option is meaningful only when verifying checksums"));
1018 usage (EXIT_FAILURE
);
1021 if (quiet
&& !do_check
)
1024 _("the --quiet option is meaningful only when verifying checksums"));
1025 usage (EXIT_FAILURE
);
1028 if (strict
& !do_check
)
1031 _("the --strict option is meaningful only when verifying checksums"));
1032 usage (EXIT_FAILURE
);
1035 if (!O_BINARY
&& binary
< 0)
1038 char **operand_lim
= argv
+ argc
;
1040 *operand_lim
++ = bad_cast ("-");
1042 for (char **operandp
= argv
+ optind
; operandp
< operand_lim
; operandp
++)
1044 char *file
= *operandp
;
1047 ok
&= digest_check (file
);
1050 int file_is_binary
= binary
;
1053 if (! digest_file (file
, &file_is_binary
, bin_buffer
, &missing
))
1057 /* We don't really need to escape, and hence detect, the '\\'
1058 char, and not doing so should be both forwards and backwards
1059 compatible, since only escaped lines would have a '\\' char at
1060 the start. However just in case users are directly comparing
1061 against old (hashed) outputs, in the presence of files
1062 containing '\\' characters, we decided to not simplify the
1063 output in this case. */
1064 bool needs_escape
= (strchr (file
, '\\') || strchr (file
, '\n'))
1072 #if HASH_ALGO_BLAKE2
1073 fputs (algorithm_out_string
[b2_algorithm
], stdout
);
1074 if (b2_length
< blake2_max_len
[b2_algorithm
] * 8)
1075 printf ("-%"PRIuMAX
, b2_length
);
1077 fputs (DIGEST_TYPE_STRING
, stdout
);
1079 fputs (" (", stdout
);
1080 print_filename (file
, needs_escape
);
1081 fputs (") = ", stdout
);
1084 /* Output a leading backslash if the file name contains
1085 a newline or backslash. */
1086 if (!prefix_tag
&& needs_escape
)
1089 for (size_t i
= 0; i
< (digest_hex_bytes
/ 2); ++i
)
1090 printf ("%02x", bin_buffer
[i
]);
1096 putchar (file_is_binary
? '*' : ' ');
1098 print_filename (file
, needs_escape
);
1106 if (have_read_stdin
&& fclose (stdin
) == EOF
)
1107 die (EXIT_FAILURE
, errno
, _("standard input"));
1109 return ok
? EXIT_SUCCESS
: EXIT_FAILURE
;