#include #include #include #include #include #include #include #include #include "stlfile.h" #include "util.h" #define MAXFILESIZE 7000 struct command { const char *name; void (*func)(char *); }; int save_submission(struct parseinfo *info, char *data, int len); void cat_cmd(char *arg); void list_cmd(char *arg); void submit_cmd(char *arg); void query_cmd(char *arg); struct command commands[] = { { "cat", cat_cmd }, { "help", list_cmd }, { "submit", submit_cmd }, { "query", query_cmd }, }; struct parseinfo cached; const char *resultdir; int save_submission(struct parseinfo *info, char *stldata, int stlsize) { DIR *d; FILE *f; char *dirpath = NULL, *infopath = NULL, *modelpath = NULL; 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); remove(infopath); remove(modelpath); remove(dirpath); free(dirpath); free(modelpath); free(infopath); return FAIL; } void cat_cmd(char *arg) { if (arg && !strncmp(arg, "flag", 4)) dump("msgs/cat_flag"); else printf("meow\n"); } void list_cmd(char *arg) { int i; printf("Available commands:\n"); for (i = 0; i < ARRSIZE(commands); i++) printf("%s%s", i ? " " : "", commands[i].name); printf("\n"); } void submit_cmd(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)); fread(contents, 1, len, stdin); 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); } free(contents); } void query_cmd(char *arg) { char *end, *scandir = NULL, *infopath = NULL, *modelpath = NULL; const char *hash; struct dirent *de; int i, which, dirstart; DIR *d = NULL; FILE *f = NULL; size_t size; if (cached.valid) hash = cached.hash; else hash = mhash(ask("> What is the model name? "), -1); if (!(d = opendir(resultdir))) return; dirstart = telldir(d); for (i = 0; (de = readdir(d));) { if (!strpfcmp(hash, de->d_name) && *de->d_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));) { if (!strpfcmp(hash, de->d_name) && *de->d_name != '.') { if (i == which) { scandir = aprintf("%s/%s", resultdir, de->d_name); break; } i++; } } if (!scandir) { fprintf(stderr, "Unexpected error!\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 cleanexit() { free_info(&cached); } int main() { char linebuf[256], *cp, *arg; int exit, i; if (!(resultdir = getenv("RESULTDIR"))) resultdir = "scans"; setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); atexit(cleanexit); dump("msgs/welcome"); exit = 0; while (!exit) { memset(linebuf, '\0', sizeof(linebuf)); printf("$ "); exit = !fgets(linebuf, sizeof(linebuf), stdin); if (exit || !*linebuf) break; if (*linebuf == '\n') continue; linebuf[strlen(linebuf) - 1] = '\0'; cp = strchr(linebuf, ' '); arg = cp ? cp + 1 : NULL; if (cp) *cp = 0; for (i = 0; i < ARRSIZE(commands); i++) { if (!strcmp(commands[i].name, linebuf)) { commands[i].func(arg); break; } } if (i == ARRSIZE(commands) && strlen(linebuf) != 0) fprintf(stderr, "No such command!\n"); } printf("see you later!\n"); free_info(&cached); }