cmogstored 1.8.1 - use default system stack size
[cmogstored.git] / digest.c
blob3990812c5531992ae81783e2aa9654601b94705c
1 /*
2 * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
3 * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
4 */
5 #include "cmogstored.h"
6 #include "digest.h"
8 __attribute__((constructor)) static void digest_init(void)
10 CHECK(Gc_rc, GC_OK, gc_init());
11 atexit(gc_done);
14 void mog_digest_init(struct mog_digest *digest, enum Gc_hash alg)
16 digest->alg = alg;
17 CHECK(Gc_rc, GC_OK, gc_hash_open(alg, 0, &digest->ctx));
20 enum mog_digest_next mog_digest_read(struct mog_digest *digest, int fd)
22 size_t len;
23 char *buf = mog_fsbuf_get(&len);
24 size_t i = 1024;
26 while (--i > 0) {
27 ssize_t r = read(fd, buf, len);
29 if (r > 0) { /* most likely */
30 gc_hash_write(digest->ctx, r, buf);
31 if (mog_thr_prepare_quit())
32 return MOG_DIGEST_YIELD;
33 } else if (r == 0) {
34 /* wait for user to call mog_digest_hex() */
35 return MOG_DIGEST_EOF;
36 } else {
37 assert(r < 0 && errno && "buggy read(2)?");
38 /* may happen on crazy FSes */
39 if (errno == EINTR)
40 continue;
41 /* bail on EAGAIN, not possible on regular files */
42 return MOG_DIGEST_ERROR;
46 return MOG_DIGEST_CONTINUE;
49 void mog_digest_hex(struct mog_digest *digest, char *buf, size_t len)
51 static const char hex[] = "0123456789abcdef";
52 char *out = buf;
53 size_t hashlen = gc_hash_digest_length(digest->alg);
54 union { const char *s; const unsigned char *u; } result;
56 result.s = gc_hash_read(digest->ctx);
58 /* hashlen = 16 for MD5, 20 for SHA-1 */
59 if (digest->alg == GC_MD5)
60 assert(hashlen == 16 && "bad hashlen");
61 assert(len >= (hashlen * 2) && "hex buffer too small");
62 assert(hashlen != 0 && "bad hashlen");
64 while (hashlen--) {
65 *out++ = hex[*result.u >> 4];
66 *out++ = hex[*result.u & 0x0f];
67 result.u++;
71 void mog_digest_destroy(struct mog_digest *digest)
73 if (digest->ctx)
74 gc_hash_close(digest->ctx);