aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2021-05-29 14:24:31 +0200
committerLouis Burda <quent.burda@gmail.com>2021-05-29 14:24:31 +0200
commit13b65f01132c41be9ab8d9f92c2c5ca605c366d8 (patch)
tree74bd5b4dee779e4600d416adf4abcd4f621addab /src/main.c
parent62d99253144a14648c4da1c2a60c01e7b06ef02c (diff)
downloadenowars5-service-stldoctor-13b65f01132c41be9ab8d9f92c2c5ca605c366d8.tar.gz
enowars5-service-stldoctor-13b65f01132c41be9ab8d9f92c2c5ca605c366d8.zip
changed repo structure and commited releease files such that default docker-compose worklow commands work in testvm
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c376
1 files changed, 376 insertions, 0 deletions
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 <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <errno.h>
+
+#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");
+ }
+}