aboutsummaryrefslogtreecommitdiffstats
path: root/bsum.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsum.c')
-rw-r--r--bsum.c269
1 files changed, 35 insertions, 234 deletions
diff --git a/bsum.c b/bsum.c
index cbc8b51..1940cf2 100644
--- a/bsum.c
+++ b/bsum.c
@@ -5,6 +5,14 @@ const char *argv0 = "bsum";
static int lenght_by_command_name = 0;
+static int flag_check = 0;
+static int flag_binary = 0;
+static int flag_lower = 0;
+static int flag_upper = 0;
+static int flag_hex = 0;
+static int flag_zero = 0;
+static int length;
+
static void
usage(void)
{
@@ -13,36 +21,24 @@ usage(void)
exit(2);
}
-static void *
-erealloc(void *ptr, size_t n)
-{
- ptr = realloc(ptr, n);
- if (!ptr) {
- fprintf(stderr, "%s: %s\n", argv0, strerror(errno));
- exit(2);
- }
- return ptr;
-}
-
static void
get_lenght_by_command_name(const char *command)
{
const char *p;
p = strrchr(command, '/');
p = p ? &p[1] : command;
- if (strstr(p, "b224sum")) {
+ if (strstr(p, "b224sum"))
lenght_by_command_name = 224;
- } else if (strstr(p, "b256sum")) {
+ else if (strstr(p, "b256sum"))
lenght_by_command_name = 256;
- } else if (strstr(p, "b384sum")) {
+ else if (strstr(p, "b384sum"))
lenght_by_command_name = 384;
- } else if (strstr(p, "b512sum")) {
+ else if (strstr(p, "b512sum"))
lenght_by_command_name = 512;
- }
}
static int
-hash_file_blake224(int fd, const char *fname, int decode_hex, unsigned char hash[], size_t *hash_lenp)
+hash_fd_blake224(int fd, const char *fname, int decode_hex, unsigned char hash[])
{
struct libblake_blake224_state state;
char *buf = NULL;
@@ -63,6 +59,7 @@ hash_file_blake224(int fd, const char *fname, int decode_hex, unsigned char hash
if (errno == EINTR)
continue;
fprintf(stderr, "%s: %s: %s\n", argv0, fname, strerror(errno));
+ free(buf);
return -1;
}
len += (size_t)r;
@@ -78,6 +75,7 @@ hash_file_blake224(int fd, const char *fname, int decode_hex, unsigned char hash
len = libblake_decode_hex(buf, len, buf, &ok);
if (!ok) {
fprintf(stderr, "%s: %s: %s\n", argv0, fname, "invalid hexadecimal input");
+ free(buf);
return -1;
}
}
@@ -85,13 +83,12 @@ hash_file_blake224(int fd, const char *fname, int decode_hex, unsigned char hash
if (req > size)
buf = erealloc(buf, size);
libblake_blake224_digest(&state, buf, len, 0, NULL, hash);
- *hash_lenp = LIBBLAKE_BLAKE224_OUTPUT_SIZE;
free(buf);
return 0;
}
static int
-hash_file_blake256(int fd, const char *fname, int decode_hex, unsigned char hash[], size_t *hash_lenp)
+hash_fd_blake256(int fd, const char *fname, int decode_hex, unsigned char hash[])
{
struct libblake_blake256_state state;
char *buf = NULL;
@@ -112,6 +109,7 @@ hash_file_blake256(int fd, const char *fname, int decode_hex, unsigned char hash
if (errno == EINTR)
continue;
fprintf(stderr, "%s: %s: %s\n", argv0, fname, strerror(errno));
+ free(buf);
return -1;
}
len += (size_t)r;
@@ -127,6 +125,7 @@ hash_file_blake256(int fd, const char *fname, int decode_hex, unsigned char hash
len = libblake_decode_hex(buf, len, buf, &ok);
if (!ok) {
fprintf(stderr, "%s: %s: %s\n", argv0, fname, "invalid hexadecimal input");
+ free(buf);
return -1;
}
}
@@ -134,13 +133,12 @@ hash_file_blake256(int fd, const char *fname, int decode_hex, unsigned char hash
if (req > size)
buf = erealloc(buf, size);
libblake_blake256_digest(&state, buf, len, 0, NULL, hash);
- *hash_lenp = LIBBLAKE_BLAKE256_OUTPUT_SIZE;
free(buf);
return 0;
}
static int
-hash_file_blake384(int fd, const char *fname, int decode_hex, unsigned char hash[], size_t *hash_lenp)
+hash_fd_blake384(int fd, const char *fname, int decode_hex, unsigned char hash[])
{
struct libblake_blake384_state state;
char *buf = NULL;
@@ -161,6 +159,7 @@ hash_file_blake384(int fd, const char *fname, int decode_hex, unsigned char hash
if (errno == EINTR)
continue;
fprintf(stderr, "%s: %s: %s\n", argv0, fname, strerror(errno));
+ free(buf);
return -1;
}
len += (size_t)r;
@@ -176,6 +175,7 @@ hash_file_blake384(int fd, const char *fname, int decode_hex, unsigned char hash
len = libblake_decode_hex(buf, len, buf, &ok);
if (!ok) {
fprintf(stderr, "%s: %s: %s\n", argv0, fname, "invalid hexadecimal input");
+ free(buf);
return -1;
}
}
@@ -183,13 +183,12 @@ hash_file_blake384(int fd, const char *fname, int decode_hex, unsigned char hash
if (req > size)
buf = erealloc(buf, size);
libblake_blake384_digest(&state, buf, len, 0, NULL, hash);
- *hash_lenp = LIBBLAKE_BLAKE384_OUTPUT_SIZE;
free(buf);
return 0;
}
static int
-hash_file_blake512(int fd, const char *fname, int decode_hex, unsigned char hash[], size_t *hash_lenp)
+hash_fd_blake512(int fd, const char *fname, int decode_hex, unsigned char hash[])
{
struct libblake_blake512_state state;
char *buf = NULL;
@@ -210,6 +209,7 @@ hash_file_blake512(int fd, const char *fname, int decode_hex, unsigned char hash
if (errno == EINTR)
continue;
fprintf(stderr, "%s: %s: %s\n", argv0, fname, strerror(errno));
+ free(buf);
return -1;
}
len += (size_t)r;
@@ -225,6 +225,7 @@ hash_file_blake512(int fd, const char *fname, int decode_hex, unsigned char hash
len = libblake_decode_hex(buf, len, buf, &ok);
if (!ok) {
fprintf(stderr, "%s: %s: %s\n", argv0, fname, "invalid hexadecimal input");
+ free(buf);
return -1;
}
}
@@ -232,232 +233,32 @@ hash_file_blake512(int fd, const char *fname, int decode_hex, unsigned char hash
if (req > size)
buf = erealloc(buf, size);
libblake_blake512_digest(&state, buf, len, 0, NULL, hash);
- *hash_lenp = LIBBLAKE_BLAKE512_OUTPUT_SIZE;
free(buf);
return 0;
}
-static int
-parse_fd(const char *name)
-{
- long int num;
- char *end;
- if (!isdigit(*name))
- return -1;
- errno = 0;
- num = strtol(name, &end, 10);
- if (num > INT_MAX || *end || errno)
- return -1;
- return (int)num;
-}
-
-static int
-open_file(const char *path, int *closep)
-{
- int fd = -1;
-
- *closep = 0;
-
- if (!strcmp(path, "-"))
- fd = STDIN_FILENO;
- else if (!strcmp(path, "/dev/stdin"))
- fd = STDIN_FILENO;
- else if (!strcmp(path, "/dev/stdout"))
- fd = STDOUT_FILENO;
- else if (!strcmp(path, "/dev/stderr"))
- fd = STDERR_FILENO;
- else if (!strncmp(path, "/dev/fd/", sizeof("/dev/fd/") - 1))
- fd = parse_fd(&path[sizeof("/dev/fd/") - 1]);
- else if (!strncmp(path, "/proc/self/fd/", sizeof("/proc/self/fd/") - 1))
- fd = parse_fd(&path[sizeof("/proc/self/fd/") - 1]);
-
- if (fd < 0) {
- fd = open(path, O_RDONLY);
- if (fd < 0)
- return -1;
- *closep = 1;
- }
-
- return fd;
-}
-
-static int
-hash_file(const char *path, int length, int decode_hex, unsigned char hash[], size_t *hash_lenp)
+int
+hash_fd(int fd, const char *fname, int decode_hex, unsigned char hash[])
{
- int ret, fd, close_fd;
-
- fd = open_file(path, &close_fd);
- if (fd < 0) {
- fprintf(stderr, "%s: %s: %s\n", argv0, path, strerror(errno));
- return -1;
- }
+ int ret;
if (length == 224)
- ret = hash_file_blake224(fd, path, decode_hex, hash, hash_lenp);
+ ret = hash_fd_blake224(fd, fname, decode_hex, hash);
else if (length == 256)
- ret = hash_file_blake256(fd, path, decode_hex, hash, hash_lenp);
+ ret = hash_fd_blake256(fd, fname, decode_hex, hash);
else if (length == 384)
- ret = hash_file_blake384(fd, path, decode_hex, hash, hash_lenp);
+ ret = hash_fd_blake384(fd, fname, decode_hex, hash);
else if (length == 512)
- ret = hash_file_blake512(fd, path, decode_hex, hash, hash_lenp);
+ ret = hash_fd_blake512(fd, fname, decode_hex, hash);
else
abort();
- if (close_fd)
- close(fd);
return ret;
}
-static int
-hash_and_print(const char *path, int length, int decode_hex, char newline, int output_case)
-{
- unsigned char hash[LIBBLAKE_BLAKE512_OUTPUT_SIZE];
- char hex[LIBBLAKE_BLAKE512_OUTPUT_SIZE * 2 + 1];
- size_t hash_len;
-
- if (hash_file(path, length, decode_hex, hash, &hash_len))
- return -1;
-
- if (output_case < 0) {
- fwrite(hash, 1, hash_len, stdout);
- } else {
- libblake_encode_hex(hash, hash_len, hex, output_case);
- printf("%s %s%c", hex, path, newline);
- }
-
- return 0;
-}
-
-static int
-check_and_print_file(const char *path, int length, int decode_hex, char *expected)
-{
- unsigned char hash[LIBBLAKE_BLAKE512_OUTPUT_SIZE];
- int r, fd, close_fd;
-
- fd = open_file(path, &close_fd);
- if (fd < 0) {
- if (errno != ENOENT)
- fprintf(stderr, "%s: %s: %s\n", argv0, path, strerror(errno));
- missing:
- printf("%s: Missing\n", path);
- return -1;
- }
-
- if (length == 224)
- r = hash_file_blake224(fd, path, decode_hex, hash, &(size_t){0});
- else if (length == 256)
- r = hash_file_blake256(fd, path, decode_hex, hash, &(size_t){0});
- else if (length == 384)
- r = hash_file_blake384(fd, path, decode_hex, hash, &(size_t){0});
- else if (length == 512)
- r = hash_file_blake512(fd, path, decode_hex, hash, &(size_t){0});
- else
- abort();
-
- if (close_fd)
- close(fd);
-
- if (r < 0)
- goto missing;
-
- libblake_decode_hex(expected, (size_t)length / 4, expected, &(int){0});
- if (!memcmp(hash, expected, (size_t)length / 8)) {
- printf("%s: OK\n", path);
- return 0;
- } else {
- printf("%s: Fail\n", path);
- return -1;
- }
-}
-
-static int
-check_and_print(const char *path, int length, int decode_hex, char newline)
-{
- int fd, close_fd, status = 0;
- char *buf = NULL;
- size_t size = 0;
- size_t len = 0;
- ssize_t r;
- size_t i, j, k;
-
- fd = open_file(path, &close_fd);
- if (fd < 0) {
- fprintf(stderr, "%s: %s: %s\n", argv0, path, strerror(errno));
- exit(2);
- }
-
- for (;;) {
- if (len == size)
- buf = erealloc(buf, size += 8 << 10);
- r = read(fd, &buf[len], size - len);
- if (r > 0) {
- len += (size_t)r;
- } else if (!r) {
- break;
- } else if (errno == EINTR) {
- continue;
- } else {
- fprintf(stderr, "%s: %s: %s\n", argv0, path, strerror(errno));
- exit(2);
- }
- }
- buf = erealloc(buf, len + 1);
- buf[len] = '\0';
-
- if (newline) {
- for (i = 0; i < len; i = k + 1) {
- while (isspace(buf[i]))
- i++;
- for (j = i; j - i < (size_t)length / 4; j++)
- if (!isxdigit(buf[j]))
- goto corrupt;
- if (j == len || !isblank(buf[j]))
- goto corrupt;
- buf[j] = '\0';
- j++;
- while (isblank(buf[j]))
- j++;
- if (!buf[j])
- goto corrupt;
- for (k = j; buf[k] && buf[k] != newline;)
- k++;
- buf[k] = '\0';
- status |= check_and_print_file(&buf[j], length, decode_hex, &buf[i]);
- }
- } else {
- for (i = 0; i < len; i = k + 1) {
- for (j = i; j - i < (size_t)length / 4; j++)
- if (!isxdigit(buf[j]))
- goto corrupt;
- if (buf[j + 0] != ' ' || buf[j + 1] != ' ')
- goto corrupt;
- buf[j] = '\0';
- j += 2;
- k = j + strlen(&buf[j]);
- status |= check_and_print_file(&buf[j], length, decode_hex, &buf[i]);
- }
- }
-
- if (close_fd)
- close(fd);
- return status;
-
-corrupt:
- fprintf(stderr, "%s: %s: invalid file content\n", argv0, path);
- exit(2);
-}
-
int
main(int argc, char *argv[])
{
- int flag_check = 0;
- int flag_binary = 0;
- int flag_lower = 0;
- int flag_upper = 0;
- int flag_hex = 0;
- int flag_zero = 0;
- int length;
-
int status = 0;
int output_case;
char newline;
@@ -510,18 +311,18 @@ main(int argc, char *argv[])
newline = flag_zero ? '\0' : '\n';
if (flag_check) {
if (!argc) {
- status |= -check_and_print("-", length, flag_hex, newline);
+ status |= -check_and_print("-", (size_t)length, flag_hex, newline);
} else {
for (; *argv; argv++)
- status |= -check_and_print(*argv, length, flag_hex, newline);
+ status |= -check_and_print(*argv, (size_t)length, flag_hex, newline);
}
} else {
output_case = flag_binary ? -1 : flag_upper;
if (!argc) {
- status |= -hash_and_print("-", length, flag_hex, newline, output_case);
+ status |= -hash_and_print("-", (size_t)length, flag_hex, newline, output_case);
} else {
for (; *argv; argv++)
- status |= -hash_and_print(*argv, length, flag_hex, newline, output_case);
+ status |= -hash_and_print(*argv, (size_t)length, flag_hex, newline, output_case);
}
}