mirror of https://github.com/dirtbags/moth.git
Changed koth to moth. Added some documentation on setting up a web server
This commit is contained in:
parent
98e0e5ef2c
commit
703a781252
53
README.md
53
README.md
|
@ -25,17 +25,55 @@ Please check out [the overview](doc/overview.md)
|
|||
for details.
|
||||
|
||||
|
||||
Dependencies
|
||||
--------------------
|
||||
If you're using Ubuntu 14.04 LTS, you should have everything you need except
|
||||
[LUA](http://lua.org).
|
||||
|
||||
$ sudo apt-get install lua5.2 -y
|
||||
|
||||
You'll also have to figure out a way to serve up CGI. Here's one way to do it
|
||||
on Ubuntu 14.04 LTS with [lighttpd](https://lighttpd.net) where the contest
|
||||
is at `/opt/moth/mycontest` accessible by user group `moth`, and the web
|
||||
server is run as user `www-data`:
|
||||
|
||||
First, make sure your web server can access the contest files:
|
||||
|
||||
$ sudo usermod -a -G moth www-data
|
||||
|
||||
Next, install lighttpd and backup the configuration:
|
||||
|
||||
$ sudo apt-get install lighttpd
|
||||
$ cp /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
|
||||
|
||||
Add an entry for your contest to your `/etc/hosts`:
|
||||
|
||||
127.0.0.1 mycontest
|
||||
|
||||
Add a virtual host entry to `/etc/lighttpd/lighttpd.conf`:
|
||||
|
||||
$HTTP["host"] == "mycontest" {
|
||||
server.document-root = "/opt/moth/mycontest/www"
|
||||
cgi.assign = ( ".cgi" => "/usr/bin/lua" )
|
||||
}
|
||||
|
||||
Finally, restart your server:
|
||||
|
||||
$ sudo service lighttpd restart
|
||||
* Stopping web server lighttpd [ OK ]
|
||||
* Starting web server lighttpd [ OK ]
|
||||
|
||||
How to set it up
|
||||
--------------------
|
||||
|
||||
It's made to be virtualized,
|
||||
so you can run multiple contests at once if you want.
|
||||
If you were to want to run it out of `/opt/koth`,
|
||||
If you were to want to run it out of `/opt/moth`,
|
||||
do the following:
|
||||
|
||||
$ mkdir -p /opt/koth/mycontest
|
||||
$ ./install /opt/koth/mycontest
|
||||
$ cp kothd /opt/koth
|
||||
$ mkdir -p /opt/moth/mycontest
|
||||
$ ./install /opt/moth/mycontest
|
||||
$ cp mothd /opt/moth
|
||||
|
||||
Yay, you've got it set up.
|
||||
|
||||
|
@ -45,17 +83,16 @@ Installing Puzzle Categories
|
|||
|
||||
Puzzle categories are distributed in a different way than the server.
|
||||
After setting up (see above), just run
|
||||
|
||||
$ /opt/koth/mycontest/bin/install-category /path/to/my/category
|
||||
$ /opt/moth/mycontest/bin/install-category /path/to/my/category
|
||||
|
||||
|
||||
Running It
|
||||
-------------
|
||||
|
||||
Get your web server to serve up files from
|
||||
`/opt/koth/mycontest/www`.
|
||||
`/opt/moth/mycontest/www`.
|
||||
|
||||
Then run `/opt/koth/kothd`.
|
||||
Then run `/opt/moth/mothd`.
|
||||
|
||||
|
||||
Permissions
|
||||
|
|
6
bin/new
6
bin/new
|
@ -6,7 +6,7 @@ if [ -z "$newdir" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
KOTH_BASE=$(cd $(dirname $0)/.. && pwd)
|
||||
MOTH_BASE=$(cd $(dirname $0)/.. && pwd)
|
||||
|
||||
echo "Figuring out web user..."
|
||||
for www in www-data http _; do
|
||||
|
@ -33,5 +33,5 @@ if ! [ -f assigned.txt ]; then
|
|||
fi
|
||||
|
||||
mkdir -p www
|
||||
cp -r $KOTH_BASE/html/* www/
|
||||
cp $KOTH_BASE/bin/*.cgi www/
|
||||
cp -r $MOTH_BASE/html/* www/
|
||||
cp $MOTH_BASE/bin/*.cgi www/
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#! /bin/sh
|
||||
|
||||
cd ${1:-$(dirname $0)}
|
||||
KOTH_BASE=$(pwd)
|
||||
MOTH_BASE=$(pwd)
|
||||
|
||||
echo "Running koth instances in $KOTH_BASE"
|
||||
echo "Running moth instances in $MOTH_BASE"
|
||||
|
||||
while true; do
|
||||
for i in $KOTH_BASE/*/assigned.txt; do
|
||||
for i in $MOTH_BASE/*/assigned.txt; do
|
||||
dir=${i%/*}
|
||||
$dir/bin/once
|
||||
done
|
|
@ -1,9 +1,9 @@
|
|||
#! /usr/bin/env lua
|
||||
|
||||
local koth = {}
|
||||
local moth = {}
|
||||
|
||||
-- cut -d$ANCHOR -f2- | grep -Fx "$NEEDLE"
|
||||
function koth.anchored_search(haystack, needle, anchor)
|
||||
function moth.anchored_search(haystack, needle, anchor)
|
||||
local f, err = io.open(haystack)
|
||||
if (not f) then
|
||||
return false, err
|
||||
|
@ -27,7 +27,7 @@ function koth.anchored_search(haystack, needle, anchor)
|
|||
return false
|
||||
end
|
||||
|
||||
function koth.page(title, body)
|
||||
function moth.page(title, body)
|
||||
if (os.getenv("REQUEST_METHOD")) then
|
||||
print("Content-type: text/html")
|
||||
print()
|
||||
|
@ -52,7 +52,7 @@ end
|
|||
--
|
||||
-- We're going to rely on `bin/once` only processing files with the right number of lines.
|
||||
--
|
||||
function koth.award_points(team, category, points, comment)
|
||||
function moth.award_points(team, category, points, comment)
|
||||
team = team:gsub("[^0-9a-f]", "-")
|
||||
if (team == "") then
|
||||
team = "-"
|
||||
|
@ -65,19 +65,19 @@ function koth.award_points(team, category, points, comment)
|
|||
entry = entry .. " " .. comment
|
||||
end
|
||||
|
||||
local f = io.open(koth.path("state/teams/" .. team))
|
||||
local f = io.open(moth.path("state/teams/" .. team))
|
||||
if (f) then
|
||||
f:close()
|
||||
else
|
||||
return false, "No such team"
|
||||
end
|
||||
|
||||
local ok = koth.anchored_search(koth.path("state/points.log"), entry, " ")
|
||||
local ok = moth.anchored_search(moth.path("state/points.log"), entry, " ")
|
||||
if (ok) then
|
||||
return false, "Points already awarded"
|
||||
end
|
||||
|
||||
local f = io.open(koth.path("state/points.new/" .. filename), "a")
|
||||
local f = io.open(moth.path("state/points.new/" .. filename), "a")
|
||||
if (not f) then
|
||||
return false, "Unable to write to points file"
|
||||
end
|
||||
|
@ -91,19 +91,19 @@ end
|
|||
-- Most web servers cd to the directory containing the CGI.
|
||||
-- Not uhttpd.
|
||||
|
||||
koth.base = ""
|
||||
function koth.path(p)
|
||||
return koth.base .. p
|
||||
moth.base = ""
|
||||
function moth.path(p)
|
||||
return moth.base .. p
|
||||
end
|
||||
|
||||
-- Traverse up to find assigned.txt
|
||||
for i = 0, 5 do
|
||||
local f = io.open(koth.path("assigned.txt"))
|
||||
local f = io.open(moth.path("assigned.txt"))
|
||||
if (f) then
|
||||
f:close()
|
||||
break
|
||||
end
|
||||
koth.base = koth.base .. "../"
|
||||
moth.base = moth.base .. "../"
|
||||
end
|
||||
|
||||
return koth
|
||||
return moth
|
|
@ -3,7 +3,7 @@
|
|||
package.path = "?.lua;cgi-bin/?.lua;www/cgi-bin/?.lua"
|
||||
|
||||
local cgi = require "cgi"
|
||||
local koth = require "koth"
|
||||
local moth = require "moth"
|
||||
|
||||
local team = cgi.fields['t'] or ""
|
||||
local category = cgi.fields['c'] or ""
|
||||
|
@ -15,20 +15,20 @@ category = category:gsub("[^A-Za-z0-9]", "-")
|
|||
|
||||
-- Check answer
|
||||
local needle = points .. " " .. answer
|
||||
local haystack = koth.path("packages/" .. category .. "/answers.txt")
|
||||
local found, err = koth.anchored_search(haystack, needle)
|
||||
local haystack = moth.path("packages/" .. category .. "/answers.txt")
|
||||
local found, err = moth.anchored_search(haystack, needle)
|
||||
|
||||
if (not found) then
|
||||
koth.page("Wrong answer", err)
|
||||
moth.page("Wrong answer", err)
|
||||
end
|
||||
|
||||
local ok, err = koth.award_points(team, category, points)
|
||||
local ok, err = moth.award_points(team, category, points)
|
||||
if (not ok) then
|
||||
koth.page("Error awarding points",
|
||||
moth.page("Error awarding points",
|
||||
"<p>You got the right answer, but there was a problem trying to give you points:</p>" ..
|
||||
"<p>" .. err .. "</p>")
|
||||
end
|
||||
|
||||
koth.page("Points awarded",
|
||||
moth.page("Points awarded",
|
||||
"<p>" .. points .. " points for " .. team .. "!</p>" ..
|
||||
"<p><a href=\"../puzzles.html\">Back to puzzles</a></p>")
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
package.path = "?.lua;cgi-bin/?.lua;www/cgi-bin/?.lua"
|
||||
|
||||
local koth = require "koth"
|
||||
local moth = require "moth"
|
||||
|
||||
local max_by_cat = {}
|
||||
|
||||
local f = io.popen("ls " .. koth.path("packages"))
|
||||
local f = io.popen("ls " .. moth.path("packages"))
|
||||
for cat in f:lines() do
|
||||
max_by_cat[cat] = 0
|
||||
end
|
||||
f:close()
|
||||
|
||||
|
||||
for line in io.lines(koth.path("state/points.log")) do
|
||||
for line in io.lines(moth.path("state/points.log")) do
|
||||
local ts, team, cat, points, comment = line:match("^(%d+) (%w+) ([%w-]+) (%d+) ?(.*)")
|
||||
points = tonumber(points) or 0
|
||||
|
||||
|
@ -29,7 +29,7 @@ for cat, biggest in pairs(max_by_cat) do
|
|||
|
||||
body = body .. "<dt>" .. cat .. "</dt>"
|
||||
body = body .. "<dd>"
|
||||
for line in io.lines(koth.path("packages/" .. cat .. "/map.txt")) do
|
||||
for line in io.lines(moth.path("packages/" .. cat .. "/map.txt")) do
|
||||
points, dirname = line:match("^(%d+) (.*)")
|
||||
points = tonumber(points)
|
||||
|
||||
|
@ -54,4 +54,4 @@ body = body .. "</form>"
|
|||
body = body .. "</fieldset>"
|
||||
body = body .. "<p>Reloading this page periodically may yield updated puzzle lists.</p>"
|
||||
|
||||
koth.page("Open Puzzles", body)
|
||||
moth.page("Open Puzzles", body)
|
||||
|
|
|
@ -4,7 +4,7 @@ package.path = "?.lua;cgi-bin/?.lua;www/cgi-bin/?.lua"
|
|||
|
||||
|
||||
local cgi = require "cgi"
|
||||
local koth = require "koth"
|
||||
local moth = require "moth"
|
||||
|
||||
local team = cgi.fields["n"] or ""
|
||||
local hash = cgi.fields["h"] or ""
|
||||
|
@ -12,22 +12,22 @@ local hash = cgi.fields["h"] or ""
|
|||
hash = hash:match("[0-9a-f]*")
|
||||
|
||||
if ((hash == "") or (team == "")) then
|
||||
koth.page("Invalid Entry", "Oops! Are you sure you got that right?")
|
||||
elseif (not koth.anchored_search(koth.path("assigned.txt"), hash)) then
|
||||
koth.page("Invalid Hash", "Oops! I don't have a record of that hash. Did you maybe use capital letters accidentally?")
|
||||
moth.page("Invalid Entry", "Oops! Are you sure you got that right?")
|
||||
elseif (not moth.anchored_search(moth.path("assigned.txt"), hash)) then
|
||||
moth.page("Invalid Hash", "Oops! I don't have a record of that hash. Did you maybe use capital letters accidentally?")
|
||||
end
|
||||
|
||||
local f = io.open(koth.path("state/teams/" .. hash))
|
||||
local f = io.open(moth.path("state/teams/" .. hash))
|
||||
if (f) then
|
||||
f:close()
|
||||
koth.page("Already Exists", "Your team has already been named! Maybe somebody on your team beat you to it.")
|
||||
moth.page("Already Exists", "Your team has already been named! Maybe somebody on your team beat you to it.")
|
||||
end
|
||||
|
||||
local f, err = io.open(koth.path("state/teams/" .. hash), "w+")
|
||||
local f, err = io.open(moth.path("state/teams/" .. hash), "w+")
|
||||
if (not f) then
|
||||
koth.page("Kersplode", err)
|
||||
moth.page("Kersplode", err)
|
||||
end
|
||||
f:write(team)
|
||||
f:close()
|
||||
|
||||
koth.page("Success", "Okay, your team has been named and you may begin using your hash!")
|
||||
moth.page("Success", "Okay, your team has been named and you may begin using your hash!")
|
||||
|
|
|
@ -3,36 +3,36 @@
|
|||
package.path = "?.lua;cgi-bin/?.lua;www/cgi-bin/?.lua"
|
||||
|
||||
local cgi = require "cgi"
|
||||
local koth = require "koth"
|
||||
local moth = require "moth"
|
||||
|
||||
local team = cgi.fields['t'] or ""
|
||||
local token = cgi.fields['k'] or ""
|
||||
|
||||
-- Check answer
|
||||
local needle = token
|
||||
local haystack = koth.path("tokens.txt")
|
||||
local found, err = koth.anchored_search(haystack, needle)
|
||||
local haystack = moth.path("tokens.txt")
|
||||
local found, err = moth.anchored_search(haystack, needle)
|
||||
|
||||
if (not found) then
|
||||
koth.page("Unrecognized token", err)
|
||||
moth.page("Unrecognized token", err)
|
||||
end
|
||||
|
||||
local category, points = token:match("^(.*):(.*):")
|
||||
if ((category == nil) or (points == nil)) then
|
||||
koth.page("Unrecognized token", "Something doesn't look right about that token")
|
||||
moth.page("Unrecognized token", "Something doesn't look right about that token")
|
||||
end
|
||||
points = tonumber(points)
|
||||
|
||||
-- Defang category name; prevent directory traversal
|
||||
category = category:gsub("[^A-Za-z0-9]", "-")
|
||||
|
||||
local ok, err = koth.award_points(team, category, points, token)
|
||||
local ok, err = moth.award_points(team, category, points, token)
|
||||
if (not ok) then
|
||||
koth.page("Error awarding points",
|
||||
moth.page("Error awarding points",
|
||||
"<p>You entered a valid token, but there was a problem trying to give you points:</p>" ..
|
||||
"<p>" .. err .. "</p>")
|
||||
end
|
||||
|
||||
koth.page("Points awarded",
|
||||
moth.page("Points awarded",
|
||||
"<p>" .. points .. " points for " .. team .. "!</p>" ..
|
||||
"<p><a href=\"../puzzles.html\">Back to puzzles</a></p>")
|
||||
|
|
Loading…
Reference in New Issue