#include #include #include #include #include #include "stlfile.h" #define ARRSIZE(x) (sizeof(x)/sizeof((x)[0])) #define MIN(x,y) ((x) > (y) ? (y) : (x)) struct command { const char *name; void (*func)(char *); }; void* checkp(void *p); const char* ask(const char *fmtstr, ...); void* die(const char *fmtstr, ...); char* aprintf(const char *fmtstr, ...); void dump(const char *filepath); void search_cmd(char *arg); void submit_cmd(char *arg); void list_cmd(char *arg); void cat_cmd(char *arg); struct command commands[] = { { "submit", submit_cmd }, { "cat", cat_cmd }, { "help", list_cmd }, { "search", search_cmd } }; struct parseinfo *lastrun = NULL; const char *resultdir; void* checkp(void *p) { if (!p) die("pointer assertion failed, OOM?\n"); return p; } const char* ask(const char *fmtstr, ...) { static char linebuf[256]; va_list ap; int fail; va_start(ap, fmtstr); vprintf(fmtstr, ap); va_end(ap); fail = !fgets(linebuf, sizeof(linebuf), stdin); if (!fail) linebuf[strlen(linebuf) - 1] = '\0'; return fail ? "" : linebuf; } void* die(const char *fmtstr, ...) { va_list ap; va_start(ap, fmtstr); vfprintf(stderr, fmtstr, ap); va_end(ap); exit(EXIT_FAILURE); } 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, ap); va_end(cpy); if (nb <= 0) die("encountered invalid fmtstr!\n"); str = checkp(malloc(nb)); va_start(ap, fmtstr); nb = vsnprintf(str, nb, fmtstr, ap); va_end(ap); return str; } char* strhash(const char *filename) { static const char *hexalph = "0123456789ABCDEF"; char *buf; int i, k; buf = checkp(malloc(33)); for (i = 0; i < MIN(32, strlen(filename)); i++) { unsigned char v = 0; for (k = i; k < strlen(filename); k += 32) v ^= filename[k]; buf[i*2+0] = hexalph[(v >> 0) & 0x0f]; buf[i*2+1] = hexalph[(v >> 4) & 0x0f]; } if (i == 0) { memset(buf, '0', 32); } else if (i < 32) { for (k = 0; k < 32; k++) buf[k] = buf[k % i]; } buf[32] = '\0'; return buf; } void dump(const char *filename) { char buf[256]; FILE *f; int nb; if (!(f = fopen(filename, "r"))) return; while ((nb = fread(buf, 1, sizeof(buf), f))) printf("%.*s\n", nb, buf); fclose(f); } void search_cmd(char *arg) { char *end, *resultfile = NULL; char *hash; struct dirent *de; int i, which; DIR *d = NULL; if (!lastrun) hash = strhash(ask("What is the model name?\n")); else hash = checkp(strdup(lastrun->namehash)); d = opendir("scans"); if (!d) return; i = 0; while ((de = readdir(d))) { if (de->d_type != DT_DIR && !strncmp(hash, de->d_name, strlen(hash))) { printf("%i : %s\n", i, de->d_name); i++; } } if (i == 0) { fprintf(stderr, "Sorry, couldnt find any matching scan result!\n"); goto cleanup; } else { which = strtoul(ask("Which of these results?\n"), &end, 10); if (which >= i || which < 0 || *end) { fprintf(stderr, "Invalid index!\n"); goto cleanup; } } while ((de = readdir(d))) { if (de->d_type != DT_DIR && !strncmp(hash, de->d_name, strlen(hash))) { if (i == which) { resultfile = aprintf("scans/%s/info", strdup(de->d_name)); break; } i++; } } if (resultfile) dump(resultfile); cleanup: free(resultfile); closedir(d); } void submit_cmd(char *arg) { const char *bufp; char *end, *contents; size_t len; bufp = ask("How large is your file?\n"); len = strtoul(bufp, &end, 10); if (len <= 0 || len >= 7000 || *end) { fprintf(stderr, "Invalid file length!\n"); return; } printf("Ok! Im listening..\n"); contents = checkp(malloc(len)); fread(contents, 1, len, stdin); if (lastrun) free_parseinfo(lastrun); lastrun = parse_file(contents, len); dump(lastrun->infopath); free(contents); } 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"); } int main() { char linebuf[256], *cp, *arg; int exit, i; setvbuf(stdin, NULL, _IONBF, 0); if (!(resultdir = getenv("RESULTDIR"))) resultdir = "/data"; dump("msgs/welcome"); exit = 0; while (!exit) { memset(linebuf, ' ', 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"); }