aboutsummaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2024-08-28 16:42:05 +0200
committerMattias Andrée <maandree@kth.se>2024-08-28 16:42:05 +0200
commita24071ae913b223487df78859c8d830f9e69f580 (patch)
treee2ec712cc29461c82cfdd477e8b1ba961b50018d /hash.c
parentFirst commit (diff)
downloadanysum-a24071ae913b223487df78859c8d830f9e69f580.tar.gz
anysum-a24071ae913b223487df78859c8d830f9e69f580.tar.bz2
anysum-a24071ae913b223487df78859c8d830f9e69f580.tar.xz
Second commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/hash.c b/hash.c
new file mode 100644
index 0000000..0784c78
--- /dev/null
+++ b/hash.c
@@ -0,0 +1,98 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+size_t
+inithashers(struct algorithm *algorithms, size_t nalgorithms)
+{
+ size_t i;
+ for (i = 0; i < nalgorithms;) {
+ if (libhashsum_init_hasher_from_string(&algorithms[i].hasher, algorithms[i].algostr)) {
+ weprintf("%s:", algorithms[i].algostr);
+ free(algorithms[i].result);
+ /* keep order */
+ memmove(&algorithms[i], &algorithms[i + 1U], (--nalgorithms - i) * sizeof(*algorithms));
+ } else {
+ algorithms[i].offset = 0;
+ i++;
+ }
+ }
+ return nalgorithms;
+}
+
+
+void
+destroyhashers(struct algorithm *algorithms, size_t nalgorithms)
+{
+ size_t i;
+ for (i = 0; i < nalgorithms; i++)
+ if (algorithms[i].hasher.destroy)
+ algorithms[i].hasher.destroy(&algorithms[i].hasher);
+}
+
+
+static void
+process(struct algorithm *algorithm, struct global_data *global)
+{
+ size_t r;
+ r = algorithm->hasher.process(&algorithm->hasher,
+ &global->buffer->buf[algorithm->offset],
+ global->buffer->ready - algorithm->offset);
+ algorithm->offset += r;
+}
+
+
+static void
+finalise(struct algorithm *algorithm, struct global_data *global)
+{
+ if (algorithm->hasher.finalise_const(&algorithm->hasher, &global->buffer->buf[algorithm->offset],
+ global->buffer->ready - algorithm->offset, 0))
+ abort();
+ format_result(algorithm, global->file, global->format, global->hexinput);
+}
+
+
+int
+calculate(const char *file, struct barrier_group *group, struct global_data *global)
+{
+ int fd, is_new_fd, r, ret = -1, saved_errno;
+ const char *fname;
+
+ global->nalgorithms = inithashers(global->algorithms, global->nalgorithms);
+ if (!global->nalgorithms)
+ return 0;
+
+ fd = openfile(file, &is_new_fd, &fname);
+ if (fd < 0)
+ return -1;
+
+ global->buffer->ready = 0;
+ global->buffer->procoff = 0;
+ global->buffer->offset = 0;
+ while (!(r = feedbuffer(fd, global->buffer, fname))) {
+ if (!global->hexinput) {
+ global->buffer->ready = global->buffer->offset;
+ global->buffer->procoff = global->buffer->offset;
+ } else {
+ if (unhex(global->buffer)) {
+ weprintf("%s: not a hexadecimal file", fname);
+ errno = 0;
+ goto fail;
+ }
+ }
+ barriersend(group, global, &process);
+ shiftbuffer(global->algorithms, global->nalgorithms, global->buffer);
+ }
+ if (r < 0)
+ goto fail;
+
+ barriersend(group, global, &finalise);
+ ret = 0;
+fail:
+ saved_errno = errno;
+ destroyhashers(global->algorithms, global->nalgorithms);
+ if (is_new_fd)
+ close(fd);
+ errno = saved_errno;
+ return ret;
+}