From ad6c8e1181a3966e35d68c1c354deb1c73f3e974 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?=
Date: Mon, 6 Sep 2021 15:17:12 +0100
Subject: [PATCH] cksum: add --algorithm option to select digest mode
* src/digest.c: Organize HASH_ALGO_CKSUM to be table driven,
and amalgamate all digest algorithms.
(main): Parse all options if HASH_ALGO_CKSUM, and disallow
--tag, --zero, and --check with the traditional bsd, sysv, and crc
checksums for now.
* src/local.mk: Reorganize to include all digest modules in cksum.
* tests/misc/cksum-a.sh: Add a new test.
* tests/misc/b2sum.sh: Update to default to checking with cksum,
as b2sum's implementation diverges a bit from the others.
* tests/local.mk: Reference the new test.
* doc/coreutils.texi (cksum invocation): Adjust the summary to
identify the new mode, and document the new --algorithm option.
* man/cksum.x: Adjust description to be more general.
* man/*sum.x: Add [See Also] section referencing cksum(1).
* NEWS: Mention the new feature.
---
NEWS | 7 +-
doc/coreutils.texi | 59 ++++++---
man/b2sum.x | 2 +
man/cksum.x | 2 +-
man/md5sum.x | 2 +
man/sha1sum.x | 2 +
man/sha224sum.x | 2 +
man/sha256sum.x | 2 +
man/sha384sum.x | 2 +
man/sha512sum.x | 2 +
src/digest.c | 302 +++++++++++++++++++++++++++++++++++-------
src/local.mk | 27 ++--
tests/local.mk | 1 +
tests/misc/b2sum.sh | 27 ++--
tests/misc/cksum-a.sh | 43 ++++++
15 files changed, 395 insertions(+), 87 deletions(-)
create mode 100755 tests/misc/cksum-a.sh
diff --git a/NEWS b/NEWS
index d9ab04529a..1db2bd0707 100644
--- a/NEWS
+++ b/NEWS
@@ -88,6 +88,11 @@ GNU coreutils NEWS -*- outline -*-
** New Features
+ cksum now supports the -a (--algorithm) option to select any
+ of the existing sum, md5sum, b2sum, sha*sum implementations etc.
+ cksum now subsumes all of these programs, and coreutils
+ will introduce no future standalone checksum utility.
+
expr and factor now support bignums on all platforms.
ls --classify now supports the "always", "auto", or "never" flags,
@@ -110,7 +115,7 @@ GNU coreutils NEWS -*- outline -*-
cat --show-ends will now show \r\n as ^M$. Previously the \r was taken
literally, thus overwriting the first character in the line with '$'.
- cksum is now up to 4 times faster by using a slice by 8 algorithm,
+ cksum [-a crc] is now up to 4 times faster by using a slice by 8 algorithm,
and at least 8 times faster where pclmul instructions are supported.
A new --debug option will indicate if pclmul is being used.
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 960df8a355..0cb478964e 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -3922,44 +3922,71 @@ next section) is preferable in new applications.
@node cksum invocation
-@section @command{cksum}: Print CRC checksum and byte counts
+@section @command{cksum}: Print and verify file checksums
@pindex cksum
@cindex cyclic redundancy check
@cindex CRC checksum
+@cindex digest
-@command{cksum} computes a cyclic redundancy check (CRC) checksum for each
-given @var{file}, or standard input if none are given or for a
-@var{file} of @samp{-}. Synopsis:
+@command{cksum} by default computes a cyclic redundancy check (CRC) checksum
+for each given @var{file}, or standard input if none are given or for a
+@var{file} of @samp{-}.
+
+cksum also supports the @option{-a,--algorithm} option to select the
+digest algorithm to use, and this is the preferred interface
+to these digests, subsuming the other standalone checksumming utilities.
+Synopsis:
@example
cksum [@var{option}]@dots{} [@var{file}]@dots{}
@end example
-@command{cksum} prints the CRC checksum for each file along with the number
-of bytes in the file, and the file name unless no arguments were given.
-
-@command{cksum} is typically used to ensure that files
-transferred by unreliable means (e.g., netnews) have not been corrupted,
+@command{cksum} is typically used to ensure that files have not been corrupted,
by comparing the @command{cksum} output for the received files with the
@command{cksum} output for the original files (typically given in the
distribution).
-The CRC algorithm is specified by the POSIX standard. It is not
-compatible with the BSD or System V @command{sum} algorithms (see the
-previous section); it is more robust.
+@command{cksum} by default prints the POSIX standard CRC checksum
+for each file along with the number of bytes in the file,
+and the file name unless no arguments were given.
-The program accepts the following options. Also see @ref{Common options}.
+The same usage and options as the @command{b2sum}
+command are supported. @xref{b2sum invocation}.
+In addition @command{cksum} supports the following options.
@table @samp
+@item -a
+@itemx --algorithm
+@opindex -a
+@opindex --algorithm
+@cindex digest algorithm
+Compute checksums using the specified digest algorithm.
+
+Supported legacy checksums (which are not supported by @option{--check}):
+@example
+@samp{sysv} equivalent to @command{sum -s}
+@samp{bsd} equivalent to @command{sum -r}
+@samp{crc} equivalent to @command{cksum} (the default)
+@end example
+
+Supported more modern digest algorithms are:
+@example
+@samp{md5} equivalent to @command{md5sum}
+@samp{sha1} equivalent to @command{sha1sum}
+@samp{sha224} equivalent to @command{sha224sum}
+@samp{sha256} equivalent to @command{sha256sum}
+@samp{sha384} equivalent to @command{sha384sum}
+@samp{sha512} equivalent to @command{sha512sum}
+@samp{blake2b} equivalent to @command{b2sum}
+@end example
+
@item --debug
@opindex --debug
Output extra information to stderr, like the checksum implementation being used.
@end table
-@exitstatus
-
@node b2sum invocation
@section @command{b2sum}: Print or check BLAKE2 digests
@@ -4078,6 +4105,8 @@ If any listed file cannot be opened or read, if any valid line has
an MD5 checksum inconsistent with the associated file, or if no valid
line is found, @command{md5sum} exits with nonzero status. Otherwise,
it exits successfully.
+Note the @command{cksum} command doesn't support @option{--check}
+with the older @samp{sysv}, @samp{bsd}, or @samp{crc} algorithms.
@item --ignore-missing
@opindex --ignore-missing
diff --git a/man/b2sum.x b/man/b2sum.x
index 3ba490aeed..5a857ca156 100644
--- a/man/b2sum.x
+++ b/man/b2sum.x
@@ -2,3 +2,5 @@
b2sum \- compute and check BLAKE2 message digest
[DESCRIPTION]
.\" Add any additional description here
+[SEE ALSO]
+cksum(1)
diff --git a/man/cksum.x b/man/cksum.x
index b70a5c46b8..28f954c53c 100644
--- a/man/cksum.x
+++ b/man/cksum.x
@@ -1,4 +1,4 @@
[NAME]
-cksum \- checksum and count the bytes in a file
+cksum \- compute and verify file checksums
[DESCRIPTION]
.\" Add any additional description here
diff --git a/man/md5sum.x b/man/md5sum.x
index bdb6cc7653..3f4cc6409a 100644
--- a/man/md5sum.x
+++ b/man/md5sum.x
@@ -7,3 +7,5 @@ Do not use the MD5 algorithm for security related purposes.
Instead, use an SHA\-2 algorithm, implemented in the programs
sha224sum(1), sha256sum(1), sha384sum(1), sha512sum(1),
or the BLAKE2 algorithm, implemented in b2sum(1)
+[SEE ALSO]
+cksum(1)
diff --git a/man/sha1sum.x b/man/sha1sum.x
index ef0852f4d1..8fd824f109 100644
--- a/man/sha1sum.x
+++ b/man/sha1sum.x
@@ -7,3 +7,5 @@ Do not use the SHA-1 algorithm for security related purposes.
Instead, use an SHA\-2 algorithm, implemented in the programs
sha224sum(1), sha256sum(1), sha384sum(1), sha512sum(1),
or the BLAKE2 algorithm, implemented in b2sum(1)
+[SEE ALSO]
+cksum(1)
diff --git a/man/sha224sum.x b/man/sha224sum.x
index 8e010a8f06..38a64d29c5 100644
--- a/man/sha224sum.x
+++ b/man/sha224sum.x
@@ -2,3 +2,5 @@
sha224sum \- compute and check SHA224 message digest
[DESCRIPTION]
.\" Add any additional description here
+[SEE ALSO]
+cksum(1)
diff --git a/man/sha256sum.x b/man/sha256sum.x
index a6cfa36c32..4ad8b35085 100644
--- a/man/sha256sum.x
+++ b/man/sha256sum.x
@@ -2,3 +2,5 @@
sha256sum \- compute and check SHA256 message digest
[DESCRIPTION]
.\" Add any additional description here
+[SEE ALSO]
+cksum(1)
diff --git a/man/sha384sum.x b/man/sha384sum.x
index 87a5a0092e..a8c09cd62c 100644
--- a/man/sha384sum.x
+++ b/man/sha384sum.x
@@ -2,3 +2,5 @@
sha384sum \- compute and check SHA384 message digest
[DESCRIPTION]
.\" Add any additional description here
+[SEE ALSO]
+cksum(1)
diff --git a/man/sha512sum.x b/man/sha512sum.x
index b38b6b4647..308bf51eec 100644
--- a/man/sha512sum.x
+++ b/man/sha512sum.x
@@ -2,3 +2,5 @@
sha512sum \- compute and check SHA512 message digest
[DESCRIPTION]
.\" Add any additional description here
+[SEE ALSO]
+cksum(1)
diff --git a/src/digest.c b/src/digest.c
index 6a48bfddcb..8039c671e7 100644
--- a/src/digest.c
+++ b/src/digest.c
@@ -27,25 +27,25 @@
#include "xdectoint.h"
#include "xstrtol.h"
-#if HASH_ALGO_SUM
+#if HASH_ALGO_SUM || HASH_ALGO_CKSUM
# include "sum.h"
#endif
#if HASH_ALGO_CKSUM
# include "cksum.h"
#endif
-#if HASH_ALGO_BLAKE2
+#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
# include "blake2/b2sum.h"
#endif
-#if HASH_ALGO_MD5
+#if HASH_ALGO_MD5 || HASH_ALGO_CKSUM
# include "md5.h"
#endif
-#if HASH_ALGO_SHA1
+#if HASH_ALGO_SHA1 || HASH_ALGO_CKSUM
# include "sha1.h"
#endif
-#if HASH_ALGO_SHA256 || HASH_ALGO_SHA224
+#if HASH_ALGO_SHA256 || HASH_ALGO_SHA224 || HASH_ALGO_CKSUM
# include "sha256.h"
#endif
-#if HASH_ALGO_SHA512 || HASH_ALGO_SHA384
+#if HASH_ALGO_SHA512 || HASH_ALGO_SHA384 || HASH_ALGO_CKSUM
# include "sha512.h"
#endif
#include "die.h"
@@ -63,12 +63,14 @@
# define DIGEST_BITS 16
# define DIGEST_ALIGN 4
#elif HASH_ALGO_CKSUM
+# define MAX_DIGEST_BITS 512
+# define MAX_DIGEST_ALIGN 8
# define PROGRAM_NAME "cksum"
-# define DIGEST_TYPE_STRING "CRC"
-# define DIGEST_STREAM crc_sum_stream
-# define DIGEST_OUT output_crc
-# define DIGEST_BITS 32
-# define DIGEST_ALIGN 4
+# define DIGEST_TYPE_STRING algorithm_tags[cksum_algorithm]
+# define DIGEST_STREAM cksumfns[cksum_algorithm]
+# define DIGEST_OUT cksum_output_fns[cksum_algorithm]
+# define DIGEST_BITS MAX_DIGEST_BITS
+# define DIGEST_ALIGN MAX_DIGEST_ALIGN
#elif HASH_ALGO_MD5
# define PROGRAM_NAME "md5sum"
# define DIGEST_TYPE_STRING "MD5"
@@ -79,7 +81,7 @@
#elif HASH_ALGO_BLAKE2
# define PROGRAM_NAME "b2sum"
# define DIGEST_TYPE_STRING "BLAKE2"
-# define DIGEST_STREAM blake2fns[b2_algorithm]
+# define DIGEST_STREAM blake2b_stream
# define DIGEST_BITS 512
# define DIGEST_REFERENCE "RFC 7693"
# define DIGEST_ALIGN 8
@@ -141,15 +143,14 @@
proper_name ("Scott Miller"), \
proper_name ("David Madore")
#endif
-#if !HASH_ALGO_BLAKE2
+#if !HASH_ALGO_BLAKE2 && !HASH_ALGO_CKSUM
# define DIGEST_HEX_BYTES (DIGEST_BITS / 4)
#endif
#define DIGEST_BIN_BYTES (DIGEST_BITS / 8)
-
/* 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
+#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
# define MIN_DIGEST_LINE_LENGTH 3 /* With -l 8. */
#else
# define MIN_DIGEST_LINE_LENGTH \
@@ -158,6 +159,12 @@
+ 1 /* minimum filename length */ )
#endif
+#if !HASH_ALGO_SUM
+static void
+output_file (char const *file, int binary_file, void const *digest,
+ bool tagged, bool args _GL_UNUSED, uintmax_t length _GL_UNUSED);
+#endif
+
/* True if any of the files read were the standard input. */
static bool have_read_stdin;
@@ -191,7 +198,7 @@ static int bsd_reversed = -1;
/* line delimiter. */
static unsigned char delim = '\n';
-#if HASH_ALGO_BLAKE2
+#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
static char const *const algorithm_in_string[] =
{
"blake2b", NULL
@@ -200,19 +207,15 @@ static char const *const algorithm_out_string[] =
{
"BLAKE2b", NULL
};
-enum Algorithm
+enum blake2_Algorithm
{
BLAKE2b
};
verify (ARRAY_CARDINALITY (algorithm_in_string) == 2);
verify (ARRAY_CARDINALITY (algorithm_out_string) == 2);
-static enum Algorithm b2_algorithm;
+static enum blake2_Algorithm b2_algorithm;
static uintmax_t b2_length;
-static blake2fn blake2fns[]=
-{
- blake2b_stream
-};
static uintmax_t blake2_max_len[]=
{
BLAKE2B_OUTBYTES
@@ -242,6 +245,109 @@ static digest_output_fn sum_output_fns[]=
#endif
#if HASH_ALGO_CKSUM
+static int
+md5_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
+{
+ return md5_stream (stream, resstream);
+}
+static int
+sha1_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
+{
+ return sha1_stream (stream, resstream);
+}
+static int
+sha224_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
+{
+ return sha224_stream (stream, resstream);
+}
+static int
+sha256_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
+{
+ return sha256_stream (stream, resstream);
+}
+static int
+sha384_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
+{
+ return sha384_stream (stream, resstream);
+}
+static int
+sha512_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
+{
+ return sha512_stream (stream, resstream);
+}
+static int
+blake2b_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
+{
+ return blake2b_stream (stream, resstream, *length);
+}
+
+enum Algorithm
+{
+ bsd,
+ sysv,
+ crc,
+ md5,
+ sha1,
+ sha224,
+ sha256,
+ sha384,
+ sha512,
+ blake2b,
+};
+
+static char const *const algorithm_args[] =
+{
+ "bsd", "sysv", "crc", "md5", "sha1", "sha224",
+ "sha256", "sha384", "sha512", "blake2b", NULL
+};
+static enum Algorithm const algorithm_types[] =
+{
+ bsd, sysv, crc, md5, sha1, sha224,
+ sha256, sha384, sha512, blake2b,
+};
+ARGMATCH_VERIFY (algorithm_args, algorithm_types);
+
+static char const *const algorithm_tags[] =
+{
+ "BSD", "SYSV", "CRC", "MD5", "SHA1", "SHA224",
+ "SHA256", "SHA384", "SHA512", "BLAKE2b", NULL
+};
+static int const algorithm_bits[] =
+{
+ 16, 16, 32, 128, 160, 224,
+ 256, 384, 512, 512, 0
+};
+
+verify (ARRAY_CARDINALITY (algorithm_bits)
+ == ARRAY_CARDINALITY (algorithm_args));
+
+static enum Algorithm cksum_algorithm = crc;
+static sumfn cksumfns[]=
+{
+ bsd_sum_stream,
+ sysv_sum_stream,
+ crc_sum_stream,
+ md5_sum_stream,
+ sha1_sum_stream,
+ sha224_sum_stream,
+ sha256_sum_stream,
+ sha384_sum_stream,
+ sha512_sum_stream,
+ blake2b_sum_stream,
+};
+static digest_output_fn cksum_output_fns[]=
+{
+ output_bsd,
+ output_sysv,
+ output_crc,
+ output_file,
+ output_file,
+ output_file,
+ output_file,
+ output_file,
+ output_file,
+ output_file,
+};
bool cksum_debug;
#endif
@@ -260,10 +366,10 @@ enum
static struct option const long_options[] =
{
-#if HASH_ALGO_BLAKE2
+#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
{ "length", required_argument, NULL, 'l'},
#endif
-#if !HASH_AGLO_SUM && !HASH_ALGO_CKSUM
+#if !HASH_ALGO_SUM
{ "binary", no_argument, NULL, 'b' },
{ "check", no_argument, NULL, 'c' },
{ "ignore-missing", no_argument, NULL, IGNORE_MISSING_OPTION},
@@ -276,6 +382,7 @@ static struct option const long_options[] =
{ "zero", no_argument, NULL, 'z' },
#endif
#if HASH_ALGO_CKSUM
+ {"algorithm", required_argument, NULL, 'a'},
{"debug", no_argument, NULL, DEBUG_PROGRAM_OPTION},
#endif
#if HASH_ALGO_SUM
@@ -295,11 +402,19 @@ usage (int status)
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
+"), program_name);
+#if HASH_ALGO_CKSUM
+ fputs (_("\
+Print or verify checksums.\n\
+By default use the 32 bit CRC algorithm.\n\
+"), stdout);
+#else
+ printf (_("\
Print or check %s (%d-bit) checksums.\n\
"),
- program_name,
DIGEST_TYPE_STRING,
DIGEST_BITS);
+#endif
emit_stdin_note ();
#if HASH_ALGO_SUM
@@ -309,22 +424,27 @@ Print or check %s (%d-bit) checksums.\n\
-s, --sysv use System V sum algorithm, use 512 bytes blocks\n\
"), stdout);
#endif
-#if !HASH_ALGO_SUM && !HASH_ALGO_CKSUM
- if (O_BINARY)
+#if HASH_ALGO_CKSUM
fputs (_("\
\n\
+ -a, --algorithm select the digest mode to operate in. See DIGEST below.\
+\n\
+"), stdout);
+#endif
+#if !HASH_ALGO_SUM
+ if (O_BINARY)
+ fputs (_("\
-b, --binary read in binary mode (default unless reading tty stdin)\n\
"), stdout);
else
fputs (_("\
-\n\
-b, --binary read in binary mode\n\
"), stdout);
- printf (_("\
- -c, --check read %s sums from the FILEs and check them\n"),
- DIGEST_TYPE_STRING);
-# if HASH_ALGO_BLAKE2
+ fputs (_("\
+ -c, --check read checksums from the FILEs and check them\n\
+"), stdout);
+# if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
fputs (_("\
-l, --length digest length in bits; must not exceed the maximum for\n\
the blake2 algorithm and must be a multiple of 8\n\
@@ -363,17 +483,40 @@ The following five options are useful only when verifying checksums:\n\
#endif
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
+#if HASH_ALGO_CKSUM
+ fputs (_("\
+\n\
+DIGEST determines the digest algorithm and default output format:\n\
+ 'sysv' (equivalent to sum -s)\n\
+ 'bsd' (equivalent to sum -r)\n\
+ 'crc' (equivalent to cksum)\n\
+ 'md5' (equivalent to md5sum)\n\
+ 'sha1' (equivalent to sha1sum)\n\
+ 'sha224' (equivalent to sha224sum)\n\
+ 'sha256' (equivalent to sha256sum)\n\
+ 'sha384' (equivalent to sha384sum)\n\
+ 'sha512' (equivalent to sha512sum)\n\
+ 'blake2b' (equivalent to b2sum)\n\
+\n"), stdout);
+#endif
#if !HASH_ALGO_SUM && !HASH_ALGO_CKSUM
printf (_("\
\n\
-The sums are computed as described in %s. When checking, the input\n\
-should be a former output of this program. The default mode is to print a\n\
-line with checksum, a space, a character indicating input mode ('*' for binary,\
-\n' ' for text or where binary is insignificant), and name for each FILE.\n\
+The sums are computed as described in %s.\n"), DIGEST_REFERENCE);
+ fputs (_("\
+When checking, the input should be a former output of this program.\n\
+The default mode is to print a line with: checksum, a space,\n\
+a character indicating input mode ('*' for binary, ' ' for text\n\
+or where binary is insignificant), and name for each FILE.\n\
\n\
Note: There is no difference between binary mode and text mode on GNU systems.\
-\n"),
- DIGEST_REFERENCE);
+\n"), stdout);
+#endif
+#if HASH_ALGO_CKSUM
+ fputs (_("\
+When checking, the input should be a former output of this program,\n\
+or equivalent standalone program.\
+\n"), stdout);
#endif
emit_ancillary_info (PROGRAM_NAME);
}
@@ -521,7 +664,10 @@ split_3 (char *s, size_t s_len,
if (STREQ_LEN (s + i, DIGEST_TYPE_STRING, algo_name_len))
{
i += algo_name_len;
-#if HASH_ALGO_BLAKE2
+#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
+# if HASH_ALGO_CKSUM
+ if (cksum_algorithm == blake2b) {
+# endif
/* Terminate and match algorithm name. */
char const *algo_name = &s[i - algo_name_len];
/* Skip algorithm variants. */
@@ -550,7 +696,9 @@ split_3 (char *s, size_t s_len,
i = siend - s;
b2_length = length;
}
-
+# if HASH_ALGO_CKSUM
+ }
+# endif
digest_hex_bytes = b2_length / 4;
#endif
if (s[i] == ' ')
@@ -574,8 +722,11 @@ split_3 (char *s, size_t s_len,
*hex_digest = (unsigned char *) &s[i];
-#if HASH_ALGO_BLAKE2
+#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
/* Auto determine length. */
+# if HASH_ALGO_CKSUM
+ if (cksum_algorithm == blake2b) {
+# endif
unsigned char const *hp = *hex_digest;
digest_hex_bytes = 0;
while (isxdigit (*hp++))
@@ -584,6 +735,9 @@ split_3 (char *s, size_t s_len,
|| blake2_max_len[b2_algorithm] * 2 < digest_hex_bytes)
return false;
b2_length = digest_hex_bytes * 4;
+# if HASH_ALGO_CKSUM
+ }
+# endif
#endif
/* The first field has to be the n-character hexadecimal
@@ -709,7 +863,11 @@ digest_file (char const *filename, int *binary, unsigned char *bin_result,
fadvise (fp, FADVISE_SEQUENTIAL);
-#if HASH_ALGO_SUM || HASH_ALGO_CKSUM
+#if HASH_ALGO_CKSUM
+ if (cksum_algorithm == blake2b)
+ *length = b2_length / 8;
+ err = DIGEST_STREAM (fp, bin_result, length);
+#elif HASH_ALGO_SUM
err = DIGEST_STREAM (fp, bin_result, length);
#elif HASH_ALGO_BLAKE2
err = DIGEST_STREAM (fp, bin_result, b2_length / 8);
@@ -731,7 +889,7 @@ digest_file (char const *filename, int *binary, unsigned char *bin_result,
return true;
}
-#if !HASH_ALGO_SUM && !HASH_ALGO_CKSUM
+#if !HASH_ALGO_SUM
static void
output_file (char const *file, int binary_file, void const *digest,
bool tagged, bool args _GL_UNUSED, uintmax_t length _GL_UNUSED)
@@ -758,6 +916,13 @@ output_file (char const *file, int binary_file, void const *digest,
printf ("-%"PRIuMAX, b2_length);
# else
fputs (DIGEST_TYPE_STRING, stdout);
+# if HASH_ALGO_CKSUM
+ if (cksum_algorithm == blake2b)
+ {
+ if (b2_length < blake2_max_len[b2_algorithm] * 8)
+ printf ("-%"PRIuMAX, b2_length);
+ }
+# endif
# endif
fputs (" (", stdout);
print_filename (file, needs_escape);
@@ -876,7 +1041,8 @@ digest_check (char const *checkfile_name)
properly_formatted_lines = true;
- ok = digest_file (filename, &binary, bin_buffer, &missing, NULL);
+ uintmax_t length;
+ ok = digest_file (filename, &binary, bin_buffer, &missing, &length);
if (!ok)
{
@@ -1023,7 +1189,8 @@ main (int argc, char **argv)
#if HASH_ALGO_SUM
const char* short_opts = "rs";
#elif HASH_ALGO_CKSUM
- const char* short_opts = "";
+ const char* short_opts = "a:l:bctwz";
+ const char* b2_length_str = "";
#elif HASH_ALGO_BLAKE2
const char* short_opts = "l:bctwz";
const char* b2_length_str = "";
@@ -1035,11 +1202,16 @@ main (int argc, char **argv)
switch (opt)
{
#if HASH_ALGO_CKSUM
+ case 'a':
+ cksum_algorithm = XARGMATCH ("--algorithm", optarg,
+ algorithm_args, algorithm_types);
+ break;
+
case DEBUG_PROGRAM_OPTION:
cksum_debug = true;
break;
#endif
-#if HASH_ALGO_BLAKE2
+#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
case 'l':
b2_length = xdectoumax (optarg, 0, UINTMAX_MAX, "",
_("invalid length"), 0);
@@ -1051,7 +1223,7 @@ main (int argc, char **argv)
}
break;
#endif
-#if !HASH_ALGO_SUM && !HASH_ALGO_CKSUM
+#if !HASH_ALGO_SUM
case 'b':
binary = 1;
break;
@@ -1106,7 +1278,12 @@ main (int argc, char **argv)
}
min_digest_line_length = MIN_DIGEST_LINE_LENGTH;
-#if HASH_ALGO_BLAKE2
+#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
+# if HASH_ALGO_CKSUM
+ if (b2_length && cksum_algorithm != blake2b)
+ die (EXIT_FAILURE, 0,
+ _("--length is only supported with --algorithm=blake2b"));
+# endif
if (b2_length > blake2_max_len[b2_algorithm] * 8)
{
error (0, 0, _("invalid length: %s"), quote (b2_length_str));
@@ -1117,11 +1294,40 @@ main (int argc, char **argv)
}
if (b2_length == 0 && ! do_check)
b2_length = blake2_max_len[b2_algorithm] * 8;
+# if HASH_ALGO_BLAKE2
digest_hex_bytes = b2_length / 4;
+# else
+ if (cksum_algorithm == blake2b)
+ digest_hex_bytes = b2_length / 4;
+ else
+ digest_hex_bytes = algorithm_bits[cksum_algorithm] / 4;
+# endif
#else
digest_hex_bytes = DIGEST_HEX_BYTES;
#endif
+#if HASH_ALGO_CKSUM
+ switch (cksum_algorithm)
+ {
+ case bsd:
+ case sysv:
+ case crc:
+ if (delim != '\n')
+ die (EXIT_FAILURE, 0,
+ _("--zero is not supported with --algorithm={bsd,sysv,crc}"));
+ if (prefix_tag)
+ die (EXIT_FAILURE, 0,
+ _("--tag is not supported with --algorithm={bsd,sysv,crc}"));
+ if (do_check)
+ die (EXIT_FAILURE, 0,
+ _("--check is not supported with --algorithm={bsd,sysv,crc}"));
+ break;
+ default:
+ break;
+ }
+
+#endif
+
if (prefix_tag && !binary)
{
/* This could be supported in a backwards compatible way
diff --git a/src/local.mk b/src/local.mk
index 54303d3052..0c8b65d39a 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -304,6 +304,7 @@ src_sha224sum_LDADD += $(LIB_CRYPTO)
src_sha256sum_LDADD += $(LIB_CRYPTO)
src_sha384sum_LDADD += $(LIB_CRYPTO)
src_sha512sum_LDADD += $(LIB_CRYPTO)
+src_cksum_LDADD += $(LIB_CRYPTO)
# for canon_host
src_pinky_LDADD += $(GETADDRINFO_LIB)
@@ -355,18 +356,6 @@ src___SOURCES = src/lbracket.c
nodist_src_coreutils_SOURCES = src/coreutils.h
src_coreutils_SOURCES = src/coreutils.c
-src_sum_SOURCES = src/sum.c src/sum.h src/digest.c
-src_sum_CPPFLAGS = -DHASH_ALGO_SUM=1 $(AM_CPPFLAGS)
-
-src_cksum_SOURCES = src/cksum.c src/cksum.h src/crctab.c src/digest.c
-src_cksum_CPPFLAGS = -DHASH_ALGO_CKSUM=1 $(AM_CPPFLAGS)
-if USE_PCLMUL_CRC32
-noinst_LIBRARIES += src/libcksum_pclmul.a
-src_libcksum_pclmul_a_SOURCES = src/cksum_pclmul.c src/cksum.h
-cksum_pclmul_ldadd = src/libcksum_pclmul.a
-src_cksum_LDADD += $(cksum_pclmul_ldadd)
-src_libcksum_pclmul_a_CFLAGS = -mavx -mpclmul $(AM_CFLAGS)
-endif
src_cp_SOURCES = src/cp.c $(copy_sources) $(selinux_sources)
src_dir_SOURCES = src/ls.c src/ls-dir.c
src_env_SOURCES = src/env.c src/operand2sig.c
@@ -401,6 +390,9 @@ src_arch_SOURCES = src/uname.c src/uname-arch.c
src_cut_SOURCES = src/cut.c src/set-fields.c
src_numfmt_SOURCES = src/numfmt.c src/set-fields.c
+src_sum_SOURCES = src/sum.c src/sum.h src/digest.c
+src_sum_CPPFLAGS = -DHASH_ALGO_SUM=1 $(AM_CPPFLAGS)
+
src_md5sum_SOURCES = src/digest.c
src_md5sum_CPPFLAGS = -DHASH_ALGO_MD5=1 $(AM_CPPFLAGS)
src_sha1sum_SOURCES = src/digest.c
@@ -419,6 +411,17 @@ src_b2sum_SOURCES = src/digest.c \
src/blake2/blake2b-ref.c \
src/blake2/b2sum.c src/blake2/b2sum.h
+src_cksum_SOURCES = $(src_b2sum_SOURCES) src/sum.c src/sum.h \
+ src/cksum.c src/cksum.h src/crctab.c
+src_cksum_CPPFLAGS = -DHASH_ALGO_CKSUM=1 -DHAVE_CONFIG_H $(AM_CPPFLAGS)
+if USE_PCLMUL_CRC32
+noinst_LIBRARIES += src/libcksum_pclmul.a
+src_libcksum_pclmul_a_SOURCES = src/cksum_pclmul.c src/cksum.h
+cksum_pclmul_ldadd = src/libcksum_pclmul.a
+src_cksum_LDADD += $(cksum_pclmul_ldadd)
+src_libcksum_pclmul_a_CFLAGS = -mavx -mpclmul $(AM_CFLAGS)
+endif
+
src_base64_SOURCES = src/basenc.c
src_base64_CPPFLAGS = -DBASE_TYPE=64 $(AM_CPPFLAGS)
src_base32_SOURCES = src/basenc.c
diff --git a/tests/local.mk b/tests/local.mk
index 4a08147dff..3ddd6f1bb8 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -289,6 +289,7 @@ all_tests = \
tests/misc/close-stdout.sh \
tests/misc/chroot-fail.sh \
tests/misc/cksum.sh \
+ tests/misc/cksum-a.sh \
tests/misc/comm.pl \
tests/misc/csplit.sh \
tests/misc/csplit-1000.sh \
diff --git a/tests/misc/b2sum.sh b/tests/misc/b2sum.sh
index 730516cb8c..c5242bed21 100755
--- a/tests/misc/b2sum.sh
+++ b/tests/misc/b2sum.sh
@@ -17,38 +17,45 @@
# along with this program. If not, see