Skip to content
This repository has been archived by the owner on Jul 18, 2020. It is now read-only.

Commit

Permalink
Add a bunch of explanatory comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
technomancy committed Jun 6, 2015
1 parent 9332f06 commit 09b7610
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 7 deletions.
3 changes: 3 additions & 0 deletions mods/calandria/server.lua
Expand Up @@ -103,6 +103,9 @@ calandria.server = {
}

pcall(calandria.server.load)

-- TODO: check to see if these have been loaded already:
-- if(not minetest.registered_items["mod:item"]) then ...
minetest.register_on_shutdown(calandria.server.save)

minetest.register_node("calandria:server", {
Expand Down
39 changes: 33 additions & 6 deletions mods/orb/fs.lua
@@ -1,5 +1,7 @@
-- fake lil filesystem
orb.fs = {

-- This gives us a raw filesystem that's just a table with permissions data
empty = function()
return {_user = "root", _group = "all", proc = {
_user = "root", _group = "all"
Expand All @@ -21,6 +23,8 @@ orb.fs = {
return parent[base]
end,

-- Actually returns both the dirname and the basename.
-- for instance, "/path/to/file" returns "/path/to" and "file"
dirname = function(path)
local t = orb.utils.split(path, "/")
local basename = t[#t]
Expand All @@ -29,8 +33,11 @@ orb.fs = {
return "/" .. table.concat(t, "/"), basename
end,

-- read/write/append here are wrappers that help you work with function
-- files, which is how pipes and other special devices are implemented.
-- read/write/append here are wrappers that help you work with
-- function files, which is how pipes and other special devices are
-- implemented. When dealing with regular files, you can just grab
-- them straight out of the filesystem as strings to read or drop strings
-- into the directory to write.
read = function(f, path)
local contents = f[path]
if(type(contents) == "string") then
Expand Down Expand Up @@ -64,8 +71,8 @@ orb.fs = {
f[home]._user = user
f[home]._group = user
orb.fs.mkdir(f, "/proc/" .. user)
f["/proc/" .. user]._user = user
f["/proc/" .. user]._group = user
f.proc[user]._user = user
f.proc[user]._group = user
end,

add_to_group = function(f, user, group)
Expand All @@ -81,6 +88,7 @@ orb.fs = {
group_dir[user] = user
end,

-- This is for copying stuff from the host OS into the virtualized OS.
copy_to_fs = function(f, fs_path, real_path)
local dir, base = orb.fs.dirname(fs_path)
local path = orb.mod_dir .. "/resources/" .. real_path
Expand Down Expand Up @@ -113,6 +121,7 @@ orb.fs = {
end
end,

-- Load up an empty filesystem.
seed = function(f, users)
for _,d in pairs({"/etc", "/home", "/tmp", "/bin", "/digi"}) do
orb.fs.mkdir(f, d)
Expand Down Expand Up @@ -166,6 +175,7 @@ orb.fs = {

reloaders = (orb.fs and orb.fs.reloaders) or {},

-- Reload all of orb's own code, and reset the /bin directory.
reloader = function(f)
return function()
dofile(orb.mod_dir .. "/init.lua")
Expand All @@ -184,6 +194,21 @@ orb.fs = {
end
end,

-- Proxying a raw filesystem has two purposes: one is to enforce filesystem
-- permissions rules (this is done using a metatable) and one is to allow
-- access using full filenames. For instance, these are equivalent:
--
-- f.home.technomancy.bin["myls"]
-- f["/home/technomancy/bin/myls"]
--
-- Raw filesystems require the first style, but the latter works with
-- proxied filesystems.
--
-- Be aware that f["/home"] will return another proxied subfilesystem
-- that looks like a filesystem but is actually just sliced off at
-- a subdirectory. This is a bit of a problem since calculating permissions
-- requires access to the "/etc/groups" directory, which is why this
-- function takes a raw_root argument as well.
proxy = function(raw, user, raw_root)
local descend = function(f, path, user)
local target = f
Expand All @@ -198,7 +223,7 @@ orb.fs = {
return target
end

local unreadable = function(_k,v)
local unreadable = function(_k, v)
return {_user = v._user, _group = v._group}
end

Expand All @@ -223,6 +248,8 @@ orb.fs = {
target[base] = content
end,

-- Unfortunately Lua 5.1 has no way to specify an iterator from the
-- metatable, so this only works with orb.utils.mtpairs. =(
__iterator = function(_f)
assert(orb.fs.readable(raw_root, raw, user), "Not readable")
local f = {}
Expand All @@ -244,7 +271,7 @@ orb.fs = {
}
setmetatable(f, mt)

-- only need this for fs roots
-- Only need this for fs roots.
if(raw == raw_root) then
orb.fs.reloaders[f] = orb.fs.reloader(raw_root)
end
Expand Down
3 changes: 2 additions & 1 deletion mods/orb/init.lua
Expand Up @@ -13,8 +13,9 @@ dofile(orb.mod_dir .. "/shell.lua")
dofile(orb.mod_dir .. "/process.lua")
-- pp = dofile(orb.mod_dir .. "/PrettyPrint.lua")

-- interactively:
-- for interactive use, but also as a sample of how the API works:
if(arg) then
-- start with an empty filesystem
f = orb.fs.empty()
f0 = orb.fs.seed(orb.fs.proxy(f, "root", f),
{"technomancy", "buddyberg", "zacherson"})
Expand Down
9 changes: 9 additions & 0 deletions mods/orb/process.lua
@@ -1,4 +1,7 @@
orb.process = {
-- Create a coroutine for a command to run inside and place it into the
-- process table. The process table is stored in the filesystem under
-- f.proc[user]
spawn = function(f, env, command)
local co = coroutine.create(function()
orb.shell.exec(f, env, "smash") end)
Expand All @@ -11,10 +14,14 @@ orb.process = {
return co, id
end,

-- The process ID is taken from lua's own tostring called on a coroutine.
id_for = function(p)
return tostring(p):match(": 0x(.+)")
end,

-- Loop through all the coroutines in the process table and give them all
-- a chance to run till they yield. No attempt at fairness or time limits
-- yet.
scheduler = function(f)
for u,procs in pairs(f.proc) do
if(type(procs) == "table") then
Expand All @@ -31,6 +38,8 @@ orb.process = {
end
end,

-- When restoring an fs from serialization, we have to repopulate special
-- nodes in the fs that were not serializable.
restore_digi = function(f)
for k,v in orb.utils.mtpairs(f.digi) do
local channel_dir = "/digi/" .. k
Expand Down
9 changes: 9 additions & 0 deletions mods/orb/shell.lua
Expand Up @@ -12,6 +12,9 @@ orb.shell = {
}
end,

-- This function does too much: it turns a command string into a tokenized
-- list of arguments, but it also searches the argument list for stdio
-- redirects and sets up the environment's read/write appropriately.
parse = function(f, env, command)
local args = {}
local tokens = orb.utils.split(command, " +")
Expand Down Expand Up @@ -56,6 +59,9 @@ orb.shell = {
return executable_name, args
end,

-- Execute a command directly in the current coroutine. This is a low-level
-- call; usually you want orb.process.spawn which creates it as a proper
-- process.
exec = function(f, env, command)
local env = orb.utils.shallow_copy(env)
local executable_name, args = orb.shell.parse(f, env, command)
Expand All @@ -72,10 +78,13 @@ orb.shell = {
error(executable_name .. " not found.")
end,

-- Like exec, but protected in a pcall.
pexec = function(f, env, command)
return pcall(function() orb.shell.exec(f, env, command) end)
end,

-- Set up the sandbox in which code runs. Need to avoid exposing anything
-- that could allow security leaks.
sandbox = function(f, env)
local read = function(...) return env.read(...) end
local write = function(...) return env.write(...) end
Expand Down
2 changes: 2 additions & 0 deletions mods/orb/utils.lua
@@ -1,5 +1,7 @@
-- utils

-- mostly functions which are inexplicable omissions from the lua standard lib

orb.utils = {
split = function(str,div)
if(div=='') then return {str} end
Expand Down

0 comments on commit 09b7610

Please sign in to comment.