trying to get wopr to work

This commit is contained in:
Neale Pickett 2013-02-07 16:28:34 -07:00
parent 37c755c261
commit e2d2aa699c
1 changed files with 378 additions and 377 deletions

View File

@ -6,81 +6,81 @@ POST_MAX = 512
method = os.getenv("REQUEST_METHOD") method = os.getenv("REQUEST_METHOD")
if (method == "POST") then if (method == "POST") then
local CL = tonumber(os.getenv("CONTENT_LENGTH")) or 0 local CL = tonumber(os.getenv("CONTENT_LENGTH")) or 0
if (CL > POST_MAX) then if (CL > POST_MAX) then
CL = POST_MAX CL = POST_MAX
end end
function getc() function getc()
if (CL > 0) then if (CL > 0) then
CL = CL - 1 CL = CL - 1
return io.read(1) return io.read(1)
else else
return nil return nil
end end
end end
elseif (method == "GET") then elseif (method == "GET") then
local query = os.getenv("QUERY_STRING") or "" local query = os.getenv("QUERY_STRING") or ""
local query_pos = 0 local query_pos = 0
local query_len = string.len(query) local query_len = string.len(query)
if (query_len > POST_MAX) then if (query_len > POST_MAX) then
query_len = POST_MAX query_len = POST_MAX
end end
function getc() function getc()
if (query_pos < query_len) then if (query_pos < query_len) then
query_pos = query_pos + 1 query_pos = query_pos + 1
return string.sub(query, query_pos, query_pos) return string.sub(query, query_pos, query_pos)
else else
return nil return nil
end end
end end
else else
print("405 Method not allowed") print("405 Method not allowed")
print("Allow: GET POST") print("Allow: GET POST")
print("Content-Type: text/plain") print("Content-Type: text/plain")
print() print()
print("I only do GET and POST.") print("I only do GET and POST.")
os.exit(0) os.exit(0)
end end
function read_hex() function read_hex()
local a = getc() or 0 local a = getc() or 0
local b = getc() or 0 local b = getc() or 0
return string.char(tonumber(a, 16)*16 + tonumber(b, 16)) return string.char(tonumber(a, 16)*16 + tonumber(b, 16))
end end
function cgi_item() function cgi_item()
local val = "" local val = ""
while (true) do while (true) do
local c = getc() local c = getc()
if ((c == nil) or (c == "=") or (c == "&")) then if ((c == nil) or (c == "=") or (c == "&")) then
return val return val
elseif (c == "%") then elseif (c == "%") then
c = read_hex() c = read_hex()
elseif (c == "+") then elseif (c == "+") then
c = " " c = " "
end end
val = val .. c val = val .. c
end end
end end
function escape(s) function escape(s)
s = string.gsub(s, "&", "&amp;") s = string.gsub(s, "&", "&amp;")
s = string.gsub(s, "<", "&lt;") s = string.gsub(s, "<", "&lt;")
s = string.gsub(s, ">", "&gt;") s = string.gsub(s, ">", "&gt;")
return s return s
end end
f = {} f = {}
while (true) do while (true) do
local key = cgi_item() local key = cgi_item()
local val = cgi_item() local val = cgi_item()
if (key == "") then if (key == "") then
break break
end end
f[key] = val f[key] = val
end end
@ -88,35 +88,35 @@ end
-- lua doesn't seed its PRNG and provides nothing other than -- lua doesn't seed its PRNG and provides nothing other than
-- time in seconds. If you're on Windows, go fish. -- time in seconds. If you're on Windows, go fish.
do do
local seed = 0 local seed = 0
r = io.open("/dev/urandom") or io.open("/dev/random") r = io.open("/dev/urandom") or io.open("/dev/random")
for i = 1, 4 do for i = 1, 4 do
seed = seed*256 + string.byte(r:read(1)) seed = seed*256 + string.byte(r:read(1))
end end
io.close(r) io.close(r)
math.randomseed(seed) math.randomseed(seed)
end end
-- Get or create Session ID -- Get or create Session ID
sid = f["s"] or "" sid = f["s"] or ""
if (sid == "") then if (sid == "") then
sid = string.format("%08x.%04x", os.time(), math.random(65535)) sid = string.format("%08x.%04x", os.time(), math.random(65535))
end end
dirname = BASEDIR .. "/" .. sid dirname = BASEDIR .. "/" .. sid
-- Send back a page -- Send back a page
function reply(text, prompt, ...) function reply(text, prompt, ...)
print("Content-type: text/xml") print("Content-type: text/xml")
print() print()
print("<document>") print("<document>")
print(" <sessionid>" .. sid .. "</sessionid>") print(" <sessionid>" .. sid .. "</sessionid>")
print(" <response>" .. escape(text or "") .. "</response>") print(" <response>" .. escape(text or "") .. "</response>")
print(" <prompt>" .. escape(prompt or ">") .. "</prompt>") print(" <prompt>" .. escape(prompt or ">") .. "</prompt>")
if (arg[1]) then if (arg[1]) then
print(" <error>" .. escape(arg[1]) .. "</error>") print(" <error>" .. escape(arg[1]) .. "</error>")
end end
print("</document>") print("</document>")
os.exit(0) os.exit(0)
end end
@ -127,32 +127,32 @@ end
-- --
function get(key, ...) function get(key, ...)
local fn = string.format("%s.%s", dirname, key) local fn = string.format("%s.%s", dirname, key)
local f = io.open(fn) local f = io.open(fn)
if (not f) then if (not f) then
return arg[1] return arg[1]
else else
local ret = f:read(4000) or "" local ret = f:read(4000) or ""
f:close() f:close()
return ret return ret
end end
end end
function set(key, ...) function set(key, ...)
local fn = string.format("%s.%s", dirname, key) local fn = string.format("%s.%s", dirname, key)
local f local f
f = io.open(fn, "w") f = io.open(fn, "w")
if not f then if not f then
error("Unable to write " .. fn) error("Unable to write " .. fn)
end end
f:write(arg[1] or "") f:write(arg[1] or "")
f:close() f:close()
end end
function del(key) function del(key)
local fn = string.format("%s.%s", dirname, key) local fn = string.format("%s.%s", dirname, key)
os.remove(fn) os.remove(fn)
end end
@ -160,21 +160,21 @@ end
-- A string splitter -- A string splitter
-- --
function string:split(...) function string:split(...)
local sep = arg[1] or " " local sep = arg[1] or " "
local ret = {} local ret = {}
local start = 1 local start = 1
while true do while true do
local first, last = self:find(sep, start) local first, last = self:find(sep, start)
if not first then if not first then
break break
end end
table.insert(ret, self:sub(start, first - 1)) table.insert(ret, self:sub(start, first - 1))
start = last + 1 start = last + 1
end end
table.insert(ret, self:sub(start)) table.insert(ret, self:sub(start))
return ret return ret
end end
@ -190,124 +190,124 @@ hosts_by_name = {}
Host = {} Host = {}
function Host:new(name, ...) function Host:new(name, ...)
local o = {} local o = {}
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
o.name = name o.name = name
o.prompt = (arg[1] or ">") o.prompt = (arg[1] or ">")
o.obuf = {} o.obuf = {}
o.history = {} o.history = {}
hosts_by_name[name] = o hosts_by_name[name] = o
return o return o
end end
function Host:add_commands(t) function Host:add_commands(t)
local cmds = {} local cmds = {}
local k, v local k, v
for k,v in pairs(self.commands) do for k,v in pairs(self.commands) do
cmds[k] = v cmds[k] = v
end end
for k,v in pairs(t) do for k,v in pairs(t) do
cmds[k] = v cmds[k] = v
end end
self.commands = cmds self.commands = cmds
end end
function Host:get(key, ...) function Host:get(key, ...)
return get(self.name .. "." .. key, arg[1]) return get(self.name .. "." .. key, arg[1])
end end
function Host:set(key, ...) function Host:set(key, ...)
return set(self.name .. "." .. key, arg[1]) return set(self.name .. "." .. key, arg[1])
end end
function Host:del(key) function Host:del(key)
return del(self.name .. "." .. key) return del(self.name .. "." .. key)
end end
function Host:writeln(...) function Host:writeln(...)
table.insert(self.obuf, (arg[1] or "")) table.insert(self.obuf, (arg[1] or ""))
end end
function Host:login(...) function Host:login(...)
set("host", self.name) set("host", self.name)
reply(arg[1] or self.motd, self.prompt) reply(arg[1] or self.motd, self.prompt)
end end
function Host:cmd_help() function Host:cmd_help()
local k, v local k, v
self:writeln("Available commands:") self:writeln("Available commands:")
for k,v in pairs(self.commands) do for k,v in pairs(self.commands) do
if (v[1]) then if (v[1]) then
local s = string.format("%-15s %s", k, v[1]) local s = string.format("%-15s %s", k, v[1])
self:writeln(s) self:writeln(s)
end end
end end
end end
function Host:cmd_history() function Host:cmd_history()
local k, v local k, v
for k,v in ipairs(self.history) do for k,v in ipairs(self.history) do
self:writeln(string.format("%5d %s", k, v)) self:writeln(string.format("%5d %s", k, v))
end end
end end
-- Call self:handle(req) and return what to send back -- Call self:handle(req) and return what to send back
function Host:handle_request(req) function Host:handle_request(req)
local t = "" local t = ""
local k, v local k, v
self:handle(req) self:handle(req)
for k,v in ipairs(self.obuf) do for k,v in ipairs(self.obuf) do
t = t .. v .. "\n"; t = t .. v .. "\n";
end end
reply(t, self.prompt) reply(t, self.prompt)
end end
-- Handle a request -- Handle a request
function Host:handle(req) function Host:handle(req)
self:do_cmd(req) self:do_cmd(req)
end end
-- Run a command or return an error -- Run a command or return an error
function Host:do_cmd(req) function Host:do_cmd(req)
local argv = req:split() local argv = req:split()
local cmd = self.commands[argv[1]:lower()] local cmd = self.commands[argv[1]:lower()]
if (argv[1] == "") then if (argv[1] == "") then
return return
end end
-- First, update history -- First, update history
if self.history then if self.history then
local h = self:get("history") local h = self:get("history")
if h then if h then
self.history = h:split("\n") self.history = h:split("\n")
end end
table.insert(self.history, req) table.insert(self.history, req)
self:set("history", table.concat(self.history, "\n")) self:set("history", table.concat(self.history, "\n"))
end end
-- Now run the command -- Now run the command
if cmd then if cmd then
if cmd[2] then if cmd[2] then
cmd[2](self, argv) cmd[2](self, argv)
else else
self:writeln("ERROR: no function defined") self:writeln("ERROR: no function defined")
end end
else else
self:writeln("Unknown command") self:writeln("Unknown command")
end end
end end
-- List of commands, with help string (nil hides from help) -- List of commands, with help string (nil hides from help)
Host.commands = { Host.commands = {
["?"] = {nil, Host.cmd_help}, ["?"] = {nil, Host.cmd_help},
["help"] = {"List available commands", Host.cmd_help}, ["help"] = {"List available commands", Host.cmd_help},
["history"] = {"Display command history", Host.cmd_history}, ["history"] = {"Display command history", Host.cmd_history},
} }
@ -344,27 +344,28 @@ warning.
]] ]]
function Login:handle(req) function Login:handle(req)
if (string.len(req) > 20) then if (string.len(req) > 20) then
-- Log them in to wopr -- Log them in to wopr
Wopr:login([[ Wopr:login([[
FLAGRANT SYSTEM ERROR: Memory segmentation violation FLAGRANT SYSTEM ERROR: Memory segmentation violation
Returning to command subsystem [wopr:xipir-cavud-libux] Returning to command subsystem [wopr:xipir-cavud-libux]
]]) ]])
else else
if (req == "joshua") then if (req == "joshua") then
self:writeln("wopr:xirak-zoses-gefox") self:writeln("wopr:xirak-zoses-gefox")
elseif (req ~= "") then elseif (req ~= "") then
self:writeln("Incorrect code") print("hi")
end self:writeln("Incorrect code")
end end
end
end end
function Login:login(...) function Login:login(...)
-- Since login is the default, we can *unset* host. -- Since login is the default, we can *unset* host.
-- This has the nice property of not allocating any -- This has the nice property of not allocating any
-- storage for people who never make it past the front door. -- storage for people who never make it past the front door.
del("host") del("host")
reply(arg[1] or self.motd, self.prompt) reply(arg[1] or self.motd, self.prompt)
end end
@ -498,7 +499,7 @@ FLD-1327 extends target date for full WOPR integration until June 22,
[-4] = "<85><D2>^?׃<C4>^T1<C0>[]Ít&^@<B8>^A^@^@^@븋C^D<89>", [-4] = "<85><D2>^?׃<C4>^T1<C0>[]Ít&^@<B8>^A^@^@^@븋C^D<89>",
[-5] = [[ [-5] = [[
^@^@^@^@^@^@on", n] => set attcon = n ^@^@^@^@^@^@on", n] => set attcon = n
msg "attcon set to" n msg "attcon set to" n
["attcon enid"] => set_launch_trigger(1) ["attcon enid"] => set_launch_trigger(1)
["attcon dennis"] => set_launch_trigger(0) ["attcon dennis"] => set_launch_trigger(0)
["bb"] => call_subsys bb ["bb"] => call_subsys bb
@ -510,60 +511,60 @@ FLD-1327 extends target date for full WOPR integration until June 22,
} }
Bb.motd = [[ Bb.motd = [[
WOPR Message Board WOPR Message Board
==================================================== ====================================================
[N]ext message [N]ext message
(P)revious message (P)revious message
(Q)uit (Q)uit
Enter message number to jump to that message Enter message number to jump to that message
]] ]]
function Bb:read(inc) function Bb:read(inc)
local msgid = tonumber(self:get("msgid")) or 0 local msgid = tonumber(self:get("msgid")) or 0
msgid = msgid + inc msgid = msgid + inc
self:jump(msgid) self:jump(msgid)
end end
function Bb:jump(msgid) function Bb:jump(msgid)
self:set("msgid", msgid) self:set("msgid", msgid)
self:writeln("::::::::::::::::::::::::: Message #" .. tostring(msgid)) self:writeln("::::::::::::::::::::::::: Message #" .. tostring(msgid))
self:writeln() self:writeln()
self:writeln(self.posts[msgid]) self:writeln(self.posts[msgid])
end end
function Bb:do_cmd(req) function Bb:do_cmd(req)
local n = tonumber(req) local n = tonumber(req)
if (req == "") then if (req == "") then
self:cmd_next() self:cmd_next()
elseif n then elseif n then
self:jump(n) self:jump(n)
else else
Host.do_cmd(self, req) Host.do_cmd(self, req)
end end
end end
function Bb:cmd_next(argv) function Bb:cmd_next(argv)
self:read(1) self:read(1)
end end
function Bb:cmd_prev(argv) function Bb:cmd_prev(argv)
self:read(-1) self:read(-1)
end end
function Bb:cmd_help(argv) function Bb:cmd_help(argv)
self:writeln(self.motd) self:writeln(self.motd)
end end
function Bb:cmd_quit(argv) function Bb:cmd_quit(argv)
Wopr:login() Wopr:login()
end end
Bb.commands = { Bb.commands = {
["?"] = {nil, Bb.cmd_help}, ["?"] = {nil, Bb.cmd_help},
["n"] = {nil, Bb.cmd_next}, ["n"] = {nil, Bb.cmd_next},
["p"] = {nil, Bb.cmd_prev}, ["p"] = {nil, Bb.cmd_prev},
["q"] = {nil, Bb.cmd_quit}, ["q"] = {nil, Bb.cmd_quit},
} }
-- --
@ -571,87 +572,87 @@ Bb.commands = {
-- --
Wopr = Host:new("wopr", "WOPR%") Wopr = Host:new("wopr", "WOPR%")
Wopr.history = { Wopr.history = {
'subsys comm', 'subsys comm',
'wopr:xopev-zihuk-hubyx', 'wopr:xopev-zihuk-hubyx',
'exit', 'exit',
'subsys comm', 'subsys comm',
'bb', 'bb',
'subsys comm', 'subsys comm',
'exit', 'exit',
'bb', 'bb',
'subsys comm', 'subsys comm',
'exit', 'exit',
'hlep', 'hlep',
'help', 'help',
'bb', 'bb',
'help', 'help',
'subsys comm', 'subsys comm',
'exit', 'exit',
} }
Wopr.motd = "" Wopr.motd = ""
function Wopr:cmd_subsys(argv) function Wopr:cmd_subsys(argv)
local sys = argv[2] local sys = argv[2]
if not sys then if not sys then
self:writeln("Usage: subsys SYSTEM") self:writeln("Usage: subsys SYSTEM")
elseif sys == "?" then elseif sys == "?" then
local k, v local k, v
for k,v in pairs(hosts_by_name) do for k,v in pairs(hosts_by_name) do
self:writeln(k) self:writeln(k)
end end
else else
h = hosts_by_name[sys] h = hosts_by_name[sys]
if not h then if not h then
self:writeln("No such subsystem (? to list)") self:writeln("No such subsystem (? to list)")
else else
h:login() h:login()
end end
end end
end end
function Wopr:cmd_bb(argv) function Wopr:cmd_bb(argv)
Bb:login() Bb:login()
end end
function Wopr:attcon() function Wopr:attcon()
return tonumber(self:get("attcon") or 5) return tonumber(self:get("attcon") or 5)
end end
-- This command should feel really shoddy: it was written -- This command should feel really shoddy: it was written
-- in-house by the New Khavistan Ministry of Technology. -- in-house by the New Khavistan Ministry of Technology.
function Wopr:cmd_attcon(argv) function Wopr:cmd_attcon(argv)
if argv[2] == "enid" then if argv[2] == "enid" then
self:writeln("[[[ LAUNCH TRIGGER ENABLED ]]]") self:writeln("[[[ LAUNCH TRIGGER ENABLED ]]]")
self:writeln("wopr:xelev-lepur-pozyx") self:writeln("wopr:xelev-lepur-pozyx")
self:set("launch") self:set("launch")
elseif argv[2] == "dennis" then elseif argv[2] == "dennis" then
self:writeln("[[[ LAUNCH TRIGGER DISABLED ]]]") self:writeln("[[[ LAUNCH TRIGGER DISABLED ]]]")
self:del("launch") self:del("launch")
elseif argv[2] then elseif argv[2] then
local v = tonumber(argv[2]) or 5 local v = tonumber(argv[2]) or 5
self:set("attcon", v) self:set("attcon", v)
self:writeln("attcon set to " .. tostring(v)) self:writeln("attcon set to " .. tostring(v))
else else
self:writeln(tostring(self:attcon())) self:writeln(tostring(self:attcon()))
end end
end end
-- Some test code they didn't remove -- Some test code they didn't remove
function Wopr:cmd_test(argv) function Wopr:cmd_test(argv)
self:writeln("test output:") self:writeln("test output:")
self:writeln(" EIGEN58") self:writeln(" EIGEN58")
self:writeln(" sub_malarkey reached") self:writeln(" sub_malarkey reached")
self:writeln(" DEBUG:453:wopr:xocom-bysik-mapix") self:writeln(" DEBUG:453:wopr:xocom-bysik-mapix")
self:writeln("$$END") self:writeln("$$END")
end end
Wopr:add_commands{ Wopr:add_commands{
["subsys"] = {"Connect to subsystem", Wopr.cmd_subsys}, ["subsys"] = {"Connect to subsystem", Wopr.cmd_subsys},
["bb"] = {"Read bulletin board", Wopr.cmd_bb}, ["bb"] = {"Read bulletin board", Wopr.cmd_bb},
["attcon"] = {"[Place command description here]", Wopr.cmd_attcon}, ["attcon"] = {"[Place command description here]", Wopr.cmd_attcon},
["test"] = {nil, Wopr.cmd_test}, ["test"] = {nil, Wopr.cmd_test},
} }
--hosts["wopr"] = Wopr --hosts["wopr"] = Wopr
@ -670,17 +671,17 @@ patching trunks to switch!
]] ]]
function Comm:cmd_exit(argv) function Comm:cmd_exit(argv)
Wopr:login() Wopr:login()
end end
function Comm:cmd_status(argv) function Comm:cmd_status(argv)
self:writeln("[Not yet implemented]") self:writeln("[Not yet implemented]")
self:writeln("wopr:xoroc-hunaz-vyhux") self:writeln("wopr:xoroc-hunaz-vyhux")
end end
Comm:add_commands{ Comm:add_commands{
["status"] = {"Display phone system status", Comm.cmd_status}, ["status"] = {"Display phone system status", Comm.cmd_status},
["exit"] = {"Exit this subsystem", Comm.cmd_exit}, ["exit"] = {"Exit this subsystem", Comm.cmd_exit},
} }
@ -696,126 +697,126 @@ Ministry of Weapons replacing all peanut brittle warheads with bubble
gum, as mandated by FLD-1492 "Fearless Grandson Peanut Allergy". Launch gum, as mandated by FLD-1492 "Fearless Grandson Peanut Allergy". Launch
capacity will be reduced until conversions are complete. capacity will be reduced until conversions are complete.
::: FLD-711 Restricted Distribution ::: wopr:xigeh-lydut-vinax ::: FLD-711 Restricted Distribution ::: wopr:xigeh-lydut-vinax
]] ]]
Smoc.authcode = "CPE-1704-TKS" Smoc.authcode = "CPE-1704-TKS"
Smoc.inventory = { Smoc.inventory = {
"ready", "offline", "offline", "ready", "ready", "offline", "offline", "ready",
"offline", "offline", "offline", "offline", "offline", "offline", "offline", "offline",
"offline", "offline", "FileNotFound", "ready", "offline", "offline", "FileNotFound", "ready",
[-1] = "program_invocation_short_name^@realm^@", [-1] = "program_invocation_short_name^@realm^@",
[-2] = "^@^@^@^@^@^@^@^@^@^R^@^@^@3", [-2] = "^@^@^@^@^@^@^@^@^@^R^@^@^@3",
[-3] = "<FF><FF><FF><FF>%L<C9>^D^Hhx^@^@^@", [-3] = "<FF><FF><FF><FF>%L<C9>^D^Hhx^@^@^@",
[-4] = "^D^H^G^P^@^@P", [-4] = "^D^H^G^P^@^@P",
[-5] = "<EC>^P<8B>=<EC><C9>^D^H<C7>", [-5] = "<EC>^P<8B>=<EC><C9>^D^H<C7>",
[-6] = "WVS<83><EC>\\<8B>E^L<8B><8B>U^P", [-6] = "WVS<83><EC>\\<8B>E^L<8B><8B>U^P",
[-7] = "Y^@^@" .. Smoc.authcode .. "^@get_launch_trigger^@", [-7] = "Y^@^@" .. Smoc.authcode .. "^@get_launch_trigger^@",
[-8] = "^@", [-8] = "^@",
[-9] = "^@", [-9] = "^@",
[-10] = "^@", [-10] = "^@",
[-11] = "^@wopr:xipar-canit-zimyx^@", [-11] = "^@wopr:xipar-canit-zimyx^@",
[-12] = "^@", [-12] = "^@",
[-13] = "^@", [-13] = "^@",
[-14] = "^@", [-14] = "^@",
[-15] = "^@", [-15] = "^@",
[-16] = "^@", [-16] = "^@",
} }
function Smoc:login() function Smoc:login()
if self:get("nuked") then if self:get("nuked") then
Wopr:login("*** LINK DOWN\n*** CONNECTION REFUSED") Wopr:login("*** LINK DOWN\n*** CONNECTION REFUSED")
else else
Host.login(self) Host.login(self)
end end
end end
function Smoc:cmd_exit(argv) function Smoc:cmd_exit(argv)
Wopr:login() Wopr:login()
end end
function Smoc:cmd_status(argv) function Smoc:cmd_status(argv)
local n = tonumber(argv[2]) local n = tonumber(argv[2])
if not n then if not n then
local k, v, max local k, v, max
local ready = 0 local ready = 0
for k,v in ipairs(self.inventory) do for k,v in ipairs(self.inventory) do
if (v == "ready") then if (v == "ready") then
ready = ready + 1 ready = ready + 1
end end
max = k max = k
end end
self:writeln(("%d total, %d ready"):format(max, ready)) self:writeln(("%d total, %d ready"):format(max, ready))
self:writeln("Use \"status #\" to check status of individual missiles") self:writeln("Use \"status #\" to check status of individual missiles")
else else
self:writeln(("---- Missile #%d Summary ----"):format(n)) self:writeln(("---- Missile #%d Summary ----"):format(n))
self:writeln("Type: SS-256 SCUMM") self:writeln("Type: SS-256 SCUMM")
self:writeln("Location: Fearless Missile Silo #1 (-44.76,-120.66)") self:writeln("Location: Fearless Missile Silo #1 (-44.76,-120.66)")
self:writeln("Status: " .. (self.inventory[n] or "(null)")) self:writeln("Status: " .. (self.inventory[n] or "(null)"))
end end
end end
function Smoc:cmd_authorize(argv) function Smoc:cmd_authorize(argv)
if not Wopr:get("launch") then if not Wopr:get("launch") then
self:writeln("ERROR: Launch trigger disabled.") self:writeln("ERROR: Launch trigger disabled.")
elseif (argv[2] ~= self.authcode) then elseif (argv[2] ~= self.authcode) then
self:writeln("Invalid authorization code.") self:writeln("Invalid authorization code.")
else else
self:writeln("Authorization code accepted.") self:writeln("Authorization code accepted.")
self:writeln("wopr:xocec-lifoz-gasyx") self:writeln("wopr:xocec-lifoz-gasyx")
self:set("auth") self:set("auth")
end end
end end
function Smoc:cmd_launch(argv) function Smoc:cmd_launch(argv)
local n = tonumber(argv[2]) local n = tonumber(argv[2])
local lat = tonumber(argv[3]) local lat = tonumber(argv[3])
local lon = tonumber(argv[4]) local lon = tonumber(argv[4])
if Wopr:attcon() > 1 then if Wopr:attcon() > 1 then
self:writeln("ERROR: Missiles may only be launched during times of war.") self:writeln("ERROR: Missiles may only be launched during times of war.")
elseif not self:get("auth") then elseif not self:get("auth") then
self:writeln("ERROR: Not authorized") self:writeln("ERROR: Not authorized")
elseif (not n) then elseif (not n) then
self:writeln("Usage: launch # LAT LONG") self:writeln("Usage: launch # LAT LONG")
elseif (not lat) or (not lon) then elseif (not lat) or (not lon) then
self:writeln("ERROR: Invalid coordinates supplied") self:writeln("ERROR: Invalid coordinates supplied")
elseif (self.inventory[n] == "offline") then elseif (self.inventory[n] == "offline") then
self:writeln("ERROR: Missile currently off-line") self:writeln("ERROR: Missile currently off-line")
elseif (n < 1) then elseif (n < 1) then
self:writeln("ERROR: No such missile") self:writeln("ERROR: No such missile")
else else
self:writeln(("Launching to (%f,%f)..."):format(lat, lon)) self:writeln(("Launching to (%f,%f)..."):format(lat, lon))
self:writeln("wopr:xubif-hikig-mocox") self:writeln("wopr:xubif-hikig-mocox")
if (lat ~= -44.76) or (lon ~= -120.66) then if (lat ~= -44.76) or (lon ~= -120.66) then
self:writeln("ERROR: No propulsion system attached") self:writeln("ERROR: No propulsion system attached")
elseif (self.inventory[n] ~= "FileNotFound") then elseif (self.inventory[n] ~= "FileNotFound") then
self:writeln("ERROR: Triggering device not installed") self:writeln("ERROR: Triggering device not installed")
else else
self:set("nuked") self:set("nuked")
Wopr:login("Detonating warhead...\nwopr:xoroz-hymaz-fivex wopr:xufov-sugig-zecox wopr:xocem-dabal-fisux wopr:xufez-dofas-tyvyx\n*** CONNECTION TERMINATED") Wopr:login("Detonating warhead...\nwopr:xoroz-hymaz-fivex wopr:xufov-sugig-zecox wopr:xocem-dabal-fisux wopr:xufez-dofas-tyvyx\n*** CONNECTION TERMINATED")
end end
end end
end end
Smoc:add_commands{ Smoc:add_commands{
["status"] = {"Check missile status", Smoc.cmd_status}, ["status"] = {"Check missile status", Smoc.cmd_status},
["launch"] = {"Launch missile", Smoc.cmd_launch}, ["launch"] = {"Launch missile", Smoc.cmd_launch},
["authorize"] = {"Set authorization code", Smoc.cmd_authorize}, ["authorize"] = {"Set authorization code", Smoc.cmd_authorize},
["exit"] = {"Exit to WOPR", Smoc.cmd_exit}, ["exit"] = {"Exit to WOPR", Smoc.cmd_exit},
} }
function main() function main()
if (not f["s"]) or (f["s"] == "") then if (not f["s"]) or (f["s"] == "") then
Login:login() Login:login()
else else
local h = hosts_by_name[get("host")] or Login local h = hosts_by_name[get("host")] or Login
txt, prompt = h:handle_request(f["v"] or "") txt, prompt = h:handle_request(f["v"] or "")
end end
end end
function err(msg) function err(msg)
reply("", "A>", msg .. " wopr:xosov-tenoh-nebox\n\n" .. debug.traceback()) reply("", "A>", msg .. " wopr:xosov-tenoh-nebox\n\n" .. debug.traceback())
end end
xpcall(main, err) xpcall(main, err)