mirror of https://github.com/dirtbags/moth.git
Cleanup from merge
This commit is contained in:
parent
ce1ff17ae4
commit
fefcc88f86
|
@ -1,109 +0,0 @@
|
||||||
#! /usr/bin/env lua
|
|
||||||
|
|
||||||
local cgi = {}
|
|
||||||
|
|
||||||
cgi.POST_MAX = 512
|
|
||||||
|
|
||||||
local CL = tonumber(os.getenv("CONTENT_LENGTH")) or 0
|
|
||||||
function getc_post()
|
|
||||||
if (CL > 0) then
|
|
||||||
CL = CL - 1
|
|
||||||
return io.read(1)
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local query = os.getenv("QUERY_STRING") or ""
|
|
||||||
local query_len = query:len()
|
|
||||||
local query_pos = 0
|
|
||||||
function getc_get()
|
|
||||||
if (query_pos < query_len) then
|
|
||||||
query_pos = query_pos + 1
|
|
||||||
return string.sub(query, query_pos, query_pos)
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function read_hex()
|
|
||||||
local a = getc() or 0
|
|
||||||
local b = getc() or 0
|
|
||||||
|
|
||||||
return string.char(tonumber(a, 16)*16 + tonumber(b, 16))
|
|
||||||
end
|
|
||||||
|
|
||||||
function item()
|
|
||||||
local val = ""
|
|
||||||
|
|
||||||
while (true) do
|
|
||||||
local c = getc()
|
|
||||||
if ((c == nil) or (c == "=") or (c == "&")) then
|
|
||||||
return val
|
|
||||||
elseif (c == "%") then
|
|
||||||
c = read_hex()
|
|
||||||
elseif (c == "+") then
|
|
||||||
c = " "
|
|
||||||
end
|
|
||||||
val = val .. c
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function init()
|
|
||||||
method = os.getenv("REQUEST_METHOD")
|
|
||||||
if (method == "POST") then
|
|
||||||
if (os.getenv("HTTP_CONTENT_TYPE") ~= "application/x-www-form-urlencoded") then
|
|
||||||
cgi.http_error(415, "Unsupported content-type", "You are sending me data in a format I can't process")
|
|
||||||
end
|
|
||||||
|
|
||||||
if (CL > cgi.POST_MAX) then
|
|
||||||
cgi.http_error(413, "Post Data Too Long", "You are sending me more data than I'm prepared to handle")
|
|
||||||
end
|
|
||||||
|
|
||||||
getc = getc_post
|
|
||||||
elseif (method == "GET") then
|
|
||||||
local query = os.getenv("QUERY_STRING") or ""
|
|
||||||
local query_pos = 0
|
|
||||||
local query_len = string.len(query)
|
|
||||||
if (query_len > cgi.POST_MAX) then
|
|
||||||
cgi.http_error(413, "Query Data Too Long", "You are sending me more data than I'm prepared to handle")
|
|
||||||
end
|
|
||||||
|
|
||||||
getc = getc_get
|
|
||||||
else
|
|
||||||
cgi.http_error(405, "Method not allowed", "I only do GET and POST.")
|
|
||||||
end
|
|
||||||
|
|
||||||
cgi.fields = {}
|
|
||||||
while (true) do
|
|
||||||
local k = item()
|
|
||||||
local v = item()
|
|
||||||
|
|
||||||
if (k == "") then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
cgi.fields[k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function cgi.http_error(code, name, info)
|
|
||||||
print(code .. " " .. name)
|
|
||||||
print("Allow: GET POST")
|
|
||||||
print("Content-type: text/html")
|
|
||||||
print()
|
|
||||||
print("<h1>" .. code .. " " .. name .. "</h1>")
|
|
||||||
print("<p>" .. info .. "</p>")
|
|
||||||
os.exit(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
function cgi.escape(s)
|
|
||||||
s = string.gsub(s, "&", "&")
|
|
||||||
s = string.gsub(s, "<", "<")
|
|
||||||
s = string.gsub(s, ">", ">")
|
|
||||||
return s
|
|
||||||
end
|
|
||||||
|
|
||||||
init()
|
|
||||||
|
|
||||||
return cgi
|
|
|
@ -1,120 +0,0 @@
|
||||||
#! /usr/bin/env lua
|
|
||||||
|
|
||||||
local koth = {}
|
|
||||||
|
|
||||||
-- cut -d$ANCHOR -f2- | grep -Fx "$NEEDLE"
|
|
||||||
function koth.anchored_search(haystack, needle, anchor)
|
|
||||||
local f, err = io.open(haystack)
|
|
||||||
if (not f) then
|
|
||||||
return false, err
|
|
||||||
end
|
|
||||||
|
|
||||||
for line in f:lines() do
|
|
||||||
if (anchor) then
|
|
||||||
pos = line:find(anchor)
|
|
||||||
if (pos) then
|
|
||||||
line = line:sub(pos+1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (line == needle) then
|
|
||||||
f:close()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
f:close()
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function koth.page(title, body)
|
|
||||||
if (os.getenv("REQUEST_METHOD")) then
|
|
||||||
print("Content-type: text/html")
|
|
||||||
print()
|
|
||||||
end
|
|
||||||
print("<!DOCTYPE html>")
|
|
||||||
print("<html><head><title>" .. title .. "</title><link rel=\"stylesheet\" href=\"../style.css\"><meta name=\"viewport\" content=\"width=device-width\"></head>")
|
|
||||||
print("<body><h1>" .. title .. "</h1>")
|
|
||||||
if (body) then
|
|
||||||
print("<section>")
|
|
||||||
print(body)
|
|
||||||
print("</section>")
|
|
||||||
end
|
|
||||||
|
|
||||||
print('<nav>')
|
|
||||||
print('<ul>')
|
|
||||||
print('<li><a href="../register.html">Register</a></li>')
|
|
||||||
print('<li><a href="../puzzles.html">Puzzles</a></li>')
|
|
||||||
print('<li><a href="../scoreboard.html">Scoreboard</a></li>')
|
|
||||||
print('</ul>')
|
|
||||||
print('</nav>')
|
|
||||||
|
|
||||||
print('<section id="sponsors">')
|
|
||||||
print('<img src="../images/logo0.png" alt="">')
|
|
||||||
print('<img src="../images/logo1.png" alt="">')
|
|
||||||
print('<img src="../images/logo2.png" alt="">')
|
|
||||||
print('<img src="../images/logo3.png" alt="">')
|
|
||||||
print('<img src="../images/logo4.png" alt="">')
|
|
||||||
print('</section>')
|
|
||||||
print("</body></html>")
|
|
||||||
os.exit(0)
|
|
||||||
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)
|
|
||||||
team = team:gsub("[^0-9a-f]", "-")
|
|
||||||
if (team == "") then
|
|
||||||
team = "-"
|
|
||||||
end
|
|
||||||
|
|
||||||
local filename = team .. "." .. category .. "." .. points
|
|
||||||
local entry = team .. " " .. category .. " " .. points
|
|
||||||
|
|
||||||
if (comment) then
|
|
||||||
entry = entry .. " " .. comment
|
|
||||||
end
|
|
||||||
|
|
||||||
local f = io.open(koth.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, " ")
|
|
||||||
if (ok) then
|
|
||||||
return false, "Points already awarded"
|
|
||||||
end
|
|
||||||
|
|
||||||
local f = io.open(koth.path("state/points.new/" .. filename), "a")
|
|
||||||
if (not f) then
|
|
||||||
return false, "Unable to write to points file"
|
|
||||||
end
|
|
||||||
|
|
||||||
f:write(os.time(), " ", entry, "\n")
|
|
||||||
f:close()
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Most web servers cd to the directory containing the CGI.
|
|
||||||
-- Not uhttpd.
|
|
||||||
|
|
||||||
koth.base = ""
|
|
||||||
function koth.path(p)
|
|
||||||
return koth.base .. p
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Traverse up to find assigned.txt
|
|
||||||
for i = 0, 5 do
|
|
||||||
local f = io.open(koth.path("state/assigned.txt"))
|
|
||||||
if (f) then
|
|
||||||
f:close()
|
|
||||||
break
|
|
||||||
end
|
|
||||||
koth.base = koth.base .. "../"
|
|
||||||
end
|
|
||||||
|
|
||||||
return koth
|
|
|
@ -1,34 +0,0 @@
|
||||||
#! /usr/bin/env lua
|
|
||||||
|
|
||||||
package.path = "?.lua;cgi-bin/?.lua;www/cgi-bin/?.lua"
|
|
||||||
|
|
||||||
local cgi = require "cgi"
|
|
||||||
local koth = require "koth"
|
|
||||||
|
|
||||||
local team = cgi.fields['t'] or ""
|
|
||||||
local category = cgi.fields['c'] or ""
|
|
||||||
local points = cgi.fields['p'] or ""
|
|
||||||
local answer = cgi.fields['a'] or ""
|
|
||||||
|
|
||||||
-- Defang category name; prevent directory traversal
|
|
||||||
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)
|
|
||||||
|
|
||||||
if (not found) then
|
|
||||||
koth.page("Wrong answer", err)
|
|
||||||
end
|
|
||||||
|
|
||||||
local ok, err = koth.award_points(team, category, points)
|
|
||||||
if (not ok) then
|
|
||||||
koth.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",
|
|
||||||
"<p>" .. points .. " points for " .. team .. "!</p>" ..
|
|
||||||
"<p><a href=\"../puzzles.html\">Back to puzzles</a></p>")
|
|
|
@ -1,33 +0,0 @@
|
||||||
#! /usr/bin/env lua
|
|
||||||
|
|
||||||
package.path = "?.lua;cgi-bin/?.lua;www/cgi-bin/?.lua"
|
|
||||||
|
|
||||||
|
|
||||||
local cgi = require "cgi"
|
|
||||||
local koth = require "koth"
|
|
||||||
|
|
||||||
local team = cgi.fields["n"] or ""
|
|
||||||
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("state/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?")
|
|
||||||
end
|
|
||||||
|
|
||||||
local f = io.open(koth.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.")
|
|
||||||
end
|
|
||||||
|
|
||||||
local f, err = io.open(koth.path("state/teams/" .. hash), "w+")
|
|
||||||
if (not f) then
|
|
||||||
koth.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!")
|
|
|
@ -1,38 +0,0 @@
|
||||||
#! /usr/bin/env lua
|
|
||||||
|
|
||||||
package.path = "?.lua;cgi-bin/?.lua;www/cgi-bin/?.lua"
|
|
||||||
|
|
||||||
local cgi = require "cgi"
|
|
||||||
local koth = require "koth"
|
|
||||||
|
|
||||||
local team = cgi.fields['t'] or ""
|
|
||||||
local token = cgi.fields['k'] or ""
|
|
||||||
|
|
||||||
-- Check answer
|
|
||||||
local needle = token
|
|
||||||
local haystack = koth.path("state/tokens.txt")
|
|
||||||
local found, err = koth.anchored_search(haystack, needle)
|
|
||||||
|
|
||||||
if (not found) then
|
|
||||||
koth.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")
|
|
||||||
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)
|
|
||||||
if (not ok) then
|
|
||||||
koth.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",
|
|
||||||
"<p>" .. points .. " points for " .. team .. "!</p>" ..
|
|
||||||
"<p><a href=\"../puzzles.html\">Back to puzzles</a></p>")
|
|
Loading…
Reference in New Issue