OC-Tsuki/ksrc/execs/velx_spec/velxspec.lua

86 lines
2.0 KiB
Lua

local velx_spec = struct {
endian = "<",
{magic="c5"},
{fver="B"},
{compression="B"},
{lver="B"},
{os="B"},
{arctype="c4"},
{psize="I3"},
{lsize="I3"},
{ssize="I3"},
{rsize="I4"}
}
local velx = {}
local exec = {}
function velx.identify(path)
local h = io.open(path, "rb")
local header = velx_spec(h:read(#velx_spec))
h:close()
return header.magic == "\27VelX"
end
function velx.load(path)
local h = io.open(path, "rb")
local header = velx_spec(h:read(#velx_spec))
local code = h:read(header.psize)
h:seek("cur", lsize)
local sig = h:read(header.ssize)
end
function velx.verify(path)
local h = io.open(path, "rb")
local header = velx_spec(h:read(#velx_spec))
local code = h:read(header.psize)
h:seek("cur", lsize)
local sig = h:read(header.ssize)
h:close()
return security.verify(code, sig)
end
function exec:link()
self.file:seek("set", #velx_spec+self.header.psize)
local linkinfo = self.file:read(self.header.lsize)
local linker = {}
local pos = 1
while true do
local size = string.unpack("<H", linkinfo:sub(pos))
pos = pos + 2
local name = linkinfo:sub(pos, pos+size-1)
pos = pos + size
size = string.unpack("<H", linkinfo:sub(pos))
pos = pos + 2
local library = linkinfo:sub(pos, pos+size-1)
pos = pos + size
if (name == "" or library == "") then
break
end
linker[#linker+1] = {name, library}
end
local linkscript = ""
for i=1, #linker do
linkscript = linkscript .. "local " .. linker[i][1] .. "=require(\"" .. linker[i][2] .. "\")\n"
end
self.code = linkscript .. self.code
return true
end
function exec:load()
self.file:seek("set", #velx_spec)
local code = self.file:read(self.header.psize)
if (self.header.compression == 0) then
self.code = code
elseif (self.header.compression == 1) then
self.code = lzss.decompress(self.code)
else
return nil, "invalid compression method"
end
return true
end
function exec:run(args, evar)
system.load(self.code, args, system.getglobalenv({_ARCHIVE=self.arc}), system.getevars(evar))
end