#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 */ struct { char cat[CAT_MAX]; long points; } points_by_cat[PUZZLES_MAX]; int ncats = 0; void read_points_by_cat() { FILE *f = fopen(srv_path("puzzler.db"), "r"); char cat[CAT_MAX]; long points; int i; if (! f) { return; } while (1) { /* XXX: tokenize like cgi_item */ 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) { 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; } } } int main(int argc, char *argv[]) { int i; DIR *srv; if (-1 == cgi_init(argv)) { return 0; } read_points_by_cat(); srv = opendir(srv_path("packages")); 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; DIR *puzzles; long catpoints[PUZZLES_MAX]; size_t ncatpoints = 0; if (! e) break; cat = e->d_name; 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/ctf/$cat/puzzles/ */ puzzles = opendir(srv_path("packages/%s/puzzles", cat)); 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; }