ComputerCraft Archive

xwos

pocket networking unknown forum

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 xwos
wget:wget https://pastebin.com/raw/BLSJGiyt xwos
Archive: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

networkingforumoperating-systems

Source

View Original Source

Code 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