#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 100 /** Keeps track of the most points yet awarded in each category */ int ncats = 0; struct { char cat[CAT_MAX]; long points; } points_by_cat[PUZZLES_MAX]; size_t read_until_char(FILE *f, char *buf, size_t buflen, char delim) { size_t i = 0; while (1) { int c = fgetc(f); if ((EOF == c) || delim == c) { if (buf) { buf[i] = '\0'; } return i; } if (i + 1 < buflen) { buf[i] = c; } i += 1; } } int main(int argc, char *argv[]) { int i; DIR *opt; if (-1 == cgi_init(argv)) { return 0; } ctf_chdir(); { FILE *f = fopen(state_path("points.log"), "r"); char cat[CAT_MAX]; char points_str[11]; long points; int i; while (f && (! feof(f))) { read_until_char(f, NULL, 0, ' '); read_until_char(f, NULL, 0, ' '); read_until_char(f, cat, sizeof(cat), ' '); read_until_char(f, points_str, sizeof(points_str), ' '); read_until_char(f, NULL, 0, '\n'); points = atol(points_str); for (i = 0; i < ncats; i += 1) { if (0 == strcmp(cat, points_by_cat[i].cat)) break; } if (i == ncats) { if (PUZZLES_MAX == ncats) { continue; } strncpy(points_by_cat[i].cat, cat, sizeof(points_by_cat[i].cat)); points_by_cat[i].points = 0; ncats += 1; } if (points > points_by_cat[i].points) { points_by_cat[i].points = points; } } if (f) fclose(f); } opt = opendir(package_path("")); if (NULL == opt) { cgi_error("Cannot open packages directory"); } cgi_head("Open puzzles"); printf("
\n"); /* For each file in /packages/ ... */ while (1) { struct dirent *e = readdir(opt); char *cat; long maxpoints = 0; FILE *map; if (! e) break; cat = e->d_name; if ('.' == cat[0]) continue; /* 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; } } /* Read in category's map file, print html until point limit reached */ map = fopen(package_path("%s/map.txt", cat), "r"); if (map == NULL) continue; printf("
%s
\n", cat); printf("
\n"); while (i < PUZZLES_MAX && (!feof(map))) { char hash[20]; char points_str[20]; long points; read_until_char(map, points_str, sizeof(points_str), ' '); read_until_char(map, hash, sizeof(hash), '\n'); points = atol(points_str); if (0 == points) { printf(" \n"); break; } printf(" %ld\n", cat, hash, points); if (points > maxpoints) break; } printf("
\n"); fclose(map); } closedir(opt); printf("
\n"); printf("

New puzzles are unlocked when any team answers the highest-scoring puzzle in a category.

"); cgi_foot(); return 0; }