diff options
author | Cem Keylan <cem@ckyln.com> | 2020-10-16 17:41:25 +0300 |
---|---|---|
committer | Cem Keylan <cem@ckyln.com> | 2020-10-16 17:41:25 +0300 |
commit | e2abcdca396661cbe0ae2ddb13d5c2b85682c13a (patch) | |
tree | acf9b5c80b645617f882c45224c6e07251711842 /lib/libc/hash/helper.c | |
download | otools-e2abcdca396661cbe0ae2ddb13d5c2b85682c13a.tar.gz |
initial commit
Diffstat (limited to 'lib/libc/hash/helper.c')
-rw-r--r-- | lib/libc/hash/helper.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/lib/libc/hash/helper.c b/lib/libc/hash/helper.c new file mode 100644 index 0000000..06e8060 --- /dev/null +++ b/lib/libc/hash/helper.c @@ -0,0 +1,118 @@ +/* $OpenBSD: helper.c,v 1.18 2019/06/28 13:32:41 deraadt Exp $ */ + +/* + * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * If we meet some day, and you think this stuff is worth it, you + * can buy me a beer in return. Poul-Henning Kamp + */ + +#include <sys/types.h> +#include <sys/cdefs.h> +#include <sys/stat.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <hashinc> + +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + +char * +HASHEnd(HASH_CTX *ctx, char *buf) +{ + int i; + u_int8_t digest[HASH_DIGEST_LENGTH]; + static const char hex[] = "0123456789abcdef"; + + if (buf == NULL && (buf = malloc(HASH_DIGEST_STRING_LENGTH)) == NULL) + return (NULL); + + HASHFinal(digest, ctx); + for (i = 0; i < HASH_DIGEST_LENGTH; i++) { + buf[i + i] = hex[digest[i] >> 4]; + buf[i + i + 1] = hex[digest[i] & 0x0f]; + } + buf[i + i] = '\0'; + explicit_bzero(digest, sizeof(digest)); + return (buf); +} +DEF_WEAK(HASHEnd); + +char * +HASHFileChunk(const char *filename, char *buf, off_t off, off_t len) +{ + struct stat sb; + u_char buffer[BUFSIZ]; + HASH_CTX ctx; + int fd, save_errno; + ssize_t nr; + + HASHInit(&ctx); + + if ((fd = open(filename, O_RDONLY)) == -1) + return (NULL); + if (len == 0) { + if (fstat(fd, &sb) == -1) { + save_errno = errno; + close(fd); + errno = save_errno; + return (NULL); + } + len = sb.st_size; + } + if (off > 0 && lseek(fd, off, SEEK_SET) == -1) { + save_errno = errno; + close(fd); + errno = save_errno; + return (NULL); + } + + while ((nr = read(fd, buffer, MINIMUM(sizeof(buffer), len))) > 0) { + HASHUpdate(&ctx, buffer, nr); + if (len > 0 && (len -= nr) == 0) + break; + } + + save_errno = errno; + close(fd); + errno = save_errno; + return (nr == -1 ? NULL : HASHEnd(&ctx, buf)); +} +DEF_WEAK(HASHFileChunk); + +char * +HASHFile(const char *filename, char *buf) +{ + return (HASHFileChunk(filename, buf, 0, 0)); +} +DEF_WEAK(HASHFile); + +char * +HASHData(const u_char *data, size_t len, char *buf) +{ + HASH_CTX ctx; + + HASHInit(&ctx); + HASHUpdate(&ctx, data, len); + return (HASHEnd(&ctx, buf)); +} +DEF_WEAK(HASHData); |