Guest User

xsh

a guest
May 14th, 2020
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.67 KB | None | 0 0
  1. local version = "1.0"
  2.  
  3. local process = package.loaded.process
  4. local fs = package.loaded.filesystem
  5. local config
  6. local loaders = {}
  7. local lua_loader = {
  8.     mode = "r",
  9.     loadfile = function(path, env)
  10.         return loadfile(path, "t", env)
  11.     end,
  12.     load = function(hand, env)
  13.         local data = ""
  14.         local lc = " "
  15.         while lc and lc ~= "" do
  16.             lc = hand:read(math.huge)
  17.             data = data .. (lc or "")
  18.         end
  19.         hand:close()
  20.         return load(data, "="..os.getenv("_"), "t", env)
  21.     end,
  22.     info = function()
  23.         print("    The default Lua loader.")
  24.         print("    ".._VERSION)
  25.     end,
  26.     version = "1.0",
  27. }
  28.  
  29. function reload_config()
  30.     if (not fs.exists("/etc/xsh.cfg")) then
  31.         print("Creating configuration...")
  32.         fs.makeDirectory("/etc/xsh")
  33.         local h = io.open("/etc/xsh.cfg", "w")
  34.         h:write("{\n    loadorder = {\n        \"lua\"\n    }\n}")
  35.         h:close()
  36.         config = {loadorder={"lua"}}
  37.         loaders = {}
  38.         loaders.lua = lua_loader
  39.     else
  40.         local h = io.open("/etc/xsh.cfg", "r")
  41.         config = load("return "..h:read("*a"))()
  42.         h:close()
  43.         loaders = {}
  44.         loaders.lua = lua_loader
  45.         for ent in fs.list("/etc/xsh") do
  46.             loaders[ent:sub(1, #ent-4)] = dofile("/etc/xsh/"..ent)
  47.         end
  48.     end
  49. end
  50.  
  51. print("Loading config...")
  52. reload_config()
  53.  
  54. local function try_load(path, env)
  55.     return function(...)
  56.         local fs, shell = require("filesystem"), require("shell")
  57.         local ext = path:match("%.(.+)$")
  58.         --print(ext)
  59.         if (ext) then
  60.             local prog = shell.resolve(path)
  61.             if (prog) then
  62.                 os.setenv("_", prog)
  63.                 local f = fs.open(prog, loaders[ext].mode)
  64.                 --print("Running program "..prog.." with loader "..config.loadorder[i])
  65.                 return assert(loaders[ext].load(f, env))(...)
  66.             else
  67.                 return require("tools/programLocations").reportNotFound(path, "not found")
  68.             end
  69.         end
  70.         for i=1, #config.loadorder do
  71.             local prog = shell.resolve(path, config.loadorder[i])
  72.             --print("Trying loader: "..config.loadorder[i])
  73.             if (prog) then
  74.                 os.setenv("_", prog)
  75.                 local f = fs.open(prog, loaders[config.loadorder[i]].mode)
  76.                 --print("Running program "..prog.." with loader "..config.loadorder[i])
  77.                 return assert(loaders[config.loadorder[i]].load(f, env))(...)
  78.             end
  79.         end
  80.         return require("tools/programLocations").reportNotFound(path, "not found")
  81.     end
  82. end
  83. local oload = process.load
  84. local function proc_load(path, env, init, name)
  85.     checkArg(1, path, "string", "function")
  86.     checkArg(2, env, "table", "nil")
  87.     checkArg(3, init, "function", "nil")
  88.     checkArg(4, name, "string", "nil")
  89.  
  90.     assert(type(path) == "string" or env == nil, "process cannot load function environments")
  91.  
  92.     local p = process.findProcess()
  93.     env = env or p.env
  94.     local code
  95.     if type(path) == "string" then
  96.         if (path == "xshinfo") then
  97.             code = function(...)
  98.                 print("xSH - eXtendable SHell")
  99.                 print("Easy shell extensions for OpenOS.\n")
  100.                 print("xSH version: "..version)
  101.                 print("OpenOS version: ".._OSVERSION)
  102.                 print("Lua version: ".._VERSION)
  103.                 print("Load order:\n    - "..table.concat(config.loadorder, "\n    - "))
  104.                 for k, v in pairs(loaders) do
  105.                     print(k .. " version: "..v.version)
  106.                     if (v.info) then
  107.                         v.info()
  108.                     end
  109.                 end
  110.                 return 0
  111.             end
  112.         else
  113.             code = try_load(path, env)
  114.         end
  115.     else -- path is code
  116.         code = path
  117.     end
  118.  
  119.     local thread = nil
  120.     thread = coroutine.create(function(...)
  121.         -- pcall code so that we can remove it from the process list on exit
  122.         local result =
  123.         {
  124.             xpcall(function(...)
  125.                     init = init or function(...) return ... end
  126.                     return code(init(...))
  127.                 end,
  128.                 function(msg)
  129.                     if type(msg) == "table" and msg.reason == "terminated" then
  130.                         return msg.code or 0
  131.                     end
  132.                     local stack = debug.traceback():gsub("^([^\n]*\n)[^\n]*\n[^\n]*\n","%1")
  133.                     io.stderr:write(string.format("%s:\n%s", msg or "", stack))
  134.                     return 128 -- syserr
  135.                 end, ...)
  136.         }
  137.  
  138.         --result[1] is false if the exception handler also crashed
  139.         if not result[1] and type(result[2]) ~= "number" then
  140.             pcall(require("event").onError, string.format("process library exception handler crashed: %s", tostring(result[2])))
  141.         end
  142.  
  143.         -- onError opens a file, you can't open a file without a process, we close the process last
  144.         process.internal.close(thread, result)
  145.  
  146.         return select(2, table.unpack(result))
  147.     end, true)
  148.     local new_proc =
  149.     {
  150.         path = path,
  151.         command = name or tostring(path),
  152.         env = env,
  153.         data =
  154.         {
  155.             handles = {},
  156.             io = {},
  157.         },
  158.         parent = p,
  159.         instances = setmetatable({}, {__mode="v"}),
  160.     }
  161.     for i,fd in pairs(p.data.io) do
  162.         new_proc.data.io[i] = io.dup(fd)
  163.     end
  164.     setmetatable(new_proc.data, {__index=p.data})
  165.     process.list[thread] = new_proc
  166.  
  167.     return thread
  168. end
  169.  
  170.  
  171. local loaded = package.loaded
  172. local loading = {}
  173. local orequire = require
  174. local function n_require(module)
  175.     checkArg(1, module, "string")
  176.     if loaded[module] ~= nil then
  177.         return loaded[module]
  178.     elseif not loading[module] then
  179.         local library, status, step
  180.  
  181.         step, library, status = "not found", package.searchpath(module, package.path)
  182.  
  183.         --print(library, library:match("%.(.+)$"))
  184.  
  185.         if library then
  186.             step, library, status = "loadfile failed", loaders[library:match("%.(.+)$")].loadfile(library)
  187.         end
  188.  
  189.         if library then
  190.             loading[module] = true
  191.             step, library, status = "load failed", pcall(library, module)
  192.             loading[module] = false
  193.         end
  194.  
  195.         assert(library, string.format("module '%s' %s:\n%s", module, step, status))
  196.         loaded[module] = status
  197.         return status
  198.     else
  199.         error("already loading: " .. module .. "\n" .. debug.traceback(), 2)
  200.     end
  201. end
  202.  
  203. function start()
  204.     _G.require = n_require
  205.     process.load = proc_load
  206.     _G._XSH = true
  207. end
  208.  
  209. function stop()
  210.     _G.require = orequire
  211.     process.load = oload
  212.     _G._XSH = nil
  213. end
Add Comment
Please, Sign In to add comment