aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--common.c87
-rwxr-xr-xtest3
-rw-r--r--xsum.man18
3 files changed, 72 insertions, 36 deletions
diff --git a/common.c b/common.c
index 26a8276..e902c29 100644
--- a/common.c
+++ b/common.c
@@ -36,7 +36,7 @@ usage(void)
{
fprintf(stderr, "usage: %s [-u | -l | -b | -c] [-R rate] [-C capacity] "
"[-N output-size] [-S state-size] [-W word-size] "
- "[-Z squeeze-count] [-vx] [file ...]\n", argv0);
+ "[-Z squeeze-count] [-vxz] [file ...]\n", argv0);
exit(2);
}
@@ -278,11 +278,13 @@ check(const struct libkeccak_spec *restrict spec, long int squeezes, const char
* @param suffix The message suffix
* @param style (unused)
* @param hex Whether to use hexadecimal input rather than binary
+ * @param nuls Whether lines end with NUL instead of LF,
+ * and parsing should be less lax
* @return An appropriate exit value
*/
static int
check_checksums(const char *restrict filename, const struct libkeccak_spec *restrict spec,
- long int squeezes, const char *restrict suffix, enum representation style, int hex)
+ long int squeezes, const char *restrict suffix, enum representation style, int hex, int nuls)
{
struct stat attr;
size_t blksize = 4096;
@@ -329,27 +331,46 @@ check_checksums(const char *restrict filename, const struct libkeccak_spec *rest
buf = erealloc(buf, size + 1);
size = ptr;
close(fd), fd = -1;
- buf[size++] = '\n';
+ buf[size++] = nuls ? '\0' : '\n';
for (ptr = 0, stage = 0; ptr < size; ptr++) {
c = buf[ptr];
- if (stage == 0) {
- if (isxdigit(c))
- ;
- else if (c == ' ' || c == '\t')
- hash_end = ptr, stage++;
- else if (c == '\n' || c == '\f' || c == '\r')
- hash_end = ptr, stage = 3;
- else
- user_error("file is malformated");
- } else if (stage == 1) {
- if (c == '\n' || c == '\f' || c == '\r')
- stage = 3;
- else if (c != ' ' && c != '\t')
- file_start = ptr, stage++;
- } else if (stage == 2) {
- if (c == '\n' || c == '\f' || c == '\r')
- file_end = ptr, stage++;
+ if (!nuls) {
+ if (stage == 0) {
+ if (isxdigit(c))
+ ;
+ else if (c == ' ' || c == '\t')
+ hash_end = ptr, stage++;
+ else if (c == '\n' || c == '\f' || c == '\r')
+ hash_end = ptr, stage = 3;
+ else
+ user_error("file is malformated");
+ } else if (stage == 1) {
+ if (c == '\n' || c == '\f' || c == '\r')
+ stage = 3;
+ else if (c != ' ' && c != '\t')
+ file_start = ptr, stage++;
+ } else if (stage == 2) {
+ if (c == '\n' || c == '\f' || c == '\r')
+ file_end = ptr, stage++;
+ }
+ } else {
+ if (stage == 0) {
+ if (c == ' ')
+ hash_end = ptr, stage++;
+ else if (c == '\0')
+ hash_end = ptr, stage = 3;
+ else if (!isxdigit(c))
+ user_error("file is malformated");
+ } else if (stage == 1) {
+ if (c == ' ')
+ file_start = ptr + 1, stage++;
+ else
+ user_error("file is malformated");
+ } else if (stage == 2) {
+ if (c == '\0')
+ file_end = ptr, stage++;
+ }
}
if (stage == 3) {
@@ -392,11 +413,12 @@ check_checksums(const char *restrict filename, const struct libkeccak_spec *rest
* @param suffix The message suffix
* @param style How the hashes shall be represented
* @param hex Whether to use hexadecimal input rather than binary
+ * @param nuls Whether lines end with NUL instead of LF
* @return An appropriate exit value
*/
static int
print_checksum(const char *restrict filename, const struct libkeccak_spec *restrict spec,
- long int squeezes, const char *restrict suffix, enum representation style, int hex)
+ long int squeezes, const char *restrict suffix, enum representation style, int hex, int nuls)
{
size_t p = 0, n = (size_t)((spec->output + 7) / 8);
ssize_t w;
@@ -408,10 +430,10 @@ print_checksum(const char *restrict filename, const struct libkeccak_spec *restr
if (style == REPRESENTATION_UPPER_CASE) {
libkeccak_behex_upper(hexsum, hashsum, n);
- printf("%s %s\n", hexsum, filename);
+ printf("%s %s%c", hexsum, filename, nuls ? '\0' : '\n');
} else if (style == REPRESENTATION_LOWER_CASE) {
libkeccak_behex_lower(hexsum, hashsum, n);
- printf("%s %s\n", hexsum, filename);
+ printf("%s %s%c", hexsum, filename, nuls ? '\0' : '\n');
} else {
fflush(stdout);
for (; p < n; p += (size_t)w)
@@ -436,12 +458,10 @@ int
run(int argc, char *argv[], struct libkeccak_generalised_spec *restrict gspec, const char *restrict suffix)
{
enum representation style = REPRESENTATION_UPPER_CASE;
- int verbose = 0;
- int hex = 0;
- int check = 0;
+ int verbose = 0, hex = 0, check = 0, nuls = 0;
long int squeezes = 1;
int (*fun)(const char *restrict filename, const struct libkeccak_spec *restrict spec,
- long int squeezes, const char *restrict suffix, enum representation style, int hex);
+ long int squeezes, const char *restrict suffix, enum representation style, int hex, int nuls);
struct libkeccak_spec spec;
int r = 0;
@@ -478,16 +498,19 @@ run(int argc, char *argv[], struct libkeccak_generalised_spec *restrict gspec, c
case 'c':
check = 1;
break;
+ case 'v':
+ verbose = 1;
+ break;
case 'x':
hex = 1;
break;
- case 'v':
- verbose = 1;
+ case 'z':
+ nuls = 1;
break;
default:
usage();
} ARGEND;
- /* -c has been added because the sha1sum, sha256sum &c have
+ /* -cz has been added because the sha1sum, sha256sum &c have
* it, but I ignore the other crap, mostly because not all
* implemention have them and binary vs text mode is stupid. */
@@ -508,9 +531,9 @@ run(int argc, char *argv[], struct libkeccak_generalised_spec *restrict gspec, c
}
if (!*argv)
- r = fun("-", &spec, squeezes, suffix, style, hex);
+ r = fun("-", &spec, squeezes, suffix, style, hex, nuls);
for (; *argv; argv++)
- r |= fun(*argv, &spec, squeezes, suffix, style, hex);
+ r |= fun(*argv, &spec, squeezes, suffix, style, hex, nuls);
free(hashsum);
free(hexsum);
diff --git a/test b/test
index 11caa5d..f536ae2 100755
--- a/test
+++ b/test
@@ -122,4 +122,7 @@ set -e
test $x = 1
+## TODO add tests with -z
+
+
rm -r .testdir
diff --git a/xsum.man b/xsum.man
index 188d55b..dc1c0fd 100644
--- a/xsum.man
+++ b/xsum.man
@@ -16,7 +16,7 @@ xsum - Compute and check Xsum message digests
.IR word-size ]
[-Z
.IR squeeze-count ]
-[-vx]
+[-vxz]
.RI [ file \ ...]
.SH DESCRIPTION
Print or check Xsum checksums. If no file
@@ -40,14 +40,24 @@ should be formated as the output of this program, or
similarly. This is not going to work if any of the
filenames in the input files starts with a regular
blank space or horizontal tab space, or if they
-contain a line feed, carriage return or form feed.
+contain a line feed, carriage return or form feed,
+unless the
+.B -z
+option is also used.
+.TP
+.B -v
+Print the hashing parameters.
.TP
.B -x
Convert input files from hexadecimal for to binary form
before calculating the checksums.
.TP
-.B -v
-Print the hashing parameters.
+.B -z
+Lines end with NUL instead of LF. If used with
+.BR -c ,
+this applies to read files (not the output), but it will
+also apply more strict parsing and allow any whitespace
+in file names.
.P
The following options change the hashing parameters:
.TP