summaryrefslogtreecommitdiff
path: root/src/md5sum.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1995-07-27 03:45:11 +0000
committerJim Meyering <jim@meyering.net>1995-07-27 03:45:11 +0000
commit28e28e6d749747b1b77878d31308c665195283ca (patch)
treeac2a6392feca58c7f1ee0c1236c3e8bbd1093048 /src/md5sum.c
parent7732d5d7cfd6326e5457953a25ba447034d7ff14 (diff)
downloadcoreutils-28e28e6d749747b1b77878d31308c665195283ca.tar.xz
(have_read_stdin): New global variable.
(md5_file, md5_check): Set it. (main): Use it. [OPENOPTS]: Depend explicitly on BINARY. (md5_file): Take a new parameter, MD5_RESULT, and no longer generate output. (md5_check): Invoke md5_file instead of calling fopen directly. When giving a diagnostic for a line with invalid format, also report the line number. (main): Generate output after a successful md5_file call. [in many places]: Upon detection of an error, rather than exiting immediately, issue a diagnostic, note that an error occurred and exit later.
Diffstat (limited to 'src/md5sum.c')
-rw-r--r--src/md5sum.c138
1 files changed, 84 insertions, 54 deletions
diff --git a/src/md5sum.c b/src/md5sum.c
index 88f4a54f3..24a3e2ca7 100644
--- a/src/md5sum.c
+++ b/src/md5sum.c
@@ -34,7 +34,7 @@
/* Most systems do not distinguish between external and internal
text representations. */
#if UNIX || __UNIX__ || unix || __unix__ || _POSIX_VERSION
-# define OPENOPTS "r"
+# define OPENOPTS(BINARY) "r"
#else
# ifdef MSDOS
# define TEXT1TO1 "rb"
@@ -49,7 +49,7 @@
"Cannot determine system type."
# endif
# endif
-# define OPENOPTS (binary != 0 ? TEXT1TO1 : TEXTCNVT)
+# define OPENOPTS(BINARY) ((BINARY) != 0 ? TEXT1TO1 : TEXTCNVT)
#endif
#undef __P
@@ -68,12 +68,15 @@
/* Hook for i18n. */
#define _(str) str
-/* FIXME: comment. */
-static int verbose = 0;
+/* Nonzero if any of the files read were the standard input. */
+static int have_read_stdin;
/* FIXME: comment. */
static int quiet = 0;
+/* FIXME: comment. */
+static int verbose = 0;
+
/* The name this program was run with. */
char *program_name;
@@ -189,33 +192,39 @@ hex_digits (s)
/* FIXME: allow newline in filename by encoding it. */
static int
-md5_file (filename, binary)
+md5_file (filename, binary, md5_result)
const char *filename;
int binary;
+ unsigned char *md5_result;
{
- unsigned char md5buffer[16];
FILE *fp;
- size_t i;
int err;
if (strcmp (filename, "-") == 0)
- fp = stdin;
+ {
+ have_read_stdin = 1;
+ fp = stdin;
+ }
else
{
/* OPENOPTS is a macro. It varies with the system.
Some systems distinguish between internal and
external text representations. */
- fp = fopen (filename, OPENOPTS);
+ fp = fopen (filename, OPENOPTS (binary));
if (fp == NULL)
- error (EXIT_FAILURE, errno, "%s", filename);
+ {
+ error (0, errno, "%s", filename);
+ return 1;
+ }
}
- err = md5_stream (fp, md5buffer);
+ err = md5_stream (fp, md5_result);
if (err)
{
error (0, errno, "%s", filename);
- fclose (fp);
+ if (fp != stdin)
+ fclose (fp);
return 1;
}
@@ -225,24 +234,23 @@ md5_file (filename, binary)
return 1;
}
- for (i = 0; i < 16; ++i)
- printf ("%02x", md5buffer[i]);
-
- printf (" %c%s\n", binary ? '*' : ' ', filename);
return 0;
}
static int
-md5_check (checkfile_name)
+md5_check (checkfile_name, binary)
const char *checkfile_name;
+ int binary;
{
FILE *checkfile_stream;
int n_tests = 0;
int n_tests_failed = 0;
unsigned char md5buffer[16];
+ size_t line_number;
if (strcmp (checkfile_name, "-") == 0)
{
+ have_read_stdin = 1;
checkfile_name = "standard input";
checkfile_stream = stdin;
}
@@ -250,12 +258,13 @@ md5_check (checkfile_name)
{
checkfile_stream = fopen (checkfile_name, "r");
if (checkfile_stream == NULL)
- if (quiet)
- exit (EXIT_FAILURE);
- else
- error (EXIT_FAILURE, errno, "%s", checkfile_name);
+ {
+ error (0, errno, "%s", checkfile_name);
+ return 1;
+ }
}
+ line_number = 0;
do
{
char line[1024];
@@ -264,6 +273,8 @@ md5_check (checkfile_name)
char *md5num;
int err;
+ ++line_number;
+
/* FIXME: Use getline, not fgets. */
if (fgets (line, 1024, checkfile_stream) == NULL)
break;
@@ -279,9 +290,12 @@ md5_check (checkfile_name)
err = split_3 (line, &md5num, &type_flag, &filename);
if (err || !hex_digits (md5num))
{
- /* FIXME: report file name and line number. */
if (verbose)
- error (0, 0, _("invalid line in check file: %s"), line);
+ {
+ /* FIXME: use fprintf rather than error? */
+ error (0, 0, _("%s: %lu: invalid MD5 checksum line"),
+ checkfile_name, (unsigned long) line_number);
+ }
}
else
{
@@ -289,46 +303,45 @@ md5_check (checkfile_name)
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f' };
- size_t cnt;
- FILE *fp;
-
- if (strcmp (filename, "-") == 0)
- fp = stdin;
- else
- {
- fp = fopen (filename, OPENOPTS);
- if (fp == NULL)
- error (EXIT_FAILURE, errno, "%s", filename);
- }
+ int fail;
++n_tests;
- md5_stream (fp, md5buffer);
- if (fp != stdin && fclose (fp) == EOF)
- error (EXIT_FAILURE, errno, "%s", filename);
+ fail = md5_file (filename, binary, md5buffer);
- /* Compare generated binary number with text representation
- in check file. Ignore case of hex digits. */
- for (cnt = 0; cnt < 16; ++cnt)
- if (TOLOWER (md5num[2 * cnt]) != bin2hex[md5buffer[cnt] >> 4]
- || TOLOWER (md5num[2 * cnt + 1])
- != (bin2hex[md5buffer[cnt] & 0xf]))
- break;
+ if (!fail)
+ {
+ size_t cnt;
+ /* Compare generated binary number with text representation
+ in check file. Ignore case of hex digits. */
+ for (cnt = 0; cnt < 16; ++cnt)
+ {
+ if (TOLOWER (md5num[2 * cnt]) != bin2hex[md5buffer[cnt] >> 4]
+ || (TOLOWER (md5num[2 * cnt + 1])
+ != (bin2hex[md5buffer[cnt] & 0xf])))
+ break;
+ }
+ if (cnt != 16)
+ fail = 1;
+ }
- if (cnt != 16)
+ if (fail)
++n_tests_failed;
+
if (!quiet)
{
- printf ("%s: %s\n", filename,
- (cnt == 16 ? _("OK") : _("FAILED")));
+ printf ("%s: %s\n", filename, (fail ? _("FAILED") : _("OK")));
fflush (stdout);
}
}
}
- while (!feof (checkfile_stream));
+ while (!feof (checkfile_stream) && !ferror (checkfile_stream));
- if (fclose (checkfile_stream) == EOF)
- error (EXIT_FAILURE, errno, "%s", checkfile_name);
+ if (checkfile_stream != stdin && fclose (checkfile_stream) == EOF)
+ {
+ error (0, errno, "%s", checkfile_name);
+ return 1;
+ }
if (!quiet)
printf (n_tests == 1 ? (n_tests_failed ? _("Test failed\n")
@@ -346,7 +359,6 @@ main (argc, argv)
char *argv[];
{
unsigned char md5buffer[16];
- int binary = 0; /* Text is default of the Plumb/Lankester format. */
int do_check = 0;
int do_help = 0;
int do_version = 0;
@@ -356,6 +368,10 @@ main (argc, argv)
size_t i;
size_t err = 0;
+ /* FIXME: comment. */
+ /* Text is default of the Plumb/Lankester format. */
+ int binary = 0;
+
/* Setting values of global variables. */
program_name = argv[0];
@@ -446,7 +462,18 @@ main (argc, argv)
for (; optind < argc; ++optind)
{
- err |= md5_file (argv[optind], binary);
+ size_t i;
+ int fail;
+
+ fail = md5_file (argv[optind], binary, md5buffer);
+ err |= fail;
+ if (!fail)
+ {
+ for (i = 0; i < 16; ++i)
+ printf ("%02x", md5buffer[i]);
+
+ printf (" %c%s\n", binary ? '*' : ' ', argv[optind]);
+ }
}
}
else
@@ -458,11 +485,14 @@ main (argc, argv)
usage (EXIT_FAILURE);
}
- err = md5_check (optind == argc ? "-" : argv[optind]);
+ err = md5_check (optind == argc ? "-" : argv[optind], binary);
}
if (fclose (stdout) == EOF)
- error (EXIT_FAILURE, errno, _("standard output"));
+ error (EXIT_FAILURE, errno, _("write error"));
+
+ if (have_read_stdin && fclose (stdin) == EOF)
+ error (EXIT_FAILURE, errno, _("standard input"));
exit (err == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}