From dc03ad94bc6da71ef7706e410a15417a08da8b38 Mon Sep 17 00:00:00 2001 From: XeonSquared Date: Tue, 23 Jul 2019 14:11:40 +1000 Subject: [PATCH] added an FRequest client and server --- exec/fget.lua | 40 ++++++++++++++++++++++++ service/fserv.lua | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 exec/fget.lua create mode 100644 service/fserv.lua diff --git a/exec/fget.lua b/exec/fget.lua new file mode 100644 index 0000000..b4e1eb4 --- /dev/null +++ b/exec/fget.lua @@ -0,0 +1,40 @@ +local minitel = require "minitel" + +local tA = {...} + +local function parseURL(url) + local proto,addr = url:match("(.-)://(.+)") + addr = addr or url + local hp, path = addr:match("(.-)(/.*)") + hp, path = hp or addr, path or "/" + local host, port = hp:match("(.+):(.+)") + host = host or hp + return proto, host, port, path +end + +local proto, host, port, path = parseURL(tA[1]) +proto,port = proto or "fget", port or 70 +local fname, rtype = tA[2] or "-", tA[3] or "t" + +local sock = minitel.open(host,port) +local f = nil +if fname ~= "-" then + f = io.open(fname,"w") + if not f then error("couldn't open file for writing") end +else + f = io.open(os.getenv("t")) + f.close = function() end +end +if not sock then error("couldn't open connection to host") end +sock:write(string.format("%s%s\n",rtype,path)) +local rtype, buf = "", "" +repeat + coroutine.yield() + rtype = sock:read(1) +until rtype ~= "" +repeat + coroutine.yield() + buf = sock:read("*a") + f:write(buf) +until sock.state == "closed" and buf == "" +f:close() diff --git a/service/fserv.lua b/service/fserv.lua new file mode 100644 index 0000000..4c518f5 --- /dev/null +++ b/service/fserv.lua @@ -0,0 +1,78 @@ +local minitel = require "minitel" +local serial = require "serialization" + +local cfg = {["path"]="/boot/srv/frequest",["port"]=70} + +f=io.open("/boot/cfg/fserv.cfg","rb") +if f then + local ncfg = serial.unserialize(f:read("*a")) + f:close() + for k,v in pairs(ncfg) do + cfg[k] = v + end +end + +local function fileHandler(socket,rtype,path) + syslog(string.format("[%s:%d] %s %s",socket.addr,socket.port,rtype,path),syslog.info,"fserv") + if rtype == "t" then + if fs.exists(path) and fs.isDirectory(path) then + socket:write("d") + for _,file in ipairs(fs.list(path)) do + socket:write(file.."\n") + end + elseif fs.exists(path) and not fs.isDirectory(path) then + local f,err = io.open(path,"rb") + if f then + socket:write("y") + while true do + local c = f:read(4096) + if not c or c == "" then break end + socket:write(c) + end + else + socket:write("fFailed to open file: "..err) + end + else + socket:write("nFile not found") + end + elseif rtype == "s" then + if fs.exists(path) then + local ftype = "f" + if fs.isDirectory(path) then + ftype = "d" + end + socket:write(string.format("y%s\n%d",ftype,fs.size(path))) + else + socket:write("nFile not found.") + end + else + socket:write("fUnknown request type") + end + socket:close() +end +local function httpHandler(socket,rtype,path) + socket:write("fHTTP requests are not yet implemented.") + socket:close() +end + +local function socketHandler(socket) + return function() + local line = nil + repeat + coroutine.yield() + line = socket:read() + until line + local rtype, path = line:match("(.)(.+)") + if path:sub(1,6) == "/http/" or path:sub(1,5) == "http/" then + httpHandler(socket,rtype,path) + else + path = (cfg.path .. "/" .. path:gsub("../","")):gsub("/+","/") + fileHandler(socket,rtype,path) + end + socket:close() + end +end + +while true do + os.spawn(socketHandler(minitel.listen(70))) +end