1
0
mirror of https://github.com/ShadowKatStudios/OC-Minitel.git synced 2024-11-23 10:38:05 +11:00

replaced fserv.lua with a much cleaner version that uses libsyslog

This commit is contained in:
Izaya 2018-07-28 05:19:58 +10:00
parent 97734851dc
commit a509630361
2 changed files with 117 additions and 70 deletions

View File

@ -1,83 +1,129 @@
local net = require "net" local net = require "net"
local fs = require "filesystem"
local event = require "event" local event = require "event"
local syslog = require "syslog"
local fs = require "filesystem"
local computer = require "computer"
local serial = require "serialization"
local prefix = "/srv" local sockets = {}
local process = nil local cfg = {}
local listener = nil cfg.path = "/srv"
local dbug = false cfg.looptime = 0.5
local timer = false
local function dprint(...) local function log(msg,level)
if dbug then syslog(msg,level,"frequestd")
print(...) end
local function loadConfig()
local fobj = io.open("/etc/fserv.cfg","rb")
if fobj then
config = serial.unserialize(fobj:read("*a")) or config
fobj:close()
end end
end end
local function writeConfig()
local fobj = io.open("/etc/fserv.cfg","wb")
if fobj then
fobj:write(serial.serialize(config))
fobj:close()
end
end
--[[
overview of how this works:
socketHandler listens for connections on port 70, places them into the sockets table
socketLoop runs quite regularly - every cfg.looptime or so.
It iterates over each socket in the sockets table, and if any of them contain a valid request, it attempts to handle it:
- calls getFile to get a status code and file contents if applicable
- writes either a failure code and message, the file contents, or the file size
Previously this was based on a listener but that caused a race condition
note to self: consider using the FS library for handling stat requests, and returning an iterator instead of an entire file for transfer requests
]]--
local function getFile(path)
path = cfg.path .. path
if not fs.exists(path) then
log(path.." not found",syslog.notice)
return "n",path.." not found"
end
if fs.isDirectory(path) then
local dlist = ""
for file in fs.list(path) do
dlist = dlist .. file .. "\n"
end
return "d", dlist
end
local f = io.open(path,"rb")
if not f then
log("unable to open "..path,syslog.notice)
return "f","unable to open "..path
end
local content = f:read("*a")
f:close()
return "y", content
end
local function socketLoop()
for sn,socket in pairs(sockets) do
local op, path = socket.rbuffer:match("([ts])(.+)\n")
if op and path then
path = fs.canonical(path)
if path:sub(1,1) ~= "/" then
path = "/" .. path
end
log("client "..tostring(socket.addr)..":"..tostring(socket.port).." requested "..path, syslog.debug)
if op == "t" and path then
local wf, file = getFile(path)
socket:write(wf .. file)
socket:close()
sockets[sn] = nil
elseif op == "s" and path then
local wf, file = getFile(path)
if wf == "y" then
socket:write(wf..file:len())
else
socket:write(wf..file)
end
socket:close()
sockets[sn] = nil
end
end
if computer.uptime() > socket.opened + 60 then
socket:close()
sockets[sn] = nil
log("dropped client "..tostring(socket.addr)..":"..tostring(socket.port).." for inactivity",syslog.debug)
elseif socket.state ~= "open" then
sockets[sn] = nil
log("client "..tostring(socket.addr)..":"..tostring(socket.port).." closed socket",syslog.debug)
end
end
end
local function socketHandler(socket)
log(tostring(socket.addr)..":"..tostring(socket.port).." opened",syslog.debug)
socket.opened = computer.uptime()
sockets[tostring(socket.addr)..":"..tostring(socket.port)] = socket
end
function start() function start()
process = net.flisten(70,function(s) loadConfig()
local buffer = "" writeConfig()
local function lf() net.flisten(70, socketHandler)
buffer=s:read(1024) timer = event.timer(cfg.looptime, socketLoop, math.huge)
local nl = buffer:find("\n")
if nl then
local rt = buffer:sub(1,1)
local path=prefix .. "/" .. buffer:sub(2,nl-1)
dprint(path)
if path:find("%.%./") then
s:write("f to pay respects")
s:close()
return
end
if fs.exists(path) then
if rt == "t" then
if fs.isDirectory(path) then
s:write("d")
if fs.exists(path.."/index") then
local f=io.open(path.."/index","rb")
s:write(f:read("*a"))
f:close()
end
local dbuffer = ""
for f in fs.list(path) do
dbuffer = dbuffer..f.."\n"
dprint(f)
end
s:write(dbuffer)
s:close()
else
s:write("y")
local f = io.open(path,"rb")
s:write(f:read("*a"))
f:close()
s:close()
end
else
s:write(tostring(fs.size(path)))
s:close()
end
else
dprint("404")
s:write("not found")
s:close()
end
end
end
listener = lf
event.listen("net_msg",lf)
end)
end end
function stop() function stop()
event.ignore("net_msg",listener) event.ignore("net_msg", socketLoop)
event.ignore("net_msg",process) event.cancel(timer)
end end
function debug() function set(k,v)
dbug = not dbug if cfg[k] then
end cfg[k] = v
function set_path(newpath) print("cfg."..k.." = "..v)
if fs.exists(newpath) then
prefix=newpath
print("prefix = "..newpath)
end end
writeConfig()
end end

View File

@ -15,10 +15,11 @@
["master/FRequest/OpenOS/etc/rc.d/fserv.lua"] = "//etc/rc.d" ["master/FRequest/OpenOS/etc/rc.d/fserv.lua"] = "//etc/rc.d"
}, },
dependencies = { dependencies = {
["minitel"] = "" ["minitel"] = "",
["libsyslog"] = ""
}, },
name = "FRequest Daemon", name = "FRequest Daemon",
description = "Dumb-as-rocks FRequest server", description = "Reasonably sane FRequest server",
authors = "Izaya", authors = "Izaya",
repo = "tree/master/" repo = "tree/master/"
}, },