xwos
Description
HiI created a new operating system upon CCraft 1.8 (1.12.2)Why "yet another operating system"? A good question. While trying to use other OS I had many problems and trying to solve them I decided to c...
Installation
Copy one of these commands into your ComputerCraft terminal:
Pastebin:
pastebin get BLSJGiyt xwoswget:
wget https://pastebin.com/raw/BLSJGiyt xwosArchive:
wget https://cc.shobie.xyz/cc/get/pb-BLSJGiyt xwos
Quick Install:
wget https://cc.shobie.xyz/cc/get/pb-BLSJGiyt xwos
Usage
Run the program after downloading
Tags
Source
View Original SourceCode Preview
local fullname = "XWOS Installer"
local data = {
[ "/kernel/common/xwos/modules/sandbox/timers.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"-----------------------",
"-- @module xwos.modules.sandbox.timers",
"local M = {}",
"",
"local kernel -- xwos.kernel#xwos.kernel",
"",
"-----------------------",
"-- injects the kernel",
"-- @function [parent=#xwos.modules.sandbox.timers] setKernel",
"-- @param xwos.kernel#xwos.kernel k the kernel",
"M.setKernel = function(k)",
" kernel = k",
"end -- function setKernel",
"",
"-------------------------------",
"-- creates a new timer",
"-- @function [parent=#xwos.modules.sandbox.timers] new",
"-- @param #number id the timer number",
"-- @param xwos.processes#xwos.process proc",
"-- @return #xwos.timer",
"M.new = function(id, proc)",
" --------------------------------",
" -- timer type",
" -- @type xwos.timer",
" local R = {}",
" ",
" --------------------------------",
" -- @field [parent=#xwos.timer] #number id the timer id",
" R.id = id",
" ",
" --------------------------------",
" -- @field [parent=#xwos.timer] #number id the timer id",
" R.proc = proc",
" ",
" --------------------------------",
" -- Remove the timer from timer table",
" -- @function [parent=#xwos.timer] remove",
" R.remove = function()",
" M[R.id] = nil",
" end -- function remove",
" ",
" -- TODO remove discarded timers on process termination",
" ",
" -- store timer",
" M[R.id] = R",
" ",
" return R",
"end -- function new",
"",
"return M",
},
[ "/kernel/common/xwos/modules/security/init.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"-----------------------",
"-- @module xwos.modules.security",
"local M = {}",
"",
"local kernel -- xwos.kernel#xwos.kernel",
"",
"local function crProfile(name)",
" -----------------------",
" -- Security profile",
" -- @type secprofile",
" local R = {}",
" ",
" -----------------------",
" -- Returns the profile name",
" -- @function [parent=#secprofile] name",
" -- @return #string profile name",
" R.name = function()",
" return name",
" end -- function name",
" ",
" -----------------------",
" -- Checks if access to given api method is granted",
" -- @function [parent=#secprofile] checkApi",
" -- @return #string api",
" -- @return #string method",
" R.checkApi = function(api, method)",
" return true -- TODO some meaningful implementation",
" end -- function checkApi",
" ",
" -----------------------",
" -- Checks if access to given acl node is granted",
" -- @function [parent=#secprofile] checkAccess",
" -- @return #string aclKey",
" R.checkAccess = function(aclKey)",
" return true -- TODO some meaningful implementation",
" end -- function checkAccess",
" return R",
"end -- function crProfile",
"",
"local profiles = {",
" root = crProfile(\"root\"),",
" admin = crProfile(\"admin\"),",
" user = crProfile(\"user\"),",
" guest = crProfile(\"guest\")",
"}",
"",
"---------------------------------",
"-- @function [parent=#xwos.modules.security] preboot",
"-- @param xwos.kernel#xwos.kernel k",
"M.preboot = function(k)",
" k.debug(\"preboot security\")",
" kernel = k",
"end -- function preboot",
"",
"---------------------------------",
"-- @function [parent=#xwos.modules.security] boot",
"-- @param xwos.kernel#xwos.kernel k",
"M.boot = function(k)",
" k.debug(\"boot security\")",
"end -- function boot",
"",
"---------------------------------",
"-- returns a security profile with given name",
"-- @function [parent=#xwos.modules.security] profile",
"-- @param #string name",
"-- @return #secprofile",
"M.profile = function(name)",
" return profiles[name]",
"end -- function boot",
"",
"---------------------------------",
"-- Creates a new security profile with given name",
"-- @function [parent=#xwos.modules.security] profile",
"-- @param #string name",
"-- @return #secprofile",
"M.createProfile = function(name)",
" -- TODO some meaningful implementation",
" local res = profiles[name]",
" if res == nil then",
" res = crProfile(name)",
" profiles[name] = res",
" end -- if profile",
" return res",
"end -- function createProfile",
"",
"return M",
},
[ "/kernel/common/xwos/modules/sandbox/evqueue.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"-----------------------",
"-- @module xwos.modules.sandbox.evqueue",
"local M = {}",
"",
"local kernel -- xwos.kernel#xwos.kernel",
"",
"local originsert = table.insert",
"",
"-----------------------",
"-- injects the kernel",
"-- @function [parent=#xwos.modules.sandbox.evqueue] setKernel",
"-- @param xwos.kernel#xwos.kernel k the kernel",
"M.setKernel = function(k)",
" kernel = k",
"end -- function setKernel",
"",
"-----------------------",
"-- Process and distribute event from event queue (part of pullEvent etc.)",
"-- @function [parent=#xwos.modules.sandbox.evqueue] processEvt",
"-- @param #number lpid the local pid for logging",
"-- @param xwos.process#xwos.process proc the process invoking this method; may be nil for kernel process",
"-- @param #table event the event to deliver",
"-- @param #string filter optional filter passed to pullEvent",
"M.processEvt = function(lpid, proc, event, filter)",
" if event[1] == nil then",
" return nil",
" end -- if event",
" kernel.debug(\"[PID\"..lpid..\"] got event \", kernel.oldGlob.unpack(event))",
" ",
" if kernel.eventLog then",
" -- TODO are we able to pass non serializable data through events?",
" -- this may cause problems at this point",
" local str = kernel.oldGlob.os.day() .. \"-\" .. kernel.oldGlob.os.time() \" EVENT: \".. kernel.oldGlob.textutils.serialize(event)",
" local f = kernel.oldGlob.fs.open(\"/core/log/event-log.txt\", kernel.oldGlob.fs.exists(\"/core/log/event-log.txt\") and \"a\" or \"w\")",
" f.writeLine(str)",
" f.close()",
" end -- if eventLog",
" ",
" local consumed = false",
" ",
" if event[1] == \"timer\" then",
" local timer = kernel.modules.instances.sandbox.timers[event[2]]",
" if timer ~= nil then",
" if timer.proc == proc then",
" if filter == nil or event[1]==filter then",
" kernel.debug(\"[PID\"..lpid..\"] returning event \", kernel.oldGlob.unpack(event))",
" return event",
" else -- if filter",
" kernel.debug(\"[PID\"..lpid..\"] discard event because of filter\", kernel.oldGlob.unpack(event))",
" consumed = true",
" end -- if filter",
" else -- if proc",
" kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to pid \"..timer.proc.pid, kernel.oldGlob.unpack(event))",
" originsert(timer.proc.evqueue, event)",
" timer.proc.wakeup()",
" consumed = true",
" end -- if not proc",
" end -- if timer",
" -- fallthrough: distribute unknown timer event to all processes",
" end -- if timer",
" ",
" if event[1] == \"xwos_wakeup\" then",
" consumed = true",
" kernel.debug(\"[PID\"..lpid..\"] wakeup received\")",
" if event[2] ~= lpid then",
" kernel.debug(\"[PID\"..lpid..\"] wrong pid, redistribute\")",
" kernel.oldGlob.os.queueEvent(kernel.oldGlob.unpack(event))",
" end -- if pid",
" end -- if xwos_wakeup",
" ",
" if event[1] == \"xwos_terminate\" then",
" consumed = true",
" kernel.debug(\"[PID\"..lpid..\"] terminate received\")",
" if event[2] ~= lpid then",
" kernel.debug(\"[PID\"..lpid..\"] wrong pid, redistribute\")",
" kernel.oldGlob.os.queueEvent(kernel.oldGlob.unpack(event))",
" else -- if pid",
" kernel.oldGlob.error('requesting process termination')",
" end -- if pid",
" end -- if xwos_terminate",
" ",
" if event[1] == \"xwos_terminated\" then",
" consumed = true",
" kernel.debug(\"[PID\"..lpid..\"] terminated received\")",
" if filter == \"xwos_terminated\" then",
" kernel.debug(\"[PID\"..lpid..\"] returning event \", kernel.oldGlob.unpack(event))",
" return event",
" end -- if filter",
" for k, v in kernel.oldGlob.pairs(kernel.processes) do",
" if kernel.oldGlob.type(v) == \"table\" and v.pid == event[2] and v.joined > 0 then",
" kernel.debug(\"[PID\"..lpid..\"] redistributing to all other processes because at least one process called join of \"..v.pid)",
" ",
" for k2, v2 in kernel.oldGlob.pairs(kernel.processes) do",
" if kernel.oldGlob.type(v2) == \"table\" and v2 ~= proc and v2.procstate~= \"finished\" then",
" kernel.debug(\"[PID\"..lpid..\"] redistributing because at least one process called join of \"..v2.pid)",
" originsert(v2.evqueue, event)",
" v2.wakeup()",
" end --",
" end -- for processes",
" end --",
" end -- for processes",
" end -- if xwos_terminated",
" ",
" if event[1] == \"char\" or event[1] == \"key\" or event[1] == \"paste\" or event[1] == \"key_up\" then",
" consumed = true",
" kernel.debug(\"[PID\"..lpid..\"] user input received\")",
" if kernel.modules.instances.sandbox.procinput.current.proc ~= nil then",
" kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to user input pid \"..kernel.modules.instances.sandbox.procinput.current.proc.pid)",
" originsert(kernel.modules.instances.sandbox.procinput.current.proc.evqueue, event)",
" kernel.modules.instances.sandbox.procinput.current.proc.wakeup()",
" else",
" -- TODO what to do with input if no one likes it?",
" -- think about special key bindings fetched from background processes",
" -- currently we silently discard that kind of input",
" end -- ",
" end -- if char",
" ",
" -- distribute event to all processes",
" if not consumed then",
" for k, v in kernel.oldGlob.pairs(kernel.processes) do",
" if kernel.oldGlob.type(v) == \"table\" and v.procstate ~= \"finished\" then",
" kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to all pids \"..v.pid, kernel.oldGlob.unpack(event))",
" originsert(v.evqueue, event)",
" v.wakeup()",
" end -- if not finished",
" end -- for processes",
" end -- if consumed",
" ",
" return nil",
"end -- function processEvt",
"",
"return M",
},
[ "/kernel/common/xwos/test2.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"local a = function()",
" print(\"a\")",
" end",
" a()",
},
[ "/kernel/common/xwos/test.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"require('/rom/xwos/kernel/common/xwos/test2')",
" print(\"foo\")",
},
[ "/kernel/common/xwos/modulesmgr.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"local kernel -- xwos.kernel#xwos.kernel",
"local moduleOrder = {}",
"",
"--------------------------------",
"-- local kernel modules",
"-- @type xwos.modulesmgr",
"local M = {}",
"",
"-------------------------------",
"-- the module instances",
"-- @type xwos.modulesmgr.instances",
"-- @field [parent=#xwos.modulesmgr] #xwos.modulesmgr.instances instances",
"M.instances = {}",
"",
"-------------------------------",
"-- sandbox kernel module",
"-- @field [parent=#xwos.modulesmgr.instances] xwos.modulesmgr.sandbox#xwos.modulesmgr.sandbox sandbox",
"",
"-------------------------------",
"-- security kernel module",
"-- @field [parent=#xwos.modulesmgr.instances] xwos.modulesmgr.security#xwos.modulesmgr.security security",
"",
"--------------------------------",
"-- @function [parent=#xwos.modulesmgr] preboot",
"-- @param xwos.kernel#xwos.kernel k the kernel",
"M.preboot = function(k)",
" kernel = k",
" -- load settings with kernel module boot order",
" moduleOrder = kernel.require(\"moduleOrder\")",
" -- helper to load kernel modules from given directory",
" local loadKernelModules = function(dir)",
" local path = dir .. \"/xwos/modules\"",
" kernel.debug(\"loading kernel modules from \" .. path)",
" if kernel.oldGlob.fs.isDir(path) then",
" for i, v in kernel.oldGlob.pairs(kernel.oldGlob.fs.list(path)) do",
" kernel.debug(\"loading kernel module from \" .. path .. \"/\" .. v)",
" M.instances[v] = kernel.oldGlob.require(path .. \"/\" .. v)",
" end -- for list",
" end -- if isdir",
" end -- function loadKernelModules",
" ",
" -- load kernel modules",
" for k, v in kernel.oldGlob.pairs(kernel.kernelpaths) do",
" loadKernelModules(v)",
" end -- for kernelpaths",
"",
" for i, v in pairs(moduleOrder) do",
" if M.instances[v] ~= nil then",
" kernel.debug(\"preboot kernel module\",v)",
" M.instances[v].preboot(kernel)",
" end -- if exists",
" end -- for moduleOrder",
" for i, v in pairs(M.instances) do",
" if not table.contains(moduleOrder, i) then",
" kernel.debug(\"preboot kernel module\",v)",
" v.preboot(kernel)",
" end -- if not contains",
" end -- for modules",
"end -- function preboot",
"",
"--------------------------------",
"-- @function [parent=#xwos.modulesmgr] boot",
"-- @param xwos.kernel#xwos.kernel k the kernel",
"M.boot = function(k)",
" for i, v in pairs(moduleOrder) do",
" if M.instances[v] ~= nil then",
" kernel.debug(\"boot kernel module\",v)",
" M.instances[v].boot(kernel)",
" end -- if exists",
" end -- for moduleOrder",
" for i, v in pairs(M.instances) do",
" if not table.contains(moduleOrder, i) then",
" kernel.debug(\"boot kernel module\",v)",
" v.boot(kernel)",
" end -- if not contains",
" end -- for modules",
"end -- function preboot",
"",
"return M",
},
[ "/kernel/common/xwos/startup.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"--------------------------------",
"-- Default startup script",
"-- @module xwos.startup",
"local M = {}",
"",
"-------------------",
"-- The installer",
"-- @function [parent=#xwos.startup] run",
"-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
"M.installer = function(kernel)",
" local installerData = { lang = nil }",
" print()",
" print(\"starting installer...\")",
" ",
" kernel.print(\"read: \", read)",
" kernel.print(\"read0: \", getfenv(0).read)",
" kernel.print(\"read1: \", getfenv(1).read)",
" kernel.print(\"read6: \", getfenv(6).read)",
" kernel.print(\"read7: \", getfenv(7).read)",
" kernel.print(\"read8: \", getfenv(8).read)",
" print()",
" print(\"********* XW-OS ********** INSTALLER\")",
" local langs = {",
" \"en\" -- TODO support language packs",
" }",
" while installerData.lang == nil do",
" print(\"\")",
" print(\"Choose your language:\")",
" local input = read()",
" if table.contains(langs, input) then",
" installerData.lang = input",
" else -- if contains",
" print(\"Invalid language. Currently supported: \")",
" for k, v in pairs(langs) do",
" write(v)",
" write(\" \")",
" end -- for langs",
" print(\"\")",
" end -- if not contains",
" end -- while not lang",
" ",
" local admin = {}",
" print(\"\")",
" print(\"Enter your administrators email address:\")",
" admin.mail = read()",
" print(\"\")",
" print(\"Enter your administrators login name:\")",
" admin.login = read()",
" while admin.pass == nil do",
" print(\"\")",
" print(\"Enter your administrators password:\")",
" local pass1 = read()",
" print(\"\")",
" print(\"Retype your administrators password:\")",
" local pass2 = read()",
" ",
" if pass1 ~= pass2 then",
" print(\"\")",
" print(\"The passwords do not match...\")",
" else -- if not pass equals",
" admin.pass = pass1",
" end -- if pass equals",
" end -- while not pass",
" ",
" local user = {}",
" print(\"\")",
" print(\"Enter your users email address:\")",
" user.mail = read()",
" print(\"\")",
" print(\"Enter your users login name:\")",
" user.login = read()",
" while user.pass == nil do",
" print(\"\")",
" print(\"Enter your users password:\")",
" local pass1 = read()",
" print(\"\")",
" print(\"Retype your users password:\")",
" local pass2 = read()",
" ",
" if pass1 ~= pass2 then",
" print(\"\")",
" print(\"The passwords do not match...\")",
" else -- if not pass equals",
" user.pass = pass1",
" end -- if pass equals",
" end -- while not pass",
" ",
" print(\"\")",
" print(\"\")",
" print(\"***** starting installation\")",
" print(\"\")",
" print(\"Creating root...\")",
" local proot = kernel.modules.security.createProfile(\"root\")",
" print(\"Creating administrator...\")",
" local padmin = kernel.modules.security.createProfile(\"admin\")",
" print(\"Creating user...\")",
" local puser = kernel.modules.security.createProfile(\"user\")",
" print(\"Creating guest (inactive)...\")",
" local pguest = kernel.modules.security.createProfile(\"guest\")",
" ",
" -- TODO start gui on primary terminal",
" -- TODO create a wizard",
" ",
" -- TODO failing installer should set kernel.shutdown = true",
" ",
" kernel.writeSecureData('core/install.dat', textutils.serialize(installerData))",
"end -- function installer",
"",
"-------------------",
"-- The login processing",
"-- @function [parent=#xwos.startup] run",
"-- @param #string installData",
"-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
"M.login = function(installData, kernel)",
" print()",
" print(\"starting login...\")",
" ",
" -- for gui see http://harryfelton.web44.net/titanium/guide/download",
" -- lua minifier: https://gitlab.com/hbomb79/Titanium/blob/develop/bin/Minify.lua",
" ",
" -- TODO start gui on primary terminal",
"end -- function installer",
"",
"-------------------",
"-- Startup processing script",
"-- @function [parent=#xwos.startup] run",
"-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
"M.run = function(kernel)",
" local installData = kernel.readSecureData('core/install.dat')",
" kernel.debug(\"[start] checking installation\")",
" if installData == nil then",
" kernel.debug(\"[start] starting installer\")",
" M.installer(kernel)",
" end -- if not installed",
" ",
" while not kernel.shutdown do",
" kernel.debug(\"[start] starting login\")",
" M.login(textutils.unserialize(installData), kernel)",
" end -- while not shutdown",
"end -- function run",
"",
"return M",
},
[ "/kernel/1/8/moduleOrder.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"return {",
" \"sandbox\",",
" \"security\"",
"}",
},
[ "/kernel/common/xwos/kernel.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"local origGetfenv = getfenv",
"local origSetfenv = setfenv",
"local origsetmeta = setmetatable",
"local origtype = type",
"local origpairs = pairs",
"local origload = load",
"local origpcall = pcall",
"local origprint = print",
"local origtostring = tostring",
"",
"local origTable = table",
"table = {}",
"for k,v in origpairs(origTable) do",
" table[k] = v",
"end -- for table",
"",
"-------------------------------------",
"-- Creates a new clone; only first level of table will be cloned, no deep clone; no metadata clone",
"-- @function [parent=#table] clone",
"-- @param #table src",
"-- @return #table new copy",
"table.clone = function(src)",
" local r = {}",
" for k, v in origpairs(src) do",
" r[k] = v",
" end -- for src",
" return r",
"end -- function table.clone",
"",
"-------------------------------------",
"-- @function [parent=#table] contains",
"-- @param #table haystack",
"-- @param #any needle",
"-- @return #boolean success",
"table.contains = function(haystack, needle)",
" for k, v in origpairs(haystack) do",
" if (v == needle) then",
" return true",
" end -- if equals",
" end -- for haystack",
" return false",
"end -- function table.contains",
"",
"-------------------------------------",
"-- @function [parent=#table] indexOf",
"-- @param #table haystack",
"-- @param #any needle",
"-- @return #number index of given element or nil if not found",
"table.indexOf = function(haystack, needle)",
" for k, v in origpairs(haystack) do",
" if (v == needle) then",
" return k",
" end -- if equals",
" end -- for haystack",
" return nil",
"end -- function table.indexOf",
"",
"-------------------------------------",
"-- @function [parent=#table] removeValue",
"-- @param #table haystack",
"-- @param #any needle",
"-- @return #boolean true if element was found and removed",
"table.removeValue = function(haystack, needle)",
" for k, v in origpairs(haystack) do",
" if (v == needle) then",
" haystack[k] = nil",
" return true",
" end -- if equals",
" end -- for haystack",
" return false",
"end -- function table.removeValue",
"",
"-------------------------------------",
"-- @function [parent=#table] containsKey",
"-- @param #table haystack",
"-- @param #any needle",
"-- @return #boolean success",
"table.containsKey = function(haystack, needle)",
" return haystack[needle] ~= nil",
"end -- function table.containsKey",
"",
"--------------------------------",
"-- local kernel",
"-- @type xwos.kernel",
"local M = {}",
"",
"local bootSequence = {",
" debug = function()",
" M.kernelDebug = true",
" M.print(\"activating kernel debug mode...\")",
" end, -- function debug",
" ",
" eventLog = function()",
" M.eventLog = true",
" M.print(\"activating kernel event log...\")",
" end -- function eventLog",
"}",
"",
"--------------------------------",
"-- Boot kernel",
"-- @function [parent=#xwos.kernel] boot",
"-- @param #string ver kernel version number",
"-- @param #table kernelpaths the paths to look for kernel files",
"-- @param #function krequire require function to include kernel files",
"-- @param global#global args the command line arguments",
"M.boot = function(ver, kernelpaths, krequire, oldGlob, args)",
" --------------------------------",
" -- @field [parent=#xwos.kernel] #table kernelpaths the paths for including kernel",
" M.kernelpaths = kernelpaths",
" --------------------------------",
" -- @field [parent=#xwos.kernel] #string version the kernel version",
" M.version = ver",
" --------------------------------",
" -- @field [parent=#xwos.kernel] #table the built in environment factories (installed from modules)",
" M.envFactories = {}",
" --------------------------------",
" -- @field [parent=#xwos.kernel] global#global oldGlob the old globals",
" M.oldGlob = oldGlob -- TODO type (global#global) does not work?",
" M.oldGlob._ENV = nil",
" --M.oldGlob.package = nil",
" M.oldGlob._G = nil",
" M.oldGlob.shell = nil",
" M.oldGlob.multishell = nil",
" --------------------------------",
" -- @field [parent=#xwos.kernel] #table args the command line args invoking the kernel",
" M.args = args or {}",
"",
" -------------------------------",
" -- @field [parent=#xwos.kernel] #boolean kernelDebug true for kernel debugging; activated through script invocation/argument (\"xwos debug\")",
" M.kernelDebug = false",
"",
" -------------------------------",
" -- @field [parent=#xwos.kernel] #boolean eventLog true for event logging; activated through script invocation/argument (\"xwos eventLog\")",
" M.eventLog = false",
" ",
" -- parse arguments",
" for i, v in origpairs(M.args) do",
" if bootSequence[v] ~= nil then",
" bootSequence[v]()",
" else -- exists",
" M.print(\"Ignoring unknown argument \" .. v)",
" end -- not exists",
" end -- for arg",
" ",
" --------------------------------",
" -- Require for kernel scripts",
" -- @function [parent=#xwos.kernel] require",
" -- @param #string path the path",
" M.require = krequire",
" ",
" M.debug(\"loading process management\")",
" --------------------------------",
" -- @field [parent=#xwos.kernel] xwos.processes#xwos.processes processes the known xwos processes",
" M.processes = M.require('xwos/processes')",
" ",
" M.debug(\"loading module management\")",
" --------------------------------",
" -- @field [parent=#xwos.kernel] xwos.modulesmgr#xwos.modulesmgr modules the kernel modules",
" M.modules = M.require('xwos/modulesmgr')",
" ",
" M.debug(\"booting modules\")",
" M.modules.preboot(M)",
" M.modules.boot(M)",
" ",
" --------------------------------",
" -- @field [parent=#xwos.kernel] #global nenv the new environment for processes",
" M.nenv = {}",
" M.debug(\"preparing sandbox for root process\", M.nenv)",
" local nenvmt = {",
" __index = function(table, key)",
" local e = origGetfenv(0)",
" if (e == M.nenv) then return nil end",
" return e[key]",
" end -- function __index",
" }",
" origsetmeta(M.nenv, nenvmt)",
" origSetfenv(nenvmt.__index, M.nenv)",
" local function wrapfenv(table, env, blacklist)",
" local R = {}",
" for k,v in origpairs(table) do",
" local t = origtype(v)",
" if t == \"function\" then",
" if blacklist[k] == nil then",
" R[k] = origGetfenv(v)",
" -- print(\"setfenv\", k, R[k])",
" origpcall(origSetfenv, v, env) -- pcall because changing internal functions will fail (silently ingore it)",
" end -- if blacklist",
" end -- if function",
" if t == \"table\" and blacklist[k] ~= \"*\" then",
" -- print(\"setfenv table \", k)",
" R[k] = wrapfenv(v, env, blacklist[k] or {})",
" end -- if table",
" end -- for table",
" return R",
" end -- function wrapfenv",
" --------------------------------",
" -- @field [parent=#xwos.kernel] #table oldfenv the old fenv for global functions",
" M.oldfenv = wrapfenv(oldGlob, M.nenv, {",
" getfenv=true,",
" setfenv=true,",
" shell={run=true, clearAlias=true, dir=true, getRunningProgram=true},",
" package=\"*\",",
" bit32={bxor=true},",
" redstone={getBundledOutput=true}",
" })",
" M.debug(\"boot finished\")",
"end -- function boot",
"",
"--------------------------------",
"-- Startup xwos",
"-- @function [parent=#xwos.kernel] startup",
"M.startup = function()",
" local nenv = {}",
" M.debug(\"preparing new environment for root process\", nenv)",
" for k,v in origpairs(M.oldGlob) do",
" nenv[k] = v",
" end -- for oldGlob",
" nenv.print = function(...) -- TODO remove",
" M.oldGlob.print(\"->\", ...)",
" end -- function print",
" ",
" M.debug(\"creating root process\")",
" local proc = M.processes.new(nil, M, nenv, M.envFactories) -- TODO factories from root profile (per profile factories)",
" local startupData = M.readSecureData('core/startup.dat', \"/rom/xwos/kernel/common/xwos/testsleep.lua\") -- TODO startup script",
" M.debug(\"spawning thread with startup script \" .. startupData)",
" proc.spawn(startupData)",
" proc.join(nil)",
" ",
" M.debug(\"cleanup root process sandbox\")",
" -- cleanup",
" local function unwrapfenv(table, old)",
" for k,v in origpairs(table) do",
" local t = origtype(v)",
" if old[k] ~= nil then",
" if t == \"function\" then",
" -- print(\"setfenv\", k, old[k])",
" origpcall(origSetfenv, v, old[k]) -- pcall because changing internal functions will fail (silently ingore it)",
" end -- if function",
" if t == \"table\" then",
" unwrapfenv(v, old[k])",
" end -- if table",
" end -- if old",
" end -- for table",
" end -- function unwrapfenv",
" unwrapfenv(M.oldGlob, M.oldfenv)",
" ",
" table = origTable",
" ",
" M.debug(\"last actions before shutdown\")",
" if proc.result[1] then",
" origprint(\"Good bye...\")",
" else -- if result",
" origprint(\"ERR: \", proc.result[2])",
" end -- if result",
"end -- function startup",
"",
"-------------------------------",
"-- debug log message",
"-- @function [parent=#xwos.kernel] debug",
"-- @param ... print message arguments",
"M.debug = function(...)",
" if M.kernelDebug then",
" M.print(...)",
" end -- if kernelDebug",
"end -- function debug",
"",
"-------------------------------",
"-- print info message",
"-- @function [parent=#xwos.kernel] print",
"-- @param ... print message arguments",
"M.print = function(...)",
" M.oldGlob.print(...) -- TODO wrap to kernel display",
" if (M.kernelDebug) then",
" local f = M.oldGlob.fs.open(\"/core/log/debug-log.txt\", M.oldGlob.fs.exists(\"/core/log/debug-log.txt\") and \"a\" or \"w\")",
" local str = M.oldGlob.os.day()..\"-\"..M.oldGlob.os.time()..\" \"",
" for k, v in origpairs({...}) do",
" str = str .. origtostring(v) .. \" \"",
" end -- for ...",
" f.writeLine(str)",
" f.close()",
" end -- if kernelDebug",
"end -- function print",
"",
"-------------------------------",
"-- read data file from secured kernel storage",
"-- @function [parent=#xwos.kernel] readSecureData",
"-- @param #string path the file to read",
"-- @param #string def optional default data",
"-- @return #string the file content or nil if file does not exist",
"M.readSecureData = function(path, def)",
" local f = \"/xwos/private/\" .. path",
" if not M.oldGlob.fs.exists(f) then",
" return def",
" end -- if not exists",
" local h = M.oldGlob.fs.open(f, \"r\")",
" local res = h.readall()",
" h.close()",
" return res",
"end -- function readSecureData",
"",
"-------------------------------",
"-- write data file to secured kernel storage",
"-- @function [parent=#xwos.kernel] writeSecureData",
"-- @param #string path the file to write",
"-- @param #string data new data",
"M.writeSecureData = function(path, data)",
" local f = \"/xwos/private/\" .. path",
" local h = M.oldGlob.fs.open(f, \"w\")",
" h.write(data)",
" h.close()",
"end -- function readSecureData",
"",
"return M",
},
[ "/kernel/common/xwos/modules/sandbox/procinput.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"-----------------------",
"-- @module xwos.modules.sandbox.procinput",
"local M = {}",
"",
"local kernel -- xwos.kernel#xwos.kernel",
"",
"-- TODO refactor following to some linked stack type",
"-----------------------",
"-- @type pinput",
"",
"----------------------------------",
"-- @field [parent=#pinput] #pinput prev the previous input",
" ",
"-----------------------",
"-- @field [parent=#pinput] xwos.processes#xwos.process proc the input process",
"",
"-----------------------",
"-- @field [parent=#xwos.modules.sandbox.procinput] #pinput current the current process input (front process)",
"M.current = nil",
"",
"-----------------------",
"-- injects the kernel",
"-- @function [parent=#xwos.modules.sandbox.procinput] setKernel",
"-- @param xwos.kernel#xwos.kernel k the kernel",
"M.setKernel = function(k)",
" kernel = k",
"end -- function setKernel",
"",
"M.acquire = function(proc)",
" -- first invocation has no kernel",
" if kernel ~= nil and proc ~= nil then",
" kernel.debug(\"[PID\"..proc.pid..\"] fetching user input (front process)\")",
" end -- if kernel",
" local r = {}",
" ---------------------",
" -- release input if proc blocks it",
" -- @function [parent=#pinput] release",
" -- @param xwos.processes#xwos.process proc2 process to release the env",
" r.release = function(proc2)",
" if r.proc == proc2 then",
" kernel.debug(\"[PID\"..proc2.pid..\"] releasing user input (front process)\")",
" M.current = r.prev",
" while M.current.proc ~= nil and M.current.proc.procstate == \"finished\" do",
" M.current = M.current.prev",
" end -- while finished",
" if M.current.proc ~= nil then",
" kernel.debug(\"[PID\"..proc2.pid..\"] switched user input to \"..M.current.proc.pid..\" (front process)\")",
" end -- if proc",
" end -- if proc",
" end -- function release",
" r.prev = M.current",
" r.proc = proc",
" M.current = r",
"end -- function acquire",
"",
"M.acquire(nil)",
"",
"return M",
},
[ "/kernel/common/xwos/testsleep.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
" local function func1()",
" print(\"[1]pid=\",pid)",
" print(\"[1]Hello World!\")",
" sleep(5)",
" print(\"[1]Hello again\");",
" end",
" local function func2()",
" print(\"[2]pid=\",pid)",
" sleep(5)",
" print(\"[2]Hello World!\")",
" sleep(5)",
" print(\"[2]Hello again\");",
" end",
" print(\"[0]pid=\",pid)",
" local proc1 = xwos.pmr.createThread()",
" local proc2 = xwos.pmr.createThread()",
" proc1.spawn(func1)",
" proc2.spawn(func2)",
" proc1.join()",
" proc2.join()",
" print(\"Ending\")",
},
[ "/kernel/common/xwos/modules/sandbox/init.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"-----------------------",
"-- @module xwos.modules.sandbox",
"local M = {}",
"",
"local kernel -- xwos.kernel#xwos.kernel",
"local originsert = table.insert",
"",
"---------------------------------",
"-- @function [parent=#xwos.modules.sandbox] preboot",
"-- @param xwos.kernel#xwos.kernel k",
"M.preboot = function(k)",
" k.debug(\"preboot sandbox\")",
" kernel = k",
" ",
" -----------------------",
" -- process input type with mapping to previous input",
" -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.procinput#xwos.modules.sandbox.procinput procinput the input process management",
" M.procinput = kernel.require(\"xwos/modules/sandbox/procinput\")",
" M.procinput.setKernel(kernel)",
" ",
" -----------------------",
" -- timers started from processes",
" -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.timers#xwos.modules.sandbox.timers timers the timer management",
" M.timers = kernel.require(\"xwos/modules/sandbox/timers\")",
" M.timers.setKernel(kernel)",
" ",
" -----------------------",
" -- event queue handling",
" -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.evqueue#xwos.modules.sandbox.evqueue evqueue event queue management",
" M.evqueue = kernel.require(\"xwos/modules/sandbox/evqueue\")",
" M.evqueue.setKernel(kernel)",
"",
"end -- function preboot",
"",
"----------------------",
"-- @param xwos.processes#xwos.process proc the underlying process",
"-- @param #global env the global process environment",
"local envFactory = function(proc, env)",
" kernel.debug(\"[PID\"..proc.pid..\"] preparing env\", env)",
" env.pid = proc.pid",
"",
" -- TODO this is partly original code from bios.",
" -- we need to redeclare it to get into wrapped os.**** methods",
" -- maybe in future we find a solution to not redeclare it here",
" local biosRead = function( _sReplaceChar, _tHistory, _fnComplete, _sDefault )",
" if _sReplaceChar ~= nil and type( _sReplaceChar ) ~= \"string\" then",
" error( \"bad argument #1 (expected string, got \" .. type( _sReplaceChar ) .. \")\", 2 ) ",
" end",
" if _tHistory ~= nil and type( _tHistory ) ~= \"table\" then",
" error( \"bad argument #2 (expected table, got \" .. type( _tHistory ) .. \")\", 2 ) ",
" end",
" if _fnComplete ~= nil and type( _fnComplete ) ~= \"function\" then",
" error( \"bad argument #3 (expected function, got \" .. type( _fnComplete ) .. \")\", 2 ) ",
" end",
" if _sDefault ~= nil and type( _sDefault ) ~= \"string\" then",
" error( \"bad argument #4 (expected string, got \" .. type( _sDefault ) .. \")\", 2 ) ",
" end",
" term.setCursorBlink( true )",
" ",
" local sLine",
" if type( _sDefault ) == \"string\" then",
" sLine = _sDefault",
" else",
" sLine = \"\"",
" end",
" local nHistoryPos",
" local nPos = #sLine",
" if _sReplaceChar then",
" _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )",
" end",
" ",
" local tCompletions",
" local nCompletion",
" local function recomplete()",
" if _fnComplete and nPos == string.len(sLine) then",
" tCompletions = _fnComplete( sLine )",
" if tCompletions and #tCompletions > 0 then",
" nCompletion = 1",
" else",
" nCompletion = nil",
" end",
" else",
" tCompletions = nil",
" nCompletion = nil",
" end",
" end",
" ",
" local function uncomplete()",
" tCompletions = nil",
" nCompletion = nil",
" end",
" ",
" local w = term.getSize()",
" local sx = term.getCursorPos()",
" ",
" local function redraw( _bClear )",
" local nScroll = 0",
" if sx + nPos >= w then",
" nScroll = (sx + nPos) - w",
" end",
" ",
" local cx,cy = term.getCursorPos()",
" term.setCursorPos( sx, cy )",
" local sReplace = (_bClear and \" \") or _sReplaceChar",
" if sReplace then",
" term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) )",
" else",
" term.write( string.sub( sLine, nScroll + 1 ) )",
" end",
" ",
" if nCompletion then",
" local sCompletion = tCompletions[ nCompletion ]",
" local oldText, oldBg",
" if not _bClear then",
" oldText = term.getTextColor()",
" oldBg = term.getBackgroundColor()",
" term.setTextColor( colors.white )",
" term.setBackgroundColor( colors.gray )",
" end",
" if sReplace then",
" term.write( string.rep( sReplace, string.len( sCompletion ) ) )",
" else",
" term.write( sCompletion )",
" end",
" if not _bClear then",
" term.setTextColor( oldText )",
" term.setBackgroundColor( oldBg )",
" end",
" end",
" ",
" term.setCursorPos( sx + nPos - nScroll, cy )",
" end",
" ",
" local function clear()",
" redraw( true )",
" end",
" ",
" recomplete()",
" redraw()",
" ",
" local function acceptCompletion()",
" if nCompletion then",
" -- Clear",
" clear()",
" ",
" -- Find the common prefix of all the other suggestions which start with the same letter as the current one",
" local sCompletion = tCompletions[ nCompletion ]",
" sLine = sLine .. sCompletion",
" nPos = string.len( sLine )",
" ",
" -- Redraw",
" recomplete()",
" redraw()",
" end",
" end",
" while true do",
" local sEvent, param = os.pullEvent()",
" if sEvent == \"char\" then",
" -- Typed key",
" clear()",
" sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )",
" nPos = nPos + 1",
" recomplete()",
" redraw()",
" ",
" elseif sEvent == \"paste\" then",
" -- Pasted text",
" clear()",
" sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )",
" nPos = nPos + string.len( param )",
" recomplete()",
" redraw()",
" ",
" elseif sEvent == \"key\" then",
" if param == keys.enter then",
" -- Enter",
" if nCompletion then",
" clear()",
" uncomplete()",
" redraw()",
" end",
" break",
" ",
" elseif param == keys.left then",
" -- Left",
" if nPos > 0 then",
" clear()",
" nPos = nPos - 1",
" recomplete()",
" redraw()",
" end",
" ",
" elseif param == keys.right then",
" -- Right ",
" if nPos < string.len(sLine) then",
" -- Move right",
" clear()",
" nPos = nPos + 1",
" recomplete()",
" redraw()",
" else",
" -- Accept autocomplete",
" acceptCompletion()",
" end",
" ",
" elseif param == keys.up or param == keys.down then",
" -- Up or down",
" if nCompletion then",
" -- Cycle completions",
" clear()",
" if param == keys.up then",
" nCompletion = nCompletion - 1",
" if nCompletion < 1 then",
" nCompletion = #tCompletions",
" end",
" elseif param == keys.down then",
" nCompletion = nCompletion + 1",
" if nCompletion > #tCompletions then",
" nCompletion = 1",
" end",
" end",
" redraw()",
" ",
" elseif _tHistory then",
" -- Cycle history",
" clear()",
" if param == keys.up then",
" -- Up",
" if nHistoryPos == nil then",
" if #_tHistory > 0 then",
" nHistoryPos = #_tHistory",
" end",
" elseif nHistoryPos > 1 then",
" nHistoryPos = nHistoryPos - 1",
" end",
" else",
" -- Down",
" if nHistoryPos == #_tHistory then",
" nHistoryPos = nil",
" elseif nHistoryPos ~= nil then",
" nHistoryPos = nHistoryPos + 1",
" end ",
" end",
" if nHistoryPos then",
" sLine = _tHistory[nHistoryPos]",
" nPos = string.len( sLine ) ",
" else",
" sLine = \"\"",
" nPos = 0",
" end",
" uncomplete()",
" redraw()",
" ",
" end",
" ",
" elseif param == keys.backspace then",
" -- Backspace",
" if nPos > 0 then",
" clear()",
" sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )",
" nPos = nPos - 1",
" recomplete()",
" redraw()",
" end",
" ",
" elseif param == keys.home then",
" -- Home",
" if nPos > 0 then",
" clear()",
" nPos = 0",
" recomplete()",
" redraw()",
" end",
" ",
" elseif param == keys.delete then",
" -- Delete",
" if nPos < string.len(sLine) then",
" clear()",
" sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 ) ",
" recomplete()",
" redraw()",
" end",
" ",
" elseif param == keys[\"end\"] then",
" -- End",
" if nPos < string.len(sLine ) then",
" clear()",
" nPos = string.len(sLine)",
" recomplete()",
" redraw()",
" end",
" ",
" elseif param == keys.tab then",
" -- Tab (accept autocomplete)",
" acceptCompletion()",
" ",
" end",
" ",
" elseif sEvent == \"term_resize\" then",
" -- Terminal resized",
" w = term.getSize()",
" redraw()",
" ",
" end",
" end",
" ",
" local cx, cy = term.getCursorPos()",
" term.setCursorBlink( false )",
" term.setCursorPos( w + 1, cy )",
" print()",
" ",
" return sLine",
" end -- function biosRead",
"",
" env.read = function( _sReplaceChar, _tHistory, _fnComplete, _sDefault )",
" proc.acquireInput()",
" local res = {pcall(biosRead, _sReplaceChar,_tHistory,_fnComplete,_sDefault)}",
" proc.releaseInput()",
" if res[1] then",
" return res[2]",
" end -- if res",
" error(res[2])",
" end -- function read",
" ",
" env.sleep = function(nTime)",
" kernel.debug(\"[PID\"..proc.pid..\"] sleep\", nTime, kernel.oldGlob.getfenv(0), kernel.oldGlob.getfenv(env.sleep))",
" if nTime ~= nil and type( nTime ) ~= \"number\" then",
" error( \"bad argument #1 (expected number, got \" .. type( nTime ) .. \")\", 2 ) ",
" end",
" local timer = os.startTimer( nTime or 0 )",
" repeat",
" local sEvent, param = os.pullEvent( \"timer\" )",
" until param == timer",
" end -- function sleep",
" ",
" -- clone os to manipulate it",
" env.os = table.clone(env.os)",
" env.os.sleep = function(nTime)",
" sleep(nTime)",
" end -- function os.sleep",
" ",
" env.os.startTimer = function(s)",
" kernel.debug(\"[PID\"..proc.pid..\"] os.startTimer\", s)",
" local timer = kernel.oldGlob.os.startTimer(s)",
" kernel.modules.instances.sandbox.timers.new(timer, proc)",
" return timer",
" end -- function os.startTimer",
" env.os.pullEventRaw = function(filter)",
" kernel.debug(\"[PID\"..proc.pid..\"] os.pullEventRaw\", filter)",
" while true do",
" for k,v in kernel.oldGlob.ipairs(proc.evqueue) do",
" proc.evqueue[k] = nil",
" if filter == nil or v[1]==filter then",
" kernel.debug(\"[PID\"..proc.pid..\"] returning event from local event queue\", kernel.oldGlob.unpack(v))",
" return kernel.oldGlob.unpack(v)",
" else -- if filter",
" kernel.debug(\"[PID\"..proc.pid..\"] discard event from local event queue because of filter\", kernel.oldGlob.unpack(v))",
" end -- if filter",
" end -- for evqueue",
" ",
" kernel.debug(\"[PID\"..proc.pid..\"] invoke os.pullEventRaw\", filter)",
" local event = M.evqueue.processEvt(proc.pid, proc, {kernel.oldGlob.os.pullEventRaw()}, filter)",
" if event ~= nil then",
" return kernel.oldGlob.unpack(event)",
" end -- if event",
" end -- endless loop",
" end -- function os.pullEventRaw",
" env.os.pullEvent = function(filter)",
" kernel.debug(\"[PID\"..proc.pid..\"] os.pullEvent\", filter)",
" local eventData = {proc.env.os.pullEventRaw(filter)}",
" if eventData[1] == \"terminate\" then",
" kernel.oldGlob.error( \"Terminated\", 0 )",
" end",
" return kernel.oldGlob.unpack(eventData)",
" end -- function os.pullEvent",
" ---------------------------------------",
" -- operating system access",
" -- @type xwos",
" -- @field [parent=#global] #xwos xwos predefined operating system accessor",
" env.xwos = {}",
" ---------------------------------------",
" -- debugging output",
" -- @function [parent=#xwos] debug",
" -- @param #string msg",
" env.xwos.debug = function(msg)",
" -- TODO find a way to pass variables etc.",
" -- check for possible sandbox breaks during tostring",
" if kernel.oldGlob.type(msg) ~= \"string\" then",
" error(\"Wrong argument type (only strings allowed)\")",
" else -- if not string",
" kernel.debug(msg)",
" end -- if string",
" end -- function debug",
" ---------------------------------------",
" -- process manager",
" -- @type xwos.pmr",
" -- @field [parent=#xwos] #xwos.pmr pmr process manager",
" env.xwos.pmr = {}",
" -- TODO demon child threads (threads to be fnished before process ends)",
" -- TODO on terminate main process terminat all child threads",
" ---------------------------------------",
" -- create a new child thread",
" -- @function [parent=#xwos.pmr] createThread",
" -- @param #table newenv the environment of the new thread",
" -- @return #xwos.pmr.thread",
" env.xwos.pmr.createThread = function(newenv)",
" local nenv = {}",
" for k,v in kernel.oldGlob.pairs(kernel.oldGlob) do",
" nenv[k] = v",
" end -- for oldGlob",
" local function wrap(target, src)",
" for k,v in kernel.oldGlob.pairs(src) do",
" if kernel.oldGlob.type(v) == \"table\" and kernel.oldGlob.type(target[k]) == \"table\" then",
" wrap(v, target[k])",
" else -- if tables",
" target[k] = v",
" end -- if tables",
" end -- for src",
" end -- function wrap",
" if newenv ~= nil then",
" wrap(nenv, newenv)",
" end -- if nenv",
" local nproc = kernel.processes.new(proc, kernel, env, kernel.envFactories)",
" ---------------------------------------",
" -- the new thread",
" -- @type xwos.pmr.thread",
" local R = {}",
" ---------------------------------------",
" -- join thread and wait for finish",
" -- @function [parent=#xwos.pmr.thread] join",
" R.join = function()",
" nproc.join(proc)",
" end -- function join",
" ---------------------------------------",
" -- terminate thread",
" -- @function [parent=#xwos.pmr.thread] terminate",
" R.termninate = function()",
" nproc.termninate()",
" end -- function termninate",
" ---------------------------------------",
" -- spawn thread and invoke function",
" -- @function [parent=#xwos.pmr.thread] spawn",
" -- @param #function func the function to invoke",
" -- @param ... arguments",
" R.spawn = function(func, ...)",
" nproc.spawn(func, ...)",
" end -- function termninate",
" -- TODO do we need this? we are declaring the functions already inside process thread with correct fenv",
" kernel.oldGlob.setfenv(R.join, kernel.nenv)",
" kernel.oldGlob.setfenv(R.terminate, kernel.nenv)",
" kernel.oldGlob.setfenv(R.spawn, kernel.nenv)",
" return R",
" end -- function createThread",
" ",
" env.dofile = function(_sFile)",
" if type( _sFile ) ~= \"string\" then",
" error( \"bad argument #1 (expected string, got \" .. type( _sFile ) .. \")\", 2 )",
" end",
" local fnFile, e = loadfile( _sFile, kernel.nenv )",
" if fnFile then",
" return fnFile()",
" else",
" error( e, 2 )",
" end",
" end -- dofile",
" ",
" -- TODO do we need this? we are declaring the functions already inside process thread with correct fenv",
" kernel.oldGlob.setfenv(biosRead, kernel.nenv)",
" kernel.oldGlob.setfenv(env.read, kernel.nenv)",
" kernel.oldGlob.setfenv(env.sleep, kernel.nenv)",
" kernel.oldGlob.setfenv(env.dofile, kernel.nenv)",
" kernel.oldGlob.setfenv(env.os.sleep, kernel.nenv)",
" kernel.oldGlob.setfenv(env.os.startTimer, kernel.nenv)",
" kernel.oldGlob.setfenv(env.os.pullEventRaw, kernel.nenv)",
" kernel.oldGlob.setfenv(env.os.pullEvent, kernel.nenv)",
" kernel.oldGlob.setfenv(env.xwos.debug, kernel.nenv)",
" kernel.oldGlob.setfenv(env.xwos.pmr.createThread, kernel.nenv)",
"end -- function envFactory",
"",
"---------------------------------",
"-- @function [parent=#xwos.modules.sandbox] boot",
"-- @param xwos.kernel#xwos.kernel k",
"M.boot = function(k)",
" k.debug(\"boot sandbox\")",
" ",
" kernel.envFactories.sandbox = envFactory",
"end -- function boot",
"",
"-- wrap lua console and wrap programs...",
"",
"---- global functions",
"--orig.print = print",
"--orig.write = write",
"--orig.load = load",
"--orig.read = read",
"--orig.error = error",
"--orig.printError = printError",
"---- relevant for sandbox",
"--orig.dofile = dofile",
"--orig.loadfile = loadfile",
"--orig.loadstring = loadstring",
"--orig.rawset = rawset",
"--orig.rawget = rawget",
"--",
"---- computercraft apis",
"--orig.redstone = redstone",
"--orig.rs = rs -- alias for redstone",
"--orig.rednet = rednet",
"--orig.fs = fs",
"--orig.gps = gps",
"--orig.disk = disk",
"--orig.http = http",
"--orig.os = os",
"--orig.commands = commands",
"--orig.io = io",
"--orig.multishell = multishell",
"--orig.peripheral = peripheral",
"--orig.settings = settings",
"--orig.shell = shell",
"--orig.turtle = turtle",
"--orig.pocket = pocket",
"--",
"---- terminal management",
"--orig.term = term",
"--orig.paintutils = paintutils",
"--orig.textutils = textutils",
"--orig.window = window",
"--",
"---- threads etc.",
"--orig.parallel = parallel",
"--orig.setfenv = setfenv",
"--orig.getfenv = getfenv",
"--orig.xpcall = xpcall",
"--orig.pcall = pcall",
"--orig.coroutine = coroutine",
"--",
"-- Events:",
"-- alarm http://computercraft.info/wiki/Alarm_(event)",
"-- char http://computercraft.info/wiki/Char_(event)",
"-- disk http://computercraft.info/wiki/Disk_(event)",
"-- disk_eject http://computercraft.info/wiki/Disk_eject_(event)",
"-- http_failure http://computercraft.info/wiki/Http_failure_(event)",
"-- http_success http://computercraft.info/wiki/Http_success_(event)",
"-- key http://computercraft.info/wiki/Key_(event)",
"-- key_up http://computercraft.info/wiki/Key_up_(event)",
"-- modem_message http://computercraft.info/wiki/Modem_message_(event) http://computercraft.info/wiki/Modem_(API)",
"-- monitor_resize http://computercraft.info/wiki/Monitor_resize_(event)",
"-- monitor_touch http://computercraft.info/wiki/Monitor_touch_(event)",
"-- mouse_click http://computercraft.info/wiki/Mouse_click_(event)",
"-- mouse_drag http://computercraft.info/wiki/Mouse_drag_(event)",
"-- mouse_scroll http://computercraft.info/wiki/Mouse_scroll_(event)",
"-- mouse_up http://computercraft.info/wiki/Mouse_up_(event)",
"-- paste http://computercraft.info/wiki/Paste_(event)",
"-- peripheral http://computercraft.info/wiki/Peripheral_(event)",
"-- peripheral_detach http://computercraft.info/wiki/Peripheral_detach_(event)",
"-- rednet_message http://computercraft.info/wiki/Rednet_message_(event) http://computercraft.info/wiki/Rednet_(API)",
"-- redstone http://computercraft.info/wiki/Redstone_(event)",
"-- task_complete http://computercraft.info/wiki/Task_complete_(event)",
"-- term_resize http://computercraft.info/wiki/Term_resize(Event) http://computercraft.info/wiki/Term_(API)",
"-- terminate http://computercraft.info/wiki/Terminate_(event)",
"-- timer http://computercraft.info/wiki/Timer_(event)",
"-- turtle_inventory http://computercraft.info/wiki/Turtle_inventory_(event)",
"",
"return M",
"",
"",
"",
"",
"",
"",
"",
},
[ "/core" ] = true,
[ "/xwos.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"term.clear()",
"",
"local tArgs = {...}",
"",
"local myver = \"0.0.1\" -- TODO manipulate through maven build",
"local osvs = os.version()",
"local osvIter = string.gmatch(osvs, \"%S+\")",
"local osn = osvIter()",
"local osv = osvIter()",
"",
"local kernelpaths = { \"\", \"/xwos/kernel/common\" }",
"local kernels = {}",
"kernels[\"CraftOS\"] = {}",
"kernels[\"CraftOS\"][\"1.8\"] = \"/xwos/kernel/1/8\"",
"",
"print(\"** booting XW-OS........\")",
"print(\"** XW-OS version \" .. myver)",
"print(\"** Copyright © 2018 by xworlds.eu.\")",
"print(\"** All rights reserved.\")",
"",
"-- check if already booted",
"if xwos then",
" print()",
" print(\"FAILED... We are already running XW-OS...\")",
" return nil",
"end -- if already booted",
"",
"-- check if valid operating system",
"if kernels[osn] == nil or kernels[osn][osv] == nil then",
" print()",
" print(\"FAILED... running on unknown operating system or version...\")",
" print(\"OS-version we got: \" .. osvs)",
" print(\"Currently we require CraftOS at version 1.8\")",
" return nil",
"end -- if valid",
"",
"-- kernel file loader",
"kernelpaths[1] = kernels[osn][osv]",
"",
"-- prepare first sandboxing for kernel",
"local old2 = getfenv(2)",
"local old1 = getfenv(1)",
"if old2 ~= _G or old1.require == nil then",
" print()",
" print(\"FAILED... please run XW-OS in startup script or on root console...\")",
" print(\"Running inside other operating systems may not be supported...\")",
" return nil",
"end -- if not globals",
"local oldGlob = {}",
"for k, v in pairs(_G) do",
" oldGlob[k] = v",
"end -- for _G",
"for k, v in pairs(old2) do",
" oldGlob[k] = v",
"end -- for _G",
"for k, v in pairs(old1) do",
" oldGlob[k] = v",
"end -- for _G",
"",
"-- create an explicit copy of globals",
"local newGlob = {}",
"for k, v in oldGlob.pairs(oldGlob) do",
" newGlob[k] = v",
"end -- for _G",
"",
"-- redirect require for kernel loading",
"-- using functions from oldGlob for security reasons",
"local function krequire(path)",
" for k, v in oldGlob.pairs(kernelpaths) do",
" local target = v .. \"/\" .. oldGlob.string.gsub(path, \"%.\", \"/\")",
" local targetFile = target .. \".lua\"",
" if oldGlob.fs.exists(targetFile) then",
" local res = oldGlob.require(target)",
" -- print(\"loaded file \"..target)",
" return res",
" end -- if file exists",
" end -- for kernelpaths",
" return nil",
"end -- function require",
"",
"setfenv(1, newGlob)",
"local state, err = pcall(function()",
" local kernel = krequire('xwos.kernel') -- xwos.kernel#xwos.kernel",
" ",
" kernel.boot(myver, kernelpaths, krequire, oldGlob, tArgs)",
" kernel.startup()",
" end -- function ex",
")",
"setfenv(1, old1)",
"",
"if not state then",
" error(err)",
"end",
"",
},
[ "/kernel/common/xwos/processes.lua" ] = {
"-- This file is part of xwos.",
"--",
"-- xwos is free software: you can redistribute it and/or modify",
"-- it under the terms of the GNU General Public License as published by",
"-- the Free Software Foundation, either version 3 of the License, or",
"-- (at your option) any later version.",
"--",
"-- xwos is distributed in the hope that it will be useful,",
"-- but WITHOUT ANY WARRANTY; without even the implied warranty of",
"-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"-- GNU General Public License for more details.",
"--",
"-- You should have received a copy of the GNU General Public License",
"-- along with xwos. If not, see <http://www.gnu.org/licenses/>.",
"",
"local cocreate = coroutine.create",
"local coresume = coroutine.resume",
"local origGetfenv = getfenv",
"local origSetfenv = setfenv",
"local origsetmeta = setmetatable",
"local origtype = type",
"local origdofile = dofile",
"local origloadfile = loadfile",
"local origpcall = pcall",
"local origpackage = package",
"local origprint = print",
"local origerror = error",
"local origser = textutils.serialize",
"local origpairs = pairs",
"local origyield = coroutine.yield",
"local originsert = table.insert",
"",
"local kernel -- xwos.kernel#xwos.kernel",
"",
"--------------------------------",
"-- local process environments",
"-- @type xwos.processes",
"local processes = {}",
"",
"--------------------------------",
"-- next pid to use for new processes",
"local nextPid = 0",
"",
"--------------------------------",
"-- creates a new process",
"-- @function [parent=#xwos.processes] new",
"-- @param p the parent process",
"-- @param xwos.kernel#xwos.kernel k the kernel table",
"-- @param #global env the global process environment",
"-- @param #table factories functions with signature (proc, env) to initialize the new process or environment",
"-- @return #xwos.process",
"processes.new = function(p, k, env, factories)",
" kernel = k",
" --------------------------------",
" -- process type",
" -- @type xwos.process",
" local R = {}",
" ",
" --------------------------------",
" -- @field [parent=#xwos.process] #number pid the process id",
" R.pid = nextPid",
" nextPid = nextPid + 1",
" ",
" --------------------------------------",
" -- @field [parent=#xwos.process] #table evqueue the process local event queue",
" R.evqueue = {}",
" ",
" ------------------------------------------",
" -- @field [parent=#xwos.process] #number joined number of processes having called method join",
" R.joined = 0",
" ",
" --------------------------------",
" -- @field [parent=#xwos.process] #string procstate the process state; \"initializing\", \"running\" or \"terminated\"",
" R.procstate = \"initializing\"",
" kernel.debug(\"[PID\"..R.pid..\"] pocstate = initializing\")",
" ",
" --------------------------------",
" -- @field [parent=#xwos.process] #xwos.process parent the parent process",
" R.parent = p",
" ",
" --------------------------------",
" -- @field [parent=#xwos.process] #global env the process environment",
" R.env = { pid = R.pid }",
" kernel.debug(\"[PID\"..R.pid..\"] environments\", env)",
" local nenvmt = {",
" __index = function(table, key)",
" local res = env[key]",
" if res == nil then",
" if R.parent ~= nil then",
" -- parent should at least lead to PID 0. PID 0 already should contain all the visible and public globals all processes are allowed to use",
" res = R.parent.env[key]",
" end -- if parent",
" end -- if not res (env)",
" return res",
" end -- function __index",
" }",
" origsetmeta(R.env, nenvmt)",
" origSetfenv(nenvmt.__index, R.env)",
" ",
" --------------------------------------",
" -- acquire input (front process)",
" -- @function [parent=#xwos.process] acquireInput",
" R.acquireInput = function()",
" -- TODO is a stack always good?",
" -- switching between processes (alt+tab in windows) is not meant to build a stack of input",
" -- a stack of input will represent some kind of modal dialog over other modal dialog where closing one will pop up the previous one",
" -- think about it...",
" kernel.modules.instances.sandbox.procinput.acquire(R)",
" end -- function acquireInput",
" ",
" ------------------------------------------",
" -- joins process and awaits it termination",
" -- @function [parent=#process] join",
" -- @param #xwos.process cproc calling process",
" R.join = function(cproc)",
" local cpid = \"*\"",
" if cproc ~= nil then",
" cpid = cproc.pid",
" end -- if cproc",
" kernel.debug(\"[PID\"..cpid..\"] joining\")",
" R.joined = R.joined + 1",
" while R.procstate ~= \"finished\" do",
" kernel.debug(\"[PID\"..cpid..\"] waiting for finished of \"..R.pid..\" (state=\"..R.procstate..\")\")",
" local event = kernel.modules.instances.sandbox.evqueue.processEvt(cpid, cproc, {origyield()}, \"xwos_terminated\")",
" if event ~= nil and event[2] ~= R.pid then",
" for k, v in kernel.oldGlob.pairs(processes) do",
" if kernel.oldGlob.type(v)==\"table\" and v.pid == event[2] and v.joined > 0 then",
" kernel.debug(\"[PID\"..cpid..\"] redistributing to all other processes because at least one process called join of \"..R.pid)",
" ",
" for k2, v2 in kernel.oldGlob.pairs(kernel.processes) do",
" if kernel.oldGlob.type(v2) == \"table\" and v2 ~= cproc and v2.procstate~= \"finished\" then",
" kernel.debug(\"[PID\"..cpid..\"] redistributing because at least one process called join of \"..R.pid)",
" originsert(v2.evqueue, event)",
" v2.wakeup()",
" end --",
" end -- for processes",
" end --",
" end -- for processes",
" end -- if pid",
" end",
" kernel.debug(\"[PID\"..cpid..\"] received finish notification or \"..R.pid)",
" R.joined = R.joined - 1",
" end -- function join",
" ",
" --------------------------------------",
" -- release input (front process)",
" -- @function [parent=#xwos.process] releaseInput",
" R.releaseInput = function()",
" kernel.modules.instances.sandbox.procinput.current.release(R)",
" end -- function acquireInput",
" ",
" --------------------------------------",
" -- wakeup process in reaction to events on local event queue",
" -- @function [parent=#xwos.process] wakeup",
" R.wakeup = function()",
" if R.co ~= nil and R.procstate ~= \"finished\" then",
" kernel.debug(\"[PID\"..R.pid..\"] wakeup requested\")",
" kernel.oldGlob.coroutine.resume(R.co)",
" end -- if proc",
" end -- function wakeup",
" ",
" --------------------------------------",
" -- request process to terminate",
" -- @function [parent=#xwos.process] terminate",
" R.terminate = function()",
" kernel.oldGlob.os.queueEvent(\"xwos_terminate\", R.pid)",
" end -- function wakeup",
" ",
" --------------------------------",
" -- Remove the process from process table",
" -- @function [parent=#xwos.process] remove",
" R.remove = function()",
" kernel.debug(\"[PID\"..R.pid..\"] removing from process table\")",
" processes[R.pid] = nil",
" end -- function remove",
" ",
" --------------------------------",
" -- Spawn the process (invoke function)",
" -- @function [parent=#xwos.process] spawn",
" -- @param #function func the function to invoke",
" -- @param ... the arguments for given function",
" R.spawn = function(func, ...)",
" local env0 = kernel.nenv",
" kernel.debug(\"[PID\"..R.pid..\"] prepare spawn\")",
" -- TODO ... may contain functions and objects with metatables; this may cause problems by mxing environments",
" -- establish an alternative for IPC (inter process communication)",
" local res = {origpcall(origser, {...})}-- this will cause an error if serializing forbidden types (functions etc.)",
" if not res[1] then",
" kernel.debug(\"[PID\"..R.pid..\"] ERR:\", res[2])",
" kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
" R.result = res",
" R.procstate = \"finished\"",
" kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
" return",
" end -- if not res",
" ",
" local spawn0 = function(...)",
" kernel.debug(\"[PID\"..R.pid..\"] pocstate = running\")",
" R.procstate = \"running\"",
" kernel.debug(\"[PID\"..R.pid..\"] using env\", R.env, env0)",
" origSetfenv(0, R.env)",
" for k, v in origpairs(factories) do",
" kernel.debug(\"[PID\"..R.pid..\"] invoke factory\", k, v)",
" v(R, R.env)",
" end -- for factories",
" if origtype(func) == \"string\" then",
" local func2 = function(...)",
" kernel.debug(\"[PID\"..R.pid..\"] doFile\", func)",
" local fnFile, e = origloadfile(func, kernel.nenv)",
" if fnFile then",
" return fnFile()",
" else -- if res",
" origerror( e, 2 )",
" end -- if not res",
" return origdofile(func, ...)",
" end -- function func2",
" origSetfenv(func2, kernel.nenv)",
" --------------------------------",
" -- @field [parent=#xwos.process] #table result the return state from process function",
" R.result = {origpcall(func2, ...)}",
" else -- if string",
" kernel.debug(\"[PID\"..R.pid..\"] invoke function\", func)",
" R.result = {origpcall(func, ...)}",
" end -- if string",
" kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
" if not R.result[1] then",
" kernel.debug(\"[PID\"..R.pid..\"] ERR:\", R.result[2])",
" end -- if not res",
" R.procstate = \"finished\"",
" kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
" end -- function spawn0",
" R.env.getfenv = function(n)",
" -- TODO: Hide kernel.nenv because one may decide to manipulate it to inject variables into other threads :-(",
" local t = origtype(n)",
" if t == \"number\" then",
" if n == 0 then",
" return kernel.nenv",
" end -- if 0",
" end -- if number",
" return origGetfenv(n)",
" end -- function get",
" R.env.setfenv = function(n, v)",
" -- TODO maybe we can compare current fenv with THIS nenv and nenv from kernel;",
" -- if matches we deny changing the fenv",
" -- if not matches we allow changing because it was loaded inside process",
" ",
" -- do not allow changing fenv at all",
" -- simply return current one",
" return R.env.getfenv(n, v)",
" end -- function setfenv",
" kernel.debug(\"[PID\"..R.pid..\"] prepare package\")",
" R.env.package = {}",
" -- taken from bios.lua; must be overriden because of env",
" -- TODO maybe we find a better solution than copying all the stuff",
" R.env.package.loaded = {",
" -- _G = _G,",
" bit32 = bit32,",
" coroutine = coroutine, -- TODO wrap",
" math = math,",
" package = R.env.package,",
" string = string,",
" table = table,",
" }",
" -- TODO paths",
" R.env.package.path = \"?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua\"",
" if turtle then",
" R.env.package.path = R.env.package.path..\";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua\"",
" elseif command then",
" R.env.package.path = R.env.package.path..\";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua\"",
" end",
" R.env.package.config = \"/\\n;\\n?\\n!\\n-\"",
" R.env.package.preload = {}",
" local loader1 = function( name )",
" if package.preload[name] then",
" return package.preload[name]",
" else",
" return nil, \"no field package.preload['\" .. name .. \"']\"",
" end",
" end -- function loader1",
" local loader2 = function( name )",
" local fname = string.gsub(name, \"%.\", \"/\")",
" local sError = \"\"",
" for pattern in string.gmatch(package.path, \"[^;]+\") do",
" local sPath = string.gsub(pattern, \"%?\", fname)",
" if sPath:sub(1,1) ~= \"/\" then",
" sPath = fs.combine(sDir, sPath)",
" end",
" if fs.exists(sPath) and not fs.isDir(sPath) then",
" local fnFile, sError = loadfile( sPath, nenv ) -- inject our new env",
" if fnFile then",
" return fnFile, sPath",
" else",
" return nil, sError",
" end",
" else",
" if #sError > 0 then",
" sError = sError .. \"\\n\"",
" end",
" sError = sError .. \"no file '\" .. sPath .. \"'\"",
" end",
" end",
" return nil, sError",
" end -- function loader2",
" R.env.package.loaders = {",
" loader1,",
" loader2",
" }",
" ",
" local sentinel = {}",
" R.env.require = function( name )",
" if type( name ) ~= \"string\" then",
" error( \"bad argument #1 (expected string, got \" .. type( name ) .. \")\", 2 )",
" end",
" if package.loaded[name] == sentinel then",
" error(\"Loop detected requiring '\" .. name .. \"'\", 0)",
" end",
" if package.loaded[name] then",
" return package.loaded[name]",
" end",
" ",
" local sError = \"Error loading module '\" .. name .. \"':\"",
" for n,searcher in ipairs(package.loaders) do",
" local loader, err = searcher(name)",
" if loader then",
" package.loaded[name] = sentinel",
" local result = loader( err )",
" if result ~= nil then",
" package.loaded[name] = result",
" return result",
" else",
" package.loaded[name] = true",
" return true",
" end",
" else",
" sError = sError .. \"\\n\" .. err",
" end",
" end",
" error(sError, 2)",
" end -- function require",
" ",
" kernel.debug(\"[PID\"..R.pid..\"] setting new env\", env0)",
" origSetfenv(spawn0, env0)",
" origSetfenv(loader1, env0)",
" origSetfenv(loader2, env0)",
" origSetfenv(R.env.require, env0)",
" origSetfenv(R.env.getfenv, env0)",
" origSetfenv(R.env.setfenv, env0)",
" --------------------------------",
" -- @field [parent=#xwos.process] coroutine#coroutine co the coroutine",
" R.co = cocreate(spawn0)",
" local res = {coresume(R.co, ...)}",
" if not res[1] then",
" kernel.debug(\"[PID\"..R.pid..\"] ERR:\", res[2])",
" kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
" R.result = res",
" R.procstate = \"finished\"",
" kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
" end -- if not res",
" end -- function spawn",
" ",
" processes[R.pid] = R",
" kernel.debug(\"[PID\"..R.pid..\"] returning new process\")",
" return R",
"end -- function new",
"",
"return processes",
},
} --paste archive data here
local tArg = {...}
local outpath = ((tArg[1] ~= "") and tArg[1]) or (shell and shell.getRunningProgram() or "xwos")
if fs.combine("",outpath):sub(1,26) == "rom/programs/http/pastebin" then
outpath = (shell and fs.combine(shell.dir(),"xwos") or "xwos")
end
local progdor = fs.getName(shell.getRunningProgram())
local dir = shell.dir()
local explode = function(div,str)
if (div=='') then return false end
local pos,arr = 0,{}
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr,str:sub(pos,st-1))
pos = sp + 1
end
table.insert(arr,str:sub(pos))
return arr
end
local sanitize = function(sani,tize)
local _,x = string.find(sani,tize)
if x then
return sani:sub(x+1)
else
return sani
end
end
local tablize = function(input)
if type(input) == "string" then
return explode("\n",input)
elseif type(input) == "table" then
return table.concat(input,"\n")
end
end
if not outpath then
outpath = input
end
local choice = function(input,verbose)
if not input then
input = "yn"
end
if verbose then
write("[")
for a = 1, #input do
write(input:sub(a,a):upper())
if a < #input then
write(",")
end
end
write("]?")
end
local evt,char
repeat
evt,char = os.pullEvent("char")
until string.find(input:lower(),char:lower())
if verbose then
print(char:upper())
end
local pos = string.find(input:lower(),char:lower())
return pos, char:lower()
end
local doPack = function(list,output,doCompress,verbose)
local tx = term.getTextColor()
if fs.isReadOnly(output) and (fs.combine("",output) ~= "") then return 5 end
local packageSelf = true
local packageReadOnly = true
local ro_asked = false
local ps_asked = false
if fs.exists(output) and (not fs.isDir(output)) then
fs.delete(output)
end
local amnt = 0
for k,v in pairs(list) do
amnt = amnt + 1
end
local num = 0
for k,v in pairs(list) do
num = num + 1
if v == true then
fs.makeDir(fs.combine(output,k))
else
local file = fs.open(fs.combine(output,k),"w")
if verbose then
write("[")
if term.isColor() then term.setTextColor(colors.lightGray) end
write(k)
term.setTextColor(tx)
write("]")
end
file.write(tablize(v))
file.close()
local tx = term.getTextColor()
if fs.getName(k):lower() == "peasant" then
if term.isColor() then
term.setTextColor(colors.orange)
end
print(" UNBURNINATED")
else
if term.isColor() then
term.setTextColor(colors.green)
end
print(" GOOD")
end
term.setTextColor(tx)
end
end
return 2
end
if not fs.isDir(outpath) then
fs.delete(outpath)
end
local success, res = pcall( function() return doPack(data,outpath,false,true) end )
if not success then
term.setTextColor(colors.white)
print("\n***Something went wrong!***")
return printError(res)
end
if res then
local msgs = {
[2] = "Successfully unpacked '"..fullname.."' to '"..outpath.."/'",
[5] = "You don't have permission.",
}
print(msgs[res])
end