From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <gentoo-commits+bounces-1596105-garchives=archives.gentoo.org@lists.gentoo.org> Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 7B76315838C for <garchives@archives.gentoo.org>; Wed, 31 Jan 2024 19:29:28 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id B2171E2B75; Wed, 31 Jan 2024 19:29:27 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 8B171E2B75 for <gentoo-commits@lists.gentoo.org>; Wed, 31 Jan 2024 19:29:27 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 921923431F2 for <gentoo-commits@lists.gentoo.org>; Wed, 31 Jan 2024 19:29:26 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 26FAD105D for <gentoo-commits@lists.gentoo.org>; Wed, 31 Jan 2024 19:29:25 +0000 (UTC) From: "Fabian Groffen" <grobian@gentoo.org> To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Fabian Groffen" <grobian@gentoo.org> Message-ID: <1706729081.bc4321f30bb95ab1c2112f045a4cde811045ed59.grobian@gentoo> Subject: [gentoo-commits] proj/portage-utils:master commit in: libq/ X-VCS-Repository: proj/portage-utils X-VCS-Files: libq/hash.c libq/hash.h X-VCS-Directories: libq/ X-VCS-Committer: grobian X-VCS-Committer-Name: Fabian Groffen X-VCS-Revision: bc4321f30bb95ab1c2112f045a4cde811045ed59 X-VCS-Branch: master Date: Wed, 31 Jan 2024 19:29:25 +0000 (UTC) Precedence: bulk List-Post: <mailto:gentoo-commits@lists.gentoo.org> List-Help: <mailto:gentoo-commits+help@lists.gentoo.org> List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org> List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org> List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org> X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 10b0b7e9-38b9-43fd-8246-ce01f8249d4f X-Archives-Hash: ce8b0d18b76eb825a45fc6ceb6461c90 commit: bc4321f30bb95ab1c2112f045a4cde811045ed59 Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> AuthorDate: Wed Jan 31 19:24:41 2024 +0000 Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> CommitDate: Wed Jan 31 19:24:41 2024 +0000 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=bc4321f3 libq/hash: add hash_string function Alternative to the implementation in PR #21, so as to reuse the same hashing code. We could add the interface to compute multiple hashes from the same string when that's actually necessary. Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> libq/hash.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++----------- libq/hash.h | 1 + 2 files changed, 114 insertions(+), 24 deletions(-) diff --git a/libq/hash.c b/libq/hash.c index 9b36bb9..f3a440f 100644 --- a/libq/hash.c +++ b/libq/hash.c @@ -98,29 +98,54 @@ hash_hex(char *out, const unsigned char *buf, const int length) } } -/** - * Computes the hashes for file fname and writes the hex-representation - * for those hashes into the address space pointed to by the return - * pointers for these hashes. The caller should ensure enough space is - * available. Only those hashes which are in the global hashes variable - * are computed, the address space pointed to for non-used hashes are - * left untouched, e.g. they can be NULL. The number of bytes read from - * the file pointed to by fname is returned in the flen argument. - */ -int -hash_multiple_file_fd( - int fd, - char *md5, - char *sha1, - char *sha256, - char *sha512, - char *blak2b, +/* len func(dest,destlen,cbctx) */ +typedef size_t (*read_cb)(char *,size_t,void *); + +static size_t read_stdio(char *dest, size_t destlen, void *ctx) +{ + FILE *io = ctx; + + return fread(dest, 1, destlen, io); +} + +struct bufctx { + const char *buf; + size_t buflen; +}; + +static size_t read_buffer(char *dest, size_t destlen, void *ctx) +{ + struct bufctx *membuf = ctx; + size_t readlen; + + readlen = destlen; + if (readlen > membuf->buflen) + readlen = membuf->buflen; + + memcpy(dest, membuf->buf, readlen); + + /* update buffer to the remainder */ + membuf->buf += readlen; + membuf->buflen -= readlen; + + return readlen; +} + +static int +hash_multiple_internal( + read_cb rcb, + void *ctx, + char *md5, + char *sha1, + char *sha256, + char *sha512, + char *blak2b, size_t *flen, - int hashes) + int hashes) { - FILE *f; - char data[8192]; size_t len; + char data[8192]; + struct md5_ctx m5; struct sha1_ctx s1; struct sha256_ctx s256; @@ -132,8 +157,6 @@ hash_multiple_file_fd( #endif *flen = 0; - if ((f = fdopen(fd, "r")) == NULL) - return -1; md5_init_ctx(&m5); sha1_init_ctx(&s1); @@ -143,7 +166,7 @@ hash_multiple_file_fd( blake2b_init(&bl2b, BLAKE2B_OUTBYTES); #endif - while ((len = fread(data, 1, sizeof(data), f)) > 0) { + while ((len = rcb(data, sizeof(data), ctx)) > 0) { *flen += len; #pragma omp parallel sections { @@ -176,7 +199,6 @@ hash_multiple_file_fd( #endif } } - fclose(f); #pragma omp parallel sections { @@ -227,6 +249,41 @@ hash_multiple_file_fd( return 0; } +/** + * Computes the hashes for file fname and writes the hex-representation + * for those hashes into the address space pointed to by the return + * pointers for these hashes. The caller should ensure enough space is + * available. Only those hashes which are in the global hashes variable + * are computed, the address space pointed to for non-used hashes are + * left untouched, e.g. they can be NULL. The number of bytes read from + * the file pointed to by fname is returned in the flen argument. + */ +int +hash_multiple_file_fd( + int fd, + char *md5, + char *sha1, + char *sha256, + char *sha512, + char *blak2b, + size_t *flen, + int hashes) +{ + FILE *f; + int ret; + + if ((f = fdopen(fd, "r")) == NULL) + return -1; + + ret = hash_multiple_internal(read_stdio, f, + md5, sha1, sha256, sha512, blak2b, + flen, hashes); + + fclose(f); + + return ret; +} + int hash_multiple_file_at_cb( int pfd, @@ -285,3 +342,35 @@ hash_file_at_cb(int pfd, const char *fname, int hash, hash_cb_t cb) return _hash_file_buf; } + +char * +hash_string(const char *buf, ssize_t buflen, int hash) +{ + struct bufctx membuf; + size_t dummy; + + if (buflen < 0) + buflen = (ssize_t)strlen(buf); + + membuf.buf = buf; + membuf.buflen = (size_t)buflen; + + switch (hash) { + case HASH_MD5: + case HASH_SHA1: + case HASH_SHA256: + case HASH_SHA512: + case HASH_BLAKE2B: + if (hash_multiple_internal(read_buffer, &membuf, + _hash_file_buf, _hash_file_buf, + _hash_file_buf, _hash_file_buf, + _hash_file_buf, + &dummy, hash) != 0) + return NULL; + break; + default: + return NULL; + } + + return _hash_file_buf; +} diff --git a/libq/hash.h b/libq/hash.h index fb4ab5f..ffbd2ef 100644 --- a/libq/hash.h +++ b/libq/hash.h @@ -44,5 +44,6 @@ int hash_multiple_file_at_cb( char *hash_file_at_cb(int pfd, const char *filename, int hash_algo, hash_cb_t cb); #define hash_file(f, h) hash_file_at_cb(AT_FDCWD, f, h, NULL) #define hash_file_at(fd, f, h) hash_file_at_cb(fd, f, h, NULL) +char *hash_string(const char *buf, ssize_t buflen, int hash); #endif