aboutsummaryrefslogtreecommitdiffstats
path: root/get.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 /get.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 'get.c')
-rw-r--r--get.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/get.c b/get.c
new file mode 100644
index 0000000..5758388
--- /dev/null
+++ b/get.c
@@ -0,0 +1,99 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+struct recursion_buffer {
+ char *buf;
+ size_t size;
+ size_t len;
+};
+
+
+static int
+calculate_and_print(const char *file, struct barrier_group *group, struct global_data *global, struct recursion_buffer *recbuf)
+{
+ struct dirent *f;
+ DIR *dir;
+ size_t i, len, old_len;
+
+ if (!recbuf)
+ goto as_file;
+ dir = opendir(file);
+ if (!dir)
+ goto as_file;
+ if (recbuf->size - recbuf->len < strlen(file) + 1U) {
+ recbuf->size = recbuf->len + strlen(file) + 1U;
+ recbuf->buf = erealloc(recbuf->buf, recbuf->size);
+ }
+ old_len = recbuf->len;
+ stpcpy(&recbuf->buf[recbuf->len], file);
+ recbuf->len += strlen(file);
+ if (recbuf->buf[recbuf->len - 1U] != '/')
+ recbuf->buf[recbuf->len++] = '/';
+ len = recbuf->len;
+ while ((errno = 0, f = readdir(dir))) {
+ if (recbuf->size - len < strlen(f->d_name) + 1U) {
+ recbuf->size = len + strlen(f->d_name) + 1U;
+ recbuf->buf = erealloc(recbuf->buf, recbuf->size);
+ }
+ stpcpy(&recbuf->buf[len], f->d_name);
+ if (calculate_and_print(recbuf->buf, group, global, recbuf))
+ goto recusion_error;
+ }
+ recbuf->len = old_len;
+ recbuf->buf[recbuf->len] = '\0';
+ if (errno) {
+ weprintf("%s:", file);
+ recusion_error:
+ closedir(dir);
+ return -1;
+ }
+ closedir(dir);
+ return 0;
+
+as_file:
+ global->file = file;
+ if (calculate(global->file, group, global))
+ return -1;
+ for (i = 0; i < global->nalgorithms; i++)
+ writeall(STDOUT_FILENO, global->algorithms[i].result, global->algorithms[i].result_length, "<stdout>");
+ return 0;
+}
+
+
+int
+calculate_and_print_each(char **files, struct algorithm *algorithms, size_t nalgorithms,
+ size_t nthreads, enum format format, int hexinput, int recursive)
+{
+ struct recursion_buffer recbuf = {NULL, 0, 0};
+ size_t wanted_nalgorithms = nalgorithms;
+ struct buffer buffer = {0};
+ struct barrier_group group;
+ struct global_data global;
+ int ret = 0;
+
+ global.format = format;
+ global.hexinput = hexinput;
+ global.buffer = &buffer;
+ global.algorithms = algorithms;
+ global.nalgorithms = nalgorithms;
+
+ if (!nthreads)
+ nthreads = getautonthreads();
+ nthreads = MAX(MIN(nalgorithms, nthreads), 1U);
+
+ createbarriergroup(&group, nthreads, &global);
+
+ for (; *files; files++)
+ if (calculate_and_print(*files, &group, &global, recursive ? &recbuf : NULL))
+ ret = 2;
+
+ if (global.nalgorithms != wanted_nalgorithms)
+ ret = 2;
+
+ killbarriergroup(&group, &global);
+
+ free(buffer.buf);
+ free(recbuf.buf);
+ return ret;
+}