/* all: anmeldeschlange anmeldeschlange: anmeldeschlange.c gcc -o $@ $< -Wall -Wextra -Werror -O2 -g -ggdb -lmicrohttpd */ #include #include #include #include #include #include #include #include struct anmeldung { struct timespec t; int nr; char keks[32]; char token[32]; void* whatever; }; struct anmeldung* thebrain = NULL; pthread_mutex_t mutti; #define MAXNUM 1000000 int verbose = 1; int nr = 0; int _running = 0; int web(void*, struct MHD_Connection*, const char*, const char*, const char*, const char*, size_t*, void**); void _handler(int sig); int main(int argc, const char* argv[]) { int ret = 0; int port = 8080; struct MHD_Daemon* mhd_daemon = NULL; pthread_mutex_init(&mutti, NULL); if (argc != 1) { fprintf(stderr, "usage: %s [port]\n", argv[0]); ret = -1; goto cleanup; } if (argc == 2) port = atoi(argv[1]); thebrain = (struct anmeldung*) malloc(MAXNUM*sizeof(struct anmeldung)); if (thebrain == NULL) { fprintf(stderr, "malloc failed: %s\n", strerror(errno)); ret = -1; goto cleanup; } mhd_daemon = MHD_start_daemon( MHD_USE_THREAD_PER_CONNECTION, port, NULL, NULL, &web, NULL, NULL, MHD_OPTION_END); _running = 1; signal(SIGINT, _handler); fprintf(stdout, "Okay, läuft auf Port %d. CTRL+C zum Ausschalten.\n", port); while (_running) { sleep(1); fprintf(stdout, "%ld: Aktuell %d Anmeldungen.\n", time(NULL), nr); } cleanup: fprintf(stdout, "Schicht im Schacht.\n"); pthread_mutex_lock(&mutti); if (thebrain) { free(thebrain); thebrain=NULL; } if (mhd_daemon) { MHD_stop_daemon(mhd_daemon); mhd_daemon = NULL; } pthread_mutex_destroy(&mutti); return ret; } int web( __attribute__((unused))void* cls, __attribute__((unused))struct MHD_Connection* conn, __attribute__((unused))const char* url, __attribute__((unused))const char* method, __attribute__((unused))const char* version, __attribute__((unused))const char* data, __attribute__((unused))size_t* len, __attribute__((unused))void** con_cls ) { struct anmeldung tmp; struct MHD_Response* response = NULL; int status = MHD_HTTP_INTERNAL_SERVER_ERROR; const char* msg = "nix.\n"; /* TODO: * check if method == HTTP_POST, * extract cookie and token from request */ if (nr >= MAXNUM) { fprintf(stderr, "error: the brain will overflow.\n"); status = MHD_HTTP_INTERNAL_SERVER_ERROR; msg = "kap0tt.\n"; goto done; } clock_gettime(CLOCK_MONOTONIC, &tmp.t); /* REALTIME is not monotonic; include some offset to get "absolute" wall clock */ pthread_mutex_lock(&mutti); tmp.nr = nr; snprintf(tmp.keks, sizeof(tmp.keks )-1, "come-to-the-dark-side"); snprintf(tmp.token, sizeof(tmp.token)-1, "3.1415926535"); tmp.whatever = NULL; memcpy(&thebrain[nr], &tmp, sizeof(tmp)); status = MHD_HTTP_OK; msg = "OK.\n"; if (verbose) fprintf(stdout, "conn %d @%ld.%06ld\n", tmp.nr, tmp.t.tv_sec, tmp.t.tv_nsec/1000); nr++; pthread_mutex_unlock(&mutti); done: response = MHD_create_response_from_buffer(strlen(msg), (void*)msg, MHD_RESPMEM_PERSISTENT); MHD_queue_response(conn, status, response); MHD_destroy_response(response); return MHD_YES; } void _handler(int sig) { if (sig == SIGINT) _running = 0; }