#include #include #include #include #include #include #include #include #include #include #include #include #include "app.h" #include "handlers/handlers.h" #include "db.gen.h" static int port = 8080; static bool daemonize = true; static bool scaffold = true; static char *db_path = NULL; // XXX: add p: for port bool parse_commandline(evapp_ctx *ctx, int argc, char **argv) { char c = 0; opterr = 0; while ((c = getopt (argc, argv, "phsSxXlcLDd:F")) != -1) switch (c) { case 's': scaffold = true; break; case 'S': scaffold = false; break; case 'x': evapp_set_xsrf_protection(ctx, true); break; case 'X': evapp_set_xsrf_protection(ctx, false); break; case 'l': evapp_set_default_templates(ctx, true); break; case 'L': evapp_set_default_templates(ctx, false); break; case 'D': evapp_set_debug_mode(ctx, true); break; case 'd': db_path = strdup(optarg); break; case 'c': evapp_set_default_domain(ctx, optarg); break; case 'p': port = atoi(optarg); break; case 'F': daemonize = false; break; case '?': if (optopt == 'd' || optopt == 'p') fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return false; case 'h': fprintf(stderr, "Usage:\n%s [options]\n\n", argv[0]); fprintf(stderr, "Options:\n" " -[s|S] enable or disable scaffolding\n" " -[x|X] enable or disable XSRF protection\n" " -[l|L] serve _default.cs if template missing\n" " -F run in the foreground\n" " -D enables debug mode\n" // TODO: add an option to guess the domain from he // hostname. just riskier. " -d set the database home dir\n" " -c set the cookie domain\n"); return false; default: return false; } if (db_path == NULL) { fprintf(stderr, "Specify a database path with -d\n"); return false; } return true; } int main(int argc, char **argv) { struct app_settings app_ctx = {}; evapp_ctx *ctx; srandom(time(NULL)); // XXX: move this intp evapp_new nerr_init(); ctx = evapp_new(argv[0], &app_ctx); if (ctx == NULL) { fprintf(stderr, "[main] failed to initialize server context\n"); return 1; } if (!parse_commandline(ctx, argc, argv)) { return 2; } if (daemonize) { int status = daemon(0, 0); if (status == -1) { perror("failed to daemonize"); return -1; } } if (!evapp_bind(ctx, "0.0.0.0", port)) { fprintf(stderr, "[main] failed to bind\n"); return 1; } if (!evapp_dbenv_init(ctx, db_path)) { fprintf(stderr, "[main] failed to initialize database\n"); return 1; } if (!evapp_db_add(ctx, "templates", "templates", NULL, NULL, NULL, NULL, NULL, NULL, NULL)) { /* not marshalled */ fprintf(stderr, "[main] failed to add the templates table\n"); return 1; } /* Register all known data types. If validation functions have been written to * check the data for any sanity, they can be attached after */ if (!schema_register(ctx)) { // registers all db types with a default name of the type. fprintf(stderr, "[main] failed to register schema types\n"); evapp_destroy(ctx); return 1; } // evapp_db_set_validate(ctx, "vuln", &vuln_validate); // XXX: add validation function evapp_register_handler(ctx, EVAPP_URIMAP_EXACT, "/lb", handle_lb); evapp_register_handler(ctx, EVAPP_URIMAP_EXACT, "/quit", handle_quit); if (scaffold) evapp_scaffold(ctx); evapp_serve(); evapp_destroy(ctx); return 0; }