From 8e1dfbd0da70dc2c2c515848cf7af7d523d360e7 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Fri, 3 Sep 2010 21:00:02 -0600 Subject: [PATCH 1/3] Add pointscli and common utils --- src/Makefile | 3 +- src/common.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ src/common.h | 11 +++++ src/pointscli.c | 37 +++++++++++++++++ 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 src/common.c create mode 100644 src/common.h create mode 100644 src/pointscli.c diff --git a/src/Makefile b/src/Makefile index d31695c..5b83d50 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,7 @@ -all: in.tokend register.cgi +all: in.tokend register.cgi pointscli in.tokend: in.tokend.o xxtea.o register.cgi: register.cgi.o cgi.o +pointscli: common.o pointscli.o diff --git a/src/common.c b/src/common.c new file mode 100644 index 0000000..d168b19 --- /dev/null +++ b/src/common.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +int +timestamp(char *now, size_t nowlen) +{ + time_t t; + struct tm tmp; + + time(&t); + if (NULL == gmtime_r(&t, &tmp)) { + perror("gmtime_r"); + return -1; + } + + if (0 == strftime(now, nowlen, "%Y-%m-%dT%H:%M:%SZ", &tmp)) { + return -1; + } + + return 0; +} + +int +team_exists(char *teamhash) +{ + struct stat buf; + char filename[100]; + int ret; + int i; + + /* Check for invalid characters. */ + for (i = 0; teamhash[i]; i += 1) { + if (! isalnum(teamhash[i])) { + return 0; + } + } + + /* Build filename. */ + ret = snprintf(filename, sizeof(filename), + "%s/%s", teamdir, teamhash); + if (sizeof(filename) == ret) { + return 0; + } + + /* lstat seems to be the preferred way to check for existence. */ + ret = lstat(filename, &buf); + if (-1 == ret) { + return 0; + } + + return 1; +} + +int +award_points(char *teamhash, char *category, int points) +{ + char now[40]; + char line[100]; + int linelen; + int fd; + int ret; + + if (! team_exists(teamhash)) { + return -2; + } + + ret = timestamp(now, sizeof(now)); + if (-1 == ret) { + return -3; + } + linelen = snprintf(line, sizeof(line), + "%s %s %s %d\n", + now, teamhash, category, points); + if (sizeof(line) == linelen) { + return -1; + } + + fd = open(pointslog, O_WRONLY | O_CREAT, 0666); + if (-1 == fd) { + return -1; + } + + ret = lockf(fd, F_LOCK, 0); + if (-1 == ret) { + close(fd); + return -1; + } + + ret = lseek(fd, 0, SEEK_END); + if (-1 == ret) { + close(fd); + return -1; + } + + write(fd, line, linelen); + close(fd); + return 0; +} diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..b8a238c --- /dev/null +++ b/src/common.h @@ -0,0 +1,11 @@ +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#define teamdir "/var/lib/ctf/teams" +#define pointslog "/var/lib/ctf/points.log" + +int timestamp(char *now, size_t nowlen); +int team_exists(char *teamhash); +int award_points(char *teamhash, char *category, int point); + +#endif diff --git a/src/pointscli.c b/src/pointscli.c new file mode 100644 index 0000000..f74d512 --- /dev/null +++ b/src/pointscli.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include "common.h" + +int +main(int argc, char *argv[]) +{ + int points; + int ret; + + if (argc != 4) { + fprintf(stderr, "Usage: pointscli TEAM CATEGORY POINTS\n"); + return EX_USAGE; + } + + points = atoi(argv[3]); + if (0 == points) { + fprintf(stderr, "Error: award 0 points?\n"); + return EX_USAGE; + } + + ret = award_points(argv[1], argv[2], points); + switch (ret) { + case -3: + fprintf(stderr, "Runtime error\n"); + return EX_SOFTWARE; + case -2: + fprintf(stderr, "No such team\n"); + return EX_NOUSER; + case -1: + perror("Couldn't award points"); + return EX_UNAVAILABLE; + } + + return 0; +} From c74c457136aeffd983eccb03a186f74f41cd0da5 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Mon, 6 Sep 2010 21:39:59 -0600 Subject: [PATCH 2/3] Use epoch time for timestamps --- src/common.c | 36 ++++++------------------------------ src/common.h | 1 - 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/src/common.c b/src/common.c index d168b19..f82c0c5 100644 --- a/src/common.c +++ b/src/common.c @@ -7,25 +7,6 @@ #include #include "common.h" -int -timestamp(char *now, size_t nowlen) -{ - time_t t; - struct tm tmp; - - time(&t); - if (NULL == gmtime_r(&t, &tmp)) { - perror("gmtime_r"); - return -1; - } - - if (0 == strftime(now, nowlen, "%Y-%m-%dT%H:%M:%SZ", &tmp)) { - return -1; - } - - return 0; -} - int team_exists(char *teamhash) { @@ -60,23 +41,18 @@ team_exists(char *teamhash) int award_points(char *teamhash, char *category, int points) { - char now[40]; - char line[100]; - int linelen; - int fd; - int ret; + char line[100]; + int linelen; + int fd; + int ret; if (! team_exists(teamhash)) { return -2; } - ret = timestamp(now, sizeof(now)); - if (-1 == ret) { - return -3; - } linelen = snprintf(line, sizeof(line), - "%s %s %s %d\n", - now, teamhash, category, points); + "%u %s %s %d\n", + time(NULL), teamhash, category, points); if (sizeof(line) == linelen) { return -1; } diff --git a/src/common.h b/src/common.h index b8a238c..745b7c4 100644 --- a/src/common.h +++ b/src/common.h @@ -4,7 +4,6 @@ #define teamdir "/var/lib/ctf/teams" #define pointslog "/var/lib/ctf/points.log" -int timestamp(char *now, size_t nowlen); int team_exists(char *teamhash); int award_points(char *teamhash, char *category, int point); From aea9f3cbeb52003141a8f1ca6bbff32f2f4e399e Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Mon, 6 Sep 2010 21:52:09 -0600 Subject: [PATCH 3/3] Start at scoreboard generation --- src/scoreboard | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 src/scoreboard diff --git a/src/scoreboard b/src/scoreboard new file mode 100755 index 0000000..adb6355 --- /dev/null +++ b/src/scoreboard @@ -0,0 +1,38 @@ +#! /usr/bin/awk -f + +function output() { + for (c in points_by_cat) { + for (t in teams) { + printf("%d %s %f\n", + (lasttime - start) / 600, + t, + points_by_cat_team[c, t] / points_by_cat[c]); + } + } +} + +{ + time = $1 + team = $2 + cat = $3 + points = int($4) + + if (! start) { + start = time + } + + # Every 10 minutes + if (time > (outtime + 600)) { + outtime = time + output() + } + lasttime = time + + teams[team] = team + points_by_cat[cat] += points + points_by_cat_team[cat, team] += points +} + +END { + output() +}