2010-09-12 22:01:21 -06:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "common.h"
|
|
|
|
|
2010-09-14 18:04:33 -06:00
|
|
|
|
2010-09-12 22:01:21 -06:00
|
|
|
int
|
|
|
|
longcmp(long *a, long *b)
|
|
|
|
{
|
|
|
|
if (*a < *b) return -1;
|
|
|
|
if (*a > *b) return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-09-14 18:04:33 -06:00
|
|
|
#define PUZZLES_MAX 100
|
2010-09-12 22:01:21 -06:00
|
|
|
|
|
|
|
/** Keeps track of the most points yet awarded in each category */
|
2010-09-16 23:18:16 -06:00
|
|
|
int ncats = 0;
|
2010-09-12 22:01:21 -06:00
|
|
|
struct {
|
|
|
|
char cat[CAT_MAX];
|
|
|
|
long points;
|
2010-09-14 18:04:33 -06:00
|
|
|
} points_by_cat[PUZZLES_MAX];
|
2010-09-16 23:18:16 -06:00
|
|
|
|
2010-09-12 22:01:21 -06:00
|
|
|
|
2010-09-16 12:20:44 -06:00
|
|
|
size_t
|
|
|
|
read_until_char(FILE *f, char *buf, size_t buflen, char delim)
|
2010-09-12 22:01:21 -06:00
|
|
|
{
|
2010-09-16 12:20:44 -06:00
|
|
|
size_t i = 0;
|
2010-09-12 22:01:21 -06:00
|
|
|
|
|
|
|
while (1) {
|
2010-09-16 12:20:44 -06:00
|
|
|
int c = fgetc(f);
|
|
|
|
|
|
|
|
if ((EOF == c) || delim == c) {
|
|
|
|
if (buf) {
|
|
|
|
buf[i] = '\0';
|
2010-09-14 18:04:33 -06:00
|
|
|
}
|
2010-09-16 12:20:44 -06:00
|
|
|
return i;
|
2010-09-12 22:01:21 -06:00
|
|
|
}
|
2010-09-16 12:20:44 -06:00
|
|
|
|
|
|
|
if (i + 1 < buflen) {
|
|
|
|
buf[i] = c;
|
2010-09-12 22:01:21 -06:00
|
|
|
}
|
2010-09-16 12:20:44 -06:00
|
|
|
i += 1;
|
2010-09-12 22:01:21 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int i;
|
2012-05-30 12:19:07 -06:00
|
|
|
DIR *opt;
|
2010-09-12 22:01:21 -06:00
|
|
|
|
2010-09-13 12:23:39 -06:00
|
|
|
if (-1 == cgi_init(argv)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-09-16 12:20:44 -06:00
|
|
|
{
|
2012-06-12 18:25:32 -06:00
|
|
|
FILE *f = fopen(state_path("points.log"), "r");
|
2012-05-30 12:19:07 -06:00
|
|
|
char cat[CAT_MAX];
|
|
|
|
char points_str[11];
|
|
|
|
long points;
|
|
|
|
int i;
|
2010-09-16 12:20:44 -06:00
|
|
|
|
|
|
|
while (f && (! feof(f))) {
|
2012-05-30 13:51:40 -06:00
|
|
|
read_until_char(f, NULL, 0, ' ');
|
2010-09-16 12:20:44 -06:00
|
|
|
read_until_char(f, NULL, 0, ' ');
|
|
|
|
read_until_char(f, cat, sizeof(cat), ' ');
|
2012-05-30 13:51:40 -06:00
|
|
|
read_until_char(f, points_str, sizeof(points_str), ' ');
|
|
|
|
read_until_char(f, NULL, 0, '\n');
|
2010-09-16 12:20:44 -06:00
|
|
|
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);
|
|
|
|
}
|
2010-09-12 22:01:21 -06:00
|
|
|
|
2012-05-30 12:19:07 -06:00
|
|
|
opt = opendir(package_path(""));
|
|
|
|
if (NULL == opt) {
|
2012-07-22 17:14:06 -06:00
|
|
|
cgi_error("Cannot open packages directory");
|
2010-09-12 22:01:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
cgi_head("Open puzzles");
|
|
|
|
printf("<dl>\n");
|
|
|
|
|
2012-07-22 17:14:06 -06:00
|
|
|
/* For each file in /packages/ ... */
|
2010-09-12 22:01:21 -06:00
|
|
|
while (1) {
|
2012-05-30 12:19:07 -06:00
|
|
|
struct dirent *e = readdir(opt);
|
2010-09-14 18:04:33 -06:00
|
|
|
char *cat;
|
2012-05-30 12:19:07 -06:00
|
|
|
long maxpoints = 0;
|
2012-06-13 11:23:16 -06:00
|
|
|
FILE *map;
|
2010-09-12 22:01:21 -06:00
|
|
|
|
|
|
|
if (! e) break;
|
2010-09-14 18:04:33 -06:00
|
|
|
|
|
|
|
cat = e->d_name;
|
2010-09-12 22:01:21 -06:00
|
|
|
if ('.' == cat[0]) continue;
|
2012-05-30 12:19:07 -06:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
2010-09-12 22:01:21 -06:00
|
|
|
}
|
|
|
|
|
2012-05-30 12:19:07 -06:00
|
|
|
/* Read in category's map file, print html until point limit reached */
|
2012-06-13 11:23:16 -06:00
|
|
|
map = fopen(package_path("%s/map.txt", cat), "r");
|
2012-05-30 12:19:07 -06:00
|
|
|
if (map == NULL) continue;
|
2010-09-12 22:01:21 -06:00
|
|
|
|
2012-05-30 12:19:07 -06:00
|
|
|
printf(" <dt>%s</dt>\n", cat);
|
|
|
|
printf(" <dd>\n");
|
2010-09-12 22:01:21 -06:00
|
|
|
|
2012-05-30 12:19:07 -06:00
|
|
|
while (i < PUZZLES_MAX && (!feof(map))) {
|
|
|
|
char hash[20];
|
|
|
|
char points_str[20];
|
|
|
|
long points;
|
2010-09-12 22:01:21 -06:00
|
|
|
|
2012-05-30 13:51:40 -06:00
|
|
|
read_until_char(map, points_str, sizeof(points_str), ' ');
|
2012-06-13 11:31:14 -06:00
|
|
|
read_until_char(map, hash, sizeof(hash), '\n');
|
|
|
|
points = atol(points_str);
|
2010-09-12 22:01:21 -06:00
|
|
|
|
2012-06-13 11:37:13 -06:00
|
|
|
printf(" <a href=\"/%s/%s/\">%ld</a>\n", cat, hash, points);
|
2010-09-12 22:01:21 -06:00
|
|
|
|
2012-05-30 12:19:07 -06:00
|
|
|
if (points > maxpoints) break;
|
2010-09-12 22:01:21 -06:00
|
|
|
}
|
2012-05-30 12:19:07 -06:00
|
|
|
|
|
|
|
printf(" </dd>\n");
|
|
|
|
fclose(map);
|
2010-09-12 22:01:21 -06:00
|
|
|
}
|
|
|
|
|
2012-05-30 12:19:07 -06:00
|
|
|
closedir(opt);
|
2010-09-12 22:01:21 -06:00
|
|
|
|
|
|
|
printf("</dl>\n");
|
2012-07-12 17:15:43 -06:00
|
|
|
|
|
|
|
printf("<p>New puzzles are unlocked when any team answers the highest-scoring puzzle in a category.</p>");
|
2010-09-12 22:01:21 -06:00
|
|
|
cgi_foot();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|