xpm
This commit is contained in:
commit
6560b7a5bc
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test.lua
|
51
example-cfg/config.cfg
Normal file
51
example-cfg/config.cfg
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
prefix = "/usr",
|
||||||
|
cache = {
|
||||||
|
clustersize = 20
|
||||||
|
},
|
||||||
|
repos = {
|
||||||
|
"OpenPrograms/mpmxyz-Programs",
|
||||||
|
"OpenPrograms/Altenius-Programs",
|
||||||
|
"OpenPrograms/pedrosgali-Programs",
|
||||||
|
"OpenPrograms/Gopher-Programs",
|
||||||
|
"OpenPrograms/ds84182-Programs",
|
||||||
|
"vifino/lua-cpuemus",
|
||||||
|
"OpenPrograms/Kenny-Programs",
|
||||||
|
"OpenPrograms/LizzyTrickster-Programs",
|
||||||
|
"OpenPrograms/Kilobyte-Programs",
|
||||||
|
"OpenPrograms/admicos-Programs",
|
||||||
|
"OpenPrograms/Wobbo-Programs",
|
||||||
|
"OpenPrograms/payonel-Programs",
|
||||||
|
"evgkul/moonscript-opencomputers",
|
||||||
|
"OpenPrograms/lperkins2-Programs",
|
||||||
|
"OpenPrograms/Forecaster-Programs",
|
||||||
|
"OpenPrograms/SuPeRMiNoR2-Programs",
|
||||||
|
"OpenPrograms/gamax92-Programs",
|
||||||
|
"OpenPrograms/Magik6k-Programs",
|
||||||
|
"OpenPrograms/Techokami-Programs",
|
||||||
|
"OpenPrograms/Wuerfel_21-OC-Toolkit",
|
||||||
|
"OpenPrograms/Wilma456-Programs",
|
||||||
|
"OpenPrograms/Sangar-Programs",
|
||||||
|
"OpenPrograms/luisau-Programs",
|
||||||
|
"OpenPrograms/Vexatos-Programs",
|
||||||
|
"OpenPrograms/Jomik-Programs",
|
||||||
|
"OpenPrograms/EvaKnievel-Programs",
|
||||||
|
"OpenPrograms/istasi-Programs",
|
||||||
|
"OpenPrograms/MiscPrograms",
|
||||||
|
"OpenPrograms/Starchasers-Programs",
|
||||||
|
"SolraBizna/SolrOC",
|
||||||
|
"OpenPrograms/Plan9k",
|
||||||
|
"OpenPrograms/asie-Programs",
|
||||||
|
"OpenPrograms/Antheus-Programs",
|
||||||
|
"ShadowKatStudios/OC-Minitel",
|
||||||
|
"Vexatos/Selene",
|
||||||
|
"OpenPrograms/Saphire-Programs",
|
||||||
|
"vilu85/OC-programs",
|
||||||
|
"OpenPrograms/Pixel-Programs",
|
||||||
|
"OpenPrograms/OpenPrograms.ru",
|
||||||
|
"OpenPrograms/Kubuxu-Programs",
|
||||||
|
"Kilobyte22/v",
|
||||||
|
"Akuukis/RobotColorWars",
|
||||||
|
"OpenPrograms/Fingercomp-Programs",
|
||||||
|
}
|
||||||
|
}
|
145
package.lua
Normal file
145
package.lua
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
local repos = {
|
||||||
|
["admicos' programs"]={
|
||||||
|
repo="OpenPrograms/admicos-Programs",
|
||||||
|
},
|
||||||
|
["Akuukis' programs"]={
|
||||||
|
repo="Akuukis/RobotColorWars",
|
||||||
|
},
|
||||||
|
["Altenius' programs"]={
|
||||||
|
repo="OpenPrograms/Altenius-Programs",
|
||||||
|
},
|
||||||
|
["Antheus' programs"]={
|
||||||
|
repo="OpenPrograms/Antheus-Programs",
|
||||||
|
},
|
||||||
|
["asie's programs"]={
|
||||||
|
repo="OpenPrograms/asie-Programs",
|
||||||
|
},
|
||||||
|
["ds84182's programs"]={
|
||||||
|
repo="OpenPrograms/ds84182-Programs",
|
||||||
|
},
|
||||||
|
["DustBin's programs"]={
|
||||||
|
programs={
|
||||||
|
["LibCompress"]={
|
||||||
|
repo="OpenPrograms/LibCompress/blob/master/LibCompress.lua",
|
||||||
|
desc="Compression API",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["EvaKnievel's programs"]={
|
||||||
|
repo="OpenPrograms/EvaKnievel-Programs",
|
||||||
|
},
|
||||||
|
["Fingercomp's programs"]={
|
||||||
|
repo="OpenPrograms/Fingercomp-Programs",
|
||||||
|
},
|
||||||
|
["Forecaster's programs"]={
|
||||||
|
repo="OpenPrograms/Forecaster-Programs",
|
||||||
|
},
|
||||||
|
["gamax92's programs"]={
|
||||||
|
repo="OpenPrograms/gamax92-Programs",
|
||||||
|
},
|
||||||
|
["Gopher's programs"]={
|
||||||
|
repo="OpenPrograms/Gopher-Programs",
|
||||||
|
},
|
||||||
|
["istasi's programs"]={
|
||||||
|
repo="OpenPrograms/istasi-Programs",
|
||||||
|
},
|
||||||
|
["Jomik's programs"]={
|
||||||
|
repo="OpenPrograms/Jomik-Programs",
|
||||||
|
},
|
||||||
|
["LizzyTrickster's programs"]={
|
||||||
|
repo="OpenPrograms/LizzyTrickster-Programs",
|
||||||
|
},
|
||||||
|
["lperkins2's programs"]={
|
||||||
|
repo="OpenPrograms/lperkins2-Programs",
|
||||||
|
},
|
||||||
|
["Luisau's programs"]={
|
||||||
|
repo="OpenPrograms/luisau-Programs",
|
||||||
|
},
|
||||||
|
["Kenny's programs"]={
|
||||||
|
repo="OpenPrograms/Kenny-Programs",
|
||||||
|
},
|
||||||
|
["Kilobyte's programs"]={
|
||||||
|
repo="OpenPrograms/Kilobyte-Programs",
|
||||||
|
},
|
||||||
|
["Kilobyte's programs (more)"]={
|
||||||
|
repo="Kilobyte22/v",
|
||||||
|
},
|
||||||
|
["Kubuxu's programs"]={
|
||||||
|
repo="OpenPrograms/Kubuxu-Programs",
|
||||||
|
},
|
||||||
|
["Magik6k's programs"]={
|
||||||
|
repo="OpenPrograms/Magik6k-Programs",
|
||||||
|
},
|
||||||
|
["Minitel"]={
|
||||||
|
repo="ShadowKatStudios/OC-Minitel",
|
||||||
|
},
|
||||||
|
["MoonOC"]={
|
||||||
|
repo="evgkul/moonscript-opencomputers",
|
||||||
|
},
|
||||||
|
["mpmxyz's programs"]={
|
||||||
|
repo="OpenPrograms/mpmxyz-Programs",
|
||||||
|
},
|
||||||
|
["OpenPrograms.ru"]={
|
||||||
|
repo="OpenPrograms/OpenPrograms.ru",
|
||||||
|
},
|
||||||
|
["payonel's programs"]={
|
||||||
|
repo="OpenPrograms/payonel-Programs",
|
||||||
|
},
|
||||||
|
["pedrosgali's programs"]={
|
||||||
|
repo="OpenPrograms/pedrosgali-Programs",
|
||||||
|
},
|
||||||
|
["PixelToast's programs"]={
|
||||||
|
repo="OpenPrograms/Pixel-Programs",
|
||||||
|
},
|
||||||
|
["Plan9k"]={
|
||||||
|
repo="OpenPrograms/Plan9k",
|
||||||
|
},
|
||||||
|
["Sangar's programs"]={
|
||||||
|
repo="OpenPrograms/Sangar-Programs",
|
||||||
|
},
|
||||||
|
["Saphire's programs"]={
|
||||||
|
repo="OpenPrograms/Saphire-Programs",
|
||||||
|
},
|
||||||
|
["Selene"]={
|
||||||
|
repo="Vexatos/Selene",
|
||||||
|
},
|
||||||
|
["SolraBizna's programs"]={
|
||||||
|
repo="SolraBizna/SolrOC",
|
||||||
|
},
|
||||||
|
["Starchasers' programs"]={
|
||||||
|
repo="OpenPrograms/Starchasers-Programs",
|
||||||
|
},
|
||||||
|
["SuPeRMiNoR2's programs"]={
|
||||||
|
repo="OpenPrograms/SuPeRMiNoR2-Programs",
|
||||||
|
},
|
||||||
|
["Techokami's programs"]={
|
||||||
|
repo="OpenPrograms/Techokami-Programs",
|
||||||
|
},
|
||||||
|
["Vexatos' programs"]={
|
||||||
|
repo="OpenPrograms/Vexatos-Programs",
|
||||||
|
},
|
||||||
|
["vifino's Lua CPU emulators"]={
|
||||||
|
repo="vifino/lua-cpuemus",
|
||||||
|
},
|
||||||
|
["vilu's programs"]={
|
||||||
|
repo="vilu85/OC-programs",
|
||||||
|
},
|
||||||
|
["Wilma456's programs"]={
|
||||||
|
repo="OpenPrograms/Wilma456-Programs",
|
||||||
|
},
|
||||||
|
["Wobbo's programs"]={
|
||||||
|
repo="OpenPrograms/Wobbo-Programs",
|
||||||
|
},
|
||||||
|
["Wuerfel_21's programs"]={
|
||||||
|
repo="OpenPrograms/Wuerfel_21-OC-Toolkit",
|
||||||
|
},
|
||||||
|
["Miscellaneous programs"]={
|
||||||
|
repo="OpenPrograms/MiscPrograms",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v in pairs(repos) do
|
||||||
|
if (v.repo) then
|
||||||
|
print(string.format("\""..v.repo.."\","))
|
||||||
|
end
|
||||||
|
end
|
247
src/blt.lua
Normal file
247
src/blt.lua
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
-- BLT, made for Lua 5.3
|
||||||
|
|
||||||
|
local blt = {}
|
||||||
|
|
||||||
|
do
|
||||||
|
local types
|
||||||
|
|
||||||
|
local function serialize(val)
|
||||||
|
local t = type(val)
|
||||||
|
if (t == "number") then
|
||||||
|
t = math.type(val)
|
||||||
|
end
|
||||||
|
local b, str = types["s"..t](val)
|
||||||
|
b = (b << 3) | types[t]
|
||||||
|
return string.char(b) .. str
|
||||||
|
end
|
||||||
|
|
||||||
|
local function deserialize(str, t)
|
||||||
|
local tb = str:byte(1)
|
||||||
|
local type_ = tb & 7
|
||||||
|
local b = tb >> 3
|
||||||
|
local v, l = types[type_](b, str:sub(2))
|
||||||
|
return v, l+1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fromdouble(f)
|
||||||
|
return 0, string.pack("<d", f)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function todouble(b, str)
|
||||||
|
return string.unpack("<d", str:sub(1, 8)), 8
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _fromlongint(i)
|
||||||
|
--print("longint")
|
||||||
|
return 8, string.pack("<l", i)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fromint(i)
|
||||||
|
--Time to rabidly optimize this.
|
||||||
|
local len = 0
|
||||||
|
local cmp2 = 0
|
||||||
|
if (i > 0xFFFFFFFFFFFFFF) then return _fromlongint(i) end
|
||||||
|
for j=0, 7 do
|
||||||
|
len = len + 1
|
||||||
|
cmp2 = cmp2 | (0xFF << j)
|
||||||
|
--print("fromint", i+((cmp2//2)), cmp2)
|
||||||
|
--if (i+((cmp2//2)) <= cmp2) then
|
||||||
|
if (math.abs(i) <= cmp2//2) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (i < 0) then
|
||||||
|
i = i + (cmp2//2)
|
||||||
|
end
|
||||||
|
--i = i + (cmp2//2)
|
||||||
|
local tmp = ""
|
||||||
|
for j=0, len-1 do
|
||||||
|
tmp = tmp .. string.char((i & (0xFF << (j*8))) >> (j*8))
|
||||||
|
end
|
||||||
|
--local tmp = string.pack("<i["..len.."]", i)
|
||||||
|
return len, tmp
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _tolongint(str)
|
||||||
|
--print("longint2")
|
||||||
|
return string.unpack("<l", str:sub(1, 8)), 8
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toint(b, str)
|
||||||
|
if (b == 8) then return _tolongint(str) end
|
||||||
|
--return string.unpack("<i["..b.."]", str:sub(1, b)), b
|
||||||
|
local tmp = 0
|
||||||
|
for i=0, b-1 do
|
||||||
|
tmp = tmp | (str:byte(i+1) << (i*8))
|
||||||
|
end
|
||||||
|
local sign = (tmp & (0x80 << ((b-1)*8)))
|
||||||
|
sign = sign << (63 - (b*8))
|
||||||
|
local int = tmp & ((0x80 << ((b-1)*8)) ~ 0xFFFFFFFFFFFFFF)
|
||||||
|
return int | sign, b
|
||||||
|
end
|
||||||
|
|
||||||
|
local function frombool(b)
|
||||||
|
return b and 1 or 0, ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tobool(b, str)
|
||||||
|
return b ~= 0, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fromstr(s)
|
||||||
|
local len, val = fromint(#s)
|
||||||
|
return len, val .. s
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tostr(b, str)
|
||||||
|
local strl, l = toint(b, str)
|
||||||
|
local rtn = str:sub(1+l, l+strl)
|
||||||
|
return rtn, strl+l
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fromarray(a)
|
||||||
|
local b, tmp = fromint(#a)
|
||||||
|
for i=1, #a do
|
||||||
|
tmp = tmp .. serialize(a[i])
|
||||||
|
end
|
||||||
|
--print("alen_s", #tmp)
|
||||||
|
return b, tmp
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toarray(b, str, arr)
|
||||||
|
local arrl, l = toint(b, str)
|
||||||
|
--print("clen", l)
|
||||||
|
--print("arr len", arrl)
|
||||||
|
local arr = {}
|
||||||
|
local i = 0
|
||||||
|
for i=1, arrl do
|
||||||
|
--print("adec", i)
|
||||||
|
local v, z = deserialize(str:sub(1+l))
|
||||||
|
--print("arr", i, v)
|
||||||
|
l = l+z
|
||||||
|
--print("clen", l, z)
|
||||||
|
arr[i] = v
|
||||||
|
end
|
||||||
|
--print("alen", l)
|
||||||
|
return arr, l
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fromtbl(t)
|
||||||
|
local tmp = ""
|
||||||
|
--See if the numerical keys are a list, and, if so, write a list
|
||||||
|
local nindex = 0
|
||||||
|
local nmax = 0
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if (type(k) == "number") then
|
||||||
|
if (math.type(k) == "integer") then
|
||||||
|
nindex = nindex + 1
|
||||||
|
if (nmax < k) then
|
||||||
|
nmax = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local ks = serialize(k)
|
||||||
|
local vs = serialize(v)
|
||||||
|
tmp = tmp .. ks .. vs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (nmax > 0) then
|
||||||
|
if (nindex == nmax) then
|
||||||
|
local ib, dat = fromarray(t)
|
||||||
|
tmp = tmp .. string.char(0) .. string.char(types.table_array | (ib << 3)) .. dat
|
||||||
|
else
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if (type(k) == "number" and math.type(k) == "integer") then
|
||||||
|
local ks = serialize(k)
|
||||||
|
local vs = serialize(v)
|
||||||
|
tmp = tmp .. ks .. vs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return 0, tmp .. string.char(0,0) --nil,nil terminated
|
||||||
|
end
|
||||||
|
|
||||||
|
local function totbl(b, str)
|
||||||
|
local t = {}
|
||||||
|
local k = ""
|
||||||
|
local v = ""
|
||||||
|
local pos = 1
|
||||||
|
--print("topen")
|
||||||
|
while true do
|
||||||
|
--print("k", str:byte(pos), str:byte(pos) & 7)
|
||||||
|
local k, l = deserialize(str:sub(pos))
|
||||||
|
pos = pos + l
|
||||||
|
--print("v", str:byte(pos), str:byte(pos) & 7)
|
||||||
|
if (str:byte(pos) & 7 == 6) then
|
||||||
|
--print("ailen", str:byte(pos) & (7 ~ 0xFF))
|
||||||
|
local r, l = deserialize(str:sub(pos))
|
||||||
|
pos = pos + l
|
||||||
|
for i=1, #r do
|
||||||
|
t[i] = r[i]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local v, l = deserialize(str:sub(pos))
|
||||||
|
pos = pos + l
|
||||||
|
if (not v and not k) then
|
||||||
|
--print("tclose")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
--print("decode", k, v)
|
||||||
|
t[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return t, pos-1 --how
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Type LUT
|
||||||
|
types = {
|
||||||
|
["nil"] = 0,
|
||||||
|
float = 1,
|
||||||
|
number = 1,
|
||||||
|
integer = 2,
|
||||||
|
string = 3,
|
||||||
|
boolean = 4,
|
||||||
|
table = 5,
|
||||||
|
table_array = 6, --Meta-value
|
||||||
|
[0] = function(b, str) return nil, 0 end,
|
||||||
|
[1] = todouble,
|
||||||
|
[2] = toint,
|
||||||
|
[3] = tostr,
|
||||||
|
[4] = tobool,
|
||||||
|
[5] = totbl,
|
||||||
|
[6] = toarray,
|
||||||
|
snil = function()return 0, ""end,
|
||||||
|
sfloat = fromdouble,
|
||||||
|
sinteger = fromint,
|
||||||
|
sstring = fromstr,
|
||||||
|
sboolean = frombool,
|
||||||
|
stable = fromtbl,
|
||||||
|
stable_array = fromarray
|
||||||
|
}
|
||||||
|
|
||||||
|
function blt.serialize(...)
|
||||||
|
local args = {...}
|
||||||
|
local tmp = string.char(#args)
|
||||||
|
for i=1, #args do
|
||||||
|
local str = serialize(args[i])
|
||||||
|
tmp = tmp .. str
|
||||||
|
end
|
||||||
|
return tmp
|
||||||
|
end
|
||||||
|
|
||||||
|
local unpack = unpack or table.unpack
|
||||||
|
|
||||||
|
function blt.deserialize(str)
|
||||||
|
local args = {}
|
||||||
|
local pos = 2
|
||||||
|
local amt = str:byte(1)
|
||||||
|
local l
|
||||||
|
for i=1, amt do
|
||||||
|
local v, l = deserialize(str:sub(pos))
|
||||||
|
args[i] = v
|
||||||
|
pos = pos + l
|
||||||
|
end
|
||||||
|
return unpack(args)
|
||||||
|
end
|
||||||
|
end
|
188
src/cache.lua
Normal file
188
src/cache.lua
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
local cache = {}
|
||||||
|
do
|
||||||
|
local function load_cache(name)
|
||||||
|
local cfile = io.open("/etc/xpm/cache/"..name.."/manifest.dat", "r")
|
||||||
|
local cachemf = blt.deserialize(cfile:read("*a"))
|
||||||
|
cfile:close()
|
||||||
|
local cached_files = {}
|
||||||
|
local mt = setmetatable({}, {__index=function(self, i)
|
||||||
|
if (cachemf[i]) then
|
||||||
|
local h = io.open(string.format("/etc/xpm/cache/%s/%x.dat", name, cachemf[i]), "r")
|
||||||
|
local t = blt.deserialize(h:read("*a"))
|
||||||
|
h:close()
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
rawset(self, k, v)
|
||||||
|
end
|
||||||
|
return rawget(self, i)
|
||||||
|
end
|
||||||
|
end})
|
||||||
|
rawset(mt, -1, cachemf)
|
||||||
|
return mt
|
||||||
|
end
|
||||||
|
local function save_cache(name, packages)
|
||||||
|
fs.makeDirectory("/etc/xpm/cache/"..name)
|
||||||
|
local manifest = io.open("/etc/xpm/cache/"..name.."/manifest.dat", "w")
|
||||||
|
local mf = {}
|
||||||
|
local current_cache = {}
|
||||||
|
local count = 0
|
||||||
|
local idx = 0
|
||||||
|
for k, v in pairs(packages) do
|
||||||
|
if (k ~= -1) then
|
||||||
|
mf[k] = count
|
||||||
|
current_cache[k] = v
|
||||||
|
idx = idx+1
|
||||||
|
if (idx > config.cache.clustersize) then
|
||||||
|
idx = 0
|
||||||
|
print(string.format("/etc/xpm/cache/%s/%x.dat", name, count))
|
||||||
|
local cf = io.open(string.format("/etc/xpm/cache/%s/%x.dat", name, count), "w")
|
||||||
|
cf:write(blt.serialize(current_cache))
|
||||||
|
cf:close()
|
||||||
|
current_cache = {}
|
||||||
|
count = count + 1
|
||||||
|
for i=1, 11 do
|
||||||
|
os.sleep(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local cf = io.open(string.format("/etc/xpm/cache/%s/%x.dat", name, count), "w")
|
||||||
|
cf:write(blt.serialize(current_cache))
|
||||||
|
cf:close()
|
||||||
|
current_cache = {}
|
||||||
|
count = count + 1
|
||||||
|
for i=1, 10 do
|
||||||
|
os.sleep(0)
|
||||||
|
end
|
||||||
|
manifest:write(blt.serialize(mf))
|
||||||
|
manifest:close()
|
||||||
|
end
|
||||||
|
local pcache = {}
|
||||||
|
local lcache = {}
|
||||||
|
if (fs.exists("/etc/xpm/cache/local")) then
|
||||||
|
lcache = load_cache("local")
|
||||||
|
end
|
||||||
|
|
||||||
|
if (fs.exists("/etc/xpm/cache/remote")) then
|
||||||
|
pcache = load_cache("remote")
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.check_cache(pkg)
|
||||||
|
return pcache[pkg]
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.update_cache()
|
||||||
|
print("Updating cache...")
|
||||||
|
pcache = {}
|
||||||
|
fs.makeDirectory("/etc/xpm/cache/remote")
|
||||||
|
local manifest = io.open("/etc/xpm/cache/remote/manifest.dat", "w")
|
||||||
|
local mf = {}
|
||||||
|
local current_cache = {}
|
||||||
|
local count = 0
|
||||||
|
local idx = 0
|
||||||
|
for i=#config.repos, 1, -1 do
|
||||||
|
print("Hit "..(#config.repos-i)..": "..config.repos[i])
|
||||||
|
local repo = serialization.unserialize(github_download(config.repos[i], "master/programs.cfg"))
|
||||||
|
if repo then
|
||||||
|
for k, v in pairs(repo) do
|
||||||
|
local e = {repo = config.repos[i], pkginfo=v}
|
||||||
|
mf[k] = count
|
||||||
|
current_cache[k] = e
|
||||||
|
idx = idx+1
|
||||||
|
if (idx > config.cache.clustersize) then
|
||||||
|
idx = 0
|
||||||
|
print(string.format("/etc/xpm/cache/%s/%x.dat", "remote", count))
|
||||||
|
local cf = io.open(string.format("/etc/xpm/cache/%s/%x.dat", "remote", count), "w")
|
||||||
|
cf:write(blt.serialize(current_cache))
|
||||||
|
cf:close()
|
||||||
|
current_cache = {}
|
||||||
|
count = count + 1
|
||||||
|
for i=1, 11 do
|
||||||
|
os.sleep(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Error "..(#config.repos-i)..": Not found.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local cf = io.open(string.format("/etc/xpm/cache/%s/%x.dat", "remote", count), "w")
|
||||||
|
cf:write(blt.serialize(current_cache))
|
||||||
|
cf:close()
|
||||||
|
current_cache = {}
|
||||||
|
count = count + 1
|
||||||
|
for i=1, 10 do
|
||||||
|
os.sleep(0)
|
||||||
|
end
|
||||||
|
manifest:write(blt.serialize(mf))
|
||||||
|
manifest:close()
|
||||||
|
--[[local h = io.open("/etc/xpm/cache/remote.dat", "w")
|
||||||
|
print("Serializing...")
|
||||||
|
local ser = blt.serialize(pcache)
|
||||||
|
print(#ser)
|
||||||
|
os.sleep(0)
|
||||||
|
print("Compressing...")
|
||||||
|
local comp = lzss.compress(ser)
|
||||||
|
print(#comp, "=", #ser/#comp)
|
||||||
|
h:write(comp)
|
||||||
|
h:close()]]
|
||||||
|
--save_cache("remote", pcache)
|
||||||
|
print("Saved cache.")
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.get_upgradable()
|
||||||
|
if not fs.exists("/etc/xpm/cache/local") then
|
||||||
|
--cache.update_cache()
|
||||||
|
--local h = io.open("/etc/xpm/cache/local.dat", "w")
|
||||||
|
--h:write(lzss.compress(blt.serialize({xpm = pcache.xpm})))
|
||||||
|
save_cache("local", {xpm = pcache.xpm})
|
||||||
|
lcache = {xpm = pcache.xpm}
|
||||||
|
--h:close()
|
||||||
|
end
|
||||||
|
local upgradable = {}
|
||||||
|
for k, v in pairs(lcache) do
|
||||||
|
if (k ~= -1) then
|
||||||
|
local lpkg, rpkg = v.pkginfo, pcache[k].pkginfo
|
||||||
|
if lpkg.xpm and rpkg.xpm and lpkg.xpm.version ~= rpkg.xpm.version then
|
||||||
|
upgradable[#upgradable+1] = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return upgradable
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.fullload(cdat, name)
|
||||||
|
for k, v in pairs(cdat[-1]) do
|
||||||
|
if (not cdat[k]) then
|
||||||
|
local h = io.open(string.format("/etc/xpm/cache/%s/%x.dat", name, v), "r")
|
||||||
|
local t = blt.deserialize(h:read("*a"))
|
||||||
|
h:close()
|
||||||
|
for l, b in pairs(t) do
|
||||||
|
rawset(cdat, l, b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.update_local_cache(pkg, info)
|
||||||
|
lcache[pkg] = info
|
||||||
|
--local h = io.open("/etc/xpm/cache/local.dat", "w")
|
||||||
|
--h:write(lzss.compress(blt.serialize(lcache)))
|
||||||
|
--h:close()
|
||||||
|
local mf = lcache[-1]
|
||||||
|
if not mf.loaded then
|
||||||
|
cache.fullload(lcache, "local")
|
||||||
|
mf.loaded = true
|
||||||
|
end
|
||||||
|
lcache[-1] = nil
|
||||||
|
save_cache("local", lcache)
|
||||||
|
lcache[-1] = mf
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.getlocal()
|
||||||
|
return lcache
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.getremote()
|
||||||
|
return pcache
|
||||||
|
end
|
||||||
|
end
|
7
src/config.lua
Normal file
7
src/config.lua
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
local config = {}
|
||||||
|
|
||||||
|
do
|
||||||
|
local fh = io.open("/etc/xpm/config.cfg", "r")
|
||||||
|
config = serialization.unserialize(fh:read("*a"))
|
||||||
|
fh:close()
|
||||||
|
end
|
23
src/github.lua
Normal file
23
src/github.lua
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
local function download_file(url)
|
||||||
|
local result, response = pcall(internet.request, url)
|
||||||
|
--print(response)
|
||||||
|
local res = ""
|
||||||
|
if result then
|
||||||
|
local result, reason = pcall(function()
|
||||||
|
for chunk in response do
|
||||||
|
res = res .. chunk
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
if not result then
|
||||||
|
return nil, reason -- for programs using wget as a function
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return nil, response -- for programs using wget as a function
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
local function github_download(repo, file)
|
||||||
|
local url = string.format("https://raw.githubusercontent.com/%s/%s", repo, file)
|
||||||
|
return download_file(url)
|
||||||
|
end
|
4
src/includes.lua
Normal file
4
src/includes.lua
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
local internet = require("internet")
|
||||||
|
local fs = require("filesystem")
|
||||||
|
local serialization = require("serialization")
|
||||||
|
local event = require("event")
|
20
src/info.lua
Normal file
20
src/info.lua
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
local function get_pkginfo(pkgname)
|
||||||
|
return cache.check_cache(pkgname) and cache.check_cache(pkgname).pkginfo
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pkg_installed(pkgname)
|
||||||
|
return cache.getlocal()[pkgname]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_version(pkgname)
|
||||||
|
local r, l = get_pkginfo(pkgname), pkg_installed(pkgname) and pkg_installed(pkgname).pkginfo
|
||||||
|
local rv, lv = true, not not l
|
||||||
|
if r.xpm and r.xpm.version then
|
||||||
|
rv = r.xpm.version
|
||||||
|
end
|
||||||
|
|
||||||
|
if lv and l.xpm and l.xpm.version then
|
||||||
|
lv = l.xpm.version
|
||||||
|
end
|
||||||
|
return rv, lv
|
||||||
|
end
|
116
src/init.lua
Normal file
116
src/init.lua
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
--#include "src/includes.lua"
|
||||||
|
--#include "src/config.lua"
|
||||||
|
--#include "src/blt.lua"
|
||||||
|
--#include "src/lzss.lua"
|
||||||
|
--#include "src/github.lua"
|
||||||
|
--#include "src/zcache.lua"
|
||||||
|
--#include "src/install.lua"
|
||||||
|
--#include "src/info.lua"
|
||||||
|
--#include "src/remove.lua"
|
||||||
|
|
||||||
|
local args = table.pack(...)
|
||||||
|
if args[1] == "update" then
|
||||||
|
cache.update_cache()
|
||||||
|
local ug = cache.get_upgradable()
|
||||||
|
if (#ug > 0) then
|
||||||
|
print(#ug .. " packages can be upgraded.")
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
elseif args[1] == "install" then
|
||||||
|
local deps = {}
|
||||||
|
print("Resolving dependencies...")
|
||||||
|
for i=2, #args do
|
||||||
|
resolve_deps(args[i], deps)
|
||||||
|
deps[#deps+1] = args[i]
|
||||||
|
deps[args[i]] = true
|
||||||
|
end
|
||||||
|
print("Packages to be installed:")
|
||||||
|
print(table.concat(deps, " "))
|
||||||
|
while event.pull(0) do end
|
||||||
|
print("\nContinue with installation? [y/n]")
|
||||||
|
local sig = {event.pull("key_down")}
|
||||||
|
if (sig[3] ~= string.byte("y")) then
|
||||||
|
print("Canceling.")
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
for i=1, #deps do
|
||||||
|
print("Installing "..deps[i])
|
||||||
|
deps[deps[i]] = install_pkg(deps[i])
|
||||||
|
end
|
||||||
|
for i=1, #deps do
|
||||||
|
print("Running postinstall for "..deps[i])
|
||||||
|
pkg_postinstall(deps[i], deps[deps[i]])
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
elseif args[1] == "info" then
|
||||||
|
local pi = get_pkginfo(args[2])
|
||||||
|
if not pi then io.stderr:write("package not found\n") os.exit(1) end
|
||||||
|
local installed = pkg_installed(args[2])
|
||||||
|
io.stdout:write(args[2] .. " ")
|
||||||
|
local remver, locver = get_version(args[2])
|
||||||
|
if (type(remver) ~= "boolean" or type(locver) ~= "boolean") then
|
||||||
|
io.stdout:write("- "..remver)
|
||||||
|
if locver then
|
||||||
|
io.stdout:write(" (installed: "..locver..")")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print("")
|
||||||
|
print("Name: "..pi.name)
|
||||||
|
print("Authors: "..pi.authors)
|
||||||
|
print(pi.description)
|
||||||
|
if pi.note then
|
||||||
|
print("NOTE: "..pi.note)
|
||||||
|
end
|
||||||
|
elseif args[1] == "list" then
|
||||||
|
local lc = cache.getremote()
|
||||||
|
local mf = lc[-1]
|
||||||
|
local filter = args[2] or "."
|
||||||
|
for k, v in pairs(mf) do
|
||||||
|
if (k:match(filter) and not lc[k].pkginfo.hidden) then
|
||||||
|
print(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif args[1] == "list-installed" then
|
||||||
|
local mf = cache.getlocal()[-1]
|
||||||
|
local filter = args[2] or "."
|
||||||
|
for k, v in pairs(mf) do
|
||||||
|
if (k:match(filter)) then
|
||||||
|
print(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif args[1] == "remove" then
|
||||||
|
local deps = {}
|
||||||
|
cache.fullload(cache.getlocal(), "local")
|
||||||
|
print("Resolving dependencies...")
|
||||||
|
for i=2, #args do
|
||||||
|
deps[#deps+1] = args[i]
|
||||||
|
deps[args[i]] = true
|
||||||
|
get_removal_deps(args[i], deps)
|
||||||
|
end
|
||||||
|
print("Packages to be removed:")
|
||||||
|
print(table.concat(deps, " "))
|
||||||
|
print("\nContinue with removal? [y/n]")
|
||||||
|
local sig = {event.pull("key_down")}
|
||||||
|
if (sig[3] ~= string.byte("y")) then
|
||||||
|
print("Canceling.")
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
for i=1, #deps do
|
||||||
|
print("Removing "..deps[i])
|
||||||
|
remove_pkg(deps[i])
|
||||||
|
end
|
||||||
|
elseif args[1] == "help" then
|
||||||
|
print("xpm update - Updates the cache")
|
||||||
|
print("xpm upgrade - Updates all packages that need to be updated.")
|
||||||
|
print("xpm install <pkg, ...> - Installs packages.")
|
||||||
|
print("xpm add-repo <repo, ...> - Adds a package repo. Does not refresh cache.")
|
||||||
|
print("xpm remove-repo <repo, ...> - Removes a repo. Does not refresh cache.")
|
||||||
|
print("xpm remove <pkg, ...> - Removes a package.")
|
||||||
|
print("xpm info <pkg> - Gets package info.")
|
||||||
|
print("xpm deptree <pkg> - Gets dependency tree.")
|
||||||
|
print("xpm list [filter] - Lists packages.")
|
||||||
|
print("xpm list-installed [filter] - Lists installed packages.")
|
||||||
|
else
|
||||||
|
print("invalid command")
|
||||||
|
return false
|
||||||
|
end
|
59
src/install.lua
Normal file
59
src/install.lua
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
local function resolve_deps(pkgname, deps)
|
||||||
|
local pkg = cache.check_cache(pkgname)
|
||||||
|
if not pkg then
|
||||||
|
io.stderr:write("Package not found.\n")
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
local info = pkg.pkginfo
|
||||||
|
if (info.dependencies) then
|
||||||
|
for k, v in pairs(info.dependencies) do
|
||||||
|
if not cache.getlocal()[k] and not deps[k] then
|
||||||
|
resolve_deps(k, deps)
|
||||||
|
deps[#deps+1] = k
|
||||||
|
deps[k] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function install_pkg(pkgname, prefix)
|
||||||
|
prefix = prefix or config.prefix
|
||||||
|
-- Look up in cache
|
||||||
|
local pkg = cache.check_cache(pkgname)
|
||||||
|
if not pkg then
|
||||||
|
io.stderr:write("Package not found.\n")
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
pkg.tracked_files = {}
|
||||||
|
for k, v in pairs(pkg.pkginfo.files) do
|
||||||
|
if (v:sub(1, 2) ~= "//") then
|
||||||
|
v = config.prefix .. v
|
||||||
|
else
|
||||||
|
v = v:sub(2)
|
||||||
|
end
|
||||||
|
if (k:sub(1, 1) ~= ":") then
|
||||||
|
--print(k)
|
||||||
|
local fp = k:sub(#k:match("^(.+)/.+$")+1)
|
||||||
|
fs.makeDirectory(v)
|
||||||
|
--print(v..fp)
|
||||||
|
local f = io.open(v..fp, "w")
|
||||||
|
f:write(github_download(pkg.repo, k))
|
||||||
|
f:close()
|
||||||
|
pkg.tracked_files[#pkg.tracked_files+1] = v .. fp
|
||||||
|
else
|
||||||
|
print(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return pkg
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pkg_postinstall(pkg, info)
|
||||||
|
cache.update_local_cache(pkg, info)
|
||||||
|
local pkgi = cache.getlocal()[pkg].pkginfo
|
||||||
|
if (pkgi.postinstall) then
|
||||||
|
local pi = pkgi.postinstall
|
||||||
|
for i=1, #pi do
|
||||||
|
os.execute(pi[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
122
src/lzss.lua
Normal file
122
src/lzss.lua
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
--[[----------------------------------------------------------------------------
|
||||||
|
LZSS - encoder / decoder
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
||||||
|
--]]----------------------------------------------------------------------------
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
local lzss = {}
|
||||||
|
do
|
||||||
|
local string, table = string, table
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
local POS_BITS = 12
|
||||||
|
local LEN_BITS = 16 - POS_BITS
|
||||||
|
local POS_SIZE = 1 << POS_BITS
|
||||||
|
local LEN_SIZE = 1 << LEN_BITS
|
||||||
|
local LEN_MIN = 3
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local cout = require("computer").uptime
|
||||||
|
local lsleep = cout()
|
||||||
|
function lzss.compress(input)
|
||||||
|
local offset, output = 1, {}
|
||||||
|
local window = ''
|
||||||
|
if (cout() - lsleep > 4) then
|
||||||
|
os.sleep(0)
|
||||||
|
lsleep = cout()
|
||||||
|
end
|
||||||
|
local function search()
|
||||||
|
for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do
|
||||||
|
local str = string.sub(input, offset, offset + i - 1)
|
||||||
|
local pos = string.find(window, str, 1, true)
|
||||||
|
if pos then
|
||||||
|
return pos, str
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while offset <= #input do
|
||||||
|
local flags, buffer = 0, {}
|
||||||
|
|
||||||
|
for i = 0, 7 do
|
||||||
|
if offset <= #input then
|
||||||
|
local pos, str = search()
|
||||||
|
if pos and #str >= LEN_MIN then
|
||||||
|
local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN)
|
||||||
|
buffer[#buffer + 1] = string.pack('>I2', tmp)
|
||||||
|
else
|
||||||
|
flags = flags | (1 << i)
|
||||||
|
str = string.sub(input, offset, offset)
|
||||||
|
buffer[#buffer + 1] = str
|
||||||
|
end
|
||||||
|
window = string.sub(window .. str, -POS_SIZE)
|
||||||
|
offset = offset + #str
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #buffer > 0 then
|
||||||
|
output[#output + 1] = string.char(flags)
|
||||||
|
output[#output + 1] = table.concat(buffer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(output)
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
function lzss.decompress(input)
|
||||||
|
local offset, output = 1, {}
|
||||||
|
local window = ''
|
||||||
|
|
||||||
|
while offset <= #input do
|
||||||
|
local flags = string.byte(input, offset)
|
||||||
|
offset = offset + 1
|
||||||
|
|
||||||
|
for i = 1, 8 do
|
||||||
|
local str = nil
|
||||||
|
if (flags & 1) ~= 0 then
|
||||||
|
if offset <= #input then
|
||||||
|
str = string.sub(input, offset, offset)
|
||||||
|
offset = offset + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if offset + 1 <= #input then
|
||||||
|
local tmp = string.unpack('>I2', input, offset)
|
||||||
|
offset = offset + 2
|
||||||
|
local pos = (tmp >> LEN_BITS) + 1
|
||||||
|
local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN
|
||||||
|
str = string.sub(window, pos, pos + len - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
flags = flags >> 1
|
||||||
|
if str then
|
||||||
|
output[#output + 1] = str
|
||||||
|
window = string.sub(window .. str, -POS_SIZE)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(output)
|
||||||
|
end
|
||||||
|
end
|
20
src/remove.lua
Normal file
20
src/remove.lua
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
local function get_removal_deps(pkgname, deps)
|
||||||
|
local packages = cache.getlocal()
|
||||||
|
for k, v in pairs(packages) do
|
||||||
|
if (k ~= -1) then
|
||||||
|
if (v.pkginfo.dependencies and v.pkginfo.dependencies[pkgname] and not deps[k]) then
|
||||||
|
deps[#deps+1] = k
|
||||||
|
deps[k] = true
|
||||||
|
get_removal_deps(k, deps)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function remove_pkg(pkgname)
|
||||||
|
local files = cache.getlocal()[pkgname].tracked_files
|
||||||
|
for i=1, #files do
|
||||||
|
fs.remove(files[i])
|
||||||
|
end
|
||||||
|
cache.update_local_cache(pkgname, nil)
|
||||||
|
end
|
0
src/tsar.lua
Normal file
0
src/tsar.lua
Normal file
175
src/zcache.lua
Normal file
175
src/zcache.lua
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
local cache = {}
|
||||||
|
do
|
||||||
|
local function load_cache(name)
|
||||||
|
local cfile = io.open("/etc/xpm/cache/"..name.."/manifest.dat", "r")
|
||||||
|
local cachemf = blt.deserialize(lzss.decompress(cfile:read("*a")))
|
||||||
|
cfile:close()
|
||||||
|
local cached_files = {}
|
||||||
|
local mt = setmetatable({}, {__index=function(self, i)
|
||||||
|
if (cachemf[i]) then
|
||||||
|
local h = io.open(string.format("/etc/xpm/cache/%s/%x.dat", name, cachemf[i]), "r")
|
||||||
|
local t = blt.deserialize(lzss.decompress(h:read("*a")))
|
||||||
|
h:close()
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
rawset(self, k, v)
|
||||||
|
end
|
||||||
|
return rawget(self, i)
|
||||||
|
end
|
||||||
|
end})
|
||||||
|
rawset(mt, -1, cachemf)
|
||||||
|
return mt
|
||||||
|
end
|
||||||
|
local function save_cache(name, packages)
|
||||||
|
fs.makeDirectory("/etc/xpm/cache/"..name)
|
||||||
|
local manifest = io.open("/etc/xpm/cache/"..name.."/manifest.dat", "w")
|
||||||
|
local mf = {}
|
||||||
|
local current_cache = {}
|
||||||
|
local count = 0
|
||||||
|
local idx = 0
|
||||||
|
for k, v in pairs(packages) do
|
||||||
|
mf[k] = count
|
||||||
|
current_cache[k] = v
|
||||||
|
idx = idx+1
|
||||||
|
if (idx > config.cache.clustersize) then
|
||||||
|
idx = 0
|
||||||
|
print(string.format("/etc/xpm/cache/%s/%x.dat", name, count))
|
||||||
|
local cf = io.open(string.format("/etc/xpm/cache/%s/%x.dat", name, count), "w")
|
||||||
|
cf:write(lzss.compress(blt.serialize(current_cache)))
|
||||||
|
cf:close()
|
||||||
|
current_cache = {}
|
||||||
|
count = count + 1
|
||||||
|
for i=1, 11 do
|
||||||
|
os.sleep(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local cf = io.open(string.format("/etc/xpm/cache/%s/%x.dat", name, count), "w")
|
||||||
|
cf:write(lzss.compress(blt.serialize(current_cache)))
|
||||||
|
cf:close()
|
||||||
|
current_cache = {}
|
||||||
|
count = count + 1
|
||||||
|
for i=1, 10 do
|
||||||
|
os.sleep(0)
|
||||||
|
end
|
||||||
|
manifest:write(lzss.compress(blt.serialize(mf)))
|
||||||
|
manifest:close()
|
||||||
|
end
|
||||||
|
local pcache = {}
|
||||||
|
local lcache = {}
|
||||||
|
if (fs.exists("/etc/xpm/cache/local")) then
|
||||||
|
lcache = load_cache("local")
|
||||||
|
end
|
||||||
|
|
||||||
|
if (fs.exists("/etc/xpm/cache/remote")) then
|
||||||
|
pcache = load_cache("remote")
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.check_cache(pkg)
|
||||||
|
return pcache[pkg]
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.update_cache()
|
||||||
|
print("Updating cache...")
|
||||||
|
pcache = {}
|
||||||
|
fs.makeDirectory("/etc/xpm/cache/remote")
|
||||||
|
local manifest = io.open("/etc/xpm/cache/remote/manifest.dat", "w")
|
||||||
|
local mf = {}
|
||||||
|
local current_cache = {}
|
||||||
|
local count = 0
|
||||||
|
local idx = 0
|
||||||
|
for i=#config.repos, 1, -1 do
|
||||||
|
print("Hit "..(#config.repos-i)..": "..config.repos[i])
|
||||||
|
local repo = serialization.unserialize(github_download(config.repos[i], "master/programs.cfg"))
|
||||||
|
if repo then
|
||||||
|
for k, v in pairs(repo) do
|
||||||
|
local e = {repo = config.repos[i], pkginfo=v}
|
||||||
|
mf[k] = count
|
||||||
|
current_cache[k] = e
|
||||||
|
idx = idx+1
|
||||||
|
if (idx > config.cache.clustersize) then
|
||||||
|
idx = 0
|
||||||
|
print(string.format("/etc/xpm/cache/%s/%x.dat", "remote", count))
|
||||||
|
local cf = io.open(string.format("/etc/xpm/cache/%s/%x.dat", "remote", count), "w")
|
||||||
|
cf:write(lzss.compress(blt.serialize(current_cache)))
|
||||||
|
cf:close()
|
||||||
|
current_cache = {}
|
||||||
|
count = count + 1
|
||||||
|
for i=1, 11 do
|
||||||
|
os.sleep(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Error "..(#config.repos-i)..": Not found.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local cf = io.open(string.format("/etc/xpm/cache/%s/%x.dat", "remote", count), "w")
|
||||||
|
cf:write(lzss.compress(blt.serialize(current_cache)))
|
||||||
|
cf:close()
|
||||||
|
current_cache = {}
|
||||||
|
count = count + 1
|
||||||
|
for i=1, 10 do
|
||||||
|
os.sleep(0)
|
||||||
|
end
|
||||||
|
manifest:write(lzss.compress(blt.serialize(mf)))
|
||||||
|
manifest:close()
|
||||||
|
print("Saved cache.")
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.get_upgradable()
|
||||||
|
if not fs.exists("/etc/xpm/cache/local") then
|
||||||
|
--cache.update_cache()
|
||||||
|
--local h = io.open("/etc/xpm/cache/local.dat", "w")
|
||||||
|
--h:write(lzss.compress(blt.serialize({xpm = pcache.xpm})))
|
||||||
|
save_cache("local", {xpm = pcache.xpm})
|
||||||
|
lcache = {xpm = pcache.xpm}
|
||||||
|
--h:close()
|
||||||
|
end
|
||||||
|
local upgradable = {}
|
||||||
|
for k, v in pairs(lcache) do
|
||||||
|
if k ~= -1 then
|
||||||
|
local lpkg, rpkg = v.pkginfo, pcache[k].pkginfo
|
||||||
|
if lpkg.xpm and rpkg.xpm and lpkg.xpm.version ~= rpkg.xpm.version then
|
||||||
|
upgradable[#upgradable+1] = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return upgradable
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.fullload(cdat, name)
|
||||||
|
for k, v in pairs(cdat[-1]) do
|
||||||
|
if (not cdat[k]) then
|
||||||
|
local h = io.open(string.format("/etc/xpm/cache/%s/%x.dat", name, v), "r")
|
||||||
|
local t = blt.deserialize(lzss.decompress(h:read("*a")))
|
||||||
|
h:close()
|
||||||
|
for l, b in pairs(t) do
|
||||||
|
rawset(cdat, l, b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.update_local_cache(pkg, info)
|
||||||
|
lcache[pkg] = info
|
||||||
|
--local h = io.open("/etc/xpm/cache/local.dat", "w")
|
||||||
|
--h:write(lzss.compress(blt.serialize(lcache)))
|
||||||
|
--h:close()
|
||||||
|
local mf = lcache[-1]
|
||||||
|
if not mf.loaded then
|
||||||
|
cache.fullload(lcache, "local")
|
||||||
|
mf.loaded = true
|
||||||
|
end
|
||||||
|
lcache[-1] = nil
|
||||||
|
save_cache("local", lcache)
|
||||||
|
lcache[-1] = mf
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.getlocal()
|
||||||
|
return lcache
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache.getremote()
|
||||||
|
return pcache
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user