From 61e69847776a79c3baf58038ecbcacfa0ee0339c Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Sun, 12 Sep 2010 22:01:21 -0600 Subject: [PATCH] Add puzzles CGI I just realized I don't need this to be a CGI. --- src/puzzles.cgi.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/puzzles.cgi.c diff --git a/src/puzzles.cgi.c b/src/puzzles.cgi.c new file mode 100644 index 0000000..643c64b --- /dev/null +++ b/src/puzzles.cgi.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +int +longcmp(long *a, long *b) +{ + if (*a < *b) return -1; + if (*a > *b) return 1; + return 0; +} + +#define PUZZLES_MAX 500 + +/** Keeps track of the most points yet awarded in each category */ +struct { + char cat[CAT_MAX]; + long points; +} points_by_cat[100]; +int ncats = 0; + +void +read_points_by_cat() +{ + FILE *f = fopen("/var/lib/ctf/puzzler.log", "r"); + char cat[CAT_MAX]; + long points; + int i; + + if (! f) { + return; + } + + while (1) { + if (2 != fscanf(f, "%*s %s %ld\n", &cat, &points)) { + break; + } + for (i = 0; i < ncats; i += 1) { + if (0 == strcmp(cat, points_by_cat[i].cat)) break; + } + if (i == ncats) { + strcpy(points_by_cat[i].cat, cat); + ncats += 1; + } + if (points > points_by_cat[i].points) { + points_by_cat[i].points = points; + } + } +} + +int +main(int argc, char *argv[]) +{ + int i; + DIR *srv; + +#if 0 + if (! cgi_init()) { + return 0; + } +#endif + + read_points_by_cat(); + +#if 0 + for (i = 0; i < ncats; i += 1) { + printf("%s: %ld\n", points_by_cat[i].cat, points_by_cat[i].points); + } +#endif + + /* Open /srv/ */ + srv = opendir("/srv"); + if (NULL == srv) { + cgi_error("Cannot opendir(\"/srv\")"); + } + + cgi_head("Open puzzles"); + printf("
\n"); + + /* For each file in /srv/ ... */ + while (1) { + struct dirent *e = readdir(srv); + char *cat = e->d_name; + DIR *puzzles; + char path[PATH_MAX]; + long catpoints[PUZZLES_MAX]; + size_t ncatpoints = 0; + + if (! e) break; + if ('.' == cat[0]) continue; + /* We have to lstat anyway to see if it's a directory; may as + well just barge ahead and watch for errors. */ + + /* Open /srv/$cat/puzzles/ */ + my_snprintf(path, sizeof(path), "/srv/%s/puzzles", cat); + puzzles = opendir(path); + if (NULL == puzzles) { + continue; + } + + while (ncatpoints < PUZZLES_MAX) { + struct dirent *pe = readdir(puzzles); + long points; + char *p; + + if (! pe) break; + + /* Only do this if it's an int */ + points = strtol(pe->d_name, &p, 10); + if (*p) continue; + + catpoints[ncatpoints++] = points; + } + + closedir(puzzles); + + /* Sort points */ + qsort(catpoints, ncatpoints, sizeof(*catpoints), + (int (*)(const void *, const void *))longcmp); + + + /* Print out point values up to one past the last solved puzzle in + this category */ + { + long maxpoints = 0; + + /* Find the most points scored in this category */ + for (i = 0; i < ncats; i += 1) { + if (0 == strcmp(cat, points_by_cat[i].cat)) { + maxpoints = points_by_cat[i].points; + break; + } + } + + printf("
%s
\n", cat); + printf("
\n"); + for (i = 0; i < ncatpoints; i += 1) { + printf(" %d\n", + cat, catpoints[i], catpoints[i]); + if (catpoints[i] > maxpoints) break; + } + printf("
\n"); + } + } + + closedir(srv); + + printf("
\n"); + cgi_foot(); + + return 0; +}