aboutsummaryrefslogtreecommitdiffstats
path: root/service/cleaner/main.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2021-07-07 23:17:31 +0200
committerLouis Burda <quent.burda@gmail.com>2021-07-07 23:17:39 +0200
commit8e430a00c145647cf6a67504640bd919af2c4fdf (patch)
tree1ad8cbac62cede66e383266d653b042337572058 /service/cleaner/main.c
parent3139342aa61d78985298d7450f97513a8aeec681 (diff)
downloadenowars5-service-stldoctor-8e430a00c145647cf6a67504640bd919af2c4fdf.tar.gz
enowars5-service-stldoctor-8e430a00c145647cf6a67504640bd919af2c4fdf.zip
stash before adding attack_info for fixing exploit variant 2
Diffstat (limited to 'service/cleaner/main.c')
-rw-r--r--service/cleaner/main.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/service/cleaner/main.c b/service/cleaner/main.c
new file mode 100644
index 0000000..ef48dfa
--- /dev/null
+++ b/service/cleaner/main.c
@@ -0,0 +1,155 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <dirent.h>
+#include <time.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+void
+die(const char *fmtstr, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "CLEANER: ");
+ va_start(ap, fmtstr);
+ vfprintf(stderr, fmtstr, ap);
+ va_end(ap);
+
+ exit(EXIT_FAILURE);
+}
+
+int
+creation_time(const char *path)
+{
+ struct stat attrib;
+
+ stat(path, &attrib);
+ return attrib.st_ctim.tv_sec;
+}
+
+char*
+aprintf(const char *fmtstr, ...)
+{
+ va_list ap, cpy;
+ size_t nb;
+ char *str;
+
+ va_copy(cpy, ap);
+
+ va_start(cpy, fmtstr);
+ nb = vsnprintf(NULL, 0, fmtstr, cpy);
+ va_end(cpy);
+
+ if (nb <= 0) die("Invalid fmtstr!\n");
+ str = malloc(nb+1);
+ if (!str) die("Alloc of fmtstr failed\n");
+
+ va_start(ap, fmtstr);
+ nb = vsnprintf(str, nb+1, fmtstr, ap);
+ va_end(ap);
+
+ return str;
+}
+
+void
+recdel(const char *path)
+{
+ struct stat attrib;
+ struct dirent *de;
+ char *subpath;
+ DIR *d;
+
+ stat(path, &attrib);
+ if (S_ISDIR(attrib.st_mode)) {
+ d = opendir(path);
+ while ((de = readdir(d))) {
+ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+ continue;
+ subpath = aprintf("%s/%s", path, de->d_name);
+ recdel(subpath);
+ free(subpath);
+ }
+ closedir(d);
+ rmdir(path);
+ } else {
+ remove(path);
+ }
+}
+
+int
+main(int argc, const char **argv)
+{
+ char buf[256], *end, *path,
+ **paths, *oldpath, *newpath;
+ unsigned long reftime;
+ int i, pathc, pathcap, nread;
+ const char *dirpath;
+ FILE *f, *fn;
+
+ if (argc != 3) die("USAGE: cleaner DIR REFTIME\n");
+
+ dirpath = argv[1];
+
+ reftime = strtoul(argv[2], &end, 10);
+ if (end && *end) die("Invalid unix time reference\n");
+
+ oldpath = aprintf("%s/.index", dirpath);
+ if (!(f = fopen(oldpath, "r+")))
+ die("Missing index file: %s\n", oldpath);
+ flock(fileno(f), LOCK_EX);
+
+ newpath = aprintf("%s/.index.next", dirpath);
+ if (!(fn = fopen(newpath, "w+")))
+ die("Failed to create index file: %s\n", newpath);
+
+ pathc = 0;
+ pathcap = 1024;
+ paths = malloc(pathcap * sizeof(char*));
+ if (!paths) die("OOM - allocating initial path array\n");
+
+ while (fgets(buf, sizeof(buf), f)) {
+ if (*buf && buf[strlen(buf)-1] == '\n')
+ buf[strlen(buf)-1] = '\0';
+
+ path = aprintf("%s/%s", dirpath, buf);
+ if (creation_time(path) < reftime) {
+ paths[pathc] = strdup(path);
+ if (!paths[pathc++]) die("OOM - during path str alloc\n");
+ if (pathc == pathcap) {
+ pathcap *= 2;
+ paths = realloc(paths, pathcap * sizeof(char*));
+ if (!paths) die("OOM - too many paths to alloc\n");
+ }
+ } else {
+ fwrite(buf, 1, strlen(buf), fn);
+ putc('\n', fn);
+ }
+ free(path);
+ }
+
+ fseek(f, 0, SEEK_SET);
+ fseek(fn, 0, SEEK_SET);
+ while ((nread = fread(buf, 1, sizeof(buf), fn)) > 0)
+ fwrite(buf, 1, nread, f);
+ ftruncate(fileno(f), ftell(f));
+
+ nread = ftell(f);
+
+ flock(fileno(f), LOCK_UN);
+ fclose(f);
+ fclose(fn);
+
+ if (!nread && getenv("DELROOT")) {
+ remove(oldpath);
+ remove(newpath);
+ }
+
+ for (i = 0; i < pathc; i++) {
+ printf("CLEANER: REMOVED %s\n", paths[i]);
+ recdel(paths[i]);
+ }
+}