diff --git a/.gitignore b/.gitignore index 57506f8..e3bd5eb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ pkg/** debug.lua luapreproc.lua zorya-neo-installer.lua +zorya-neo-utils-installer.lua bsrc/** \ No newline at end of file diff --git a/release.lua b/release.lua index 1b00c8b..8ace8bc 100644 --- a/release.lua +++ b/release.lua @@ -37,5 +37,7 @@ os.execute("cp utils/ser.lua pkg/init.lua") os.execute("cp -r installer_dat pkg") status("Packing installer...") os.execute("cd pkg; find * -depth | lua ../utils/make_tsar.lua | lua ../utils/mkselfextract.lua > ../zorya-neo-installer.lua") +status("Making OpenOS util installer...") +os.execute("cd util; find * -depth | lua ../utils/make_tsar.lua | lua ../utils/mkselfextract.lua > ../zorya-neo-utils-installer.lua") status("Build complete.") status(string.format("Took %ds.", os.time()-start)) \ No newline at end of file diff --git a/src/zy-neo/builtins/init_managed/init.lua b/src/zy-neo/builtins/init_managed/init.lua index 13e8987..2fef1fd 100644 --- a/src/zy-neo/builtins/init_managed/init.lua +++ b/src/zy-neo/builtins/init_managed/init.lua @@ -1,3 +1,4 @@ +_ZLOADER = "managed" local readfile=function(f,h) local b="" local d,r=f.read(h,math.huge) @@ -23,7 +24,7 @@ assert(bootfs.exists(".zy2/image.tsar"), "No boot image!") local romfs_file = assert(bootfs.open(".zy2/image.tsar", "rb")) -local romfs_dev = romfs.read(function(a) +local romfs_dev = tsar.read(function(a) local c = "" local d while a > 0 do diff --git a/src/zy-neo/builtins/util_tsar.lua b/src/zy-neo/builtins/util_tsar.lua index cfe4cff..b0ad1db 100644 --- a/src/zy-neo/builtins/util_tsar.lua +++ b/src/zy-neo/builtins/util_tsar.lua @@ -63,11 +63,12 @@ local tsar = { e.name = read(e.namesize) e.pos = seek(e.namesize & 1) seek(e.filesize + (e.filesize & 1)) + utils.debug_log(e.name, e.namesize, e.filesize, e.pos) lname = e.name if lname ~= "TRAILER!!!" then tbl[#tbl+1] = e end end - return setmetatable({tbl = tbl, read = read, seek = seek, close = close}, {__index=tsar}) + return setmetatable({tbl = tbl, read = read, seek = seek, close = close}, {__index=arc}) end } \ No newline at end of file diff --git a/util/OpenOS/config.d/00_includes.lua b/util/OpenOS/config.d/00_includes.lua new file mode 100644 index 0000000..0adea52 --- /dev/null +++ b/util/OpenOS/config.d/00_includes.lua @@ -0,0 +1,15 @@ +local cfgadd = ... +local addr = require("component").eeprom.getData() +print("Zorya NEO is installed at "..addr) +cfgadd([[ +local menu = loadmod("menu_classic") +]]) +if (_ZLOADER == "managed") then + cfgadd(string.format([[ +do + local sp = loadmod("util_searchpaths") + sp.add_mod_path("%s", ".zy2/mods") + sp.add_lib_path("%s", ".zy2/lib") +end +]], addr, addr)) +end \ No newline at end of file diff --git a/util/OpenOS/config.d/01_openos.lua b/util/OpenOS/config.d/01_openos.lua new file mode 100644 index 0000000..4bd0d73 --- /dev/null +++ b/util/OpenOS/config.d/01_openos.lua @@ -0,0 +1,12 @@ +local cfgadd = ... +local comp = require("component") +for fs in comp.list("filesystem") do + if comp.invoke(fs, "getLabel") == "OpenOS" and comp.invoke(fs, "exists", "init.lua") then + print("OpenOS discovered on "..fs) + cfgadd(string.format([[ +menu.add("OpenOS on %s", function() + return loadmod("loader_openos")("%s") +end) +]], fs:sub(1, 3), fs)) + end +end \ No newline at end of file diff --git a/util/OpenOS/config.d/96_vbios.lua b/util/OpenOS/config.d/96_vbios.lua new file mode 100644 index 0000000..d15562b --- /dev/null +++ b/util/OpenOS/config.d/96_vbios.lua @@ -0,0 +1,24 @@ +local cfgadd = ... +local addr = require("component").eeprom.getData() +local fs = require("filesystem") +if not fs.exists("/.zy2/vbios/") then + return +end +cfgadd([[ +do + local function add_bios(drive, path) + local h = component.invoke(drive, "open", path.."/label.txt") + local name = component.invoke(drive, "read", h, math.huge) + component.invoke(drive, "close", h) + menu.add(name .. " (vBIOS)", function() + local vb = loadmod("vdev_vbios")(drive, path) + vb() + end) + end +]]) +for ent in fs.list("/.zy2/vbios") do + cfgadd(string.format([[ add_bios("%s", ".zy2/vbios/%s")]].."\n", addr, ent:sub(1, #ent-1))) +end +cfgadd[[ +end +]] \ No newline at end of file diff --git a/util/OpenOS/config.d/97_addent.lua b/util/OpenOS/config.d/97_addent.lua new file mode 100644 index 0000000..1300d17 --- /dev/null +++ b/util/OpenOS/config.d/97_addent.lua @@ -0,0 +1,19 @@ +local cfgadd = ... +local fs = require("filesystem") +if not fs.exists("/etc/zorya-neo/entries/") then + return +end +local function readfile(path) + local f = io.open(path) + local dat = f:read("*a") + f:close() + return dat +end +for ent in fs.list("/etc/zorya-neo/entries/") do + local label = readfile("/etc/zorya-neo/entries/"..ent.."/label.txt") + local code = readfile("/etc/zorya-neo/entries/"..ent.."/code.lua") + cfgadd(string.format([[ +menu.add("%s", function()) +%s +end)]], label, code)) +end \ No newline at end of file diff --git a/util/OpenOS/config.d/98_custom.lua b/util/OpenOS/config.d/98_custom.lua new file mode 100644 index 0000000..a260d94 --- /dev/null +++ b/util/OpenOS/config.d/98_custom.lua @@ -0,0 +1,8 @@ +local cfgadd = ... +local fs = require("filesystem") +if not fs.exists("/etc/zorya-neo/custom.lua") then + return +end +local f = io.open("/etc/zorya-neo/custom.lua") +cfgadd(f:read("*a")) +f:close() \ No newline at end of file diff --git a/util/OpenOS/config.d/99_menu.lua b/util/OpenOS/config.d/99_menu.lua new file mode 100644 index 0000000..e89b4d8 --- /dev/null +++ b/util/OpenOS/config.d/99_menu.lua @@ -0,0 +1,4 @@ +local cfgadd = ... +cfgadd([[ +menu.draw() +]]) \ No newline at end of file diff --git a/util/OpenOS/initramfs.d/00_zymod.lua b/util/OpenOS/initramfs.d/00_zymod.lua new file mode 100644 index 0000000..1907ddb --- /dev/null +++ b/util/OpenOS/initramfs.d/00_zymod.lua @@ -0,0 +1,13 @@ +local arc = ... +arc.dir(".zy2") +arc.dir(".zy2/mods") +local fs = require("filesystem") +local function readfile(path) + local f = io.open(path) + local dat = f:read("*a") + f:close() + return dat +end +for ent in fs.list("/etc/zorya-neo/mods") do + arc.file(".zy2/mods/"..ent, "r-xr-xr-x", readfile("/etc/zorya-neo/mods/"..ent)) +end \ No newline at end of file diff --git a/util/OpenOS/initramfs.d/01_zylib.lua b/util/OpenOS/initramfs.d/01_zylib.lua new file mode 100644 index 0000000..41df438 --- /dev/null +++ b/util/OpenOS/initramfs.d/01_zylib.lua @@ -0,0 +1,12 @@ +local arc = ... +arc.dir(".zy2/lib") +local fs = require("filesystem") +local function readfile(path) + local f = io.open(path) + local dat = f:read("*a") + f:close() + return dat +end +for ent in fs.list("/etc/zorya-neo/lib") do + arc.file(".zy2/lib/"..ent, "r-xr-xr-x", readfile("/etc/zorya-neo/lib/"..ent)) +end diff --git a/util/OpenOS/zyneo-gencfg.lua b/util/OpenOS/zyneo-gencfg.lua new file mode 100644 index 0000000..a7963d4 --- /dev/null +++ b/util/OpenOS/zyneo-gencfg.lua @@ -0,0 +1,19 @@ +local fs = require("filesystem") +print("Regenerating Zorya NEO configuration...") +fs.copy("/.zy2/cfg.lua", "/.zy2/cfg.lua.old") +local f = io.open("/.zy2/cfg.lua", "wb") +local lst = {} +for ent in fs.list("/etc/zorya-neo/config.d") do + if ent:sub(#ent) ~= "/" then + lst[#lst+1] = ent + end +end +table.sort(lst) +for i=1, #lst do + print("> "..lst[i]) + assert(loadfile("/etc/zorya-neo/config.d/"..lst[i]))(function(code) + f:write(code) + end) +end +f:close() +print("Generated new configuration.") \ No newline at end of file diff --git a/util/OpenOS/zyneo-geninitramfs.lua b/util/OpenOS/zyneo-geninitramfs.lua new file mode 100644 index 0000000..816042b --- /dev/null +++ b/util/OpenOS/zyneo-geninitramfs.lua @@ -0,0 +1,89 @@ +local fs = require("filesystem") +print("Regenerating Zorya NEO initramfs...") +fs.copy("/.zy2/boot.tsar", "/.zy2/boot.tsar.old") +local f = io.open("/.zy2/boot.tsar", "wb") +local lst = {} +for ent in fs.list("/etc/zorya-neo/initramfs.d") do + if ent:sub(#ent) ~= "/" then + lst[#lst+1] = ent + end +end +table.sort(lst) +local modes = { + ["fifo"] = 1, + ["char device"] = 2, + ["directory"] = 4, + ["block device"] = 6, + ["file"] = 8, + ["link"] = 0xA, + ["socket"] = 0xC +} +local function getperm(perm, mode) + local md = 0 + for i=1, 9 do + if (perm:sub(10-i,10-i) ~= "-") then + md = md | (1 << (i-1)) + end + end + return md | (modes[mode] << 12) +end +local function create_node(attr) + local ent = { + magic = 0x5f7d, + namesize = #attr.name, + name = attr.name, + mode = getperm(attr.permissions, attr.mode), + uid = attr.uid, + gid = attr.gid, + filesize = attr.filesize, + mtime = attr.mtime + } + if attr.mode ~= "file" then + ent.filesize = 0 + end + f:write(string.pack("=I2I2I2I2I2I6I6", ent.magic, ent.namesize, ent.mode, ent.uid, ent.gid, ent.filesize, ent.mtime)) + f:write(attr.data or "") +end +local arc = {} +function arc.file(path, perm, data) + create_node({ + data = data, + filesize = #data, + uid = 0, + gid = 0, + mtime = os.time(), + name = path, + permissions = perm or "rw-r--r--", + mode = "file" + }) +end + +function arc.dir(path, perm) + create_node({ + uid = 0, + filesize = 0, + gid = 0, + mtime = os.time(), + name = path, + permissions = perm or "rwxr-xr-x", + mode = "directory" + }) +end + +for i=1, #lst do + print("> "..lst[i]) + loadfile("/etc/zorya-neo/initramfs.d/"..lst[i])(arc) +end +local zy_dat = [[{os="Zorya NEO", version={2,0,0}, generator="OpenOS"}]] +create_node({ + data = zy_dat, + filesize = #zy_dat, + uid = 0, + gid = 0, + mtime = os.time(), + name = "TRAILER!!!", + permissions = "---------", + mode = "file" +}) +f:close() +print("Generated new initramfs.") \ No newline at end of file diff --git a/util/init.lua b/util/init.lua new file mode 100644 index 0000000..a5f0a42 --- /dev/null +++ b/util/init.lua @@ -0,0 +1,138 @@ +local args = {...} +local tbl = args[1] +local dat = args[2] +table.remove(args, 1) +table.remove(args, 1) + +local function getfile(path) + for i=1, #tbl do + if (tbl[i].name == path) then + return dat:sub(tbl[i].pos, tbl[i].pos+tbl[i].filesize-1) + end + end +end + +local function writefile(p2, dat) + local f = io.open(p2, "wb") + f:write(dat) + f:close() +end + +if (debug.debug) then + print("This software cannot be run on a normal computer. This is only for OpenOS.") + os.exit(1) +end + +local magic = 0x5f7d +local magic_rev = 0x7d5f +local header_fmt = "I2I2I2I2I2I6I6" +local en = string.unpack("=I2", string.char(0x7d, 0x5f)) == magic -- true = LE, false = BE +local function get_end(e) + return (e and "<") or ">" +end +local function read_header(dat) + local e = get_end(en) + local m = string.unpack(e.."I2", dat) + if m ~= magic and m ~= magic_rev then return nil, "bad magic" end + if m ~= magic then + e = get_end(not en) + end + local ent = {} + ent.magic, ent.namesize, ent.mode, ent.uid, ent.gid, ent.filesize, ent.mtime = string.unpack(e..header_fmt, dat) + return ent +end + +local arc = {} + +function arc:fetch(path) + for i=1, #self.tbl do + if (self.tbl[i].name == path and self.tbl[i].mode & 32768 > 0) then + self.seek(self.tbl[i].pos-self.seek(0)) + return self.read(self.tbl[i].filesize), self.tbl[i] + end + end + return nil, "file not found" +end + +function arc:exists(path) + for i=1, #self.tbl do + if (self.tbl[i].name == path) then + return true + end + end + return false +end + +function arc:list(path) + if path:sub(#path) ~= "/" then path = path .. "/" end + local ent = {} + for i=1, #self.tbl do + if (self.tbl[i].name:sub(1, #path) == path and not self.tbl[i].name:find("/", #path+1, false)) then + ent[#ent+1] = self.tbl[i].name + end + end + return ent +end + +function arc:close() + self.close() +end + +local tsar = { + read = function(read, seek, close) + local tbl = {} + local lname = "" + while lname ~= "TRAILER!!!" do + local dat = read(22) + local e = read_header(dat) + e.name = read(e.namesize) + e.pos = seek(e.namesize & 1) + seek(e.filesize + (e.filesize & 1)) + lname = e.name + if lname ~= "TRAILER!!!" then + tbl[#tbl+1] = e + end + end + return setmetatable({tbl = tbl, read = read, seek = seek, close = close}, {__index=arc}) + end +} + +local fs = require("filesystem") +print("Installing Zorya NEO utils.") +fs.makeDirectory("/etc/zorya-neo") +fs.makeDirectory("/etc/zorya-neo/mods") +fs.makeDirectory("/etc/zorya-neo/lib") +fs.makeDirectory("/etc/zorya-neo/config.d") +fs.makeDirectory("/etc/zorya-neo/initramfs.d") +print("Installing utils to /usr") +writefile("/usr/bin/zyneo-gencfg.lua", getfile("OpenOS/zyneo-gencfg.lua")) +writefile("/usr/bin/zyneo-geninitramfs.lua", getfile("OpenOS/zyneo-geninitramfs.lua")) +print("Installing scripts...") +for i=1, #tbl do + if tbl[i].name:sub(1, 16) == "OpenOS/config.d/" then + writefile("/etc/zorya-neo/config.d/"..tbl[i].name:sub(17), getfile(tbl[i].name)) + elseif tbl[i].name:sub(1, 19) == "OpenOS/initramfs.d/" then + writefile("/etc/zorya-neo/initramfs.d/"..tbl[i].name:sub(20), getfile(tbl[i].name)) + end +end +print("Extracting image.tsar...") +local t = io.open("/.zy2/image.tsar", "rb") +local arc = tsar.read(function(a) + return t:read(a) +end, function(a) + return t:seek("cur", a) +end, function() + return t:close() +end) +local lst = arc:list(".zy2/mods") +for i=1, #lst do + print(lst[i]) + writefile("/etc/zorya-neo/mods/"..lst[i]:sub(10), arc:fetch(lst[i])) +end +local lst = arc:list(".zy2/lib") +for i=1, #lst do + print(lst[i]) + writefile("/etc/zorya-neo/lib/"..lst[i]:sub(9), arc:fetch(lst[i])) +end +arc:close() +print("Installation complete.") \ No newline at end of file diff --git a/utils/make_tsar.lua b/utils/make_tsar.lua index e517d8a..0d24173 100644 --- a/utils/make_tsar.lua +++ b/utils/make_tsar.lua @@ -17,7 +17,7 @@ local modes = { local function getperm() local md = 0 for i=1, 9 do - if (attr.permissions:sub(i,i) ~= "-") then + if (attr.permissions:sub(10-i,10-i) ~= "-") then md = md | (1 << (i-1)) end end diff --git a/utils/selfextract.lua b/utils/selfextract.lua index 26a5bce..29d76e8 100644 --- a/utils/selfextract.lua +++ b/utils/selfextract.lua @@ -139,6 +139,7 @@ local unpack = unpack or table.unpack for i=1, #tbl do if (tbl[i].name == "init.lua") then load(dat:sub(tbl[i].pos, tbl[i].pos+tbl[i].filesize-1))(tbl, dat, unpack(arg)) + if os.exit then os.exit(0) else return end end end diff --git a/utils/ser.lua b/utils/ser.lua index e7ea93b..bd28abf 100644 --- a/utils/ser.lua +++ b/utils/ser.lua @@ -146,6 +146,9 @@ function makeDirectory(path) } fs.write(romfs, string.pack("=I2I2I2I2I2I6I6", ent.magic, ent.namesize, ent.mode, ent.uid, ent.gid, ent.filesize, ent.mtime)) fs.write(romfs, path) + if ent.namesize & 1 > 0 then + fs.write(romfs, "\0") + end end makeDirectory(".zy2") @@ -165,6 +168,8 @@ function writeFile(path, data) -- fs.write(romfs, "-") --end --fs.write(romfs, data) + + local ext = path:sub(#path-2) local ent = { name = path, namesize = #path, @@ -178,12 +183,11 @@ function writeFile(path, data) fs.write(romfs, string.pack("=I2I2I2I2I2I6I6", ent.magic, ent.namesize, ent.mode, ent.uid, ent.gid, ent.filesize, ent.mtime)) fs.write(romfs, path) if ent.namesize & 1 > 0 then - io.stdout:write("\0") + fs.write(romfs, "\0") end fs.write(romfs, data) if ent.filesize & 1 > 0 then - io.stdout:write("\0") - size = size+1 + fs.write(romfs, "\0") end end