enowars5-service-stldoctor

STL-Analyzing A/D Service for ENOWARS5 in 2021
git clone https://git.sinitax.com/sinitax/enowars5-service-stldoctor
Log | Files | Refs | README | LICENSE | sfeed.txt

commit 3139342aa61d78985298d7450f97513a8aeec681
parent 8ee81f0d908bee3991248d3c86e5ce0ab2219a05
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed,  7 Jul 2021 14:22:52 +0200

added .index file for upload and search

Diffstat:
Mservice/src/main.c | 114+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mservice/src/util.c | 8++++----
Msrc/main.c | 118++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msrc/util.c | 8++++----
4 files changed, 148 insertions(+), 100 deletions(-)

diff --git a/service/src/main.c b/service/src/main.c @@ -4,14 +4,16 @@ #include <unistd.h> #include <dirent.h> #include <fcntl.h> -#include <sys/stat.h> #include <time.h> #include <errno.h> +#include <sys/stat.h> +#include <sys/file.h> + #include "stlfile.h" #include "util.h" -#define MAXFILESIZE 50000 +#define MAXFILESIZE 1000000 struct command { const char *name; @@ -50,15 +52,15 @@ int echo = 0, loggedin = 0; int save_submission(struct parseinfo *info, char *stldata, int stlsize) { - char *dirpath = NULL, *infopath = NULL, *modelpath = NULL; + char *dirpath = NULL, *infopath = NULL, *modeldir = NULL, + *indexpath = NULL, *modelpath = NULL; FILE *f = NULL; int status = OK; DIR *d; - if (loggedin) - dirpath = aprintf("%s/.%s-%i", resultdir, info->hash, time(NULL)); - else - dirpath = aprintf("%s/%s-%i", resultdir, info->hash, time(NULL)); + modeldir = aprintf("%s%s-%i", loggedin ? "." : "", + info->hash, time(NULL)); + dirpath = aprintf("%s/%s", resultdir, modeldir); if (mkdir(dirpath, S_IRWXU | S_IRWXG | S_IRWXO)) goto fail; modelpath = aprintf("%s/%s", dirpath, "model"); @@ -71,12 +73,22 @@ save_submission(struct parseinfo *info, char *stldata, int stlsize) if (save_info(info, f) != OK) goto fail; FCLOSE(f); + indexpath = aprintf("%s/.index", resultdir); + if (!(f = fopen(indexpath, "a+"))) goto fail; + flock(fileno(f), LOCK_EX); + fwrite(modeldir, 1, strlen(modeldir), f); + fputc('\n', f); + flock(fileno(f), LOCK_UN); + FCLOSE(f); + exit: - if (f) fclose(f); + FCLOSE(f); free(dirpath); free(modelpath); free(infopath); + free(indexpath); + free(modeldir); return status; @@ -119,7 +131,7 @@ handle_download(const char *scandir) print_info(&cached); - if (strchr(ask("Download the model? "), 'y')) { + if (strchr(ask("> Download model? "), 'y')) { modelpath = aprintf("%s/%s", scandir, "model"); if (!(f = fopen(modelpath, "r"))) { ERR("Failed to access file!\n"); @@ -222,13 +234,13 @@ upload_cmd(const char *arg) const char *resp; size_t len; - modelname = checkp(strdup(ask("Enter a model name: "))); + modelname = checkp(strdup(ask("> Model name: "))); if (!strlen(modelname)) { ERR("Empty model names are not allowed"); goto exit; } - resp = ask("How large is your file? "); + resp = ask("> File size: "); len = strtoul(resp, &end, 10); if (len <= 0 || len >= MAXFILESIZE || *end) { ERR("Invalid file length!\n"); @@ -258,11 +270,10 @@ exit: void search_cmd(const char *arg) { - char *end, *scandir = NULL, **paths = NULL; - int i, which, pathc, pathcap = 100; - const char *hash, *name, *resp; - struct dirent *de; - DIR *d = NULL; + const char *hash, *resp = NULL; + char *indexpath = NULL, *seldir = NULL; + FILE *f; + int i, c, matchlen, reslen; if (arg && !strcmp(arg, "last")) { if (!cached.valid) { @@ -271,53 +282,64 @@ search_cmd(const char *arg) } hash = cached.hash; } else { - hash = mhash(arg ? arg : ask("Model name: "), -1); + hash = mhash(arg ? arg : ask("> Model name: "), -1); } - if (!(d = opendir(resultdir))) { - ERR("Unable to access upload directory!\n"); - return; + indexpath = aprintf("%s/.index", resultdir); + if (!(f = fopen(indexpath, "r"))) { + ERR("Sorry, no files currently available\n"); + goto exit; } - - paths = checkp(malloc(pathcap * sizeof(char*))); - for (pathc = 0; (de = readdir(d));) { - if (access_authorized(de->d_name) - && !strpfcmp(hash, de->d_name + (loggedin ? 1 : 0))) { - printf("%i : %s\n", pathc, de->d_name); - paths[pathc++] = checkp(strdup(de->d_name)); - if (pathc == pathcap) { - pathcap *= 2; - paths = realloc(paths, pathcap * sizeof(char*)); - checkp(paths); + flock(fileno(f), LOCK_SH); + + reslen = matchlen = 0; + while ((c = fgetc(f)) > 0) { + if (c == '\n') { + matchlen = 0; + } else if (matchlen == -1) { + continue; + } else if (c == hash[matchlen]) { + matchlen += 1; + if (matchlen == strlen(hash)) { + fseek(f, -matchlen, SEEK_CUR); + putchar(' '); + while ((c = fgetc(f)) > 0 && c != '\n') + putchar(c); + putchar('\n'); + matchlen = 0; + reslen += 1; } + } else { + matchlen = -1; } } - closedir(d); - if (pathc == 0) { - ERR("Couldn't find a matching scan result!\n"); + flock(fileno(f), LOCK_UN); + fclose(f); + + if (!reslen) { + ERR("Sorry, no files matching that name\n"); goto exit; } while (1) { - resp = ask("Which result [q to quit]? "); + resp = ask("> Enter %s [q to quit]: ", + resp ? "another" : "hash"); if (strchr(resp, 'q')) break; - which = strtoul(resp, &end, 10); - if (which >= pathc || which < 0 || *end) { - ERR("Invalid index!\n"); + if (checkalph(resp, "abcdef0123456789-") != OK) { + ERR("Invalid model id specified\n"); goto exit; } - scandir = aprintf("%s/%s", resultdir, paths[which]); - if (handle_download(scandir) != OK) goto exit; - FREE(scandir); + seldir = aprintf("%s/%s", resultdir, resp); + if (handle_download(seldir) != OK) goto exit; + FREE(seldir); } exit: - FREE(scandir); - - for (i = 0; i < pathc; i++) free(paths[i]); - free(paths); + free(seldir); + free(indexpath); + return; } void @@ -366,7 +388,7 @@ auth_cmd(const char *arg) return; } - hash = mhash(arg ? arg : ask("Enter a password: "), -1); + hash = mhash(arg ? arg : ask("> Enter a password: "), -1); ndir = aprintf("%s/.%s", resultdir, hash); ret = mkdir(ndir, S_IRWXU | S_IRWXG | S_IRWXO); if (!ret) { diff --git a/service/src/util.c b/service/src/util.c @@ -64,12 +64,12 @@ mhash(const char *str, int len) int checkalph(const char *str, const char *alph) { - int i; + const char *c; - for (i = 0; i < strlen(str); i++) - if (str[i] && !strchr(alph, str[i])) return 0; + for (c = str; *c; c++) + if (!strchr(alph, *c)) return FAIL; - return 1; + return OK; } void diff --git a/src/main.c b/src/main.c @@ -4,14 +4,16 @@ #include <unistd.h> #include <dirent.h> #include <fcntl.h> -#include <sys/stat.h> #include <time.h> #include <errno.h> +#include <sys/stat.h> +#include <sys/file.h> + #include "stlfile.h" #include "util.h" -#define MAXFILESIZE 50000 // 20kB file limit +#define MAXFILESIZE 1000000 struct command { const char *name; @@ -50,15 +52,15 @@ int echo = 0, loggedin = 0; int save_submission(struct parseinfo *info, char *stldata, int stlsize) { - char *dirpath = NULL, *infopath = NULL, *modelpath = NULL; + char *dirpath = NULL, *infopath = NULL, *modeldir = NULL, + *indexpath = NULL, *modelpath = NULL; FILE *f = NULL; int status = OK; DIR *d; - if (loggedin) - dirpath = aprintf("%s/.%s-%i", resultdir, info->hash, time(NULL)); - else - dirpath = aprintf("%s/%s-%i", resultdir, info->hash, time(NULL)); + modeldir = aprintf("%s%s-%i", loggedin ? "." : "", + info->hash, time(NULL)); + dirpath = aprintf("%s/%s", resultdir, modeldir); if (mkdir(dirpath, S_IRWXU | S_IRWXG | S_IRWXO)) goto fail; modelpath = aprintf("%s/%s", dirpath, "model"); @@ -71,12 +73,22 @@ save_submission(struct parseinfo *info, char *stldata, int stlsize) if (save_info(info, f) != OK) goto fail; FCLOSE(f); + indexpath = aprintf("%s/.index", resultdir); + if (!(f = fopen(indexpath, "a+"))) goto fail; + flock(fileno(f), LOCK_EX); + fwrite(modeldir, 1, strlen(modeldir), f); + fputc('\n', f); + flock(fileno(f), LOCK_UN); + FCLOSE(f); + exit: - if (f) fclose(f); + FCLOSE(f); free(dirpath); free(modelpath); free(infopath); + free(indexpath); + free(modeldir); return status; @@ -119,7 +131,7 @@ handle_download(const char *scandir) print_info(&cached); - if (strchr(ask("Download the model? "), 'y')) { + if (strchr(ask("> Download model? "), 'y')) { modelpath = aprintf("%s/%s", scandir, "model"); if (!(f = fopen(modelpath, "r"))) { ERR("Failed to access file!\n"); @@ -222,13 +234,13 @@ upload_cmd(const char *arg) const char *resp; size_t len; - modelname = checkp(strdup(ask("Enter a model name: "))); + modelname = checkp(strdup(ask("> Model name: "))); if (!strlen(modelname)) { ERR("Empty model names are not allowed"); goto exit; } - resp = ask("How large is your file? "); + resp = ask("> File size: "); len = strtoul(resp, &end, 10); if (len <= 0 || len >= MAXFILESIZE || *end) { ERR("Invalid file length!\n"); @@ -258,12 +270,12 @@ exit: void search_cmd(const char *arg) { - char *end, *scandir = NULL, **paths = NULL; - int i, which, pathc, pathcap = 100; - const char *hash, *name, *resp; - struct dirent *de; - DIR *d = NULL; + const char *hash, *resp = NULL; + char *indexpath = NULL, *seldir = NULL; + FILE *f; + int i, c, matchlen, reslen; + /* either choose cached or request new entry */ if (arg && !strcmp(arg, "last")) { if (!cached.valid) { ERR("No cached info report available\n"); @@ -271,53 +283,67 @@ search_cmd(const char *arg) } hash = cached.hash; } else { - hash = mhash(arg ? arg : ask("Model name: "), -1); + hash = mhash(arg ? arg : ask("> Model name: "), -1); } - if (!(d = opendir(resultdir))) { - ERR("Unable to access upload directory!\n"); - return; + /* open and lock index file access */ + indexpath = aprintf("%s/.index", resultdir); + if (!(f = fopen(indexpath, "r"))) { + ERR("Sorry, no files currently available\n"); + goto exit; } - - paths = checkp(malloc(pathcap * sizeof(char*))); - for (pathc = 0; (de = readdir(d));) { - if (access_authorized(de->d_name) - && !strpfcmp(hash, de->d_name + (loggedin ? 1 : 0))) { - printf("%i : %s\n", pathc, de->d_name); - paths[pathc++] = checkp(strdup(de->d_name)); - if (pathc == pathcap) { - pathcap *= 2; - paths = realloc(paths, pathcap * sizeof(char*)); - checkp(paths); + flock(fileno(f), LOCK_SH); + + /* output lines that have hash as prefix */ + reslen = matchlen = 0; + while ((c = fgetc(f)) > 0) { + if (c == '\n') { + matchlen = 0; + } else if (matchlen == -1) { + continue; + } else if (c == hash[matchlen]) { + matchlen += 1; + if (matchlen == strlen(hash)) { + fseek(f, -matchlen, SEEK_CUR); + putchar(' '); + while ((c = fgetc(f)) > 0 && c != '\n') + putchar(c); + putchar('\n'); + matchlen = 0; + reslen += 1; } + } else { + matchlen = -1; } } - closedir(d); - if (pathc == 0) { - ERR("Couldn't find a matching scan result!\n"); + flock(fileno(f), LOCK_UN); + fclose(f); + + if (!reslen) { + ERR("Sorry, no files matching that name\n"); goto exit; } + /* allow user to choose files to access */ while (1) { - resp = ask("Which result [q to quit]? "); + resp = ask("> Enter %s [q to quit]: ", + resp ? "another" : "hash"); if (strchr(resp, 'q')) break; - which = strtoul(resp, &end, 10); - if (which >= pathc || which < 0 || *end) { - ERR("Invalid index!\n"); + if (checkalph(resp, "abcdef0123456789-") != OK) { + ERR("Invalid model id specified\n"); goto exit; } - scandir = aprintf("%s/%s", resultdir, paths[which]); - if (handle_download(scandir) != OK) goto exit; - FREE(scandir); + seldir = aprintf("%s/%s", resultdir, resp); + if (handle_download(seldir) != OK) goto exit; + FREE(seldir); } exit: - FREE(scandir); - - for (i = 0; i < pathc; i++) free(paths[i]); - free(paths); + free(seldir); + free(indexpath); + return; } void @@ -366,7 +392,7 @@ auth_cmd(const char *arg) return; } - hash = mhash(arg ? arg : ask("Enter a password: "), -1); + hash = mhash(arg ? arg : ask("> Enter a password: "), -1); ndir = aprintf("%s/.%s", resultdir, hash); ret = mkdir(ndir, S_IRWXU | S_IRWXG | S_IRWXO); if (!ret) { diff --git a/src/util.c b/src/util.c @@ -67,12 +67,12 @@ mhash(const char *str, int len) int checkalph(const char *str, const char *alph) { - int i; + const char *c; - for (i = 0; i < strlen(str); i++) - if (str[i] && !strchr(alph, str[i])) return 0; + for (c = str; *c; c++) + if (!strchr(alph, *c)) return FAIL; - return 1; + return OK; } void