OC-DSS2/OpenOS/server/etc/rc.d/searchsrv.lua

89 lines
2.1 KiB
Lua

local serial = require "serialization"
local minitel = require "minitel"
local thread = require "thread"
local syslog = require "syslog"
local lz16 = require "liblz16"
local inv = require "inv"
local rpc = require "rpc"
local listeners = {}
local coro = {}
local config = {port=15,logfile="/tmp/dss.log"}
function reload()
local f = io.open("/etc/dss/dss.cfg","rb")
if not f then
os.execute("mkdir /etc/dss")
f=io.open("/etc/dss/dss.cfg", "wb")
f:write(serial.serialize(config))
f:close()
end
config = serial.unserialize(f:read("*a"))
f:close()
local alias = inv.getAliases()
for fn,_ in pairs(inv) do
for hn,_ in pairs(alias) do
rpc.allow(fn,hn)
end
end
end
local function parseSearch(str)
local criteria = {}
for arg in str:gmatch("[^\t]+") do
local k,v = arg:match("(.+)=(.*)")
criteria[k] = tonumber(v) or v or ""
end
local fuzzy, compress = criteria.fuzzy or false, criteria.compress or false
criteria.fuzzy, criteria.compress = nil, nil
return criteria, fuzzy, compress
end
local function formatEntry(stack)
local ft = {}
for k,v in pairs(stack) do
if type(v) == "string" or type(v) == "number" then
ft[k] = v
end
end
return serial.serialize(ft) .. "\n"
end
local function handleSocket(socket)
coro[#coro+1] = thread.create(function()
local query
repeat
os.sleep(0.5)
query = socket:read()
until query
syslog(string.format("[%s:%i] %s",socket.addr,socket.port,query),syslog.info,"mtdss")
local criteria, fuzzy, compress = parseSearch(query)
local lsock
if compress then
socket.mode={w=true}
lsock = lz16.buffer(socket)
else
lsock = socket
end
for slot, stack in pairs(inv.matchAll(criteria,fuzzy)) do
lsock:write(formatEntry(stack))
end
lsock:close()
socket:close()
end)
syslog(string.format("Connection from %s:%i",socket.addr,socket.port),syslog.info, "mtdss")
end
function start()
for k,v in pairs(inv) do
rpc.register("inv_"..k, v)
end
reload()
listeners[#listeners+1] = minitel.flisten(config.port,handleSocket)
end
function stop()
thread.waitForAll(coro)
for k,v in pairs(listeners) do
event.ignore("net_msg",v)
end
end