Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

10 changed files with 151 additions and 307 deletions

View File

@ -93,7 +93,6 @@ Unlike most "OS"es for CC (primarily excluding Opus OS, which is actually useful
- Live threat updates using our advanced algorithms. - Live threat updates using our advanced algorithms.
- PotatOS Epenthesis' rewritten security model fixes many exploits and adds others while reducing boot times. - PotatOS Epenthesis' rewritten security model fixes many exploits and adds others while reducing boot times.
- IPC mechanism. - IPC mechanism.
- Virtual filesystems abstraction.
## Architecture ## Architecture

File diff suppressed because one or more lines are too long

View File

@ -1,60 +1,3 @@
local prefixes = {
{-12, "p"},
{-9, "n"},
{-6, "u"},
{-3, "m"},
{0, ""},
{3, "k"},
{6, "M"}
}
local function SI_prefix(value, unit)
local x = math.log(value, 10)
local last
for _, t in ipairs(prefixes) do
if t[1] > x then
break
end
last = t
end
local dp = 2 - math.floor(x - last[1])
return (("%%.%df%%s%%s"):format(dp)):format(value / 10^(last[1]), last[2], unit)
end
local w = term.getSize()
local rows = {}
for _, info in pairs(process.list()) do for _, info in pairs(process.list()) do
table.insert(rows, { info.name or tostring(info.ID), SI_prefix(info.execution_time, "s"), SI_prefix(info.ctime, "s") }) textutils.pagedPrint(("%s %f %f"):format(info.name or info.ID, info.execution_time, info.ctime))
end
local max_width_per_column = {}
for _, row in ipairs(rows) do
for i, cell in ipairs(row) do
max_width_per_column[i] = math.max(max_width_per_column[i] or 0, cell:len() + 1)
end
end
local vw_width = 0
for i = #max_width_per_column, 1, -1 do
if i > 1 then
vw_width = vw_width + max_width_per_column[i]
end
end
local fw_start = w - vw_width
for _, row in ipairs(rows) do
local s
for i, cell in ipairs(row) do
if i == 1 then
s = cell:sub(1, fw_start - 1) .. (" "):rep((fw_start - 1) - cell:len())
else
cell = " " .. cell
s = s .. (" "):rep(max_width_per_column[i] - cell:len()) .. cell
end
end
textutils.pagedPrint(s)
end end

View File

@ -24,7 +24,7 @@ print()
print(snd) print(snd)
print() print()
if arg == "headless" then if arg == "headless" then
if ccemux then ccemux.echo "ready" end ccemux.echo "ready"
while true do coroutine.yield() end while true do coroutine.yield() end
else else
print "Press a key to continue..." print "Press a key to continue..."

View File

@ -13,11 +13,6 @@ end
function sandboxlib.dispatch_if_restricted(rkey, original, restricted) function sandboxlib.dispatch_if_restricted(rkey, original, restricted)
local out = {} local out = {}
for k, v in pairs(restricted) do
if not original[k] then
out[k] = v
end
end
for k, v in pairs(original) do for k, v in pairs(original) do
out[k] = function(...) out[k] = function(...)
if processrestriction(rkey) then if processrestriction(rkey) then

View File

@ -77,10 +77,31 @@ local function add_to_table(t1, t2)
end end
end end
local fscombine, fsgetname, fsgetdir = fs.combine, fs.getName, fs.getDir
-- Convert path to canonical form -- Convert path to canonical form
local function canonicalize(path) local function canonicalize(path)
return fscombine(path, "") return fs.combine(path, "")
end
-- Checks whether a path is in a directory
local function path_in(p, dir)
return starts_with(canonicalize(p), canonicalize(dir))
end
local function make_mappings(root)
return {
["/disk"] = "/disk",
["/rom"] = "/rom",
default = root
}
end
local function get_root(path, mappings)
for mapfrom, mapto in pairs(mappings) do
if path_in(path, mapfrom) then
return mapto, mapfrom
end
end
return mappings.default, "/"
end end
-- Escapes lua patterns in a string. Should not be needed, but lua is stupid so the only string.replace thing is gsub -- Escapes lua patterns in a string. Should not be needed, but lua is stupid so the only string.replace thing is gsub
@ -93,12 +114,19 @@ local function strip(p, root)
return p:gsub("^" .. escape(canonicalize(root)), "") return p:gsub("^" .. escape(canonicalize(root)), "")
end end
local function resolve_path(path, mappings)
local root, to_strip = get_root(path, mappings)
local newpath = strip(fs.combine(root, path), to_strip)
if path_in(newpath, root) then return newpath end
return resolve_path(newpath, mappings)
end
local function segments(path) local function segments(path)
local segs, rest = {}, canonicalize(path) local segs, rest = {}, canonicalize(path)
if rest == "" then return {} end -- otherwise we'd get "root" and ".." for some broken reason if rest == "" then return {} end -- otherwise we'd get "root" and ".." for some broken reason
repeat repeat
table.insert(segs, 1, fsgetname(rest)) table.insert(segs, 1, fs.getName(rest))
rest = fsgetdir(rest) rest = fs.getDir(rest)
until rest == "" until rest == ""
return segs return segs
end end
@ -106,7 +134,7 @@ end
local function combine(segs) local function combine(segs)
local out = "" local out = ""
for _, p in pairs(segs) do for _, p in pairs(segs) do
out = fscombine(out, p) out = fs.combine(out, p)
end end
return out return out
end end
@ -151,176 +179,98 @@ end
local this_level_env = _G local this_level_env = _G
-- make virtual filesystem from files (no nested directories for simplicity) -- Create a modified FS table which confines you to root and has some extra read-only pseudofiles.
local function vfs_from_files(files) local function create_FS(root, overlay)
return {
list = function(path)
if path ~= "" then return {} end
local out = {}
for k, v in pairs(files) do
table.insert(out, k)
end
return out
end,
open = function(path, mode)
return make_handle(files[path])
end,
exists = function(path)
return files[path] ~= nil or path == ""
end,
isReadOnly = function(path)
return true
end,
isDir = function(path)
if path == "" then return true end
return false
end,
getDrive = function(_) return "memory" end,
getSize = function(path)
return #files[path]
end,
getFreeSpace = function() return 0 end,
makeDir = function() end,
delete = function() end,
move = function() end,
copy = function() end,
attributes = function(path)
return {
size = #files[path],
modification = os.epoch "utc"
}
end
}
end
local function create_FS(vfstree)
local fs = fs local fs = fs
local mappings = make_mappings(root)
local function is_usable_node(node) local vfstree = {
return node.mount or node.vfs mount = "potatOS",
end children = {
["disk"] = { mount = "disk" },
["rom"] = { mount = "rom" },
--["virtual_test"] = { virtual = "bees" }
}
}
local function resolve(sandbox_path, ignore_usability) local function resolve(sandbox_path)
local segs = segments(sandbox_path) local segs = segments(sandbox_path)
local current_tree = vfstree local current_tree = vfstree
local last_usable_node, last_segs = nil, nil
while true do while true do
if is_usable_node(current_tree) then
last_usable_node = current_tree
last_segs = copy(segs)
end
local seg = segs[1] local seg = segs[1]
if seg and current_tree.children and current_tree.children[seg] then if current_tree.children and current_tree.children[seg] then
table.remove(segs, 1) table.remove(segs, 1)
current_tree = current_tree.children[seg] current_tree = current_tree.children[seg]
else break end else break end
end end
if ignore_usability then return current_tree, segs end
return last_usable_node, last_segs
end end
local function resolve_node_segs(node, segs) local new_overlay = {}
if node.mount then return fs, fscombine(node.mount, combine(segs)) end for k, v in pairs(overlay) do
return node.vfs, combine(segs) new_overlay[canonicalize(k)] = v
end
local function resolve_path(sandbox_path)
local node, segs = resolve(sandbox_path)
return resolve_node_segs(node, segs)
end end
local function lift_to_sandbox(f, n) local function lift_to_sandbox(f, n)
return function(path) return function(...)
local vfs, path = resolve_path(path) local args = map(function(x) return resolve_path(x, mappings) end, {...})
return vfs[n](path) return f(table.unpack(args))
end end
end end
local new = copy_some_keys {"getDir", "getName", "combine", "complete"} (fs) local new = copy_some_keys {"getDir", "getName", "combine", "complete"} (fs)
function new.isReadOnly(path)
return path_in_overlay(new_overlay, path) or starts_with(canonicalize(path), "rom")
end
function new.open(path, mode) function new.open(path, mode)
if (contains(mode, "w") or contains(mode, "a")) and new.isReadOnly(path) then if (contains(mode, "w") or contains(mode, "a")) and new.isReadOnly(path) then
error "Access denied" error "Access denied"
else else
local vfs, path = resolve_path(path) local overlay_data = path_in_overlay(new_overlay, path)
return vfs.open(path, mode) if overlay_data then
if type(overlay_data) == "function" then overlay_data = overlay_data(this_level_env) end
return make_handle(overlay_data), "YAFSS overlay"
end
return fs.open(resolve_path(path, mappings), mode)
end end
end end
function new.move(src, dest) function new.exists(path)
local src_vfs, src_path = resolve_path(src) if path_in_overlay(new_overlay, path) ~= nil then return true end
local dest_vfs, dest_path = resolve_path(dest) return fs.exists(resolve_path(path, mappings))
if src_vfs == dest_vfs then
return src_vfs.move(src_path, dest_path)
else
if src_vfs.isReadOnly(src_path) then error "Access denied" end
new.copy(src, dest)
src_vfs.delete(src_path)
end
end end
function new.copy(src, dest) function new.overlay()
local src_vfs, src_path = resolve_path(src) return map(function(x)
local dest_vfs, dest_path = resolve_path(dest) if type(x) == "function" then return x(this_level_env)
if src_vfs == dest_vfs then else return x end
return src_vfs.copy(src_path, dest_path) end, new_overlay)
else end
if src_vfs.isDir(src_path) then
dest_vfs.makeDir(dest_path) function new.list(dir)
for _, f in pairs(src_vfs.list(src_path)) do local sdir = canonicalize(resolve_path(dir, mappings))
new.copy(fscombine(src, f), fscombine(dest, f)) local ocontents = {}
end for opath in pairs(new_overlay) do
else if fs.getDir(opath) == sdir then
local dest_fh = dest_vfs.open(dest_path, "wb") table.insert(ocontents, fs.getName(opath))
local src_fh = src_vfs.open(src_path, "rb")
dest_fh.write(src_fh.readAll())
src_fh.close()
dest_fh.close()
end end
end end
end local ok, contents = pcall(fs.list, sdir)
-- in case of error (nonexistent dir, probably) return overlay contents
function new.mountVFS(path, vfs) -- very awful temporary hack until I can get a nicer treeized VFS done
local node, relpath = resolve(path) if not ok then
while #relpath > 0 do if #ocontents > 0 then return ocontents end
local seg = table.remove(relpath, 1) error(contents)
if not node.children then node.children = {} end
if not node.children[seg] then node.children[seg] = {} end
node = node.children[seg]
end
node.vfs = vfs
end
function new.unmountVFS(path)
local node, relpath = resolve(path)
if #relpath == 0 then
node.vfs = nil
else else
error "Not a mountpoint" for _, v in pairs(ocontents) do
end table.insert(contents, v)
end
function new.list(path)
local node, segs = resolve(path, true)
local vfs, path = resolve_path(path)
if #segs > 0 then return vfs.list(path) end
local out = {}
local seen = {}
for k, v in pairs(node.children or {}) do
table.insert(out, k)
seen[k] = true
end
for _, v in pairs(vfs.list(path)) do
if not seen[v] then
table.insert(out, v)
end end
return contents
end end
return out
end end
add_to_table(new, map(lift_to_sandbox, copy_some_keys {"isDir", "getDrive", "getSize", "getFreeSpace", "makeDir", "delete", "isDriveRoot", "exists", "isReadOnly", "attributes"} (fs))) add_to_table(new, map(lift_to_sandbox, copy_some_keys {"isDir", "getDrive", "getSize", "getFreeSpace", "makeDir", "move", "copy", "delete", "isDriveRoot"} (fs)))
function new.find(wildcard) function new.find(wildcard)
local function recurse_spec(results, path, spec) -- From here: https://github.com/Sorroko/cclite/blob/62677542ed63bd4db212f83da1357cb953e82ce3/src/emulator/native_api.lua local function recurse_spec(results, path, spec) -- From here: https://github.com/Sorroko/cclite/blob/62677542ed63bd4db212f83da1357cb953e82ce3/src/emulator/native_api.lua
@ -360,7 +310,7 @@ local function create_FS(vfstree)
to_add.c = new.dump(path) to_add.c = new.dump(path)
to_add.t = "d" to_add.t = "d"
else else
local fh = new.open(path, "rb") local fh = new.open(path, "r")
to_add.c = fh.readAll() to_add.c = fh.readAll()
fh.close() fh.close()
end end
@ -377,7 +327,7 @@ local function create_FS(vfstree)
new.makeDir(path) new.makeDir(path)
new.load(f.c, path) new.load(f.c, path)
else else
local fh = new.open(path, "wb") local fh = new.open(path, "w")
fh.write(f.c) fh.write(f.c)
fh.close() fh.close()
end end
@ -455,11 +405,30 @@ local gf, sf = getfenv, setfenv
-- a map of paths to either strings containing their contents or functions returning them -- a map of paths to either strings containing their contents or functions returning them
-- and a table of extra APIs and partial overrides for existing APIs -- and a table of extra APIs and partial overrides for existing APIs
local function make_environment(API_overrides, current_process) local function make_environment(API_overrides, current_process)
local env_host = string.format("YAFSS on %s", _HOST)
local environment = copy_some_keys(allowed_APIs)(_G) local environment = copy_some_keys(allowed_APIs)(_G)
-- if function is not from within the VM, return env from within sandbox
function environment.getfenv(arg)
local env
if type(arg) == "number" then return gf() end
if not env or type(env._HOST) ~= "string" or not env._HOST == env_host then
return gf()
else
return env
end
end
-- I sure hope this doesn't readd the security issues! --[[
environment.getfenv = getfenv Fix PS#AD2A532C
environment.setfenv = setfenv Allowing `setfenv` to operate on any function meant that privileged code could in some cases be manipulated to leak information or operate undesirably. Due to this, we restrict it, similarly to getfenv.
]]
function environment.setfenv(fn, env)
local nenv = gf(fn)
if not nenv or type(nenv._HOST) ~= "string" or not nenv._HOST == env_host then
return false
end
return sf(fn, env)
end
local load = load local load = load
function environment.load(code, file, mode, env) function environment.load(code, file, mode, env)
@ -468,6 +437,7 @@ local function make_environment(API_overrides, current_process)
environment._G = environment environment._G = environment
environment._ENV = environment environment._ENV = environment
environment._HOST = env_host
function environment.os.shutdown() function environment.os.shutdown()
process.IPC(current_process, "power_state", "shutdown") process.IPC(current_process, "power_state", "shutdown")
@ -515,4 +485,4 @@ local function run(API_overrides, init, logger)
end end
end end
return { run = run, create_FS = create_FS, vfs_from_files = vfs_from_files } return { run = run, create_FS = create_FS }

View File

@ -1297,61 +1297,26 @@ local function run_with_sandbox()
end or v end or v
end end
local yafss = require "yafss" -- Provide many, many useful or not useful programs to the potatOS shell.
local FS_overlay = {
local drive_mounts = { ["secret/.pkey"] = fproxy "signing-key.tbl",
children = {}, ["secret/log"] = function() return potatOS_proxy.get_log() end,
vfs = {} -- The API backing this no longer exists due to excessive server load.
-----["/rom/programs/dwarf.lua"] = "print(potatOS.dwarf())",
["/secret/processes"] = function()
return tostring(process.list())
end,
["/rom/heavlisp_lib/stdlib.hvl"] = fproxy "stdlib.hvl"
} }
function drive_mounts.vfs.list(path) for _, file in pairs(fs.list "bin") do
local out = {} FS_overlay[fs.combine("rom/programs", file)] = fproxy(fs.combine("bin", file))
for k, v in pairs(drive_mounts.children) do
table.insert(out, k)
end
return out
end end
function drive_mounts.vfs.exists(path) for _, file in pairs(fs.list "xlib") do
return drive_mounts.children[path] ~= nil FS_overlay[fs.combine("rom/potato_xlib", file)] = fproxy(fs.combine("xlib", file))
end end
function drive_mounts.vfs.isDir(path) return true end
function drive_mounts.vfs.getDrive(path) return "disks" end
function drive_mounts.vfs.getSize(path) return 0 end
function drive_mounts.vfs.getFreeSpace(path) return 0 end
function drive_mounts.vfs.makeDir(path) end
function drive_mounts.vfs.delete(path) end
function drive_mounts.vfs.isReadOnly(path) return true end
local vfstree = {
mount = "potatOS",
children = {
["rom"] = {
mount = "rom",
children = {
["potatOS_xlib"] = { mount = "/xlib" },
programs = {
children = {
["potatOS"] = { mount = "/bin" }
}
},
["autorun"] = {
vfs = yafss.vfs_from_files {
["fix_path.lua"] = [[shell.setPath("/rom/programs/potatOS:"..shell.path())]],
}
},
["heavlisp_lib"] = {
vfs = yafss.vfs_from_files {
["stdlib.hvl"] = fproxy "stdlib.hvl"
}
}
}
},
["disks"] = drive_mounts
}
}
local API_overrides = { local API_overrides = {
process = process, process = process,
json = json, json = json,
@ -1388,18 +1353,6 @@ local function run_with_sandbox()
local computers = {} local computers = {}
local compcount = 0 local compcount = 0
local signs = {} local signs = {}
local function mount_disk(drive_name)
local mountpoint = peripheral.call(drive_name, "getMountPath")
if mountpoint then
drive_mounts.children[drive_name] = { mount = mountpoint }
end
end
local function unmount_disk(drive_name)
drive_mounts.children[drive_name] = nil
end
local function add_peripheral(name) local function add_peripheral(name)
local typ = peripheral.getType(name) local typ = peripheral.getType(name)
if typ == "modem" then if typ == "modem" then
@ -1409,16 +1362,10 @@ local function run_with_sandbox()
compcount = compcount + 1 compcount = compcount + 1
elseif typ == "minecraft:sign" then elseif typ == "minecraft:sign" then
signs[name] = true signs[name] = true
elseif typ == "drive" then
if peripheral.call(name, "isDiskPresent") then
mount_disk(name)
end
end end
end end
for _, name in pairs(peripheral.getNames()) do add_peripheral(name) end for _, name in pairs(peripheral.getNames()) do add_peripheral(name) end
local timer = os.startTimer(1) local timer = os.startTimer(1)
while true do while true do
local e, name, channel, _, message = os.pullEvent() local e, name, channel, _, message = os.pullEvent()
if e == "peripheral" then add_peripheral(name) if e == "peripheral" then add_peripheral(name)
@ -1426,8 +1373,7 @@ local function run_with_sandbox()
local typ = peripheral.getType(name) local typ = peripheral.getType(name)
if typ == "computer" then computers[name] = nil compcount = compcount - 1 if typ == "computer" then computers[name] = nil compcount = compcount - 1
elseif typ == "modem" then modems[name] = nil elseif typ == "modem" then modems[name] = nil
elseif typ == "minecraft:sign" then signs[name] = nil elseif typ == "minecraft:sign" then signs[name] = nil end
elseif typ == "drive" then unmount_disk(name) end
elseif e == "modem_message" then elseif e == "modem_message" then
if channel == 62381 and type(message) == "string" then if channel == 62381 and type(message) == "string" then
add_log("netd message %s", message) add_log("netd message %s", message)
@ -1448,19 +1394,17 @@ local function run_with_sandbox()
end end
end end
timer = os.startTimer(1 + math.random(0, compcount * 2)) timer = os.startTimer(1 + math.random(0, compcount * 2))
elseif e == "disk" then
mount_disk(name)
elseif e == "disk_eject" then
unmount_disk(name)
end end
end end
end, "netd", { grants = { [notermsentinel] = true }, restrictions = {} }) end, "netd", { grants = { [notermsentinel] = true }, restrictions = {} })
require "metatable_improvements"(potatOS_proxy.add_log, potatOS_proxy.report_incident) require "metatable_improvements"(potatOS_proxy.add_log, potatOS_proxy.report_incident)
local yafss = require "yafss"
local fss_sentinel = sandboxlib.create_sentinel "fs-sandbox" local fss_sentinel = sandboxlib.create_sentinel "fs-sandbox"
local debug_sentinel = sandboxlib.create_sentinel "constrained-debug" local debug_sentinel = sandboxlib.create_sentinel "constrained-debug"
local sandbox_filesystem = yafss.create_FS(vfstree) local sandbox_filesystem = yafss.create_FS("potatOS", FS_overlay)
_G.fs = sandboxlib.dispatch_if_restricted(fss_sentinel, _G.fs, sandbox_filesystem) _G.fs = sandboxlib.dispatch_if_restricted(fss_sentinel, _G.fs, sandbox_filesystem)
_G.debug = sandboxlib.allow_whitelisted(debug_sentinel, _G.debug, { _G.debug = sandboxlib.allow_whitelisted(debug_sentinel, _G.debug, {
"traceback", "traceback",

View File

@ -459,18 +459,13 @@ local old_error = error
local old_os_shutdown = os.shutdown local old_os_shutdown = os.shutdown
local old_term_redirect = term.redirect local old_term_redirect = term.redirect
local old_term_native = term.native local old_term_native = term.native
local old_printError = printError
function error() end function error() end
function term.redirect() end function term.redirect() end
function term.native() end function term.native() end
function printError() end
function os.shutdown() function os.shutdown()
error = old_error error = old_error
_G.error = old_error _G.error = old_error
_ENV.error = old_error _ENV.error = old_error
printError = old_printError
_G.printError = old_printError
_ENV.printError = old_printError
term.native = old_term_native term.native = old_term_native
term.redirect = old_term_redirect term.redirect = old_term_redirect
os.shutdown = old_os_shutdown os.shutdown = old_os_shutdown

View File

@ -391,12 +391,6 @@ do
local native = term.native() local native = term.native()
local last_redirected local last_redirected
-- horrors
local idmap = {}
local function termid(t)
return idmap[tostring(t.blit)]
end
local ix = 0 local ix = 0
process.spawn(function() process.spawn(function()
while true do while true do
@ -414,11 +408,17 @@ do
ix = ix + 1 ix = ix + 1
process.queue_in(process.get_running().parent, "term_resize", true) process.queue_in(process.get_running().parent, "term_resize", true)
elseif ev == "ipc" and arg2 == "redraw_native" then elseif ev == "ipc" and arg2 == "redraw_native" then
potatOS.framebuffers[termid(native)].redraw() potatOS.framebuffers[native.id].redraw()
end end
end end
end, "termd") end, "termd")
-- horrors
local idmap = {}
local function termid(t)
return idmap[tostring(t.blit)]
end
local function assignid(t) local function assignid(t)
if not termid(t) then idmap[tostring(t.blit)] = potatOS.gen_uuid() end if not termid(t) then idmap[tostring(t.blit)] = potatOS.gen_uuid() end
end end
@ -573,7 +573,7 @@ local function boot_require(package)
return pkg return pkg
end end
local npackage = package:gsub("%.", "/") local npackage = package:gsub("%.", "/")
for _, search_path in next, {"/", "lib", "rom/modules/main", "rom/modules/turtle", "rom/modules/command", "rom/potatOS_xlib"} do for _, search_path in next, {"/", "lib", "rom/modules/main", "rom/modules/turtle", "rom/modules/command", "rom/potato_xlib"} do
local path = try_paths(search_path, {npackage, npackage .. ".lua"}) local path = try_paths(search_path, {npackage, npackage .. ".lua"})
if path then if path then
local ok, res = pcall(dofile, path) local ok, res = pcall(dofile, path)
@ -589,7 +589,7 @@ _G.require = boot_require
_ENV.require = boot_require _ENV.require = boot_require
local libs = {} local libs = {}
for _, f in pairs(fs.list "rom/potatOS_xlib") do for _, f in pairs(fs.list "rom/potato_xlib") do
table.insert(libs, f) table.insert(libs, f)
end end
table.sort(libs) table.sort(libs)
@ -1245,8 +1245,7 @@ function potatOS.llm(prompt, max_tokens, stop_sequences)
local res, err = http.post("https://gpt.osmarks.net/v1/completions", json.encode { local res, err = http.post("https://gpt.osmarks.net/v1/completions", json.encode {
prompt = prompt, prompt = prompt,
max_tokens = max_tokens, max_tokens = max_tokens,
stop = stop_sequences, stop = stop_sequences
client = "potatOS"
}, {["content-type"]="application/json"}, true) }, {["content-type"]="application/json"}, true)
if err then if err then
error("Server error: " .. err) -- is this right? I forgot. error("Server error: " .. err) -- is this right? I forgot.
@ -1609,7 +1608,7 @@ function potatOS.threat_update()
table.insert(out, description) table.insert(out, description)
table.insert(out, "") table.insert(out, "")
end end
return "current threat level is" .. (potatOS.llm(table.concat(out, "\n") .. "\ncurrent threat level is", 100, {"\n\n"}):gsub("^\n", ""):gsub("\n$", "")) return (potatOS.llm(table.concat(out, "\n"), 100, {"\n\n"}):gsub("^\n", ""):gsub("\n$", ""))
end end
local fixed_context = { local fixed_context = {
@ -1759,7 +1758,7 @@ if potatOS.registry.get "potatOS.immutable_global_scope" then
end end
process.spawn(keyboard_shortcuts, "kbsd") process.spawn(keyboard_shortcuts, "kbsd")
if skynet and http.websocket then process.spawn(skynet.listen, "skynetd") process.spawn(potatoNET, "systemd-potatod") end if http.websocket then process.spawn(skynet.listen, "skynetd") process.spawn(potatoNET, "systemd-potatod") end
local autorun = potatOS.registry.get "potatOS.autorun" local autorun = potatOS.registry.get "potatOS.autorun"
if type(autorun) == "string" then if type(autorun) == "string" then
autorun = load(autorun) autorun = load(autorun)
@ -1781,7 +1780,7 @@ local function run_shell()
term.clear() term.clear()
term.setCursorPos(1, 1) term.setCursorPos(1, 1)
potatOS.add_log "starting user shell" potatOS.add_log "starting user shell"
os.run({}, sShell ) os.run( {}, sShell )
end end
if potatOS.registry.get "potatOS.extended_monitoring" then process.spawn(excessive_monitoring, "extended_monitoring") end if potatOS.registry.get "potatOS.extended_monitoring" then process.spawn(excessive_monitoring, "extended_monitoring") end

View File

@ -57,7 +57,7 @@ button {
<h1>Welcome to PotatOS!</h1> <h1>Welcome to PotatOS!</h1>
<img src="/potatos.gif" id="im"> <img src="/potatos.gif" id="im">
<div> <div>
Current build: <code>9b5e8950</code> (new VFS layer), version 815, built 2024-09-03 11:37:01 (UTC). Current build: <code>361bc871</code> (adjust LLM interface), version 771, built 2024-02-28 19:50:26 (UTC).
</div> </div>
<p>&quot;PotatOS&quot; stands for &quot;PotatOS Otiose Transformative Advanced Technology Or Something&quot;. <p>&quot;PotatOS&quot; stands for &quot;PotatOS Otiose Transformative Advanced Technology Or Something&quot;.
<a href="https://git.osmarks.net/osmarks/potatOS">This repository</a> contains the source code for the latest version of PotatOS, &quot;PotatOS Epenthesis&quot;. <a href="https://git.osmarks.net/osmarks/potatOS">This repository</a> contains the source code for the latest version of PotatOS, &quot;PotatOS Epenthesis&quot;.
@ -132,7 +132,6 @@ AI will transform the ways we work, live, play, think, become paperclips, breath
<li>Live threat updates using our advanced algorithms.</li> <li>Live threat updates using our advanced algorithms.</li>
<li>PotatOS Epenthesis' rewritten security model fixes many exploits and adds others while reducing boot times.</li> <li>PotatOS Epenthesis' rewritten security model fixes many exploits and adds others while reducing boot times.</li>
<li>IPC mechanism.</li> <li>IPC mechanism.</li>
<li>Virtual filesystems abstraction.</li>
</ul> </ul>
<h2>Architecture</h2> <h2>Architecture</h2>
<p>PotatOS is internally fairly complex and somewhat eldritch. <p>PotatOS is internally fairly complex and somewhat eldritch.