From 13b65f01132c41be9ab8d9f92c2c5ca605c366d8 Mon Sep 17 00:00:00 2001 From: Louis Burda Date: Sat, 29 May 2021 14:24:31 +0200 Subject: changed repo structure and commited releease files such that default docker-compose worklow commands work in testvm --- src/main.c | 376 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 376 insertions(+) create mode 100644 src/main.c (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..de2bd48 --- /dev/null +++ b/src/main.c @@ -0,0 +1,376 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stlfile.h" +#include "util.h" + +#define MAXFILESIZE 7000 + +struct command { + const char *name; + void (*func)(const char *); + const char *desc; +}; + +int save_submission(struct parseinfo *info, char *data, int len); + +void cat_cmd(const char *arg); +void help_cmd(const char *arg); +void exit_cmd(const char *arg); +void echo_cmd(const char *arg); +void upload_cmd(const char *arg); +void search_cmd(const char *arg); +void list_cmd(const char *arg); +void auth_cmd(const char *arg); + +void cleanexit(); + +struct command commands[] = { + { "cat", cat_cmd, "Cat cmd go prrrrr." }, + { "help", help_cmd, "You already know what this does." }, + { "exit", exit_cmd, "Closes the session." }, + { "echo", echo_cmd, "Repeat after me!" }, + { "upload", upload_cmd, "Upload an STL file to analyze." }, + { "search", search_cmd, "Search for an STL file by model name." }, + { "list", list_cmd, "List your uploaded files." }, + { "auth", auth_cmd, "Login to upload files to a private dir." } +}; + +struct parseinfo cached; +char *resultdir; +int echo = 0, loggedin = 0; + +int +save_submission(struct parseinfo *info, char *stldata, int stlsize) +{ + DIR *d; + FILE *f = NULL; + char *dirpath = NULL, *infopath = NULL, *modelpath = NULL; + + if (loggedin) + dirpath = aprintf("%s/.%s-%i", resultdir, info->hash, time(NULL)); + else + dirpath = aprintf("%s/%s-%i", resultdir, info->hash, time(NULL)); + if (mkdir(dirpath, S_IRWXU | S_IRWXG | S_IRWXO)) goto fail; + + modelpath = aprintf("%s/%s", dirpath, "model"); + if (!(f = fopen(modelpath, "w+"))) goto fail; + if (fwrite(stldata, 1, stlsize, f) != stlsize) goto fail; + fclose(f); + f = NULL; + + infopath = aprintf("%s/%s", dirpath, "info"); + if (!(f = fopen(infopath, "w+"))) goto fail; + if (save_info(info, f) != OK) goto fail; + fclose(f); + f = NULL; + + free(dirpath); + free(modelpath); + free(infopath); + + return OK; + +fail: + if (f) fclose(f); + + if (infopath) remove(infopath); + if (modelpath) remove(modelpath); + if (dirpath) remove(dirpath); + + free(dirpath); + free(modelpath); + free(infopath); + + return FAIL; +} + +void +cat_cmd(const char *arg) +{ + if (arg && !strncmp(arg, "flag", 4)) + dump("msgs/cat_flag"); + else + printf("meow\n"); +} + +void +help_cmd(const char *arg) +{ + int i; + + if (arg) { + for (i = 0; i < ARRSIZE(commands); i++) { + if (!strcmp(commands[i].name, arg)) { + printf("%s\n", commands[i].desc); + return; + } + } + } + + printf("Available commands:\n"); + for (i = 0; i < ARRSIZE(commands); i++) + printf("%s%s", i ? " " : "", commands[i].name); + printf("\n"); +} + +void +exit_cmd(const char *arg) +{ + exit(0); +} + +void +echo_cmd(const char *arg) +{ + echo ^= 1; + printf("Echo is %s\n", echo ? "enabled" : "disabled"); +} + +void +upload_cmd(const char *arg) +{ + const char *bufp; + char *end, *contents; + size_t len; + + bufp = ask("How large is your file? "); + len = strtoul(bufp, &end, 10); + if (len <= 0 || len >= MAXFILESIZE || *end) { + fprintf(stderr, "Invalid file length!\n"); + return; + } + + printf("Ok! Im listening..\n"); + contents = checkp(malloc(len + 1)); + if (fread(contents, 1, len, stdin) != len) { + fprintf(stderr, "Hm, I'm missing some bytes.. try again!\n"); + goto cleanup; + } + contents[len] = '\0'; + + if ((cached.valid = parse_file(&cached, contents, len))) { + if (save_submission(&cached, contents, len) != OK) + fprintf(stderr, "Failed to save your submission!\n"); + else + printf("Your file was saved with ID %s!\n", cached.hash); + } + +cleanup: + free(contents); +} + +void +search_cmd(const char *arg) +{ + char *end, *scandir = NULL, *infopath = NULL, *modelpath = NULL; + int i, which, dirstart, ishidden; + const char *hash, *name; + struct dirent *de; + DIR *d = NULL; + FILE *f = NULL; + size_t size; + + if (arg && !strcmp(arg, "last")) { + if (!cached.valid) { + fprintf(stderr, "No cached info report available\n"); + return; + } + hash = cached.hash; + } else { + hash = mhash(arg ? arg : ask("Model name: "), -1); + } + + if (!(d = opendir(resultdir))) return; + + dirstart = telldir(d); + for (i = 0; (de = readdir(d));) { + name = de->d_name; + if (loggedin && *name == '.' && !strpfcmp(hash, name + 1) + || !loggedin && *name != '.' && !strpfcmp(hash, name)) { + printf("%i : %s\n", i, de->d_name); + i++; + } + } + + if (i == 0) { + fprintf(stderr, "Sorry, couldnt find a matching scan result!\n"); + goto cleanup; + } else { + which = strtoul(ask("Which of these results? "), &end, 10); + if (which >= i || which < 0 || *end) { + fprintf(stderr, "Invalid index!\n"); + goto cleanup; + } + } + + seekdir(d, dirstart); + for (i = 0; (de = readdir(d));) { + name = de->d_name; + if (loggedin && *name == '.' && !strpfcmp(hash, name + 1) + || !loggedin && *name != '.' && !strpfcmp(hash, name)) { + if (i == which) { + scandir = aprintf("%s/%s", resultdir, de->d_name); + break; + } + i++; + } + } + + /* file got cleaned up during race condition by background task */ + if (!scandir) { + fprintf(stderr, "Selected result spontaneously combusted!\n"); + goto cleanup; + } + + infopath = aprintf("%s/%s", scandir, "info"); + if (!(f = fopen(infopath, "r"))) goto cleanup; + free_info(&cached); + if (load_info(&cached, f) != OK) goto cleanup; + fclose(f); + f = NULL; + + print_info(&cached); + + if (strchr(ask("Download the model? "), 'y')) { + modelpath = aprintf("%s/%s", scandir, "model"); + if (!(f = fopen(modelpath, "r"))) goto cleanup; + fseek(f, 0, SEEK_END); + size = ftell(f); + fseek(f, 0, SEEK_SET); + if (size > MAXFILESIZE) goto cleanup; + printf("Here you go.. (%liB)\n", size); + while ((i = getc(f)) != EOF) + putc(i, stdout); + fclose(f); + f = NULL; + } + +cleanup: + if (f) fclose(f); + closedir(d); + free(scandir); + free(infopath); + free(modelpath); +} + +void +list_cmd(const char *arg) +{ + struct dirent *de; + struct parseinfo info; + char *path; + FILE *f; + DIR *d; + + if (!loggedin) { + fprintf(stderr, "Not logged in!\n"); + return; + } + + if (!(d = opendir(resultdir))) return; + + while ((de = readdir(d))) { + if (*de->d_name == '.' && !strchr(".", de->d_name[1])) { + printf(">> %s\n", de->d_name); + path = aprintf("%s/%s/info", resultdir, de->d_name); + if ((f = fopen(path, "r"))) { + if (load_info(&info, f) != OK) + fprintf(stderr, "Failed to read saved file info!\n"); + else + print_info(&info); + fclose(f); + } + free(path); + } + } +} + +void +auth_cmd(const char *arg) +{ + const char *hash; + char *ndir; + int ret; + + if (loggedin) { + fprintf(stderr, "Already logged in!\n"); + return; + } + + 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) { + printf("Success!\n"); + } else if (ret && errno == EEXIST) { + printf("Success!\nWelcome back!\n"); + } else { + fprintf(stderr, "Auth failed!\n"); + return; + } + + free(resultdir); + resultdir = ndir; + loggedin = 1; + cached.valid = 0; +} + +void +cleanexit() +{ + printf("see you later!\n"); + free_info(&cached); + free(resultdir); +} + +int +main() +{ + const char *cmd; + char *cp, *arg; + int exit, i, cmdlen; + + if (!(resultdir = checkp(strdup(getenv("RESULTDIR"))))) { + fprintf(stderr, "RESULTDIR not defined\n"); + return 1; + } + + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + atexit(cleanexit); + + dump("msgs/welcome"); + + exit = 0; + while (!exit) { + errno = 0; + cmd = ask("$ "); + if (!*cmd && errno == EBADMSG) break; + if (!*cmd) continue; + + cp = strchr(cmd, ' '); + arg = cp ? cp + 1 : NULL; + cmdlen = cp ? cp - cmd : strlen(cmd); + + for (i = 0; i < ARRSIZE(commands); i++) { + if (!strncmp(commands[i].name, cmd, cmdlen) + && cmdlen == strlen(commands[i].name)) { + commands[i].func(arg); + break; + } + } + + if (i == ARRSIZE(commands) && strlen(cmd) != 0) + fprintf(stderr, "No such command!\n"); + } +} -- cgit v1.2.3-71-gd317