stty: fix sane setting of susp to ^z on Solaris
[coreutils.git] / src / md5sum.c
blob3ed1b65e7c8e78bc4a994546a5bf6080614b2cc4
1 /* Compute checksums of files or strings.
2 Copyright (C) 1995-2016 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 <http://www.gnu.org/licenses/>. */
17 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>. */
19 #include <config.h>
21 #include <getopt.h>
22 #include <sys/types.h>
24 #include "system.h"
26 #if HASH_ALGO_MD5
27 # include "md5.h"
28 #endif
29 #if HASH_ALGO_SHA1
30 # include "sha1.h"
31 #endif
32 #if HASH_ALGO_SHA256 || HASH_ALGO_SHA224
33 # include "sha256.h"
34 #endif
35 #if HASH_ALGO_SHA512 || HASH_ALGO_SHA384
36 # include "sha512.h"
37 #endif
38 #include "error.h"
39 #include "fadvise.h"
40 #include "stdio--.h"
41 #include "xfreopen.h"
43 /* The official name of this program (e.g., no 'g' prefix). */
44 #if HASH_ALGO_MD5
45 # define PROGRAM_NAME "md5sum"
46 # define DIGEST_TYPE_STRING "MD5"
47 # define DIGEST_STREAM md5_stream
48 # define DIGEST_BITS 128
49 # define DIGEST_REFERENCE "RFC 1321"
50 # define DIGEST_ALIGN 4
51 #elif HASH_ALGO_SHA1
52 # define PROGRAM_NAME "sha1sum"
53 # define DIGEST_TYPE_STRING "SHA1"
54 # define DIGEST_STREAM sha1_stream
55 # define DIGEST_BITS 160
56 # define DIGEST_REFERENCE "FIPS-180-1"
57 # define DIGEST_ALIGN 4
58 #elif HASH_ALGO_SHA256
59 # define PROGRAM_NAME "sha256sum"
60 # define DIGEST_TYPE_STRING "SHA256"
61 # define DIGEST_STREAM sha256_stream
62 # define DIGEST_BITS 256
63 # define DIGEST_REFERENCE "FIPS-180-2"
64 # define DIGEST_ALIGN 4
65 #elif HASH_ALGO_SHA224
66 # define PROGRAM_NAME "sha224sum"
67 # define DIGEST_TYPE_STRING "SHA224"
68 # define DIGEST_STREAM sha224_stream
69 # define DIGEST_BITS 224
70 # define DIGEST_REFERENCE "RFC 3874"
71 # define DIGEST_ALIGN 4
72 #elif HASH_ALGO_SHA512
73 # define PROGRAM_NAME "sha512sum"
74 # define DIGEST_TYPE_STRING "SHA512"
75 # define DIGEST_STREAM sha512_stream
76 # define DIGEST_BITS 512
77 # define DIGEST_REFERENCE "FIPS-180-2"
78 # define DIGEST_ALIGN 8
79 #elif HASH_ALGO_SHA384
80 # define PROGRAM_NAME "sha384sum"
81 # define DIGEST_TYPE_STRING "SHA384"
82 # define DIGEST_STREAM sha384_stream
83 # define DIGEST_BITS 384
84 # define DIGEST_REFERENCE "FIPS-180-2"
85 # define DIGEST_ALIGN 8
86 #else
87 # error "Can't decide which hash algorithm to compile."
88 #endif
90 #define DIGEST_HEX_BYTES (DIGEST_BITS / 4)
91 #define DIGEST_BIN_BYTES (DIGEST_BITS / 8)
93 #define AUTHORS \
94 proper_name ("Ulrich Drepper"), \
95 proper_name ("Scott Miller"), \
96 proper_name ("David Madore")
98 /* The minimum length of a valid digest line. This length does
99 not include any newline character at the end of a line. */
100 #define MIN_DIGEST_LINE_LENGTH \
101 (DIGEST_HEX_BYTES /* length of hexadecimal message digest */ \
102 + 1 /* blank */ \
103 + 1 /* minimum filename length */ )
105 /* True if any of the files read were the standard input. */
106 static bool have_read_stdin;
108 /* The minimum length of a valid checksum line for the selected algorithm. */
109 static size_t min_digest_line_length;
111 /* Set to the length of a digest hex string for the selected algorithm. */
112 static size_t digest_hex_bytes;
114 /* With --check, don't generate any output.
115 The exit code indicates success or failure. */
116 static bool status_only = false;
118 /* With --check, print a message to standard error warning about each
119 improperly formatted checksum line. */
120 static bool warn = false;
122 /* With --check, ignore missing files. */
123 static bool ignore_missing = false;
125 /* With --check, suppress the "OK" printed for each verified file. */
126 static bool quiet = false;
128 /* With --check, exit with a non-zero return code if any line is
129 improperly formatted. */
130 static bool strict = false;
132 /* Whether a BSD reversed format checksum is detected. */
133 static int bsd_reversed = -1;
135 /* For long options that have no equivalent short option, use a
136 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
137 enum
139 IGNORE_MISSING_OPTION = CHAR_MAX + 1,
140 STATUS_OPTION,
141 QUIET_OPTION,
142 STRICT_OPTION,
143 TAG_OPTION
146 static struct option const long_options[] =
148 { "binary", no_argument, NULL, 'b' },
149 { "check", no_argument, NULL, 'c' },
150 { "ignore-missing", no_argument, NULL, IGNORE_MISSING_OPTION},
151 { "quiet", no_argument, NULL, QUIET_OPTION },
152 { "status", no_argument, NULL, STATUS_OPTION },
153 { "text", no_argument, NULL, 't' },
154 { "warn", no_argument, NULL, 'w' },
155 { "strict", no_argument, NULL, STRICT_OPTION },
156 { "tag", no_argument, NULL, TAG_OPTION },
157 { GETOPT_HELP_OPTION_DECL },
158 { GETOPT_VERSION_OPTION_DECL },
159 { NULL, 0, NULL, 0 }
162 void
163 usage (int status)
165 if (status != EXIT_SUCCESS)
166 emit_try_help ();
167 else
169 printf (_("\
170 Usage: %s [OPTION]... [FILE]...\n\
171 Print or check %s (%d-bit) checksums.\n\
173 program_name,
174 DIGEST_TYPE_STRING,
175 DIGEST_BITS);
177 emit_stdin_note ();
179 if (O_BINARY)
180 fputs (_("\
182 -b, --binary read in binary mode (default unless reading tty stdin)\n\
183 "), stdout);
184 else
185 fputs (_("\
187 -b, --binary read in binary mode\n\
188 "), stdout);
189 printf (_("\
190 -c, --check read %s sums from the FILEs and check them\n"),
191 DIGEST_TYPE_STRING);
192 fputs (_("\
193 --tag create a BSD-style checksum\n\
194 "), stdout);
195 if (O_BINARY)
196 fputs (_("\
197 -t, --text read in text mode (default if reading tty stdin)\n\
198 "), stdout);
199 else
200 fputs (_("\
201 -t, --text read in text mode (default)\n\
202 "), stdout);
203 fputs (_("\
205 The following five options are useful only when verifying checksums:\n\
206 --ignore-missing don't fail or report status for missing files\n\
207 --quiet don't print OK for each successfully verified file\n\
208 --status don't output anything, status code shows success\n\
209 --strict exit non-zero for improperly formatted checksum lines\n\
210 -w, --warn warn about improperly formatted checksum lines\n\
212 "), stdout);
213 fputs (HELP_OPTION_DESCRIPTION, stdout);
214 fputs (VERSION_OPTION_DESCRIPTION, stdout);
215 printf (_("\
217 The sums are computed as described in %s. When checking, the input\n\
218 should be a former output of this program. The default mode is to print a\n\
219 line with checksum, a space, a character indicating input mode ('*' for binary,\
220 \n' ' for text or where binary is insignificant), and name for each FILE.\n"),
221 DIGEST_REFERENCE);
222 emit_ancillary_info (PROGRAM_NAME);
225 exit (status);
228 #define ISWHITE(c) ((c) == ' ' || (c) == '\t')
230 /* Given a file name, S of length S_LEN, that is not NUL-terminated,
231 modify it in place, performing the equivalent of this sed substitution:
232 's/\\n/\n/g;s/\\\\/\\/g' i.e., replacing each "\\n" string with a newline
233 and each "\\\\" with a single backslash, NUL-terminate it and return S.
234 If S is not a valid escaped file name, i.e., if it ends with an odd number
235 of backslashes or if it contains a backslash followed by anything other
236 than "n" or another backslash, return NULL. */
238 static char *
239 filename_unescape (char *s, size_t s_len)
241 char *dst = s;
243 for (size_t i = 0; i < s_len; i++)
245 switch (s[i])
247 case '\\':
248 if (i == s_len - 1)
250 /* File name ends with an unescaped backslash: invalid. */
251 return NULL;
253 ++i;
254 switch (s[i])
256 case 'n':
257 *dst++ = '\n';
258 break;
259 case '\\':
260 *dst++ = '\\';
261 break;
262 default:
263 /* Only '\' or 'n' may follow a backslash. */
264 return NULL;
266 break;
268 case '\0':
269 /* The file name may not contain a NUL. */
270 return NULL;
272 default:
273 *dst++ = s[i];
274 break;
277 if (dst < s + s_len)
278 *dst = '\0';
280 return s;
283 /* Split the checksum string S (of length S_LEN) from a BSD 'md5' or
284 'sha1' command into two parts: a hexadecimal digest, and the file
285 name. S is modified. Return true if successful. */
287 static bool
288 bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest,
289 char **file_name, bool escaped_filename)
291 size_t i;
293 if (s_len == 0)
294 return false;
296 /* Find end of filename. */
297 i = s_len - 1;
298 while (i && s[i] != ')')
299 i--;
301 if (s[i] != ')')
302 return false;
304 *file_name = s;
306 if (escaped_filename && filename_unescape (s, i) == NULL)
307 return false;
309 s[i++] = '\0';
311 while (ISWHITE (s[i]))
312 i++;
314 if (s[i] != '=')
315 return false;
317 i++;
319 while (ISWHITE (s[i]))
320 i++;
322 *hex_digest = (unsigned char *) &s[i];
323 return true;
326 /* Split the string S (of length S_LEN) into three parts:
327 a hexadecimal digest, binary flag, and the file name.
328 S is modified. Return true if successful. */
330 static bool
331 split_3 (char *s, size_t s_len,
332 unsigned char **hex_digest, int *binary, char **file_name)
334 bool escaped_filename = false;
335 size_t algo_name_len;
337 size_t i = 0;
338 while (ISWHITE (s[i]))
339 ++i;
341 if (s[i] == '\\')
343 ++i;
344 escaped_filename = true;
347 /* Check for BSD-style checksum line. */
349 algo_name_len = strlen (DIGEST_TYPE_STRING);
350 if (STREQ_LEN (s + i, DIGEST_TYPE_STRING, algo_name_len))
352 if (s[i + algo_name_len] == ' ')
353 ++i;
354 if (s[i + algo_name_len] == '(')
356 *binary = 0;
357 return bsd_split_3 (s + i + algo_name_len + 1,
358 s_len - (i + algo_name_len + 1),
359 hex_digest, file_name, escaped_filename);
363 /* Ignore this line if it is too short.
364 Each line must have at least 'min_digest_line_length - 1' (or one more, if
365 the first is a backslash) more characters to contain correct message digest
366 information. */
367 if (s_len - i < min_digest_line_length + (s[i] == '\\'))
368 return false;
370 *hex_digest = (unsigned char *) &s[i];
372 /* The first field has to be the n-character hexadecimal
373 representation of the message digest. If it is not followed
374 immediately by a white space it's an error. */
375 i += digest_hex_bytes;
376 if (!ISWHITE (s[i]))
377 return false;
379 s[i++] = '\0';
381 /* If "bsd reversed" format detected. */
382 if ((s_len - i == 1) || (s[i] != ' ' && s[i] != '*'))
384 /* Don't allow mixing bsd and standard formats,
385 to minimize security issues with attackers
386 renaming files with leading spaces.
387 This assumes that with bsd format checksums
388 that the first file name does not have
389 a leading ' ' or '*'. */
390 if (bsd_reversed == 0)
391 return false;
392 bsd_reversed = 1;
394 else if (bsd_reversed != 1)
396 bsd_reversed = 0;
397 *binary = (s[i++] == '*');
400 /* All characters between the type indicator and end of line are
401 significant -- that includes leading and trailing white space. */
402 *file_name = &s[i];
404 if (escaped_filename)
405 return filename_unescape (&s[i], s_len - i) != NULL;
407 return true;
410 /* Return true if S is a NUL-terminated string of DIGEST_HEX_BYTES hex digits.
411 Otherwise, return false. */
412 static bool _GL_ATTRIBUTE_PURE
413 hex_digits (unsigned char const *s)
415 unsigned int i;
416 for (i = 0; i < digest_hex_bytes; i++)
418 if (!isxdigit (*s))
419 return false;
420 ++s;
422 return *s == '\0';
425 /* If ESCAPE is true, then translate each NEWLINE byte to the string, "\\n",
426 and each backslash to "\\\\". */
427 static void
428 print_filename (char const *file, bool escape)
430 if (! escape)
432 fputs (file, stdout);
433 return;
436 while (*file)
438 switch (*file)
440 case '\n':
441 fputs ("\\n", stdout);
442 break;
444 case '\\':
445 fputs ("\\\\", stdout);
446 break;
448 default:
449 putchar (*file);
450 break;
452 file++;
456 /* An interface to the function, DIGEST_STREAM.
457 Operate on FILENAME (it may be "-").
459 *BINARY indicates whether the file is binary. BINARY < 0 means it
460 depends on whether binary mode makes any difference and the file is
461 a terminal; in that case, clear *BINARY if the file was treated as
462 text because it was a terminal.
464 Put the checksum in *BIN_RESULT, which must be properly aligned.
465 Return true if successful. */
467 static bool
468 digest_file (const char *filename, int *binary, unsigned char *bin_result)
470 FILE *fp;
471 int err;
472 bool is_stdin = STREQ (filename, "-");
474 if (is_stdin)
476 have_read_stdin = true;
477 fp = stdin;
478 if (O_BINARY && *binary)
480 if (*binary < 0)
481 *binary = ! isatty (STDIN_FILENO);
482 if (*binary)
483 xfreopen (NULL, "rb", stdin);
486 else
488 fp = fopen (filename, (O_BINARY && *binary ? "rb" : "r"));
489 if (fp == NULL)
491 if (ignore_missing && errno == ENOENT)
493 *bin_result = '\0';
494 return true;
496 error (0, errno, "%s", quotef (filename));
497 return false;
501 fadvise (fp, FADVISE_SEQUENTIAL);
503 err = DIGEST_STREAM (fp, bin_result);
504 if (err)
506 error (0, errno, "%s", quotef (filename));
507 if (fp != stdin)
508 fclose (fp);
509 return false;
512 if (!is_stdin && fclose (fp) != 0)
514 error (0, errno, "%s", quotef (filename));
515 return false;
518 return true;
521 static bool
522 digest_check (const char *checkfile_name)
524 FILE *checkfile_stream;
525 uintmax_t n_misformatted_lines = 0;
526 uintmax_t n_improperly_formatted_lines = 0;
527 uintmax_t n_mismatched_checksums = 0;
528 uintmax_t n_open_or_read_failures = 0;
529 bool properly_formatted_lines = false;
530 bool matched_checksums = false;
531 unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];
532 /* Make sure bin_buffer is properly aligned. */
533 unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN);
534 uintmax_t line_number;
535 char *line;
536 size_t line_chars_allocated;
537 bool is_stdin = STREQ (checkfile_name, "-");
539 if (is_stdin)
541 have_read_stdin = true;
542 checkfile_name = _("standard input");
543 checkfile_stream = stdin;
545 else
547 checkfile_stream = fopen (checkfile_name, "r");
548 if (checkfile_stream == NULL)
550 error (0, errno, "%s", quotef (checkfile_name));
551 return false;
555 line_number = 0;
556 line = NULL;
557 line_chars_allocated = 0;
560 char *filename IF_LINT ( = NULL);
561 int binary;
562 unsigned char *hex_digest IF_LINT ( = NULL);
563 ssize_t line_length;
565 ++line_number;
566 if (line_number == 0)
567 error (EXIT_FAILURE, 0, _("%s: too many checksum lines"),
568 quotef (checkfile_name));
570 line_length = getline (&line, &line_chars_allocated, checkfile_stream);
571 if (line_length <= 0)
572 break;
574 /* Ignore comment lines, which begin with a '#' character. */
575 if (line[0] == '#')
576 continue;
578 /* Remove any trailing newline. */
579 if (line[line_length - 1] == '\n')
580 line[--line_length] = '\0';
582 if (! (split_3 (line, line_length, &hex_digest, &binary, &filename)
583 && ! (is_stdin && STREQ (filename, "-"))
584 && hex_digits (hex_digest)))
586 ++n_misformatted_lines;
588 if (warn)
590 error (0, 0,
591 _("%s: %" PRIuMAX
592 ": improperly formatted %s checksum line"),
593 quotef (checkfile_name), line_number,
594 DIGEST_TYPE_STRING);
597 ++n_improperly_formatted_lines;
599 else
601 static const char bin2hex[] = { '0', '1', '2', '3',
602 '4', '5', '6', '7',
603 '8', '9', 'a', 'b',
604 'c', 'd', 'e', 'f' };
605 bool ok;
606 /* Only escape in the edge case producing multiple lines,
607 to ease automatic processing of status output. */
608 bool needs_escape = ! status_only && strchr (filename, '\n');
610 properly_formatted_lines = true;
612 *bin_buffer = '\1'; /* flag set to 0 for ignored missing files. */
613 ok = digest_file (filename, &binary, bin_buffer);
615 if (!ok)
617 ++n_open_or_read_failures;
618 if (!status_only)
620 if (needs_escape)
621 putchar ('\\');
622 print_filename (filename, needs_escape);
623 printf (": %s\n", _("FAILED open or read"));
626 else if (ignore_missing && ! *bin_buffer)
628 /* Treat an empty buffer as meaning a missing file,
629 which is ignored with --ignore-missing. */
632 else
634 size_t digest_bin_bytes = digest_hex_bytes / 2;
635 size_t cnt;
637 /* Compare generated binary number with text representation
638 in check file. Ignore case of hex digits. */
639 for (cnt = 0; cnt < digest_bin_bytes; ++cnt)
641 if (tolower (hex_digest[2 * cnt])
642 != bin2hex[bin_buffer[cnt] >> 4]
643 || (tolower (hex_digest[2 * cnt + 1])
644 != (bin2hex[bin_buffer[cnt] & 0xf])))
645 break;
647 if (cnt != digest_bin_bytes)
648 ++n_mismatched_checksums;
649 else
650 matched_checksums = true;
652 if (!status_only)
654 if (cnt != digest_bin_bytes || ! quiet)
656 if (needs_escape)
657 putchar ('\\');
658 print_filename (filename, needs_escape);
661 if (cnt != digest_bin_bytes)
662 printf (": %s\n", _("FAILED"));
663 else if (!quiet)
664 printf (": %s\n", _("OK"));
669 while (!feof (checkfile_stream) && !ferror (checkfile_stream));
671 free (line);
673 if (ferror (checkfile_stream))
675 error (0, 0, _("%s: read error"), quotef (checkfile_name));
676 return false;
679 if (!is_stdin && fclose (checkfile_stream) != 0)
681 error (0, errno, "%s", quotef (checkfile_name));
682 return false;
685 if (! properly_formatted_lines)
687 /* Warn if no tests are found. */
688 error (0, 0, _("%s: no properly formatted %s checksum lines found"),
689 quotef (checkfile_name), DIGEST_TYPE_STRING);
691 else
693 if (!status_only)
695 if (n_misformatted_lines != 0)
696 error (0, 0,
697 (ngettext
698 ("WARNING: %" PRIuMAX " line is improperly formatted",
699 "WARNING: %" PRIuMAX " lines are improperly formatted",
700 select_plural (n_misformatted_lines))),
701 n_misformatted_lines);
703 if (n_open_or_read_failures != 0)
704 error (0, 0,
705 (ngettext
706 ("WARNING: %" PRIuMAX " listed file could not be read",
707 "WARNING: %" PRIuMAX " listed files could not be read",
708 select_plural (n_open_or_read_failures))),
709 n_open_or_read_failures);
711 if (n_mismatched_checksums != 0)
712 error (0, 0,
713 (ngettext
714 ("WARNING: %" PRIuMAX " computed checksum did NOT match",
715 "WARNING: %" PRIuMAX " computed checksums did NOT match",
716 select_plural (n_mismatched_checksums))),
717 n_mismatched_checksums);
719 if (ignore_missing && ! matched_checksums)
720 error (0, 0, _("%s: no file was verified"),
721 quotef (checkfile_name));
725 return (properly_formatted_lines
726 && matched_checksums
727 && n_mismatched_checksums == 0
728 && n_open_or_read_failures == 0
729 && (!strict || n_improperly_formatted_lines == 0));
733 main (int argc, char **argv)
735 unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];
736 /* Make sure bin_buffer is properly aligned. */
737 unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN);
738 bool do_check = false;
739 int opt;
740 bool ok = true;
741 int binary = -1;
742 bool prefix_tag = false;
744 /* Setting values of global variables. */
745 initialize_main (&argc, &argv);
746 set_program_name (argv[0]);
747 setlocale (LC_ALL, "");
748 bindtextdomain (PACKAGE, LOCALEDIR);
749 textdomain (PACKAGE);
751 atexit (close_stdout);
753 /* Line buffer stdout to ensure lines are written atomically and immediately
754 so that processes running in parallel do not intersperse their output. */
755 setvbuf (stdout, NULL, _IOLBF, 0);
757 while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1)
758 switch (opt)
760 case 'b':
761 binary = 1;
762 break;
763 case 'c':
764 do_check = true;
765 break;
766 case STATUS_OPTION:
767 status_only = true;
768 warn = false;
769 quiet = false;
770 break;
771 case 't':
772 binary = 0;
773 break;
774 case 'w':
775 status_only = false;
776 warn = true;
777 quiet = false;
778 break;
779 case IGNORE_MISSING_OPTION:
780 ignore_missing = true;
781 break;
782 case QUIET_OPTION:
783 status_only = false;
784 warn = false;
785 quiet = true;
786 break;
787 case STRICT_OPTION:
788 strict = true;
789 break;
790 case TAG_OPTION:
791 prefix_tag = true;
792 binary = 1;
793 break;
794 case_GETOPT_HELP_CHAR;
795 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
796 default:
797 usage (EXIT_FAILURE);
800 min_digest_line_length = MIN_DIGEST_LINE_LENGTH;
801 digest_hex_bytes = DIGEST_HEX_BYTES;
803 if (prefix_tag && !binary)
805 /* This could be supported in a backwards compatible way
806 by prefixing the output line with a space in text mode.
807 However that's invasive enough that it was agreed to
808 not support this mode with --tag, as --text use cases
809 are adequately supported by the default output format. */
810 error (0, 0, _("--tag does not support --text mode"));
811 usage (EXIT_FAILURE);
814 if (prefix_tag && do_check)
816 error (0, 0, _("the --tag option is meaningless when "
817 "verifying checksums"));
818 usage (EXIT_FAILURE);
821 if (0 <= binary && do_check)
823 error (0, 0, _("the --binary and --text options are meaningless when "
824 "verifying checksums"));
825 usage (EXIT_FAILURE);
828 if (ignore_missing && !do_check)
830 error (0, 0,
831 _("the --ignore-missing option is meaningful only when "
832 "verifying checksums"));
833 usage (EXIT_FAILURE);
836 if (status_only && !do_check)
838 error (0, 0,
839 _("the --status option is meaningful only when verifying checksums"));
840 usage (EXIT_FAILURE);
843 if (warn && !do_check)
845 error (0, 0,
846 _("the --warn option is meaningful only when verifying checksums"));
847 usage (EXIT_FAILURE);
850 if (quiet && !do_check)
852 error (0, 0,
853 _("the --quiet option is meaningful only when verifying checksums"));
854 usage (EXIT_FAILURE);
857 if (strict & !do_check)
859 error (0, 0,
860 _("the --strict option is meaningful only when verifying checksums"));
861 usage (EXIT_FAILURE);
864 if (!O_BINARY && binary < 0)
865 binary = 0;
867 char **operand_lim = argv + argc;
868 if (optind == argc)
869 *operand_lim++ = bad_cast ("-");
871 for (char **operandp = argv + optind; operandp < operand_lim; operandp++)
873 char *file = *operandp;
875 if (do_check)
876 ok &= digest_check (file);
877 else
879 int file_is_binary = binary;
881 if (! digest_file (file, &file_is_binary, bin_buffer))
882 ok = false;
883 else
885 /* We don't really need to escape, and hence detect, the '\\'
886 char, and not doing so should be both forwards and backwards
887 compatible, since only escaped lines would have a '\\' char at
888 the start. However just in case users are directly comparing
889 against old (hashed) outputs, in the presence of files
890 containing '\\' characters, we decided to not simplify the
891 output in this case. */
892 bool needs_escape = strchr (file, '\\') || strchr (file, '\n');
894 if (prefix_tag)
896 if (needs_escape)
897 putchar ('\\');
899 fputs (DIGEST_TYPE_STRING, stdout);
900 fputs (" (", stdout);
901 print_filename (file, needs_escape);
902 fputs (") = ", stdout);
905 size_t i;
907 /* Output a leading backslash if the file name contains
908 a newline or backslash. */
909 if (!prefix_tag && needs_escape)
910 putchar ('\\');
912 for (i = 0; i < (digest_hex_bytes / 2); ++i)
913 printf ("%02x", bin_buffer[i]);
915 if (!prefix_tag)
917 putchar (' ');
919 putchar (file_is_binary ? '*' : ' ');
921 print_filename (file, needs_escape);
924 putchar ('\n');
929 if (have_read_stdin && fclose (stdin) == EOF)
930 error (EXIT_FAILURE, errno, _("standard input"));
932 return ok ? EXIT_SUCCESS : EXIT_FAILURE;