-- install Monolith -- local CPIO = "https://raw.githubusercontent.com/ocawesome101/oc-monolith/master/release.cpio" local ARCPATH = "/mnt/monolith.cpio" local MOUNT = "/mnt/install/" -- pretty requires local serialization = require("serialization") local component = require("component") local computer = require("computer") local internet = require("internet") local fs = require("filesystem") if fs.get("/").isReadOnly() then print("Your root filesystem must be writable - exiting") os.exit(1) end -- get sha3 if we don't have it if not pcall(require, "sha3") then print("SHA-3 library not found - downloading") assert(loadfile("/bin/wget.lua"))("https://github.com/ocawesome101/oc-monolith/raw/master/util/lib/sha3.lua", "/lib/sha3.lua") end local sha3 = require("sha3") local ask = {} local fsl = component.list("filesystem") local blacklist = {[computer.getBootAddress()] = true, [computer.tmpAddress()] = true} for fsa, _ in fsl do if not blacklist[fsa] then ask[#ask + 1] = fsa end end -- uncpio credit to AdorableCatgirl, slightly modified local function uncpio(file, dest) checkArg(1, file, "string") checkArg(2, dest, "string") local dir = dest local file = io.open(file, "rb") local filesystem = fs local dent = { magic = 0, dev = 0, ino = 0, mode = 0, uid = 0, gid = 0, nlink = 0, rdev = 0, mtime = 0, namesize = 0, filesize = 0, } local function readint(amt, rev) local tmp = 0 for i=(rev and amt) or 1, (rev and 1) or amt, (rev and -1) or 1 do tmp = tmp | (file:read(1):byte() << ((i-1)*8)) end return tmp end local function fwrite() local _dir = dent.name:match("(.+)/.*%.?.+") if (_dir) then filesystem.makeDirectory(dir.."/".._dir) -- dir = dir .. "/" .. _dir end local hand = assert(io.open(dir.."/"..dent.name, "w")) hand:write(file:read(dent.filesize)) hand:close() end while true do dent.magic = readint(2) local rev = false if (dent.magic ~= tonumber("070707", 8)) then rev = true end dent.dev = readint(2) dent.ino = readint(2) dent.mode = readint(2) dent.uid = readint(2) dent.gid = readint(2) dent.nlink = readint(2) dent.rdev = readint(2) dent.mtime = (readint(2) << 16) | readint(2) dent.namesize = readint(2) dent.filesize = (readint(2) << 16) | readint(2) local name = file:read(dent.namesize):sub(1, dent.namesize-1) if (name == "TRAILER!!!") then break end dent.name = name print(name) if (dent.namesize % 2 ~= 0) then file:seek("cur", 1) end if (dent.mode & 32768 ~= 0) then fwrite() end if (dent.filesize % 2 ~= 0) then file:seek("cur", 1) end end end local function menu(opts) print("\27[2J\27[1;1HPlease choose one:") for k, v in ipairs(opts) do print(string.format(" %d. %s", k, v)) end local n repeat print("Enter a number.") io.write("> ") n = io.read():gsub("\n", "") until tonumber(n) return opts[tonumber(n)] end local function prompt(msg) local inp = "" repeat io.write(msg) inp = (io.read() or ""):gsub("\n", "") until inp ~= "" return inp end local function download(url, file) local handle, err = internet.request(url) if not handle then error(err) end local out = io.open(file, "w") if not out then error(err) end for chunk in handle do out:write(chunk) end out:close() end ask[#ask + 1] = "Quit" local ifs = menu(ask) if ifs == "Quit" then return 0 end fs.mount(ifs, MOUNT) print("Mounted install fs at " .. MOUNT) print("Downloading " .. CPIO .. " as " .. ARCPATH) download(CPIO, ARCPATH) print("Extracting CPIO to " .. MOUNT) uncpio(ARCPATH, MOUNT) print("Cleaning up installation files...") fs.remove(ARCPATH) print("Now that the system has been installed, you should set up a user.") local rootpass = prompt("root password: \27[30;40m") io.write("\27[0m") local name = prompt("username: ") local password = prompt("password: \27[30;40m") local passwd = fs.concat(MOUNT, "/etc/passwd") local function tohex(str) local r = "" for char in str:gmatch(".") do r = r .. string.format("%02x", char:byte()) end return r end -- remove special chars from a string local function strip(str) local special = "[^%w%-_]" return str:gsub(special, "_") end local tpasswd = { [0] = { u = 0, c = true, n = "root", h = "/root", p = tohex(sha3.sha256(rootpass)) }, [1] = { u = 1, c = true, n = name, h = "/home/" .. strip(name), p = tohex(sha3.sha256(password)) } } print("\27[0mAdding user to /etc/passwd") local handle, err = io.open(passwd, "w") if not handle then error("failed opening etc/passwd: " .. err) end handle:write(serialization.serialize(tpasswd)) handle:close() print("Creating user home directories") fs.makeDirectory(fs.concat(MOUNT, "/root")) fs.makeDirectory(fs.concat(MOUNT, "/home")) fs.makeDirectory(fs.concat(MOUNT, tpasswd[1].h)) print("Done.")