md5sum, sha*sum: improve help for --check related options
[coreutils.git] / src / md5sum.c
blobee2bbb781a4f32dc9d66b69880a47e95fd927a80
1 /* Compute checksums of files or strings.
2 Copyright (C) 1995-2013 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, suppress the "OK" printed for each verified file. */
123 static bool quiet = false;
125 /* With --check, exit with a non-zero return code if any line is
126 improperly formatted. */
127 static bool strict = false;
129 /* Whether a BSD reversed format checksum is detected. */
130 static int bsd_reversed = -1;
132 /* For long options that have no equivalent short option, use a
133 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
134 enum
136 STATUS_OPTION = CHAR_MAX + 1,
137 QUIET_OPTION,
138 STRICT_OPTION,
139 TAG_OPTION
142 static struct option const long_options[] =
144 { "binary", no_argument, NULL, 'b' },
145 { "check", no_argument, NULL, 'c' },
146 { "quiet", no_argument, NULL, QUIET_OPTION },
147 { "status", no_argument, NULL, STATUS_OPTION },
148 { "text", no_argument, NULL, 't' },
149 { "warn", no_argument, NULL, 'w' },
150 { "strict", no_argument, NULL, STRICT_OPTION },
151 { "tag", no_argument, NULL, TAG_OPTION },
152 { GETOPT_HELP_OPTION_DECL },
153 { GETOPT_VERSION_OPTION_DECL },
154 { NULL, 0, NULL, 0 }
157 void
158 usage (int status)
160 if (status != EXIT_SUCCESS)
161 emit_try_help ();
162 else
164 printf (_("\
165 Usage: %s [OPTION]... [FILE]...\n\
166 Print or check %s (%d-bit) checksums.\n\
167 With no FILE, or when FILE is -, read standard input.\n\
170 program_name,
171 DIGEST_TYPE_STRING,
172 DIGEST_BITS);
173 if (O_BINARY)
174 fputs (_("\
175 -b, --binary read in binary mode (default unless reading tty stdin)\n\
176 "), stdout);
177 else
178 fputs (_("\
179 -b, --binary read in binary mode\n\
180 "), stdout);
181 printf (_("\
182 -c, --check read %s sums from the FILEs and check them\n"),
183 DIGEST_TYPE_STRING);
184 fputs (_("\
185 --tag create a BSD-style checksum\n\
186 "), stdout);
187 if (O_BINARY)
188 fputs (_("\
189 -t, --text read in text mode (default if reading tty stdin)\n\
190 "), stdout);
191 else
192 fputs (_("\
193 -t, --text read in text mode (default)\n\
194 "), stdout);
195 fputs (_("\
197 The following four options are useful only when verifying checksums:\n\
198 --quiet don't print OK for each successfully verified file\n\
199 --status don't output anything, status code shows success\n\
200 --strict exit non-zero for improperly formatted checksum lines\n\
201 -w, --warn warn about improperly formatted checksum lines\n\
203 "), stdout);
204 fputs (HELP_OPTION_DESCRIPTION, stdout);
205 fputs (VERSION_OPTION_DESCRIPTION, stdout);
206 printf (_("\
208 The sums are computed as described in %s. When checking, the input\n\
209 should be a former output of this program. The default mode is to print\n\
210 a line with checksum, a character indicating input mode ('*' for binary,\n\
211 space for text), and name for each FILE.\n"),
212 DIGEST_REFERENCE);
213 emit_ancillary_info ();
216 exit (status);
219 #define ISWHITE(c) ((c) == ' ' || (c) == '\t')
221 /* Given a file name, S of length S_LEN, that is not NUL-terminated,
222 modify it in place, performing the equivalent of this sed substitution:
223 's/\\n/\n/g;s/\\\\/\\/g' i.e., replacing each "\\n" string with a newline
224 and each "\\\\" with a single backslash, NUL-terminate it and return S.
225 If S is not a valid escaped file name, i.e., if it ends with an odd number
226 of backslashes or if it contains a backslash followed by anything other
227 than "n" or another backslash, return NULL. */
229 static char *
230 filename_unescape (char *s, size_t s_len)
232 char *dst = s;
234 for (size_t i = 0; i < s_len; i++)
236 switch (s[i])
238 case '\\':
239 if (i == s_len - 1)
241 /* File name ends with an unescaped backslash: invalid. */
242 return NULL;
244 ++i;
245 switch (s[i])
247 case 'n':
248 *dst++ = '\n';
249 break;
250 case '\\':
251 *dst++ = '\\';
252 break;
253 default:
254 /* Only '\' or 'n' may follow a backslash. */
255 return NULL;
257 break;
259 case '\0':
260 /* The file name may not contain a NUL. */
261 return NULL;
263 default:
264 *dst++ = s[i];
265 break;
268 if (dst < s + s_len)
269 *dst = '\0';
271 return s;
274 /* Split the checksum string S (of length S_LEN) from a BSD 'md5' or
275 'sha1' command into two parts: a hexadecimal digest, and the file
276 name. S is modified. Return true if successful. */
278 static bool
279 bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest,
280 char **file_name, bool escaped_filename)
282 size_t i;
284 if (s_len == 0)
285 return false;
287 /* Find end of filename. */
288 i = s_len - 1;
289 while (i && s[i] != ')')
290 i--;
292 if (s[i] != ')')
293 return false;
295 *file_name = s;
297 if (escaped_filename && filename_unescape (s, i) == NULL)
298 return false;
300 s[i++] = '\0';
302 while (ISWHITE (s[i]))
303 i++;
305 if (s[i] != '=')
306 return false;
308 i++;
310 while (ISWHITE (s[i]))
311 i++;
313 *hex_digest = (unsigned char *) &s[i];
314 return true;
317 /* Split the string S (of length S_LEN) into three parts:
318 a hexadecimal digest, binary flag, and the file name.
319 S is modified. Return true if successful. */
321 static bool
322 split_3 (char *s, size_t s_len,
323 unsigned char **hex_digest, int *binary, char **file_name)
325 bool escaped_filename = false;
326 size_t algo_name_len;
328 size_t i = 0;
329 while (ISWHITE (s[i]))
330 ++i;
332 if (s[i] == '\\')
334 ++i;
335 escaped_filename = true;
338 /* Check for BSD-style checksum line. */
340 algo_name_len = strlen (DIGEST_TYPE_STRING);
341 if (STREQ_LEN (s + i, DIGEST_TYPE_STRING, algo_name_len))
343 if (s[i + algo_name_len] == ' ')
344 ++i;
345 if (s[i + algo_name_len] == '(')
347 *binary = 0;
348 return bsd_split_3 (s + i + algo_name_len + 1,
349 s_len - (i + algo_name_len + 1),
350 hex_digest, file_name, escaped_filename);
354 /* Ignore this line if it is too short.
355 Each line must have at least 'min_digest_line_length - 1' (or one more, if
356 the first is a backslash) more characters to contain correct message digest
357 information. */
358 if (s_len - i < min_digest_line_length + (s[i] == '\\'))
359 return false;
361 *hex_digest = (unsigned char *) &s[i];
363 /* The first field has to be the n-character hexadecimal
364 representation of the message digest. If it is not followed
365 immediately by a white space it's an error. */
366 i += digest_hex_bytes;
367 if (!ISWHITE (s[i]))
368 return false;
370 s[i++] = '\0';
372 /* If "bsd reversed" format detected. */
373 if ((s_len - i == 1) || (s[i] != ' ' && s[i] != '*'))
375 /* Don't allow mixing bsd and standard formats,
376 to minimize security issues with attackers
377 renaming files with leading spaces.
378 This assumes that with bsd format checksums
379 that the first file name does not have
380 a leading ' ' or '*'. */
381 if (bsd_reversed == 0)
382 return false;
383 bsd_reversed = 1;
385 else if (bsd_reversed != 1)
387 bsd_reversed = 0;
388 *binary = (s[i++] == '*');
391 /* All characters between the type indicator and end of line are
392 significant -- that includes leading and trailing white space. */
393 *file_name = &s[i];
395 if (escaped_filename)
396 return filename_unescape (&s[i], s_len - i) != NULL;
398 return true;
401 /* Return true if S is a NUL-terminated string of DIGEST_HEX_BYTES hex digits.
402 Otherwise, return false. */
403 static bool _GL_ATTRIBUTE_PURE
404 hex_digits (unsigned char const *s)
406 unsigned int i;
407 for (i = 0; i < digest_hex_bytes; i++)
409 if (!isxdigit (*s))
410 return false;
411 ++s;
413 return *s == '\0';
416 /* An interface to the function, DIGEST_STREAM.
417 Operate on FILENAME (it may be "-").
419 *BINARY indicates whether the file is binary. BINARY < 0 means it
420 depends on whether binary mode makes any difference and the file is
421 a terminal; in that case, clear *BINARY if the file was treated as
422 text because it was a terminal.
424 Put the checksum in *BIN_RESULT, which must be properly aligned.
425 Return true if successful. */
427 static bool
428 digest_file (const char *filename, int *binary, unsigned char *bin_result)
430 FILE *fp;
431 int err;
432 bool is_stdin = STREQ (filename, "-");
434 if (is_stdin)
436 have_read_stdin = true;
437 fp = stdin;
438 if (O_BINARY && *binary)
440 if (*binary < 0)
441 *binary = ! isatty (STDIN_FILENO);
442 if (*binary)
443 xfreopen (NULL, "rb", stdin);
446 else
448 fp = fopen (filename, (O_BINARY && *binary ? "rb" : "r"));
449 if (fp == NULL)
451 error (0, errno, "%s", filename);
452 return false;
456 fadvise (fp, FADVISE_SEQUENTIAL);
458 err = DIGEST_STREAM (fp, bin_result);
459 if (err)
461 error (0, errno, "%s", filename);
462 if (fp != stdin)
463 fclose (fp);
464 return false;
467 if (!is_stdin && fclose (fp) != 0)
469 error (0, errno, "%s", filename);
470 return false;
473 return true;
476 static bool
477 digest_check (const char *checkfile_name)
479 FILE *checkfile_stream;
480 uintmax_t n_misformatted_lines = 0;
481 uintmax_t n_properly_formatted_lines = 0;
482 uintmax_t n_improperly_formatted_lines = 0;
483 uintmax_t n_mismatched_checksums = 0;
484 uintmax_t n_open_or_read_failures = 0;
485 unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];
486 /* Make sure bin_buffer is properly aligned. */
487 unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN);
488 uintmax_t line_number;
489 char *line;
490 size_t line_chars_allocated;
491 bool is_stdin = STREQ (checkfile_name, "-");
493 if (is_stdin)
495 have_read_stdin = true;
496 checkfile_name = _("standard input");
497 checkfile_stream = stdin;
499 else
501 checkfile_stream = fopen (checkfile_name, "r");
502 if (checkfile_stream == NULL)
504 error (0, errno, "%s", checkfile_name);
505 return false;
509 line_number = 0;
510 line = NULL;
511 line_chars_allocated = 0;
514 char *filename IF_LINT ( = NULL);
515 int binary;
516 unsigned char *hex_digest IF_LINT ( = NULL);
517 ssize_t line_length;
519 ++line_number;
520 if (line_number == 0)
521 error (EXIT_FAILURE, 0, _("%s: too many checksum lines"),
522 checkfile_name);
524 line_length = getline (&line, &line_chars_allocated, checkfile_stream);
525 if (line_length <= 0)
526 break;
528 /* Ignore comment lines, which begin with a '#' character. */
529 if (line[0] == '#')
530 continue;
532 /* Remove any trailing newline. */
533 if (line[line_length - 1] == '\n')
534 line[--line_length] = '\0';
536 if (! (split_3 (line, line_length, &hex_digest, &binary, &filename)
537 && ! (is_stdin && STREQ (filename, "-"))
538 && hex_digits (hex_digest)))
540 ++n_misformatted_lines;
542 if (warn)
544 error (0, 0,
545 _("%s: %" PRIuMAX
546 ": improperly formatted %s checksum line"),
547 checkfile_name, line_number,
548 DIGEST_TYPE_STRING);
551 ++n_improperly_formatted_lines;
553 else
555 static const char bin2hex[] = { '0', '1', '2', '3',
556 '4', '5', '6', '7',
557 '8', '9', 'a', 'b',
558 'c', 'd', 'e', 'f' };
559 bool ok;
561 ++n_properly_formatted_lines;
563 ok = digest_file (filename, &binary, bin_buffer);
565 if (!ok)
567 ++n_open_or_read_failures;
568 if (!status_only)
570 printf (_("%s: FAILED open or read\n"), filename);
573 else
575 size_t digest_bin_bytes = digest_hex_bytes / 2;
576 size_t cnt;
577 /* Compare generated binary number with text representation
578 in check file. Ignore case of hex digits. */
579 for (cnt = 0; cnt < digest_bin_bytes; ++cnt)
581 if (tolower (hex_digest[2 * cnt])
582 != bin2hex[bin_buffer[cnt] >> 4]
583 || (tolower (hex_digest[2 * cnt + 1])
584 != (bin2hex[bin_buffer[cnt] & 0xf])))
585 break;
587 if (cnt != digest_bin_bytes)
588 ++n_mismatched_checksums;
590 if (!status_only)
592 if (cnt != digest_bin_bytes)
593 printf ("%s: %s\n", filename, _("FAILED"));
594 else if (!quiet)
595 printf ("%s: %s\n", filename, _("OK"));
600 while (!feof (checkfile_stream) && !ferror (checkfile_stream));
602 free (line);
604 if (ferror (checkfile_stream))
606 error (0, 0, _("%s: read error"), checkfile_name);
607 return false;
610 if (!is_stdin && fclose (checkfile_stream) != 0)
612 error (0, errno, "%s", checkfile_name);
613 return false;
616 if (n_properly_formatted_lines == 0)
618 /* Warn if no tests are found. */
619 error (0, 0, _("%s: no properly formatted %s checksum lines found"),
620 checkfile_name, DIGEST_TYPE_STRING);
622 else
624 if (!status_only)
626 if (n_misformatted_lines != 0)
627 error (0, 0,
628 (ngettext
629 ("WARNING: %" PRIuMAX " line is improperly formatted",
630 "WARNING: %" PRIuMAX " lines are improperly formatted",
631 select_plural (n_misformatted_lines))),
632 n_misformatted_lines);
634 if (n_open_or_read_failures != 0)
635 error (0, 0,
636 (ngettext
637 ("WARNING: %" PRIuMAX " listed file could not be read",
638 "WARNING: %" PRIuMAX " listed files could not be read",
639 select_plural (n_open_or_read_failures))),
640 n_open_or_read_failures);
642 if (n_mismatched_checksums != 0)
643 error (0, 0,
644 (ngettext
645 ("WARNING: %" PRIuMAX " computed checksum did NOT match",
646 "WARNING: %" PRIuMAX " computed checksums did NOT match",
647 select_plural (n_mismatched_checksums))),
648 n_mismatched_checksums);
652 return (n_properly_formatted_lines != 0
653 && n_mismatched_checksums == 0
654 && n_open_or_read_failures == 0
655 && (!strict || n_improperly_formatted_lines == 0));
658 /* If ESCAPE is true, then translate each NEWLINE byte to the string, "\\n",
659 and each backslash to "\\\\". */
660 static void
661 print_filename (char const *file, bool escape)
663 if (! escape)
665 fputs (file, stdout);
666 return;
669 while (*file)
671 switch (*file)
673 case '\n':
674 fputs ("\\n", stdout);
675 break;
677 case '\\':
678 fputs ("\\\\", stdout);
679 break;
681 default:
682 putchar (*file);
683 break;
685 file++;
690 main (int argc, char **argv)
692 unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];
693 /* Make sure bin_buffer is properly aligned. */
694 unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN);
695 bool do_check = false;
696 int opt;
697 bool ok = true;
698 int binary = -1;
699 bool prefix_tag = false;
701 /* Setting values of global variables. */
702 initialize_main (&argc, &argv);
703 set_program_name (argv[0]);
704 setlocale (LC_ALL, "");
705 bindtextdomain (PACKAGE, LOCALEDIR);
706 textdomain (PACKAGE);
708 atexit (close_stdout);
710 /* Line buffer stdout to ensure lines are written atomically and immediately
711 so that processes running in parallel do not intersperse their output. */
712 setvbuf (stdout, NULL, _IOLBF, 0);
714 while ((opt = getopt_long (argc, argv, "bctw", long_options, NULL)) != -1)
715 switch (opt)
717 case 'b':
718 binary = 1;
719 break;
720 case 'c':
721 do_check = true;
722 break;
723 case STATUS_OPTION:
724 status_only = true;
725 warn = false;
726 quiet = false;
727 break;
728 case 't':
729 binary = 0;
730 break;
731 case 'w':
732 status_only = false;
733 warn = true;
734 quiet = false;
735 break;
736 case QUIET_OPTION:
737 status_only = false;
738 warn = false;
739 quiet = true;
740 break;
741 case STRICT_OPTION:
742 strict = true;
743 break;
744 case TAG_OPTION:
745 prefix_tag = true;
746 binary = 1;
747 break;
748 case_GETOPT_HELP_CHAR;
749 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
750 default:
751 usage (EXIT_FAILURE);
754 min_digest_line_length = MIN_DIGEST_LINE_LENGTH;
755 digest_hex_bytes = DIGEST_HEX_BYTES;
757 if (prefix_tag && !binary)
759 /* This could be supported in a backwards compatible way
760 by prefixing the output line with a space in text mode.
761 However that's invasive enough that it was agreed to
762 not support this mode with --tag, as --text use cases
763 are adequately supported by the default output format. */
764 error (0, 0, _("--tag does not support --text mode"));
765 usage (EXIT_FAILURE);
768 if (prefix_tag && do_check)
770 error (0, 0, _("the --tag option is meaningless when "
771 "verifying checksums"));
772 usage (EXIT_FAILURE);
775 if (0 <= binary && do_check)
777 error (0, 0, _("the --binary and --text options are meaningless when "
778 "verifying checksums"));
779 usage (EXIT_FAILURE);
782 if (status_only && !do_check)
784 error (0, 0,
785 _("the --status option is meaningful only when verifying checksums"));
786 usage (EXIT_FAILURE);
789 if (warn && !do_check)
791 error (0, 0,
792 _("the --warn option is meaningful only when verifying checksums"));
793 usage (EXIT_FAILURE);
796 if (quiet && !do_check)
798 error (0, 0,
799 _("the --quiet option is meaningful only when verifying checksums"));
800 usage (EXIT_FAILURE);
803 if (strict & !do_check)
805 error (0, 0,
806 _("the --strict option is meaningful only when verifying checksums"));
807 usage (EXIT_FAILURE);
810 if (!O_BINARY && binary < 0)
811 binary = 0;
813 if (optind == argc)
814 argv[argc++] = bad_cast ("-");
816 for (; optind < argc; ++optind)
818 char *file = argv[optind];
820 if (do_check)
821 ok &= digest_check (file);
822 else
824 int file_is_binary = binary;
826 if (! digest_file (file, &file_is_binary, bin_buffer))
827 ok = false;
828 else
830 /* We don't really need to escape, and hence detect, the '\\'
831 char, and not doing so should be both forwards and backwards
832 compatible, since only escaped lines would have a '\\' char at
833 the start. However just in case users are directly comparing
834 against old (hashed) outputs, in the presence of files
835 containing '\\' characters, we decided to not simplify the
836 output in this case. */
837 bool needs_escape = strchr (file, '\\') || strchr (file, '\n');
839 if (prefix_tag)
841 if (needs_escape)
842 putchar ('\\');
844 fputs (DIGEST_TYPE_STRING, stdout);
845 fputs (" (", stdout);
846 print_filename (file, needs_escape);
847 fputs (") = ", stdout);
850 size_t i;
852 /* Output a leading backslash if the file name contains
853 a newline or backslash. */
854 if (!prefix_tag && needs_escape)
855 putchar ('\\');
857 for (i = 0; i < (digest_hex_bytes / 2); ++i)
858 printf ("%02x", bin_buffer[i]);
860 if (!prefix_tag)
862 putchar (' ');
864 putchar (file_is_binary ? '*' : ' ');
866 print_filename (file, needs_escape);
869 putchar ('\n');
874 if (have_read_stdin && fclose (stdin) == EOF)
875 error (EXIT_FAILURE, errno, _("standard input"));
877 exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);