Advertisement
LDDestroier

XWOS Installer (progdor autoextract)

Mar 6th, 2018
367
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 97.57 KB | None | 0 0
  1. local fullname = "XWOS Installer"
  2. local data = {
  3.   [ "/kernel/common/xwos/modules/sandbox/timers.lua" ] = {
  4.     "--    This file is part of xwos.",
  5.     "--",
  6.     "--    xwos is free software: you can redistribute it and/or modify",
  7.     "--    it under the terms of the GNU General Public License as published by",
  8.     "--    the Free Software Foundation, either version 3 of the License, or",
  9.     "--    (at your option) any later version.",
  10.     "--",
  11.     "--    xwos is distributed in the hope that it will be useful,",
  12.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  13.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  14.     "--    GNU General Public License for more details.",
  15.     "--",
  16.     "--    You should have received a copy of the GNU General Public License",
  17.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  18.     "",
  19.     "-----------------------",
  20.     "-- @module xwos.modules.sandbox.timers",
  21.     "local M = {}",
  22.     "",
  23.     "local kernel -- xwos.kernel#xwos.kernel",
  24.     "",
  25.     "-----------------------",
  26.     "-- injects the kernel",
  27.     "-- @function [parent=#xwos.modules.sandbox.timers] setKernel",
  28.     "-- @param xwos.kernel#xwos.kernel k the kernel",
  29.     "M.setKernel = function(k)",
  30.     "    kernel = k",
  31.     "end -- function setKernel",
  32.     "",
  33.     "-------------------------------",
  34.     "-- creates a new timer",
  35.     "-- @function [parent=#xwos.modules.sandbox.timers] new",
  36.     "-- @param #number id the timer number",
  37.     "-- @param xwos.processes#xwos.process proc",
  38.     "-- @return #xwos.timer",
  39.     "M.new = function(id, proc)",
  40.     "    --------------------------------",
  41.     "    -- timer type",
  42.     "    -- @type xwos.timer",
  43.     "    local R = {}",
  44.     "    ",
  45.     "    --------------------------------",
  46.     "    -- @field [parent=#xwos.timer] #number id the timer id",
  47.     "    R.id = id",
  48.     "    ",
  49.     "    --------------------------------",
  50.     "    -- @field [parent=#xwos.timer] #number id the timer id",
  51.     "    R.proc = proc",
  52.     "    ",
  53.     "    --------------------------------",
  54.     "    -- Remove the timer from timer table",
  55.     "    -- @function [parent=#xwos.timer] remove",
  56.     "    R.remove = function()",
  57.     "        M[R.id] = nil",
  58.     "    end -- function remove",
  59.     "    ",
  60.     "    -- TODO remove discarded timers on process termination",
  61.     "    ",
  62.     "    -- store timer",
  63.     "    M[R.id] = R",
  64.     "                    ",
  65.     "    return R",
  66.     "end -- function new",
  67.     "",
  68.     "return M",
  69.   },
  70.   [ "/kernel/common/xwos/modules/security/init.lua" ] = {
  71.     "--    This file is part of xwos.",
  72.     "--",
  73.     "--    xwos is free software: you can redistribute it and/or modify",
  74.     "--    it under the terms of the GNU General Public License as published by",
  75.     "--    the Free Software Foundation, either version 3 of the License, or",
  76.     "--    (at your option) any later version.",
  77.     "--",
  78.     "--    xwos is distributed in the hope that it will be useful,",
  79.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  80.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  81.     "--    GNU General Public License for more details.",
  82.     "--",
  83.     "--    You should have received a copy of the GNU General Public License",
  84.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  85.     "",
  86.     "-----------------------",
  87.     "-- @module xwos.modules.security",
  88.     "local M = {}",
  89.     "",
  90.     "local kernel -- xwos.kernel#xwos.kernel",
  91.     "",
  92.     "local function crProfile(name)",
  93.     "    -----------------------",
  94.     "    -- Security profile",
  95.     "    -- @type secprofile",
  96.     "    local R = {}",
  97.     "    ",
  98.     "    -----------------------",
  99.     "    -- Returns the profile name",
  100.     "    -- @function [parent=#secprofile] name",
  101.     "    -- @return #string profile name",
  102.     "    R.name = function()",
  103.     "        return name",
  104.     "    end -- function name",
  105.     "    ",
  106.     "    -----------------------",
  107.     "    -- Checks if access to given api method is granted",
  108.     "    -- @function [parent=#secprofile] checkApi",
  109.     "    -- @return #string api",
  110.     "    -- @return #string method",
  111.     "    R.checkApi = function(api, method)",
  112.     "        return true -- TODO some meaningful implementation",
  113.     "    end -- function checkApi",
  114.     "    ",
  115.     "    -----------------------",
  116.     "    -- Checks if access to given acl node is granted",
  117.     "    -- @function [parent=#secprofile] checkAccess",
  118.     "    -- @return #string aclKey",
  119.     "    R.checkAccess = function(aclKey)",
  120.     "        return true -- TODO some meaningful implementation",
  121.     "    end -- function checkAccess",
  122.     "    return R",
  123.     "end -- function crProfile",
  124.     "",
  125.     "local profiles = {",
  126.     "    root = crProfile(\"root\"),",
  127.     "    admin = crProfile(\"admin\"),",
  128.     "    user = crProfile(\"user\"),",
  129.     "    guest = crProfile(\"guest\")",
  130.     "}",
  131.     "",
  132.     "---------------------------------",
  133.     "-- @function [parent=#xwos.modules.security] preboot",
  134.     "-- @param xwos.kernel#xwos.kernel k",
  135.     "M.preboot = function(k)",
  136.     "    k.debug(\"preboot security\")",
  137.     "    kernel = k",
  138.     "end -- function preboot",
  139.     "",
  140.     "---------------------------------",
  141.     "-- @function [parent=#xwos.modules.security] boot",
  142.     "-- @param xwos.kernel#xwos.kernel k",
  143.     "M.boot = function(k)",
  144.     "    k.debug(\"boot security\")",
  145.     "end -- function boot",
  146.     "",
  147.     "---------------------------------",
  148.     "-- returns a security profile with given name",
  149.     "-- @function [parent=#xwos.modules.security] profile",
  150.     "-- @param #string name",
  151.     "-- @return #secprofile",
  152.     "M.profile = function(name)",
  153.     "    return profiles[name]",
  154.     "end -- function boot",
  155.     "",
  156.     "---------------------------------",
  157.     "-- Creates a new security profile with given name",
  158.     "-- @function [parent=#xwos.modules.security] profile",
  159.     "-- @param #string name",
  160.     "-- @return #secprofile",
  161.     "M.createProfile = function(name)",
  162.     "    -- TODO some meaningful implementation",
  163.     "    local res = profiles[name]",
  164.     "    if res == nil then",
  165.     "        res = crProfile(name)",
  166.     "        profiles[name] = res",
  167.     "    end -- if profile",
  168.     "    return res",
  169.     "end -- function createProfile",
  170.     "",
  171.     "return M",
  172.   },
  173.   [ "/kernel/common/xwos/modules/sandbox/evqueue.lua" ] = {
  174.     "--    This file is part of xwos.",
  175.     "--",
  176.     "--    xwos is free software: you can redistribute it and/or modify",
  177.     "--    it under the terms of the GNU General Public License as published by",
  178.     "--    the Free Software Foundation, either version 3 of the License, or",
  179.     "--    (at your option) any later version.",
  180.     "--",
  181.     "--    xwos is distributed in the hope that it will be useful,",
  182.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  183.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  184.     "--    GNU General Public License for more details.",
  185.     "--",
  186.     "--    You should have received a copy of the GNU General Public License",
  187.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  188.     "",
  189.     "-----------------------",
  190.     "-- @module xwos.modules.sandbox.evqueue",
  191.     "local M = {}",
  192.     "",
  193.     "local kernel -- xwos.kernel#xwos.kernel",
  194.     "",
  195.     "local originsert = table.insert",
  196.     "",
  197.     "-----------------------",
  198.     "-- injects the kernel",
  199.     "-- @function [parent=#xwos.modules.sandbox.evqueue] setKernel",
  200.     "-- @param xwos.kernel#xwos.kernel k the kernel",
  201.     "M.setKernel = function(k)",
  202.     "    kernel = k",
  203.     "end -- function setKernel",
  204.     "",
  205.     "-----------------------",
  206.     "-- Process and distribute event from event queue (part of pullEvent etc.)",
  207.     "-- @function [parent=#xwos.modules.sandbox.evqueue] processEvt",
  208.     "-- @param #number lpid the local pid for logging",
  209.     "-- @param xwos.process#xwos.process proc the process invoking this method; may be nil for kernel process",
  210.     "-- @param #table event the event to deliver",
  211.     "-- @param #string filter optional filter passed to pullEvent",
  212.     "M.processEvt = function(lpid, proc, event, filter)",
  213.     "    if event[1] == nil then",
  214.     "        return nil",
  215.     "    end -- if event",
  216.     "    kernel.debug(\"[PID\"..lpid..\"] got event \", kernel.oldGlob.unpack(event))",
  217.     "    ",
  218.     "    if kernel.eventLog then",
  219.     "        -- TODO are we able to pass non serializable data through events?",
  220.     "        -- this may cause problems at this point",
  221.     "        local str = kernel.oldGlob.os.day() .. \"-\" .. kernel.oldGlob.os.time() \" EVENT: \".. kernel.oldGlob.textutils.serialize(event)",
  222.     "        local f = kernel.oldGlob.fs.open(\"/core/log/event-log.txt\", kernel.oldGlob.fs.exists(\"/core/log/event-log.txt\") and \"a\" or \"w\")",
  223.     "        f.writeLine(str)",
  224.     "        f.close()",
  225.     "    end -- if eventLog",
  226.     "    ",
  227.     "    local consumed = false",
  228.     "    ",
  229.     "    if event[1] == \"timer\" then",
  230.     "        local timer = kernel.modules.instances.sandbox.timers[event[2]]",
  231.     "        if timer ~= nil then",
  232.     "            if timer.proc == proc then",
  233.     "                if filter == nil or event[1]==filter then",
  234.     "                    kernel.debug(\"[PID\"..lpid..\"] returning event \", kernel.oldGlob.unpack(event))",
  235.     "                    return event",
  236.     "                else -- if filter",
  237.     "                    kernel.debug(\"[PID\"..lpid..\"] discard event because of filter\", kernel.oldGlob.unpack(event))",
  238.     "                    consumed = true",
  239.     "                end -- if filter",
  240.     "            else -- if proc",
  241.     "                kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to pid \"..timer.proc.pid, kernel.oldGlob.unpack(event))",
  242.     "                originsert(timer.proc.evqueue, event)",
  243.     "                timer.proc.wakeup()",
  244.     "                consumed = true",
  245.     "            end -- if not proc",
  246.     "        end -- if timer",
  247.     "        -- fallthrough: distribute unknown timer event to all processes",
  248.     "    end -- if timer",
  249.     "    ",
  250.     "    if event[1] == \"xwos_wakeup\" then",
  251.     "        consumed = true",
  252.     "        kernel.debug(\"[PID\"..lpid..\"] wakeup received\")",
  253.     "        if event[2] ~= lpid then",
  254.     "            kernel.debug(\"[PID\"..lpid..\"] wrong pid, redistribute\")",
  255.     "            kernel.oldGlob.os.queueEvent(kernel.oldGlob.unpack(event))",
  256.     "        end -- if pid",
  257.     "    end -- if xwos_wakeup",
  258.     "    ",
  259.     "    if event[1] == \"xwos_terminate\" then",
  260.     "        consumed = true",
  261.     "        kernel.debug(\"[PID\"..lpid..\"] terminate received\")",
  262.     "        if event[2] ~= lpid then",
  263.     "            kernel.debug(\"[PID\"..lpid..\"] wrong pid, redistribute\")",
  264.     "            kernel.oldGlob.os.queueEvent(kernel.oldGlob.unpack(event))",
  265.     "        else -- if pid",
  266.     "            kernel.oldGlob.error('requesting process termination')",
  267.     "        end -- if pid",
  268.     "    end -- if xwos_terminate",
  269.     "    ",
  270.     "    if event[1] == \"xwos_terminated\" then",
  271.     "        consumed = true",
  272.     "        kernel.debug(\"[PID\"..lpid..\"] terminated received\")",
  273.     "        if filter == \"xwos_terminated\" then",
  274.     "            kernel.debug(\"[PID\"..lpid..\"] returning event \", kernel.oldGlob.unpack(event))",
  275.     "            return event",
  276.     "        end -- if filter",
  277.     "        for k, v in kernel.oldGlob.pairs(kernel.processes) do",
  278.     "            if kernel.oldGlob.type(v) == \"table\" and v.pid == event[2] and v.joined > 0 then",
  279.     "                kernel.debug(\"[PID\"..lpid..\"] redistributing to all other processes because at least one process called join of \"..v.pid)",
  280.     "                        ",
  281.     "                for k2, v2 in kernel.oldGlob.pairs(kernel.processes) do",
  282.     "                    if kernel.oldGlob.type(v2) == \"table\" and v2 ~= proc and v2.procstate~= \"finished\" then",
  283.     "                        kernel.debug(\"[PID\"..lpid..\"] redistributing because at least one process called join of \"..v2.pid)",
  284.     "                        originsert(v2.evqueue, event)",
  285.     "                        v2.wakeup()",
  286.     "                    end --",
  287.     "                end -- for processes",
  288.     "            end --",
  289.     "        end -- for processes",
  290.     "    end -- if xwos_terminated",
  291.     "    ",
  292.     "    if event[1] == \"char\" or event[1] == \"key\" or event[1] == \"paste\" or event[1] == \"key_up\" then",
  293.     "        consumed = true",
  294.     "        kernel.debug(\"[PID\"..lpid..\"] user input received\")",
  295.     "        if kernel.modules.instances.sandbox.procinput.current.proc ~= nil then",
  296.     "            kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to user input pid \"..kernel.modules.instances.sandbox.procinput.current.proc.pid)",
  297.     "            originsert(kernel.modules.instances.sandbox.procinput.current.proc.evqueue, event)",
  298.     "            kernel.modules.instances.sandbox.procinput.current.proc.wakeup()",
  299.     "        else",
  300.     "            -- TODO what to do with input if no one likes it?",
  301.     "            -- think about special key bindings fetched from background processes",
  302.     "            -- currently we silently discard that kind of input",
  303.     "        end -- ",
  304.     "    end -- if char",
  305.     "    ",
  306.     "    -- distribute event to all processes",
  307.     "    if not consumed then",
  308.     "        for k, v in kernel.oldGlob.pairs(kernel.processes) do",
  309.     "            if kernel.oldGlob.type(v) == \"table\" and v.procstate ~= \"finished\" then",
  310.     "                kernel.debug(\"[PID\"..lpid..\"] queue event for distribution to all pids \"..v.pid, kernel.oldGlob.unpack(event))",
  311.     "                originsert(v.evqueue, event)",
  312.     "                v.wakeup()",
  313.     "            end -- if not finished",
  314.     "        end -- for processes",
  315.     "    end -- if consumed",
  316.     "    ",
  317.     "    return nil",
  318.     "end -- function processEvt",
  319.     "",
  320.     "return M",
  321.   },
  322.   [ "/kernel/common/xwos/test2.lua" ] = {
  323.     "--    This file is part of xwos.",
  324.     "--",
  325.     "--    xwos is free software: you can redistribute it and/or modify",
  326.     "--    it under the terms of the GNU General Public License as published by",
  327.     "--    the Free Software Foundation, either version 3 of the License, or",
  328.     "--    (at your option) any later version.",
  329.     "--",
  330.     "--    xwos is distributed in the hope that it will be useful,",
  331.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  332.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  333.     "--    GNU General Public License for more details.",
  334.     "--",
  335.     "--    You should have received a copy of the GNU General Public License",
  336.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  337.     "",
  338.     "local a = function()",
  339.     "            print(\"a\")",
  340.     "        end",
  341.     "        a()",
  342.   },
  343.   [ "/kernel/common/xwos/test.lua" ] = {
  344.     "--    This file is part of xwos.",
  345.     "--",
  346.     "--    xwos is free software: you can redistribute it and/or modify",
  347.     "--    it under the terms of the GNU General Public License as published by",
  348.     "--    the Free Software Foundation, either version 3 of the License, or",
  349.     "--    (at your option) any later version.",
  350.     "--",
  351.     "--    xwos is distributed in the hope that it will be useful,",
  352.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  353.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  354.     "--    GNU General Public License for more details.",
  355.     "--",
  356.     "--    You should have received a copy of the GNU General Public License",
  357.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  358.     "",
  359.     "require('/rom/xwos/kernel/common/xwos/test2')",
  360.     "        print(\"foo\")",
  361.   },
  362.   [ "/kernel/common/xwos/modulesmgr.lua" ] = {
  363.     "--    This file is part of xwos.",
  364.     "--",
  365.     "--    xwos is free software: you can redistribute it and/or modify",
  366.     "--    it under the terms of the GNU General Public License as published by",
  367.     "--    the Free Software Foundation, either version 3 of the License, or",
  368.     "--    (at your option) any later version.",
  369.     "--",
  370.     "--    xwos is distributed in the hope that it will be useful,",
  371.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  372.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  373.     "--    GNU General Public License for more details.",
  374.     "--",
  375.     "--    You should have received a copy of the GNU General Public License",
  376.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  377.     "",
  378.     "local kernel -- xwos.kernel#xwos.kernel",
  379.     "local moduleOrder = {}",
  380.     "",
  381.     "--------------------------------",
  382.     "-- local kernel modules",
  383.     "-- @type xwos.modulesmgr",
  384.     "local M = {}",
  385.     "",
  386.     "-------------------------------",
  387.     "-- the module instances",
  388.     "-- @type xwos.modulesmgr.instances",
  389.     "-- @field [parent=#xwos.modulesmgr] #xwos.modulesmgr.instances instances",
  390.     "M.instances = {}",
  391.     "",
  392.     "-------------------------------",
  393.     "-- sandbox kernel module",
  394.     "-- @field [parent=#xwos.modulesmgr.instances] xwos.modulesmgr.sandbox#xwos.modulesmgr.sandbox sandbox",
  395.     "",
  396.     "-------------------------------",
  397.     "-- security kernel module",
  398.     "-- @field [parent=#xwos.modulesmgr.instances] xwos.modulesmgr.security#xwos.modulesmgr.security security",
  399.     "",
  400.     "--------------------------------",
  401.     "-- @function [parent=#xwos.modulesmgr] preboot",
  402.     "-- @param xwos.kernel#xwos.kernel k the kernel",
  403.     "M.preboot = function(k)",
  404.     "    kernel = k",
  405.     "    -- load settings with kernel module boot order",
  406.     "    moduleOrder = kernel.require(\"moduleOrder\")",
  407.     "    -- helper to load kernel modules from given directory",
  408.     "    local loadKernelModules = function(dir)",
  409.     "        local path = dir .. \"/xwos/modules\"",
  410.     "        kernel.debug(\"loading kernel modules from \" .. path)",
  411.     "        if kernel.oldGlob.fs.isDir(path) then",
  412.     "            for i, v in kernel.oldGlob.pairs(kernel.oldGlob.fs.list(path)) do",
  413.     "                kernel.debug(\"loading kernel module from \" .. path .. \"/\" .. v)",
  414.     "                M.instances[v] = kernel.oldGlob.require(path .. \"/\" .. v)",
  415.     "            end -- for list",
  416.     "        end -- if isdir",
  417.     "    end --  function loadKernelModules",
  418.     "  ",
  419.     "    -- load kernel modules",
  420.     "    for k, v in kernel.oldGlob.pairs(kernel.kernelpaths) do",
  421.     "        loadKernelModules(v)",
  422.     "    end -- for kernelpaths",
  423.     "",
  424.     "    for i, v in pairs(moduleOrder) do",
  425.     "        if M.instances[v] ~= nil then",
  426.     "            kernel.debug(\"preboot kernel module\",v)",
  427.     "            M.instances[v].preboot(kernel)",
  428.     "        end -- if exists",
  429.     "    end -- for moduleOrder",
  430.     "    for i, v in pairs(M.instances) do",
  431.     "        if not table.contains(moduleOrder, i) then",
  432.     "            kernel.debug(\"preboot kernel module\",v)",
  433.     "            v.preboot(kernel)",
  434.     "        end -- if not contains",
  435.     "    end -- for modules",
  436.     "end -- function preboot",
  437.     "",
  438.     "--------------------------------",
  439.     "-- @function [parent=#xwos.modulesmgr] boot",
  440.     "-- @param xwos.kernel#xwos.kernel k the kernel",
  441.     "M.boot = function(k)",
  442.     "    for i, v in pairs(moduleOrder) do",
  443.     "        if M.instances[v] ~= nil then",
  444.     "            kernel.debug(\"boot kernel module\",v)",
  445.     "            M.instances[v].boot(kernel)",
  446.     "        end -- if exists",
  447.     "    end -- for moduleOrder",
  448.     "    for i, v in pairs(M.instances) do",
  449.     "        if not table.contains(moduleOrder, i) then",
  450.     "            kernel.debug(\"boot kernel module\",v)",
  451.     "            v.boot(kernel)",
  452.     "        end -- if not contains",
  453.     "    end -- for modules",
  454.     "end -- function preboot",
  455.     "",
  456.     "return M",
  457.   },
  458.   [ "/kernel/common/xwos/startup.lua" ] = {
  459.     "--    This file is part of xwos.",
  460.     "--",
  461.     "--    xwos is free software: you can redistribute it and/or modify",
  462.     "--    it under the terms of the GNU General Public License as published by",
  463.     "--    the Free Software Foundation, either version 3 of the License, or",
  464.     "--    (at your option) any later version.",
  465.     "--",
  466.     "--    xwos is distributed in the hope that it will be useful,",
  467.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  468.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  469.     "--    GNU General Public License for more details.",
  470.     "--",
  471.     "--    You should have received a copy of the GNU General Public License",
  472.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  473.     "",
  474.     "--------------------------------",
  475.     "-- Default startup script",
  476.     "-- @module xwos.startup",
  477.     "local M = {}",
  478.     "",
  479.     "-------------------",
  480.     "-- The installer",
  481.     "-- @function [parent=#xwos.startup] run",
  482.     "-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
  483.     "M.installer = function(kernel)",
  484.     "    local installerData = { lang = nil }",
  485.     "    print()",
  486.     "    print(\"starting installer...\")",
  487.     "    ",
  488.     "    kernel.print(\"read: \", read)",
  489.     "    kernel.print(\"read0: \", getfenv(0).read)",
  490.     "    kernel.print(\"read1: \", getfenv(1).read)",
  491.     "    kernel.print(\"read6: \", getfenv(6).read)",
  492.     "    kernel.print(\"read7: \", getfenv(7).read)",
  493.     "    kernel.print(\"read8: \", getfenv(8).read)",
  494.     "    print()",
  495.     "    print(\"********* XW-OS ********** INSTALLER\")",
  496.     "    local langs = {",
  497.     "        \"en\" -- TODO support language packs",
  498.     "    }",
  499.     "    while installerData.lang == nil do",
  500.     "      print(\"\")",
  501.     "      print(\"Choose your language:\")",
  502.     "      local input = read()",
  503.     "      if table.contains(langs, input) then",
  504.     "          installerData.lang = input",
  505.     "      else -- if contains",
  506.     "          print(\"Invalid language. Currently supported: \")",
  507.     "          for k, v in pairs(langs) do",
  508.     "              write(v)",
  509.     "              write(\" \")",
  510.     "          end -- for langs",
  511.     "          print(\"\")",
  512.     "      end -- if not contains",
  513.     "    end -- while not lang",
  514.     "    ",
  515.     "    local admin = {}",
  516.     "    print(\"\")",
  517.     "    print(\"Enter your administrators email address:\")",
  518.     "    admin.mail = read()",
  519.     "    print(\"\")",
  520.     "    print(\"Enter your administrators login name:\")",
  521.     "    admin.login = read()",
  522.     "    while admin.pass == nil do",
  523.     "        print(\"\")",
  524.     "        print(\"Enter your administrators password:\")",
  525.     "        local pass1 = read()",
  526.     "        print(\"\")",
  527.     "        print(\"Retype your administrators password:\")",
  528.     "        local pass2 = read()",
  529.     "        ",
  530.     "        if pass1 ~= pass2 then",
  531.     "            print(\"\")",
  532.     "            print(\"The passwords do not match...\")",
  533.     "        else -- if not pass equals",
  534.     "            admin.pass = pass1",
  535.     "        end -- if pass equals",
  536.     "    end -- while not pass",
  537.     "    ",
  538.     "    local user = {}",
  539.     "    print(\"\")",
  540.     "    print(\"Enter your users email address:\")",
  541.     "    user.mail = read()",
  542.     "    print(\"\")",
  543.     "    print(\"Enter your users login name:\")",
  544.     "    user.login = read()",
  545.     "    while user.pass == nil do",
  546.     "        print(\"\")",
  547.     "        print(\"Enter your users password:\")",
  548.     "        local pass1 = read()",
  549.     "        print(\"\")",
  550.     "        print(\"Retype your users password:\")",
  551.     "        local pass2 = read()",
  552.     "        ",
  553.     "        if pass1 ~= pass2 then",
  554.     "            print(\"\")",
  555.     "            print(\"The passwords do not match...\")",
  556.     "        else -- if not pass equals",
  557.     "            user.pass = pass1",
  558.     "        end -- if pass equals",
  559.     "    end -- while not pass",
  560.     "    ",
  561.     "    print(\"\")",
  562.     "    print(\"\")",
  563.     "    print(\"***** starting installation\")",
  564.     "    print(\"\")",
  565.     "    print(\"Creating root...\")",
  566.     "    local proot = kernel.modules.security.createProfile(\"root\")",
  567.     "    print(\"Creating administrator...\")",
  568.     "    local padmin = kernel.modules.security.createProfile(\"admin\")",
  569.     "    print(\"Creating user...\")",
  570.     "    local puser = kernel.modules.security.createProfile(\"user\")",
  571.     "    print(\"Creating guest (inactive)...\")",
  572.     "    local pguest = kernel.modules.security.createProfile(\"guest\")",
  573.     "    ",
  574.     "    -- TODO start gui on primary terminal",
  575.     "    -- TODO create a wizard",
  576.     "    ",
  577.     "    -- TODO failing installer should set kernel.shutdown = true",
  578.     "    ",
  579.     "    kernel.writeSecureData('core/install.dat', textutils.serialize(installerData))",
  580.     "end -- function installer",
  581.     "",
  582.     "-------------------",
  583.     "-- The login processing",
  584.     "-- @function [parent=#xwos.startup] run",
  585.     "-- @param #string installData",
  586.     "-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
  587.     "M.login = function(installData, kernel)",
  588.     "    print()",
  589.     "    print(\"starting login...\")",
  590.     "    ",
  591.     "    -- for gui see http://harryfelton.web44.net/titanium/guide/download",
  592.     "    -- lua minifier: https://gitlab.com/hbomb79/Titanium/blob/develop/bin/Minify.lua",
  593.     "    ",
  594.     "    -- TODO start gui on primary terminal",
  595.     "end -- function installer",
  596.     "",
  597.     "-------------------",
  598.     "-- Startup processing script",
  599.     "-- @function [parent=#xwos.startup] run",
  600.     "-- @param xwos.kernel#xwos.kernel kernel the kernel reference",
  601.     "M.run = function(kernel)",
  602.     "    local installData = kernel.readSecureData('core/install.dat')",
  603.     "    kernel.debug(\"[start] checking installation\")",
  604.     "    if installData == nil then",
  605.     "        kernel.debug(\"[start] starting installer\")",
  606.     "        M.installer(kernel)",
  607.     "    end -- if not installed",
  608.     "    ",
  609.     "    while not kernel.shutdown do",
  610.     "        kernel.debug(\"[start] starting login\")",
  611.     "        M.login(textutils.unserialize(installData), kernel)",
  612.     "    end -- while not shutdown",
  613.     "end -- function run",
  614.     "",
  615.     "return M",
  616.   },
  617.   [ "/kernel/1/8/moduleOrder.lua" ] = {
  618.     "--    This file is part of xwos.",
  619.     "--",
  620.     "--    xwos is free software: you can redistribute it and/or modify",
  621.     "--    it under the terms of the GNU General Public License as published by",
  622.     "--    the Free Software Foundation, either version 3 of the License, or",
  623.     "--    (at your option) any later version.",
  624.     "--",
  625.     "--    xwos is distributed in the hope that it will be useful,",
  626.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  627.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  628.     "--    GNU General Public License for more details.",
  629.     "--",
  630.     "--    You should have received a copy of the GNU General Public License",
  631.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  632.     "",
  633.     "return {",
  634.     " \"sandbox\",",
  635.     " \"security\"",
  636.     "}",
  637.   },
  638.   [ "/kernel/common/xwos/kernel.lua" ] = {
  639.     "--    This file is part of xwos.",
  640.     "--",
  641.     "--    xwos is free software: you can redistribute it and/or modify",
  642.     "--    it under the terms of the GNU General Public License as published by",
  643.     "--    the Free Software Foundation, either version 3 of the License, or",
  644.     "--    (at your option) any later version.",
  645.     "--",
  646.     "--    xwos is distributed in the hope that it will be useful,",
  647.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  648.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  649.     "--    GNU General Public License for more details.",
  650.     "--",
  651.     "--    You should have received a copy of the GNU General Public License",
  652.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  653.     "",
  654.     "local origGetfenv = getfenv",
  655.     "local origSetfenv = setfenv",
  656.     "local origsetmeta = setmetatable",
  657.     "local origtype = type",
  658.     "local origpairs = pairs",
  659.     "local origload = load",
  660.     "local origpcall = pcall",
  661.     "local origprint = print",
  662.     "local origtostring = tostring",
  663.     "",
  664.     "local origTable = table",
  665.     "table = {}",
  666.     "for k,v in origpairs(origTable) do",
  667.     "    table[k] = v",
  668.     "end -- for table",
  669.     "",
  670.     "-------------------------------------",
  671.     "-- Creates a new clone; only first level of table will be cloned, no deep clone; no metadata clone",
  672.     "-- @function [parent=#table] clone",
  673.     "-- @param #table src",
  674.     "-- @return #table new copy",
  675.     "table.clone = function(src)",
  676.     "    local r = {}",
  677.     "    for k, v in origpairs(src) do",
  678.     "        r[k] = v",
  679.     "    end -- for src",
  680.     "    return r",
  681.     "end -- function table.clone",
  682.     "",
  683.     "-------------------------------------",
  684.     "-- @function [parent=#table] contains",
  685.     "-- @param #table haystack",
  686.     "-- @param #any needle",
  687.     "-- @return #boolean success",
  688.     "table.contains = function(haystack, needle)",
  689.     "    for k, v in origpairs(haystack) do",
  690.     "        if (v == needle) then",
  691.     "            return true",
  692.     "        end -- if equals",
  693.     "    end -- for haystack",
  694.     "    return false",
  695.     "end -- function table.contains",
  696.     "",
  697.     "-------------------------------------",
  698.     "-- @function [parent=#table] indexOf",
  699.     "-- @param #table haystack",
  700.     "-- @param #any needle",
  701.     "-- @return #number index of given element or nil if not found",
  702.     "table.indexOf = function(haystack, needle)",
  703.     "    for k, v in origpairs(haystack) do",
  704.     "        if (v == needle) then",
  705.     "            return k",
  706.     "        end -- if equals",
  707.     "    end -- for haystack",
  708.     "    return nil",
  709.     "end -- function table.indexOf",
  710.     "",
  711.     "-------------------------------------",
  712.     "-- @function [parent=#table] removeValue",
  713.     "-- @param #table haystack",
  714.     "-- @param #any needle",
  715.     "-- @return #boolean true if element was found and removed",
  716.     "table.removeValue = function(haystack, needle)",
  717.     "    for k, v in origpairs(haystack) do",
  718.     "        if (v == needle) then",
  719.     "            haystack[k] = nil",
  720.     "            return true",
  721.     "        end -- if equals",
  722.     "    end -- for haystack",
  723.     "    return false",
  724.     "end -- function table.removeValue",
  725.     "",
  726.     "-------------------------------------",
  727.     "-- @function [parent=#table] containsKey",
  728.     "-- @param #table haystack",
  729.     "-- @param #any needle",
  730.     "-- @return #boolean success",
  731.     "table.containsKey = function(haystack, needle)",
  732.     "    return haystack[needle] ~= nil",
  733.     "end -- function table.containsKey",
  734.     "",
  735.     "--------------------------------",
  736.     "-- local kernel",
  737.     "-- @type xwos.kernel",
  738.     "local M = {}",
  739.     "",
  740.     "local bootSequence = {",
  741.     "    debug = function()",
  742.     "        M.kernelDebug = true",
  743.     "        M.print(\"activating kernel debug mode...\")",
  744.     "    end, -- function debug",
  745.     "    ",
  746.     "    eventLog = function()",
  747.     "        M.eventLog = true",
  748.     "        M.print(\"activating kernel event log...\")",
  749.     "    end -- function eventLog",
  750.     "}",
  751.     "",
  752.     "--------------------------------",
  753.     "-- Boot kernel",
  754.     "-- @function [parent=#xwos.kernel] boot",
  755.     "-- @param #string ver kernel version number",
  756.     "-- @param #table kernelpaths the paths to look for kernel files",
  757.     "-- @param #function krequire require function to include kernel files",
  758.     "-- @param global#global args the command line arguments",
  759.     "M.boot = function(ver, kernelpaths, krequire, oldGlob, args)",
  760.     "    --------------------------------",
  761.     "    -- @field [parent=#xwos.kernel] #table kernelpaths the paths for including kernel",
  762.     "    M.kernelpaths = kernelpaths",
  763.     "    --------------------------------",
  764.     "    -- @field [parent=#xwos.kernel] #string version the kernel version",
  765.     "    M.version = ver",
  766.     "    --------------------------------",
  767.     "    -- @field [parent=#xwos.kernel] #table the built in environment factories (installed from modules)",
  768.     "    M.envFactories = {}",
  769.     "    --------------------------------",
  770.     "    -- @field [parent=#xwos.kernel] global#global oldGlob the old globals",
  771.     "    M.oldGlob = oldGlob -- TODO type (global#global) does not work?",
  772.     "    M.oldGlob._ENV = nil",
  773.     "    --M.oldGlob.package = nil",
  774.     "    M.oldGlob._G = nil",
  775.     "    M.oldGlob.shell = nil",
  776.     "    M.oldGlob.multishell = nil",
  777.     "    --------------------------------",
  778.     "    -- @field [parent=#xwos.kernel] #table args the command line args invoking the kernel",
  779.     "    M.args = args or {}",
  780.     "",
  781.     "    -------------------------------",
  782.     "    -- @field [parent=#xwos.kernel] #boolean kernelDebug true for kernel debugging; activated through script invocation/argument (\"xwos debug\")",
  783.     "    M.kernelDebug = false",
  784.     "",
  785.     "    -------------------------------",
  786.     "    -- @field [parent=#xwos.kernel] #boolean eventLog true for event logging; activated through script invocation/argument (\"xwos eventLog\")",
  787.     "    M.eventLog = false",
  788.     "    ",
  789.     "    -- parse arguments",
  790.     "    for i, v in origpairs(M.args) do",
  791.     "        if bootSequence[v] ~= nil then",
  792.     "            bootSequence[v]()",
  793.     "        else -- exists",
  794.     "            M.print(\"Ignoring unknown argument \" .. v)",
  795.     "        end -- not exists",
  796.     "    end -- for arg",
  797.     "    ",
  798.     "    --------------------------------",
  799.     "    -- Require for kernel scripts",
  800.     "    -- @function [parent=#xwos.kernel] require",
  801.     "    -- @param #string path the path",
  802.     "    M.require = krequire",
  803.     "    ",
  804.     "    M.debug(\"loading process management\")",
  805.     "    --------------------------------",
  806.     "    -- @field [parent=#xwos.kernel] xwos.processes#xwos.processes processes the known xwos processes",
  807.     "    M.processes = M.require('xwos/processes')",
  808.     "    ",
  809.     "    M.debug(\"loading module management\")",
  810.     "    --------------------------------",
  811.     "    -- @field [parent=#xwos.kernel] xwos.modulesmgr#xwos.modulesmgr modules the kernel modules",
  812.     "    M.modules = M.require('xwos/modulesmgr')",
  813.     "    ",
  814.     "    M.debug(\"booting modules\")",
  815.     "    M.modules.preboot(M)",
  816.     "    M.modules.boot(M)",
  817.     "    ",
  818.     "    --------------------------------",
  819.     "    -- @field [parent=#xwos.kernel] #global nenv the new environment for processes",
  820.     "    M.nenv = {}",
  821.     "    M.debug(\"preparing sandbox for root process\", M.nenv)",
  822.     "    local nenvmt = {",
  823.     "        __index = function(table, key)",
  824.     "            local e = origGetfenv(0)",
  825.     "            if (e == M.nenv) then return nil end",
  826.     "            return e[key]",
  827.     "        end -- function __index",
  828.     "    }",
  829.     "    origsetmeta(M.nenv, nenvmt)",
  830.     "    origSetfenv(nenvmt.__index, M.nenv)",
  831.     "    local function wrapfenv(table, env, blacklist)",
  832.     "        local R = {}",
  833.     "        for k,v in origpairs(table) do",
  834.     "            local t = origtype(v)",
  835.     "            if t == \"function\" then",
  836.     "                if blacklist[k] == nil then",
  837.     "                    R[k] = origGetfenv(v)",
  838.     "                    -- print(\"setfenv\", k, R[k])",
  839.     "                    origpcall(origSetfenv, v, env) -- pcall because changing internal functions will fail (silently ingore it)",
  840.     "                end -- if blacklist",
  841.     "            end -- if function",
  842.     "            if t == \"table\" and blacklist[k] ~= \"*\" then",
  843.     "                -- print(\"setfenv table \", k)",
  844.     "                R[k] = wrapfenv(v, env, blacklist[k] or {})",
  845.     "            end -- if table",
  846.     "        end -- for table",
  847.     "        return R",
  848.     "    end -- function wrapfenv",
  849.     "    --------------------------------",
  850.     "    -- @field [parent=#xwos.kernel] #table oldfenv the old fenv for global functions",
  851.     "    M.oldfenv = wrapfenv(oldGlob, M.nenv, {",
  852.     "        getfenv=true,",
  853.     "        setfenv=true,",
  854.     "        shell={run=true, clearAlias=true, dir=true, getRunningProgram=true},",
  855.     "        package=\"*\",",
  856.     "        bit32={bxor=true},",
  857.     "        redstone={getBundledOutput=true}",
  858.     "    })",
  859.     "    M.debug(\"boot finished\")",
  860.     "end -- function boot",
  861.     "",
  862.     "--------------------------------",
  863.     "-- Startup xwos",
  864.     "-- @function [parent=#xwos.kernel] startup",
  865.     "M.startup = function()",
  866.     "    local nenv = {}",
  867.     "    M.debug(\"preparing new environment for root process\", nenv)",
  868.     "    for k,v in origpairs(M.oldGlob) do",
  869.     "        nenv[k] = v",
  870.     "    end -- for oldGlob",
  871.     "    nenv.print = function(...) -- TODO remove",
  872.     "        M.oldGlob.print(\"->\", ...)",
  873.     "    end -- function print",
  874.     "    ",
  875.     "    M.debug(\"creating root process\")",
  876.     "    local proc = M.processes.new(nil, M, nenv, M.envFactories) -- TODO factories from root profile (per profile factories)",
  877.     "    local startupData = M.readSecureData('core/startup.dat', \"/rom/xwos/kernel/common/xwos/testsleep.lua\") -- TODO startup script",
  878.     "    M.debug(\"spawning thread with startup script \" .. startupData)",
  879.     "    proc.spawn(startupData)",
  880.     "    proc.join(nil)",
  881.     "    ",
  882.     "    M.debug(\"cleanup root process sandbox\")",
  883.     "    -- cleanup",
  884.     "    local function unwrapfenv(table, old)",
  885.     "        for k,v in origpairs(table) do",
  886.     "            local t = origtype(v)",
  887.     "            if old[k] ~= nil then",
  888.     "                if t == \"function\" then",
  889.     "                    -- print(\"setfenv\", k, old[k])",
  890.     "                    origpcall(origSetfenv, v, old[k]) -- pcall because changing internal functions will fail (silently ingore it)",
  891.     "                end -- if function",
  892.     "                if t == \"table\" then",
  893.     "                    unwrapfenv(v, old[k])",
  894.     "                end -- if table",
  895.     "            end -- if old",
  896.     "        end -- for table",
  897.     "    end -- function unwrapfenv",
  898.     "    unwrapfenv(M.oldGlob, M.oldfenv)",
  899.     "    ",
  900.     "    table = origTable",
  901.     "    ",
  902.     "    M.debug(\"last actions before shutdown\")",
  903.     "    if proc.result[1] then",
  904.     "        origprint(\"Good bye...\")",
  905.     "    else -- if result",
  906.     "        origprint(\"ERR: \", proc.result[2])",
  907.     "    end -- if result",
  908.     "end -- function startup",
  909.     "",
  910.     "-------------------------------",
  911.     "-- debug log message",
  912.     "-- @function [parent=#xwos.kernel] debug",
  913.     "-- @param ... print message arguments",
  914.     "M.debug = function(...)",
  915.     "    if M.kernelDebug then",
  916.     "        M.print(...)",
  917.     "    end -- if kernelDebug",
  918.     "end -- function debug",
  919.     "",
  920.     "-------------------------------",
  921.     "-- print info message",
  922.     "-- @function [parent=#xwos.kernel] print",
  923.     "-- @param ... print message arguments",
  924.     "M.print = function(...)",
  925.     "    M.oldGlob.print(...) -- TODO wrap to kernel display",
  926.     "    if (M.kernelDebug) then",
  927.     "        local f = M.oldGlob.fs.open(\"/core/log/debug-log.txt\", M.oldGlob.fs.exists(\"/core/log/debug-log.txt\") and \"a\" or \"w\")",
  928.     "        local str = M.oldGlob.os.day()..\"-\"..M.oldGlob.os.time()..\" \"",
  929.     "        for k, v in origpairs({...}) do",
  930.     "            str = str .. origtostring(v) .. \" \"",
  931.     "        end -- for ...",
  932.     "        f.writeLine(str)",
  933.     "        f.close()",
  934.     "    end -- if kernelDebug",
  935.     "end -- function print",
  936.     "",
  937.     "-------------------------------",
  938.     "-- read data file from secured kernel storage",
  939.     "-- @function [parent=#xwos.kernel] readSecureData",
  940.     "-- @param #string path the file to read",
  941.     "-- @param #string def optional default data",
  942.     "-- @return #string the file content or nil if file does not exist",
  943.     "M.readSecureData = function(path, def)",
  944.     "    local f = \"/xwos/private/\" .. path",
  945.     "    if not M.oldGlob.fs.exists(f) then",
  946.     "        return def",
  947.     "    end -- if not exists",
  948.     "    local h = M.oldGlob.fs.open(f, \"r\")",
  949.     "    local res = h.readall()",
  950.     "    h.close()",
  951.     "    return res",
  952.     "end -- function readSecureData",
  953.     "",
  954.     "-------------------------------",
  955.     "-- write data file to secured kernel storage",
  956.     "-- @function [parent=#xwos.kernel] writeSecureData",
  957.     "-- @param #string path the file to write",
  958.     "-- @param #string data new data",
  959.     "M.writeSecureData = function(path, data)",
  960.     "    local f = \"/xwos/private/\" .. path",
  961.     "    local h = M.oldGlob.fs.open(f, \"w\")",
  962.     "    h.write(data)",
  963.     "    h.close()",
  964.     "end -- function readSecureData",
  965.     "",
  966.     "return M",
  967.   },
  968.   [ "/kernel/common/xwos/modules/sandbox/procinput.lua" ] = {
  969.     "--    This file is part of xwos.",
  970.     "--",
  971.     "--    xwos is free software: you can redistribute it and/or modify",
  972.     "--    it under the terms of the GNU General Public License as published by",
  973.     "--    the Free Software Foundation, either version 3 of the License, or",
  974.     "--    (at your option) any later version.",
  975.     "--",
  976.     "--    xwos is distributed in the hope that it will be useful,",
  977.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  978.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  979.     "--    GNU General Public License for more details.",
  980.     "--",
  981.     "--    You should have received a copy of the GNU General Public License",
  982.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  983.     "",
  984.     "-----------------------",
  985.     "-- @module xwos.modules.sandbox.procinput",
  986.     "local M = {}",
  987.     "",
  988.     "local kernel -- xwos.kernel#xwos.kernel",
  989.     "",
  990.     "-- TODO refactor following to some linked stack type",
  991.     "-----------------------",
  992.     "-- @type pinput",
  993.     "",
  994.     "----------------------------------",
  995.     "-- @field [parent=#pinput] #pinput prev the previous input",
  996.     "     ",
  997.     "-----------------------",
  998.     "-- @field [parent=#pinput] xwos.processes#xwos.process proc the input process",
  999.     "",
  1000.     "-----------------------",
  1001.     "-- @field [parent=#xwos.modules.sandbox.procinput] #pinput current the current process input (front process)",
  1002.     "M.current = nil",
  1003.     "",
  1004.     "-----------------------",
  1005.     "-- injects the kernel",
  1006.     "-- @function [parent=#xwos.modules.sandbox.procinput] setKernel",
  1007.     "-- @param xwos.kernel#xwos.kernel k the kernel",
  1008.     "M.setKernel = function(k)",
  1009.     "    kernel = k",
  1010.     "end -- function setKernel",
  1011.     "",
  1012.     "M.acquire = function(proc)",
  1013.     "    -- first invocation has no kernel",
  1014.     "    if kernel ~= nil and proc ~= nil then",
  1015.     "        kernel.debug(\"[PID\"..proc.pid..\"] fetching user input (front process)\")",
  1016.     "    end -- if kernel",
  1017.     "    local r = {}",
  1018.     "    ---------------------",
  1019.     "    -- release input if proc blocks it",
  1020.     "    -- @function [parent=#pinput] release",
  1021.     "    -- @param xwos.processes#xwos.process proc2 process to release the env",
  1022.     "    r.release = function(proc2)",
  1023.     "        if r.proc == proc2 then",
  1024.     "            kernel.debug(\"[PID\"..proc2.pid..\"] releasing user input (front process)\")",
  1025.     "            M.current = r.prev",
  1026.     "            while M.current.proc ~= nil and M.current.proc.procstate == \"finished\" do",
  1027.     "                M.current = M.current.prev",
  1028.     "            end -- while finished",
  1029.     "            if M.current.proc ~= nil then",
  1030.     "                kernel.debug(\"[PID\"..proc2.pid..\"] switched user input to \"..M.current.proc.pid..\" (front process)\")",
  1031.     "            end -- if proc",
  1032.     "        end -- if proc",
  1033.     "    end -- function release",
  1034.     "    r.prev = M.current",
  1035.     "    r.proc = proc",
  1036.     "    M.current = r",
  1037.     "end -- function acquire",
  1038.     "",
  1039.     "M.acquire(nil)",
  1040.     "",
  1041.     "return M",
  1042.   },
  1043.   [ "/kernel/common/xwos/testsleep.lua" ] = {
  1044.     "--    This file is part of xwos.",
  1045.     "--",
  1046.     "--    xwos is free software: you can redistribute it and/or modify",
  1047.     "--    it under the terms of the GNU General Public License as published by",
  1048.     "--    the Free Software Foundation, either version 3 of the License, or",
  1049.     "--    (at your option) any later version.",
  1050.     "--",
  1051.     "--    xwos is distributed in the hope that it will be useful,",
  1052.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  1053.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  1054.     "--    GNU General Public License for more details.",
  1055.     "--",
  1056.     "--    You should have received a copy of the GNU General Public License",
  1057.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  1058.     "",
  1059.     "    local function func1()",
  1060.     "        print(\"[1]pid=\",pid)",
  1061.     "        print(\"[1]Hello World!\")",
  1062.     "        sleep(5)",
  1063.     "        print(\"[1]Hello again\");",
  1064.     "    end",
  1065.     "    local function func2()",
  1066.     "        print(\"[2]pid=\",pid)",
  1067.     "        sleep(5)",
  1068.     "        print(\"[2]Hello World!\")",
  1069.     "        sleep(5)",
  1070.     "        print(\"[2]Hello again\");",
  1071.     "    end",
  1072.     "    print(\"[0]pid=\",pid)",
  1073.     "    local proc1 = xwos.pmr.createThread()",
  1074.     "    local proc2 = xwos.pmr.createThread()",
  1075.     "    proc1.spawn(func1)",
  1076.     "    proc2.spawn(func2)",
  1077.     "    proc1.join()",
  1078.     "    proc2.join()",
  1079.     "    print(\"Ending\")",
  1080.   },
  1081.   [ "/kernel/common/xwos/modules/sandbox/init.lua" ] = {
  1082.     "--    This file is part of xwos.",
  1083.     "--",
  1084.     "--    xwos is free software: you can redistribute it and/or modify",
  1085.     "--    it under the terms of the GNU General Public License as published by",
  1086.     "--    the Free Software Foundation, either version 3 of the License, or",
  1087.     "--    (at your option) any later version.",
  1088.     "--",
  1089.     "--    xwos is distributed in the hope that it will be useful,",
  1090.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  1091.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  1092.     "--    GNU General Public License for more details.",
  1093.     "--",
  1094.     "--    You should have received a copy of the GNU General Public License",
  1095.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  1096.     "",
  1097.     "-----------------------",
  1098.     "-- @module xwos.modules.sandbox",
  1099.     "local M = {}",
  1100.     "",
  1101.     "local kernel -- xwos.kernel#xwos.kernel",
  1102.     "local originsert = table.insert",
  1103.     "",
  1104.     "---------------------------------",
  1105.     "-- @function [parent=#xwos.modules.sandbox] preboot",
  1106.     "-- @param xwos.kernel#xwos.kernel k",
  1107.     "M.preboot = function(k)",
  1108.     "    k.debug(\"preboot sandbox\")",
  1109.     "    kernel = k",
  1110.     "    ",
  1111.     "    -----------------------",
  1112.     "    -- process input type with mapping to previous input",
  1113.     "    -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.procinput#xwos.modules.sandbox.procinput procinput the input process management",
  1114.     "    M.procinput = kernel.require(\"xwos/modules/sandbox/procinput\")",
  1115.     "    M.procinput.setKernel(kernel)",
  1116.     "    ",
  1117.     "    -----------------------",
  1118.     "    -- timers started from processes",
  1119.     "    -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.timers#xwos.modules.sandbox.timers timers the timer management",
  1120.     "    M.timers = kernel.require(\"xwos/modules/sandbox/timers\")",
  1121.     "    M.timers.setKernel(kernel)",
  1122.     "    ",
  1123.     "    -----------------------",
  1124.     "    -- event queue handling",
  1125.     "    -- @field [parent=#xwos.modules.sandbox] xwos.modules.sandbox.evqueue#xwos.modules.sandbox.evqueue evqueue event queue management",
  1126.     "    M.evqueue = kernel.require(\"xwos/modules/sandbox/evqueue\")",
  1127.     "    M.evqueue.setKernel(kernel)",
  1128.     "",
  1129.     "end -- function preboot",
  1130.     "",
  1131.     "----------------------",
  1132.     "-- @param xwos.processes#xwos.process proc the underlying process",
  1133.     "-- @param #global env the global process environment",
  1134.     "local envFactory = function(proc, env)",
  1135.     "    kernel.debug(\"[PID\"..proc.pid..\"] preparing env\", env)",
  1136.     "    env.pid = proc.pid",
  1137.     "",
  1138.     "    -- TODO this is partly original code from bios.",
  1139.     "    -- we need to redeclare it to get into wrapped os.**** methods",
  1140.     "    -- maybe in future we find a solution to not redeclare it here",
  1141.     "    local biosRead = function( _sReplaceChar, _tHistory, _fnComplete, _sDefault )",
  1142.     "        if _sReplaceChar ~= nil and type( _sReplaceChar ) ~= \"string\" then",
  1143.     "            error( \"bad argument #1 (expected string, got \" .. type( _sReplaceChar ) .. \")\", 2 ) ",
  1144.     "        end",
  1145.     "        if _tHistory ~= nil and type( _tHistory ) ~= \"table\" then",
  1146.     "            error( \"bad argument #2 (expected table, got \" .. type( _tHistory ) .. \")\", 2 ) ",
  1147.     "        end",
  1148.     "        if _fnComplete ~= nil and type( _fnComplete ) ~= \"function\" then",
  1149.     "            error( \"bad argument #3 (expected function, got \" .. type( _fnComplete ) .. \")\", 2 ) ",
  1150.     "        end",
  1151.     "        if _sDefault ~= nil and type( _sDefault ) ~= \"string\" then",
  1152.     "            error( \"bad argument #4 (expected string, got \" .. type( _sDefault ) .. \")\", 2 ) ",
  1153.     "        end",
  1154.     "        term.setCursorBlink( true )",
  1155.     "    ",
  1156.     "        local sLine",
  1157.     "        if type( _sDefault ) == \"string\" then",
  1158.     "            sLine = _sDefault",
  1159.     "        else",
  1160.     "            sLine = \"\"",
  1161.     "        end",
  1162.     "        local nHistoryPos",
  1163.     "        local nPos = #sLine",
  1164.     "        if _sReplaceChar then",
  1165.     "            _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )",
  1166.     "        end",
  1167.     "    ",
  1168.     "        local tCompletions",
  1169.     "        local nCompletion",
  1170.     "        local function recomplete()",
  1171.     "            if _fnComplete and nPos == string.len(sLine) then",
  1172.     "                tCompletions = _fnComplete( sLine )",
  1173.     "                if tCompletions and #tCompletions > 0 then",
  1174.     "                    nCompletion = 1",
  1175.     "                else",
  1176.     "                    nCompletion = nil",
  1177.     "                end",
  1178.     "            else",
  1179.     "                tCompletions = nil",
  1180.     "                nCompletion = nil",
  1181.     "            end",
  1182.     "        end",
  1183.     "    ",
  1184.     "        local function uncomplete()",
  1185.     "            tCompletions = nil",
  1186.     "            nCompletion = nil",
  1187.     "        end",
  1188.     "    ",
  1189.     "        local w = term.getSize()",
  1190.     "        local sx = term.getCursorPos()",
  1191.     "    ",
  1192.     "        local function redraw( _bClear )",
  1193.     "            local nScroll = 0",
  1194.     "            if sx + nPos >= w then",
  1195.     "                nScroll = (sx + nPos) - w",
  1196.     "            end",
  1197.     "    ",
  1198.     "            local cx,cy = term.getCursorPos()",
  1199.     "            term.setCursorPos( sx, cy )",
  1200.     "            local sReplace = (_bClear and \" \") or _sReplaceChar",
  1201.     "            if sReplace then",
  1202.     "                term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) )",
  1203.     "            else",
  1204.     "                term.write( string.sub( sLine, nScroll + 1 ) )",
  1205.     "            end",
  1206.     "    ",
  1207.     "            if nCompletion then",
  1208.     "                local sCompletion = tCompletions[ nCompletion ]",
  1209.     "                local oldText, oldBg",
  1210.     "                if not _bClear then",
  1211.     "                    oldText = term.getTextColor()",
  1212.     "                    oldBg = term.getBackgroundColor()",
  1213.     "                    term.setTextColor( colors.white )",
  1214.     "                    term.setBackgroundColor( colors.gray )",
  1215.     "                end",
  1216.     "                if sReplace then",
  1217.     "                    term.write( string.rep( sReplace, string.len( sCompletion ) ) )",
  1218.     "                else",
  1219.     "                    term.write( sCompletion )",
  1220.     "                end",
  1221.     "                if not _bClear then",
  1222.     "                    term.setTextColor( oldText )",
  1223.     "                    term.setBackgroundColor( oldBg )",
  1224.     "                end",
  1225.     "            end",
  1226.     "    ",
  1227.     "            term.setCursorPos( sx + nPos - nScroll, cy )",
  1228.     "        end",
  1229.     "        ",
  1230.     "        local function clear()",
  1231.     "            redraw( true )",
  1232.     "        end",
  1233.     "    ",
  1234.     "        recomplete()",
  1235.     "        redraw()",
  1236.     "    ",
  1237.     "        local function acceptCompletion()",
  1238.     "            if nCompletion then",
  1239.     "                -- Clear",
  1240.     "                clear()",
  1241.     "    ",
  1242.     "                -- Find the common prefix of all the other suggestions which start with the same letter as the current one",
  1243.     "                local sCompletion = tCompletions[ nCompletion ]",
  1244.     "                sLine = sLine .. sCompletion",
  1245.     "                nPos = string.len( sLine )",
  1246.     "    ",
  1247.     "                -- Redraw",
  1248.     "                recomplete()",
  1249.     "                redraw()",
  1250.     "            end",
  1251.     "        end",
  1252.     "        while true do",
  1253.     "            local sEvent, param = os.pullEvent()",
  1254.     "            if sEvent == \"char\" then",
  1255.     "                -- Typed key",
  1256.     "                clear()",
  1257.     "                sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )",
  1258.     "                nPos = nPos + 1",
  1259.     "                recomplete()",
  1260.     "                redraw()",
  1261.     "    ",
  1262.     "            elseif sEvent == \"paste\" then",
  1263.     "                -- Pasted text",
  1264.     "                clear()",
  1265.     "                sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )",
  1266.     "                nPos = nPos + string.len( param )",
  1267.     "                recomplete()",
  1268.     "                redraw()",
  1269.     "    ",
  1270.     "            elseif sEvent == \"key\" then",
  1271.     "                if param == keys.enter then",
  1272.     "                    -- Enter",
  1273.     "                    if nCompletion then",
  1274.     "                        clear()",
  1275.     "                        uncomplete()",
  1276.     "                        redraw()",
  1277.     "                    end",
  1278.     "                    break",
  1279.     "                    ",
  1280.     "                elseif param == keys.left then",
  1281.     "                    -- Left",
  1282.     "                    if nPos > 0 then",
  1283.     "                        clear()",
  1284.     "                        nPos = nPos - 1",
  1285.     "                        recomplete()",
  1286.     "                        redraw()",
  1287.     "                    end",
  1288.     "                    ",
  1289.     "                elseif param == keys.right then",
  1290.     "                    -- Right                ",
  1291.     "                    if nPos < string.len(sLine) then",
  1292.     "                        -- Move right",
  1293.     "                        clear()",
  1294.     "                        nPos = nPos + 1",
  1295.     "                        recomplete()",
  1296.     "                        redraw()",
  1297.     "                    else",
  1298.     "                        -- Accept autocomplete",
  1299.     "                        acceptCompletion()",
  1300.     "                    end",
  1301.     "    ",
  1302.     "                elseif param == keys.up or param == keys.down then",
  1303.     "                    -- Up or down",
  1304.     "                    if nCompletion then",
  1305.     "                        -- Cycle completions",
  1306.     "                        clear()",
  1307.     "                        if param == keys.up then",
  1308.     "                            nCompletion = nCompletion - 1",
  1309.     "                            if nCompletion < 1 then",
  1310.     "                                nCompletion = #tCompletions",
  1311.     "                            end",
  1312.     "                        elseif param == keys.down then",
  1313.     "                            nCompletion = nCompletion + 1",
  1314.     "                            if nCompletion > #tCompletions then",
  1315.     "                                nCompletion = 1",
  1316.     "                            end",
  1317.     "                        end",
  1318.     "                        redraw()",
  1319.     "    ",
  1320.     "                    elseif _tHistory then",
  1321.     "                        -- Cycle history",
  1322.     "                        clear()",
  1323.     "                        if param == keys.up then",
  1324.     "                            -- Up",
  1325.     "                            if nHistoryPos == nil then",
  1326.     "                                if #_tHistory > 0 then",
  1327.     "                                    nHistoryPos = #_tHistory",
  1328.     "                                end",
  1329.     "                            elseif nHistoryPos > 1 then",
  1330.     "                                nHistoryPos = nHistoryPos - 1",
  1331.     "                            end",
  1332.     "                        else",
  1333.     "                            -- Down",
  1334.     "                            if nHistoryPos == #_tHistory then",
  1335.     "                                nHistoryPos = nil",
  1336.     "                            elseif nHistoryPos ~= nil then",
  1337.     "                                nHistoryPos = nHistoryPos + 1",
  1338.     "                            end                        ",
  1339.     "                        end",
  1340.     "                        if nHistoryPos then",
  1341.     "                            sLine = _tHistory[nHistoryPos]",
  1342.     "                            nPos = string.len( sLine ) ",
  1343.     "                        else",
  1344.     "                            sLine = \"\"",
  1345.     "                            nPos = 0",
  1346.     "                        end",
  1347.     "                        uncomplete()",
  1348.     "                        redraw()",
  1349.     "    ",
  1350.     "                    end",
  1351.     "    ",
  1352.     "                elseif param == keys.backspace then",
  1353.     "                    -- Backspace",
  1354.     "                    if nPos > 0 then",
  1355.     "                        clear()",
  1356.     "                        sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )",
  1357.     "                        nPos = nPos - 1",
  1358.     "                        recomplete()",
  1359.     "                        redraw()",
  1360.     "                    end",
  1361.     "    ",
  1362.     "                elseif param == keys.home then",
  1363.     "                    -- Home",
  1364.     "                    if nPos > 0 then",
  1365.     "                        clear()",
  1366.     "                        nPos = 0",
  1367.     "                        recomplete()",
  1368.     "                        redraw()",
  1369.     "                    end",
  1370.     "    ",
  1371.     "                elseif param == keys.delete then",
  1372.     "                    -- Delete",
  1373.     "                    if nPos < string.len(sLine) then",
  1374.     "                        clear()",
  1375.     "                        sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )                ",
  1376.     "                        recomplete()",
  1377.     "                        redraw()",
  1378.     "                    end",
  1379.     "    ",
  1380.     "                elseif param == keys[\"end\"] then",
  1381.     "                    -- End",
  1382.     "                    if nPos < string.len(sLine ) then",
  1383.     "                        clear()",
  1384.     "                        nPos = string.len(sLine)",
  1385.     "                        recomplete()",
  1386.     "                        redraw()",
  1387.     "                    end",
  1388.     "    ",
  1389.     "                elseif param == keys.tab then",
  1390.     "                    -- Tab (accept autocomplete)",
  1391.     "                    acceptCompletion()",
  1392.     "    ",
  1393.     "                end",
  1394.     "    ",
  1395.     "            elseif sEvent == \"term_resize\" then",
  1396.     "                -- Terminal resized",
  1397.     "                w = term.getSize()",
  1398.     "                redraw()",
  1399.     "    ",
  1400.     "            end",
  1401.     "        end",
  1402.     "    ",
  1403.     "        local cx, cy = term.getCursorPos()",
  1404.     "        term.setCursorBlink( false )",
  1405.     "        term.setCursorPos( w + 1, cy )",
  1406.     "        print()",
  1407.     "        ",
  1408.     "        return sLine",
  1409.     "    end -- function biosRead",
  1410.     "",
  1411.     "    env.read = function( _sReplaceChar, _tHistory, _fnComplete, _sDefault )",
  1412.     "        proc.acquireInput()",
  1413.     "        local res = {pcall(biosRead, _sReplaceChar,_tHistory,_fnComplete,_sDefault)}",
  1414.     "        proc.releaseInput()",
  1415.     "        if res[1] then",
  1416.     "            return res[2]",
  1417.     "        end -- if res",
  1418.     "        error(res[2])",
  1419.     "    end -- function read",
  1420.     "    ",
  1421.     "    env.sleep = function(nTime)",
  1422.     "      kernel.debug(\"[PID\"..proc.pid..\"] sleep\", nTime, kernel.oldGlob.getfenv(0), kernel.oldGlob.getfenv(env.sleep))",
  1423.     "      if nTime ~= nil and type( nTime ) ~= \"number\" then",
  1424.     "          error( \"bad argument #1 (expected number, got \" .. type( nTime ) .. \")\", 2 ) ",
  1425.     "      end",
  1426.     "      local timer = os.startTimer( nTime or 0 )",
  1427.     "      repeat",
  1428.     "          local sEvent, param = os.pullEvent( \"timer\" )",
  1429.     "      until param == timer",
  1430.     "    end -- function sleep",
  1431.     "    ",
  1432.     "    -- clone os to manipulate it",
  1433.     "    env.os = table.clone(env.os)",
  1434.     "    env.os.sleep = function(nTime)",
  1435.     "      sleep(nTime)",
  1436.     "    end -- function os.sleep",
  1437.     "    ",
  1438.     "    env.os.startTimer = function(s)",
  1439.     "        kernel.debug(\"[PID\"..proc.pid..\"] os.startTimer\", s)",
  1440.     "        local timer = kernel.oldGlob.os.startTimer(s)",
  1441.     "        kernel.modules.instances.sandbox.timers.new(timer, proc)",
  1442.     "        return timer",
  1443.     "    end -- function os.startTimer",
  1444.     "    env.os.pullEventRaw = function(filter)",
  1445.     "        kernel.debug(\"[PID\"..proc.pid..\"] os.pullEventRaw\", filter)",
  1446.     "        while true do",
  1447.     "            for k,v in kernel.oldGlob.ipairs(proc.evqueue) do",
  1448.     "                proc.evqueue[k] = nil",
  1449.     "                if filter == nil or v[1]==filter then",
  1450.     "                    kernel.debug(\"[PID\"..proc.pid..\"] returning event from local event queue\", kernel.oldGlob.unpack(v))",
  1451.     "                    return kernel.oldGlob.unpack(v)",
  1452.     "                else -- if filter",
  1453.     "                    kernel.debug(\"[PID\"..proc.pid..\"] discard event from local event queue because of filter\", kernel.oldGlob.unpack(v))",
  1454.     "                end -- if filter",
  1455.     "            end -- for evqueue",
  1456.     "            ",
  1457.     "            kernel.debug(\"[PID\"..proc.pid..\"] invoke os.pullEventRaw\", filter)",
  1458.     "            local event = M.evqueue.processEvt(proc.pid, proc, {kernel.oldGlob.os.pullEventRaw()}, filter)",
  1459.     "            if event ~= nil then",
  1460.     "                return kernel.oldGlob.unpack(event)",
  1461.     "            end -- if event",
  1462.     "        end -- endless loop",
  1463.     "    end -- function os.pullEventRaw",
  1464.     "    env.os.pullEvent = function(filter)",
  1465.     "        kernel.debug(\"[PID\"..proc.pid..\"] os.pullEvent\", filter)",
  1466.     "        local eventData = {proc.env.os.pullEventRaw(filter)}",
  1467.     "        if eventData[1] == \"terminate\" then",
  1468.     "            kernel.oldGlob.error( \"Terminated\", 0 )",
  1469.     "        end",
  1470.     "        return kernel.oldGlob.unpack(eventData)",
  1471.     "    end -- function os.pullEvent",
  1472.     "    ---------------------------------------",
  1473.     "    -- operating system access",
  1474.     "    -- @type xwos",
  1475.     "    -- @field [parent=#global] #xwos xwos predefined operating system accessor",
  1476.     "    env.xwos = {}",
  1477.     "    ---------------------------------------",
  1478.     "    -- debugging output",
  1479.     "    -- @function [parent=#xwos] debug",
  1480.     "    -- @param #string msg",
  1481.     "    env.xwos.debug = function(msg)",
  1482.     "        -- TODO find a way to pass variables etc.",
  1483.     "        -- check for possible sandbox breaks during tostring",
  1484.     "        if kernel.oldGlob.type(msg) ~= \"string\" then",
  1485.     "            error(\"Wrong argument type (only strings allowed)\")",
  1486.     "        else -- if not string",
  1487.     "            kernel.debug(msg)",
  1488.     "        end -- if string",
  1489.     "    end -- function debug",
  1490.     "    ---------------------------------------",
  1491.     "    -- process manager",
  1492.     "    -- @type xwos.pmr",
  1493.     "    -- @field [parent=#xwos] #xwos.pmr pmr process manager",
  1494.     "    env.xwos.pmr = {}",
  1495.     "    -- TODO demon child threads (threads to be fnished before process ends)",
  1496.     "    -- TODO on terminate main process terminat all child threads",
  1497.     "    ---------------------------------------",
  1498.     "    -- create a new child thread",
  1499.     "    -- @function [parent=#xwos.pmr] createThread",
  1500.     "    -- @param #table newenv the environment of the new thread",
  1501.     "    -- @return #xwos.pmr.thread",
  1502.     "    env.xwos.pmr.createThread = function(newenv)",
  1503.     "        local nenv = {}",
  1504.     "        for k,v in kernel.oldGlob.pairs(kernel.oldGlob) do",
  1505.     "            nenv[k] = v",
  1506.     "        end -- for oldGlob",
  1507.     "        local function wrap(target, src)",
  1508.     "            for k,v in kernel.oldGlob.pairs(src) do",
  1509.     "                if kernel.oldGlob.type(v) == \"table\" and kernel.oldGlob.type(target[k]) == \"table\" then",
  1510.     "                    wrap(v, target[k])",
  1511.     "                else -- if tables",
  1512.     "                    target[k] = v",
  1513.     "                end -- if tables",
  1514.     "            end -- for src",
  1515.     "        end -- function wrap",
  1516.     "        if newenv ~= nil then",
  1517.     "            wrap(nenv, newenv)",
  1518.     "        end -- if nenv",
  1519.     "        local nproc = kernel.processes.new(proc, kernel, env, kernel.envFactories)",
  1520.     "        ---------------------------------------",
  1521.     "        -- the new thread",
  1522.     "        -- @type xwos.pmr.thread",
  1523.     "        local R = {}",
  1524.     "        ---------------------------------------",
  1525.     "        -- join thread and wait for finish",
  1526.     "        -- @function [parent=#xwos.pmr.thread] join",
  1527.     "        R.join = function()",
  1528.     "            nproc.join(proc)",
  1529.     "        end -- function join",
  1530.     "        ---------------------------------------",
  1531.     "        -- terminate thread",
  1532.     "        -- @function [parent=#xwos.pmr.thread] terminate",
  1533.     "        R.termninate = function()",
  1534.     "            nproc.termninate()",
  1535.     "        end -- function termninate",
  1536.     "        ---------------------------------------",
  1537.     "        -- spawn thread and invoke function",
  1538.     "        -- @function [parent=#xwos.pmr.thread] spawn",
  1539.     "        -- @param #function func the function to invoke",
  1540.     "        -- @param ... arguments",
  1541.     "        R.spawn = function(func, ...)",
  1542.     "            nproc.spawn(func, ...)",
  1543.     "        end -- function termninate",
  1544.     "        -- TODO do we need this? we are declaring the functions already inside process thread with correct fenv",
  1545.     "        kernel.oldGlob.setfenv(R.join, kernel.nenv)",
  1546.     "        kernel.oldGlob.setfenv(R.terminate, kernel.nenv)",
  1547.     "        kernel.oldGlob.setfenv(R.spawn, kernel.nenv)",
  1548.     "        return R",
  1549.     "    end -- function createThread",
  1550.     "    ",
  1551.     "    env.dofile = function(_sFile)",
  1552.     "        if type( _sFile ) ~= \"string\" then",
  1553.     "            error( \"bad argument #1 (expected string, got \" .. type( _sFile ) .. \")\", 2 )",
  1554.     "        end",
  1555.     "        local fnFile, e = loadfile( _sFile, kernel.nenv )",
  1556.     "        if fnFile then",
  1557.     "            return fnFile()",
  1558.     "        else",
  1559.     "            error( e, 2 )",
  1560.     "        end",
  1561.     "    end -- dofile",
  1562.     "    ",
  1563.     "    -- TODO do we need this? we are declaring the functions already inside process thread with correct fenv",
  1564.     "    kernel.oldGlob.setfenv(biosRead, kernel.nenv)",
  1565.     "    kernel.oldGlob.setfenv(env.read, kernel.nenv)",
  1566.     "    kernel.oldGlob.setfenv(env.sleep, kernel.nenv)",
  1567.     "    kernel.oldGlob.setfenv(env.dofile, kernel.nenv)",
  1568.     "    kernel.oldGlob.setfenv(env.os.sleep, kernel.nenv)",
  1569.     "    kernel.oldGlob.setfenv(env.os.startTimer, kernel.nenv)",
  1570.     "    kernel.oldGlob.setfenv(env.os.pullEventRaw, kernel.nenv)",
  1571.     "    kernel.oldGlob.setfenv(env.os.pullEvent, kernel.nenv)",
  1572.     "    kernel.oldGlob.setfenv(env.xwos.debug, kernel.nenv)",
  1573.     "    kernel.oldGlob.setfenv(env.xwos.pmr.createThread, kernel.nenv)",
  1574.     "end -- function envFactory",
  1575.     "",
  1576.     "---------------------------------",
  1577.     "-- @function [parent=#xwos.modules.sandbox] boot",
  1578.     "-- @param xwos.kernel#xwos.kernel k",
  1579.     "M.boot = function(k)",
  1580.     "    k.debug(\"boot sandbox\")",
  1581.     "    ",
  1582.     "    kernel.envFactories.sandbox = envFactory",
  1583.     "end -- function boot",
  1584.     "",
  1585.     "-- wrap lua console and wrap programs...",
  1586.     "",
  1587.     "---- global functions",
  1588.     "--orig.print = print",
  1589.     "--orig.write = write",
  1590.     "--orig.load = load",
  1591.     "--orig.read = read",
  1592.     "--orig.error = error",
  1593.     "--orig.printError = printError",
  1594.     "---- relevant for sandbox",
  1595.     "--orig.dofile = dofile",
  1596.     "--orig.loadfile = loadfile",
  1597.     "--orig.loadstring = loadstring",
  1598.     "--orig.rawset = rawset",
  1599.     "--orig.rawget = rawget",
  1600.     "--",
  1601.     "---- computercraft apis",
  1602.     "--orig.redstone = redstone",
  1603.     "--orig.rs = rs -- alias for redstone",
  1604.     "--orig.rednet = rednet",
  1605.     "--orig.fs = fs",
  1606.     "--orig.gps = gps",
  1607.     "--orig.disk = disk",
  1608.     "--orig.http = http",
  1609.     "--orig.os = os",
  1610.     "--orig.commands = commands",
  1611.     "--orig.io = io",
  1612.     "--orig.multishell = multishell",
  1613.     "--orig.peripheral = peripheral",
  1614.     "--orig.settings = settings",
  1615.     "--orig.shell = shell",
  1616.     "--orig.turtle = turtle",
  1617.     "--orig.pocket = pocket",
  1618.     "--",
  1619.     "---- terminal management",
  1620.     "--orig.term = term",
  1621.     "--orig.paintutils = paintutils",
  1622.     "--orig.textutils = textutils",
  1623.     "--orig.window = window",
  1624.     "--",
  1625.     "---- threads etc.",
  1626.     "--orig.parallel = parallel",
  1627.     "--orig.setfenv = setfenv",
  1628.     "--orig.getfenv = getfenv",
  1629.     "--orig.xpcall = xpcall",
  1630.     "--orig.pcall = pcall",
  1631.     "--orig.coroutine = coroutine",
  1632.     "--",
  1633.     "-- Events:",
  1634.     "-- alarm                http://computercraft.info/wiki/Alarm_(event)",
  1635.     "-- char                 http://computercraft.info/wiki/Char_(event)",
  1636.     "-- disk                 http://computercraft.info/wiki/Disk_(event)",
  1637.     "-- disk_eject           http://computercraft.info/wiki/Disk_eject_(event)",
  1638.     "-- http_failure         http://computercraft.info/wiki/Http_failure_(event)",
  1639.     "-- http_success         http://computercraft.info/wiki/Http_success_(event)",
  1640.     "-- key                  http://computercraft.info/wiki/Key_(event)",
  1641.     "-- key_up               http://computercraft.info/wiki/Key_up_(event)",
  1642.     "-- modem_message        http://computercraft.info/wiki/Modem_message_(event)           http://computercraft.info/wiki/Modem_(API)",
  1643.     "-- monitor_resize       http://computercraft.info/wiki/Monitor_resize_(event)",
  1644.     "-- monitor_touch        http://computercraft.info/wiki/Monitor_touch_(event)",
  1645.     "-- mouse_click          http://computercraft.info/wiki/Mouse_click_(event)",
  1646.     "-- mouse_drag           http://computercraft.info/wiki/Mouse_drag_(event)",
  1647.     "-- mouse_scroll         http://computercraft.info/wiki/Mouse_scroll_(event)",
  1648.     "-- mouse_up             http://computercraft.info/wiki/Mouse_up_(event)",
  1649.     "-- paste                http://computercraft.info/wiki/Paste_(event)",
  1650.     "-- peripheral           http://computercraft.info/wiki/Peripheral_(event)",
  1651.     "-- peripheral_detach    http://computercraft.info/wiki/Peripheral_detach_(event)",
  1652.     "-- rednet_message       http://computercraft.info/wiki/Rednet_message_(event)         http://computercraft.info/wiki/Rednet_(API)",
  1653.     "-- redstone             http://computercraft.info/wiki/Redstone_(event)",
  1654.     "-- task_complete        http://computercraft.info/wiki/Task_complete_(event)",
  1655.     "-- term_resize          http://computercraft.info/wiki/Term_resize(Event)             http://computercraft.info/wiki/Term_(API)",
  1656.     "-- terminate            http://computercraft.info/wiki/Terminate_(event)",
  1657.     "-- timer                http://computercraft.info/wiki/Timer_(event)",
  1658.     "-- turtle_inventory     http://computercraft.info/wiki/Turtle_inventory_(event)",
  1659.     "",
  1660.     "return M",
  1661.     "",
  1662.     "",
  1663.     "",
  1664.     "",
  1665.     "",
  1666.     "",
  1667.     "",
  1668.   },
  1669.   [ "/core" ] = true,
  1670.   [ "/xwos.lua" ] = {
  1671.     "--    This file is part of xwos.",
  1672.     "--",
  1673.     "--    xwos is free software: you can redistribute it and/or modify",
  1674.     "--    it under the terms of the GNU General Public License as published by",
  1675.     "--    the Free Software Foundation, either version 3 of the License, or",
  1676.     "--    (at your option) any later version.",
  1677.     "--",
  1678.     "--    xwos is distributed in the hope that it will be useful,",
  1679.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  1680.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  1681.     "--    GNU General Public License for more details.",
  1682.     "--",
  1683.     "--    You should have received a copy of the GNU General Public License",
  1684.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  1685.     "",
  1686.     "term.clear()",
  1687.     "",
  1688.     "local tArgs = {...}",
  1689.     "",
  1690.     "local myver = \"0.0.1\" -- TODO manipulate through maven build",
  1691.     "local osvs = os.version()",
  1692.     "local osvIter = string.gmatch(osvs, \"%S+\")",
  1693.     "local osn = osvIter()",
  1694.     "local osv = osvIter()",
  1695.     "",
  1696.     "local kernelpaths = { \"\", \"/xwos/kernel/common\" }",
  1697.     "local kernels = {}",
  1698.     "kernels[\"CraftOS\"] = {}",
  1699.     "kernels[\"CraftOS\"][\"1.8\"] = \"/xwos/kernel/1/8\"",
  1700.     "",
  1701.     "print(\"** booting XW-OS........\")",
  1702.     "print(\"** XW-OS version \" .. myver)",
  1703.     "print(\"** Copyright © 2018 by xworlds.eu.\")",
  1704.     "print(\"** All rights reserved.\")",
  1705.     "",
  1706.     "-- check if already booted",
  1707.     "if xwos then",
  1708.     "  print()",
  1709.     "  print(\"FAILED... We are already running XW-OS...\")",
  1710.     "  return nil",
  1711.     "end -- if already booted",
  1712.     "",
  1713.     "-- check if valid operating system",
  1714.     "if kernels[osn] == nil or kernels[osn][osv] == nil then",
  1715.     "    print()",
  1716.     "    print(\"FAILED... running on unknown operating system or version...\")",
  1717.     "    print(\"OS-version we got: \" .. osvs)",
  1718.     "    print(\"Currently we require CraftOS at version 1.8\")",
  1719.     "    return nil",
  1720.     "end -- if valid",
  1721.     "",
  1722.     "-- kernel file loader",
  1723.     "kernelpaths[1] = kernels[osn][osv]",
  1724.     "",
  1725.     "-- prepare first sandboxing for kernel",
  1726.     "local old2 = getfenv(2)",
  1727.     "local old1 = getfenv(1)",
  1728.     "if old2 ~= _G or old1.require == nil then",
  1729.     "    print()",
  1730.     "    print(\"FAILED... please run XW-OS in startup script or on root console...\")",
  1731.     "    print(\"Running inside other operating systems may not be supported...\")",
  1732.     "    return nil",
  1733.     "end -- if not globals",
  1734.     "local oldGlob = {}",
  1735.     "for k, v in pairs(_G) do",
  1736.     "    oldGlob[k] = v",
  1737.     "end -- for _G",
  1738.     "for k, v in pairs(old2) do",
  1739.     "    oldGlob[k] = v",
  1740.     "end -- for _G",
  1741.     "for k, v in pairs(old1) do",
  1742.     "    oldGlob[k] = v",
  1743.     "end -- for _G",
  1744.     "",
  1745.     "-- create an explicit copy of globals",
  1746.     "local newGlob = {}",
  1747.     "for k, v in oldGlob.pairs(oldGlob) do",
  1748.     "    newGlob[k] = v",
  1749.     "end -- for _G",
  1750.     "",
  1751.     "-- redirect require for kernel loading",
  1752.     "-- using functions from oldGlob for security reasons",
  1753.     "local function krequire(path)",
  1754.     "    for k, v in oldGlob.pairs(kernelpaths) do",
  1755.     "        local target = v .. \"/\" .. oldGlob.string.gsub(path, \"%.\", \"/\")",
  1756.     "        local targetFile = target .. \".lua\"",
  1757.     "        if oldGlob.fs.exists(targetFile) then",
  1758.     "            local res = oldGlob.require(target)",
  1759.     "            -- print(\"loaded file \"..target)",
  1760.     "            return res",
  1761.     "        end -- if file exists",
  1762.     "    end -- for kernelpaths",
  1763.     "    return nil",
  1764.     "end -- function require",
  1765.     "",
  1766.     "setfenv(1, newGlob)",
  1767.     "local state, err = pcall(function()",
  1768.     "        local kernel = krequire('xwos.kernel') -- xwos.kernel#xwos.kernel",
  1769.     "        ",
  1770.     "        kernel.boot(myver, kernelpaths, krequire, oldGlob, tArgs)",
  1771.     "        kernel.startup()",
  1772.     "    end -- function ex",
  1773.     ")",
  1774.     "setfenv(1, old1)",
  1775.     "",
  1776.     "if not state then",
  1777.     "    error(err)",
  1778.     "end",
  1779.     "",
  1780.   },
  1781.   [ "/kernel/common/xwos/processes.lua" ] = {
  1782.     "--    This file is part of xwos.",
  1783.     "--",
  1784.     "--    xwos is free software: you can redistribute it and/or modify",
  1785.     "--    it under the terms of the GNU General Public License as published by",
  1786.     "--    the Free Software Foundation, either version 3 of the License, or",
  1787.     "--    (at your option) any later version.",
  1788.     "--",
  1789.     "--    xwos is distributed in the hope that it will be useful,",
  1790.     "--    but WITHOUT ANY WARRANTY; without even the implied warranty of",
  1791.     "--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",
  1792.     "--    GNU General Public License for more details.",
  1793.     "--",
  1794.     "--    You should have received a copy of the GNU General Public License",
  1795.     "--    along with xwos.  If not, see <http://www.gnu.org/licenses/>.",
  1796.     "",
  1797.     "local cocreate = coroutine.create",
  1798.     "local coresume = coroutine.resume",
  1799.     "local origGetfenv = getfenv",
  1800.     "local origSetfenv = setfenv",
  1801.     "local origsetmeta = setmetatable",
  1802.     "local origtype = type",
  1803.     "local origdofile = dofile",
  1804.     "local origloadfile = loadfile",
  1805.     "local origpcall = pcall",
  1806.     "local origpackage = package",
  1807.     "local origprint = print",
  1808.     "local origerror = error",
  1809.     "local origser = textutils.serialize",
  1810.     "local origpairs = pairs",
  1811.     "local origyield = coroutine.yield",
  1812.     "local originsert = table.insert",
  1813.     "",
  1814.     "local kernel -- xwos.kernel#xwos.kernel",
  1815.     "",
  1816.     "--------------------------------",
  1817.     "-- local process environments",
  1818.     "-- @type xwos.processes",
  1819.     "local processes = {}",
  1820.     "",
  1821.     "--------------------------------",
  1822.     "-- next pid to use for new processes",
  1823.     "local nextPid = 0",
  1824.     "",
  1825.     "--------------------------------",
  1826.     "-- creates a new process",
  1827.     "-- @function [parent=#xwos.processes] new",
  1828.     "-- @param p the parent process",
  1829.     "-- @param xwos.kernel#xwos.kernel k the kernel table",
  1830.     "-- @param #global env the global process environment",
  1831.     "-- @param #table factories functions with signature (proc, env) to initialize the new process or environment",
  1832.     "-- @return #xwos.process",
  1833.     "processes.new = function(p, k, env, factories)",
  1834.     "    kernel = k",
  1835.     "    --------------------------------",
  1836.     "    -- process type",
  1837.     "    -- @type xwos.process",
  1838.     "    local R = {}",
  1839.     "    ",
  1840.     "    --------------------------------",
  1841.     "    -- @field [parent=#xwos.process] #number pid the process id",
  1842.     "    R.pid = nextPid",
  1843.     "    nextPid = nextPid + 1",
  1844.     "        ",
  1845.     "    --------------------------------------",
  1846.     "    -- @field [parent=#xwos.process] #table evqueue the process local event queue",
  1847.     "    R.evqueue = {}",
  1848.     "    ",
  1849.     "    ------------------------------------------",
  1850.     "    -- @field [parent=#xwos.process] #number joined number of processes having called method join",
  1851.     "    R.joined = 0",
  1852.     "    ",
  1853.     "    --------------------------------",
  1854.     "    -- @field [parent=#xwos.process] #string procstate the process state; \"initializing\", \"running\" or \"terminated\"",
  1855.     "    R.procstate = \"initializing\"",
  1856.     "    kernel.debug(\"[PID\"..R.pid..\"] pocstate = initializing\")",
  1857.     "    ",
  1858.     "    --------------------------------",
  1859.     "    -- @field [parent=#xwos.process] #xwos.process parent the parent process",
  1860.     "    R.parent = p",
  1861.     "    ",
  1862.     "    --------------------------------",
  1863.     "    -- @field [parent=#xwos.process] #global env the process environment",
  1864.     "    R.env = { pid = R.pid }",
  1865.     "    kernel.debug(\"[PID\"..R.pid..\"] environments\", env)",
  1866.     "    local nenvmt = {",
  1867.     "        __index = function(table, key)",
  1868.     "            local res = env[key]",
  1869.     "            if res == nil then",
  1870.     "                if R.parent ~= nil then",
  1871.     "                    -- 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",
  1872.     "                    res = R.parent.env[key]",
  1873.     "                end -- if parent",
  1874.     "            end -- if not res (env)",
  1875.     "            return res",
  1876.     "        end -- function __index",
  1877.     "    }",
  1878.     "    origsetmeta(R.env, nenvmt)",
  1879.     "    origSetfenv(nenvmt.__index, R.env)",
  1880.     "        ",
  1881.     "    --------------------------------------",
  1882.     "    -- acquire input (front process)",
  1883.     "    -- @function [parent=#xwos.process] acquireInput",
  1884.     "    R.acquireInput = function()",
  1885.     "        -- TODO is a stack always good?",
  1886.     "        -- switching between processes (alt+tab in windows) is not meant to build a stack of input",
  1887.     "        -- a stack of input will represent some kind of modal dialog over other modal dialog where closing one will pop up the previous one",
  1888.     "        -- think about it...",
  1889.     "        kernel.modules.instances.sandbox.procinput.acquire(R)",
  1890.     "    end -- function acquireInput",
  1891.     "        ",
  1892.     "    ------------------------------------------",
  1893.     "    -- joins process and awaits it termination",
  1894.     "    -- @function [parent=#process] join",
  1895.     "    -- @param #xwos.process cproc calling process",
  1896.     "    R.join = function(cproc)",
  1897.     "        local cpid = \"*\"",
  1898.     "        if cproc ~= nil then",
  1899.     "            cpid = cproc.pid",
  1900.     "        end -- if cproc",
  1901.     "        kernel.debug(\"[PID\"..cpid..\"] joining\")",
  1902.     "        R.joined = R.joined + 1",
  1903.     "        while R.procstate ~= \"finished\" do",
  1904.     "            kernel.debug(\"[PID\"..cpid..\"] waiting for finished of \"..R.pid..\" (state=\"..R.procstate..\")\")",
  1905.     "            local event = kernel.modules.instances.sandbox.evqueue.processEvt(cpid, cproc, {origyield()}, \"xwos_terminated\")",
  1906.     "            if event ~= nil and event[2] ~= R.pid then",
  1907.     "                for k, v in kernel.oldGlob.pairs(processes) do",
  1908.     "                    if kernel.oldGlob.type(v)==\"table\" and v.pid == event[2] and v.joined > 0 then",
  1909.     "                        kernel.debug(\"[PID\"..cpid..\"] redistributing to all other processes because at least one process called join of \"..R.pid)",
  1910.     "                        ",
  1911.     "                        for k2, v2 in kernel.oldGlob.pairs(kernel.processes) do",
  1912.     "                            if kernel.oldGlob.type(v2) == \"table\" and v2 ~= cproc and v2.procstate~= \"finished\" then",
  1913.     "                                kernel.debug(\"[PID\"..cpid..\"] redistributing because at least one process called join of \"..R.pid)",
  1914.     "                                originsert(v2.evqueue, event)",
  1915.     "                                v2.wakeup()",
  1916.     "                            end --",
  1917.     "                        end -- for processes",
  1918.     "                    end --",
  1919.     "                end -- for processes",
  1920.     "            end -- if pid",
  1921.     "        end",
  1922.     "        kernel.debug(\"[PID\"..cpid..\"] received finish notification or \"..R.pid)",
  1923.     "        R.joined = R.joined - 1",
  1924.     "    end -- function join",
  1925.     "        ",
  1926.     "    --------------------------------------",
  1927.     "    -- release input (front process)",
  1928.     "    -- @function [parent=#xwos.process] releaseInput",
  1929.     "    R.releaseInput = function()",
  1930.     "        kernel.modules.instances.sandbox.procinput.current.release(R)",
  1931.     "    end -- function acquireInput",
  1932.     "        ",
  1933.     "    --------------------------------------",
  1934.     "    -- wakeup process in reaction to events on local event queue",
  1935.     "    -- @function [parent=#xwos.process] wakeup",
  1936.     "    R.wakeup = function()",
  1937.     "        if R.co ~= nil and R.procstate ~= \"finished\" then",
  1938.     "            kernel.debug(\"[PID\"..R.pid..\"] wakeup requested\")",
  1939.     "            kernel.oldGlob.coroutine.resume(R.co)",
  1940.     "        end -- if proc",
  1941.     "    end -- function wakeup",
  1942.     "        ",
  1943.     "    --------------------------------------",
  1944.     "    -- request process to terminate",
  1945.     "    -- @function [parent=#xwos.process] terminate",
  1946.     "    R.terminate = function()",
  1947.     "        kernel.oldGlob.os.queueEvent(\"xwos_terminate\", R.pid)",
  1948.     "    end -- function wakeup",
  1949.     "    ",
  1950.     "    --------------------------------",
  1951.     "    -- Remove the process from process table",
  1952.     "    -- @function [parent=#xwos.process] remove",
  1953.     "    R.remove = function()",
  1954.     "        kernel.debug(\"[PID\"..R.pid..\"] removing from process table\")",
  1955.     "        processes[R.pid] = nil",
  1956.     "    end -- function remove",
  1957.     "    ",
  1958.     "    --------------------------------",
  1959.     "    -- Spawn the process (invoke function)",
  1960.     "    -- @function [parent=#xwos.process] spawn",
  1961.     "    -- @param #function func the function to invoke",
  1962.     "    -- @param ... the arguments for given function",
  1963.     "    R.spawn = function(func, ...)",
  1964.     "        local env0 = kernel.nenv",
  1965.     "        kernel.debug(\"[PID\"..R.pid..\"] prepare spawn\")",
  1966.     "        -- TODO ... may contain functions and objects with metatables; this may cause problems by mxing environments",
  1967.     "        -- establish an alternative for IPC (inter process communication)",
  1968.     "        local res = {origpcall(origser, {...})}-- this will cause an error if serializing forbidden types (functions etc.)",
  1969.     "        if not res[1] then",
  1970.     "            kernel.debug(\"[PID\"..R.pid..\"] ERR:\", res[2])",
  1971.     "            kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
  1972.     "            R.result = res",
  1973.     "            R.procstate = \"finished\"",
  1974.     "            kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
  1975.     "            return",
  1976.     "        end -- if not res",
  1977.     "        ",
  1978.     "        local spawn0 = function(...)",
  1979.     "            kernel.debug(\"[PID\"..R.pid..\"] pocstate = running\")",
  1980.     "            R.procstate = \"running\"",
  1981.     "            kernel.debug(\"[PID\"..R.pid..\"] using env\", R.env, env0)",
  1982.     "            origSetfenv(0, R.env)",
  1983.     "            for k, v in origpairs(factories) do",
  1984.     "                kernel.debug(\"[PID\"..R.pid..\"] invoke factory\", k, v)",
  1985.     "                v(R, R.env)",
  1986.     "            end -- for factories",
  1987.     "            if origtype(func) == \"string\" then",
  1988.     "                local func2 = function(...)",
  1989.     "                    kernel.debug(\"[PID\"..R.pid..\"] doFile\", func)",
  1990.     "                    local fnFile, e = origloadfile(func, kernel.nenv)",
  1991.     "                    if fnFile then",
  1992.     "                        return fnFile()",
  1993.     "                    else -- if res",
  1994.     "                        origerror( e, 2 )",
  1995.     "                    end -- if not res",
  1996.     "                    return origdofile(func, ...)",
  1997.     "                end -- function func2",
  1998.     "                origSetfenv(func2, kernel.nenv)",
  1999.     "                --------------------------------",
  2000.     "                -- @field [parent=#xwos.process] #table result the return state from process function",
  2001.     "                R.result = {origpcall(func2, ...)}",
  2002.     "            else -- if string",
  2003.     "                kernel.debug(\"[PID\"..R.pid..\"] invoke function\", func)",
  2004.     "                R.result = {origpcall(func, ...)}",
  2005.     "            end -- if string",
  2006.     "            kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
  2007.     "            if not R.result[1] then",
  2008.     "                kernel.debug(\"[PID\"..R.pid..\"] ERR:\", R.result[2])",
  2009.     "            end -- if not res",
  2010.     "            R.procstate = \"finished\"",
  2011.     "            kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
  2012.     "        end -- function spawn0",
  2013.     "        R.env.getfenv = function(n)",
  2014.     "            -- TODO: Hide kernel.nenv because one may decide to manipulate it to inject variables into other threads :-(",
  2015.     "            local t = origtype(n)",
  2016.     "            if t == \"number\" then",
  2017.     "                if n == 0 then",
  2018.     "                    return kernel.nenv",
  2019.     "                end -- if 0",
  2020.     "            end -- if number",
  2021.     "            return origGetfenv(n)",
  2022.     "        end -- function get",
  2023.     "        R.env.setfenv = function(n, v)",
  2024.     "            -- TODO maybe we can compare current fenv with THIS nenv and nenv from kernel;",
  2025.     "            -- if matches we deny changing the fenv",
  2026.     "            -- if not matches we allow changing because it was loaded inside process",
  2027.     "            ",
  2028.     "            -- do not allow changing fenv at all",
  2029.     "            -- simply return current one",
  2030.     "            return R.env.getfenv(n, v)",
  2031.     "        end -- function setfenv",
  2032.     "        kernel.debug(\"[PID\"..R.pid..\"] prepare package\")",
  2033.     "        R.env.package = {}",
  2034.     "        -- taken from bios.lua; must be overriden because of env",
  2035.     "        -- TODO maybe we find a better solution than copying all the stuff",
  2036.     "        R.env.package.loaded = {",
  2037.     "            -- _G = _G,",
  2038.     "            bit32 = bit32,",
  2039.     "            coroutine = coroutine, -- TODO wrap",
  2040.     "            math = math,",
  2041.     "            package = R.env.package,",
  2042.     "            string = string,",
  2043.     "            table = table,",
  2044.     "        }",
  2045.     "        -- TODO paths",
  2046.     "        R.env.package.path = \"?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua\"",
  2047.     "        if turtle then",
  2048.     "            R.env.package.path = R.env.package.path..\";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua\"",
  2049.     "        elseif command then",
  2050.     "            R.env.package.path = R.env.package.path..\";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua\"",
  2051.     "        end",
  2052.     "        R.env.package.config = \"/\\n;\\n?\\n!\\n-\"",
  2053.     "        R.env.package.preload = {}",
  2054.     "        local loader1 =  function( name )",
  2055.     "            if package.preload[name] then",
  2056.     "                return package.preload[name]",
  2057.     "            else",
  2058.     "                return nil, \"no field package.preload['\" .. name .. \"']\"",
  2059.     "            end",
  2060.     "        end -- function loader1",
  2061.     "        local loader2 =  function( name )",
  2062.     "            local fname = string.gsub(name, \"%.\", \"/\")",
  2063.     "            local sError = \"\"",
  2064.     "            for pattern in string.gmatch(package.path, \"[^;]+\") do",
  2065.     "                local sPath = string.gsub(pattern, \"%?\", fname)",
  2066.     "                if sPath:sub(1,1) ~= \"/\" then",
  2067.     "                    sPath = fs.combine(sDir, sPath)",
  2068.     "                end",
  2069.     "                if fs.exists(sPath) and not fs.isDir(sPath) then",
  2070.     "                    local fnFile, sError = loadfile( sPath, nenv ) -- inject our new env",
  2071.     "                    if fnFile then",
  2072.     "                        return fnFile, sPath",
  2073.     "                    else",
  2074.     "                        return nil, sError",
  2075.     "                    end",
  2076.     "                else",
  2077.     "                    if #sError > 0 then",
  2078.     "                        sError = sError .. \"\\n\"",
  2079.     "                    end",
  2080.     "                    sError = sError .. \"no file '\" .. sPath .. \"'\"",
  2081.     "                end",
  2082.     "            end",
  2083.     "            return nil, sError",
  2084.     "        end -- function loader2",
  2085.     "        R.env.package.loaders = {",
  2086.     "            loader1,",
  2087.     "            loader2",
  2088.     "        }",
  2089.     "  ",
  2090.     "        local sentinel = {}",
  2091.     "        R.env.require = function( name )",
  2092.     "            if type( name ) ~= \"string\" then",
  2093.     "                error( \"bad argument #1 (expected string, got \" .. type( name ) .. \")\", 2 )",
  2094.     "            end",
  2095.     "            if package.loaded[name] == sentinel then",
  2096.     "                error(\"Loop detected requiring '\" .. name .. \"'\", 0)",
  2097.     "            end",
  2098.     "            if package.loaded[name] then",
  2099.     "                return package.loaded[name]",
  2100.     "            end",
  2101.     "      ",
  2102.     "            local sError = \"Error loading module '\" .. name .. \"':\"",
  2103.     "            for n,searcher in ipairs(package.loaders) do",
  2104.     "                local loader, err = searcher(name)",
  2105.     "                if loader then",
  2106.     "                    package.loaded[name] = sentinel",
  2107.     "                    local result = loader( err )",
  2108.     "                    if result ~= nil then",
  2109.     "                        package.loaded[name] = result",
  2110.     "                        return result",
  2111.     "                    else",
  2112.     "                        package.loaded[name] = true",
  2113.     "                        return true",
  2114.     "                    end",
  2115.     "                else",
  2116.     "                    sError = sError .. \"\\n\" .. err",
  2117.     "                end",
  2118.     "            end",
  2119.     "            error(sError, 2)",
  2120.     "        end -- function require",
  2121.     "        ",
  2122.     "        kernel.debug(\"[PID\"..R.pid..\"] setting new env\", env0)",
  2123.     "        origSetfenv(spawn0, env0)",
  2124.     "        origSetfenv(loader1, env0)",
  2125.     "        origSetfenv(loader2, env0)",
  2126.     "        origSetfenv(R.env.require, env0)",
  2127.     "        origSetfenv(R.env.getfenv, env0)",
  2128.     "        origSetfenv(R.env.setfenv, env0)",
  2129.     "        --------------------------------",
  2130.     "        -- @field [parent=#xwos.process] coroutine#coroutine co the coroutine",
  2131.     "        R.co = cocreate(spawn0)",
  2132.     "        local res = {coresume(R.co, ...)}",
  2133.     "        if not res[1] then",
  2134.     "            kernel.debug(\"[PID\"..R.pid..\"] ERR:\", res[2])",
  2135.     "            kernel.debug(\"[PID\"..R.pid..\"] pocstate = finished\")",
  2136.     "            R.result = res",
  2137.     "            R.procstate = \"finished\"",
  2138.     "            kernel.oldGlob.os.queueEvent(\"xwos_terminated\", R.pid)",
  2139.     "        end -- if not res",
  2140.     "    end -- function spawn",
  2141.     "    ",
  2142.     "    processes[R.pid] = R",
  2143.     "    kernel.debug(\"[PID\"..R.pid..\"] returning new process\")",
  2144.     "    return R",
  2145.     "end -- function new",
  2146.     "",
  2147.     "return processes",
  2148.   },
  2149. } --paste archive data here
  2150.  
  2151. local tArg = {...}
  2152. local outpath = ((tArg[1] ~= "") and tArg[1]) or (shell and shell.getRunningProgram() or "xwos")
  2153. if fs.combine("",outpath):sub(1,26) == "rom/programs/http/pastebin" then
  2154.     outpath = (shell and fs.combine(shell.dir(),"xwos") or "xwos")
  2155. end
  2156.  
  2157. local progdor = fs.getName(shell.getRunningProgram())
  2158. local dir = shell.dir()
  2159.  
  2160. local explode = function(div,str)
  2161.     if (div=='') then return false end
  2162.     local pos,arr = 0,{}
  2163.     for st,sp in function() return string.find(str,div,pos,true) end do
  2164.         table.insert(arr,str:sub(pos,st-1))
  2165.         pos = sp + 1
  2166.     end
  2167.     table.insert(arr,str:sub(pos))
  2168.     return arr
  2169. end
  2170. local sanitize = function(sani,tize)
  2171.     local _,x = string.find(sani,tize)
  2172.     if x then
  2173.         return sani:sub(x+1)
  2174.     else
  2175.         return sani
  2176.     end
  2177. end
  2178. local tablize = function(input)
  2179.     if type(input) == "string" then
  2180.         return explode("\n",input)
  2181.     elseif type(input) == "table" then
  2182.         return table.concat(input,"\n")
  2183.     end
  2184. end
  2185.  
  2186. if not outpath then
  2187.     outpath = input
  2188. end
  2189.  
  2190. local choice = function(input,verbose)
  2191.     if not input then
  2192.         input = "yn"
  2193.     end
  2194.     if verbose then
  2195.         write("[")
  2196.         for a = 1, #input do
  2197.             write(input:sub(a,a):upper())
  2198.             if a < #input then
  2199.                 write(",")
  2200.             end
  2201.         end
  2202.         write("]?")
  2203.     end
  2204.     local evt,char
  2205.     repeat
  2206.         evt,char = os.pullEvent("char")
  2207.     until string.find(input:lower(),char:lower())
  2208.     if verbose then
  2209.         print(char:upper())
  2210.     end
  2211.     local pos = string.find(input:lower(),char:lower())
  2212.     return pos, char:lower()
  2213. end
  2214.  
  2215. local doPack = function(list,output,doCompress,verbose)
  2216.     local tx = term.getTextColor()
  2217.     if fs.isReadOnly(output) and (fs.combine("",output) ~= "") then return 5 end
  2218.     local packageSelf = true
  2219.     local packageReadOnly = true
  2220.     local ro_asked = false
  2221.     local ps_asked = false
  2222.     if fs.exists(output) and (not fs.isDir(output)) then
  2223.         fs.delete(output)
  2224.     end
  2225.     local amnt = 0
  2226.     for k,v in pairs(list) do
  2227.         amnt = amnt + 1
  2228.     end
  2229.     local num = 0
  2230.     for k,v in pairs(list) do
  2231.         num = num + 1
  2232.         if v == true then
  2233.             fs.makeDir(fs.combine(output,k))
  2234.         else
  2235.             local file = fs.open(fs.combine(output,k),"w")
  2236.             if verbose then
  2237.                 write("[")
  2238.                 if term.isColor() then term.setTextColor(colors.lightGray) end
  2239.                 write(k)
  2240.                 term.setTextColor(tx)
  2241.                 write("]")
  2242.             end
  2243.             file.write(tablize(v))
  2244.             file.close()
  2245.             local tx = term.getTextColor()
  2246.             if fs.getName(k):lower() == "peasant" then
  2247.                 if term.isColor() then
  2248.                     term.setTextColor(colors.orange)
  2249.                 end
  2250.                 print(" UNBURNINATED")
  2251.             else
  2252.                 if term.isColor() then
  2253.                     term.setTextColor(colors.green)
  2254.                 end
  2255.                 print(" GOOD")
  2256.             end
  2257.             term.setTextColor(tx)
  2258.         end
  2259.     end
  2260.     return 2
  2261. end
  2262.  
  2263. if not fs.isDir(outpath) then
  2264.     fs.delete(outpath)
  2265. end
  2266.  
  2267. local success, res = pcall( function() return doPack(data,outpath,false,true) end )
  2268.  
  2269. if not success then
  2270.     term.setTextColor(colors.white)
  2271.     print("\n***Something went wrong!***")
  2272.     return printError(res)
  2273. end
  2274.  
  2275. if res then
  2276.     local msgs = {
  2277.         [2] = "Successfully unpacked '"..fullname.."' to '"..outpath.."/'",
  2278.         [5] = "You don't have permission.",
  2279.     }
  2280.     print(msgs[res])
  2281. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement