From 05020632bc1cb10a84805143e19d01f7244059be Mon Sep 17 00:00:00 2001 From: Luis Gerhorst <privat@luisgerhorst.de> Date: Thu, 13 May 2021 20:42:41 +0200 Subject: [PATCH] fp-based find-magic --- src/task-find-magic | 2 +- src/task_filter_magic.c | 67 ++++++++++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/task-find-magic b/src/task-find-magic index a97489e..f3d77e6 100755 --- a/src/task-find-magic +++ b/src/task-find-magic @@ -6,4 +6,4 @@ args=${@:2} src_dir=$(dirname "$(command -v $0)") -find "${path}" | env -C "$src_dir" ./task_filter_magic ${args} +find "${path}" | ${src_dir}/task_filter_magic ${args} diff --git a/src/task_filter_magic.c b/src/task_filter_magic.c index 45a0c7a..4194008 100644 --- a/src/task_filter_magic.c +++ b/src/task_filter_magic.c @@ -181,20 +181,17 @@ destroy: return EXIT_SUCCESS; } -static char *safe_fgets(char *s, int size, FILE *stream) { - char *res = fgets(s, size, stream); - if (res == NULL && ferror(stream)) { - perror("fgets"); - exit(EXIT_FAILURE); - } - return res; -} - #define MAX_PATHLEN 512 static int filter_magic(size_t offset, const char *magic) { + int err; + size_t magic_size = strlen(magic) + 1; + char buf[magic_size]; + buf[magic_size-1] = '\0'; + while (true) { char pathbuf[MAX_PATHLEN]; + /* TODO: What if line too long? */ char *ptr = fgets(pathbuf, MAX_PATHLEN, stdin); if (ptr == NULL) { if (ferror(stdin)) { @@ -206,9 +203,57 @@ static int filter_magic(size_t offset, const char *magic) { } } - pathbuf[strlen(pathbuf)] = '\0'; - + /* Line must end with a newline. */ + pathbuf[strlen(pathbuf)-1] = '\0'; log_debug("pathbuf = %s", pathbuf); + + FILE *fp = fopen(pathbuf, "r"); + if (!fp) { + perror(pathbuf); + return EXIT_FAILURE; + } + + struct stat statbuf; + err = fstat(fileno(fp), &statbuf); + if (err != 0) { + log_debug("Skipping %s: Error fstat()ing file.", pathbuf); + goto fclose; + } + + // handling only regular files and FIFOs + if (!S_ISREG(statbuf.st_mode) && !S_ISFIFO(statbuf.st_mode)) { + log_debug("Skipping %s: Mode %u is not a file.", pathbuf, statbuf.st_mode); + goto fclose; + } + + if (statbuf.st_size < offset + magic_size-1) { + goto fclose; + } + + if (offset) { + err = fseek(fp, offset, SEEK_SET); + if (err) { + perror("fseek"); + return EXIT_FAILURE; + } + } + + size_t nread = fread(buf, sizeof(char), magic_size-1, fp); + if (nread < magic_size-1) { + log_err("fread(%s) returned short item count", pathbuf); + return EXIT_FAILURE; + } + + if (strcmp(magic, buf) == 0) { + printf("%s\n", pathbuf); + } + + fclose: + err = fclose(fp); + if (err) { + perror("fclose"); + return EXIT_FAILURE; + } } } -- GitLab