diff options
Diffstat (limited to 'bsum.c')
-rw-r--r-- | bsum.c | 269 |
1 files changed, 35 insertions, 234 deletions
@@ -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); } } |