Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local datafolder = ".data"
- local allowedRootFolders = {
- "rom",
- "disk[%d+]?"
- }
- local _fs = fs
- vfs = {}
- local function hardcopy(tbl)
- for k,v in pairs(tbl) do
- if type(v) == "table" then
- if v == tbl then
- tbl[k] = tbl
- else
- tbl[k] = hardcopy(v)
- end
- else
- tbl[k] = v
- end
- end
- return tbl
- end
- local function assert(case, message, level)
- if not case then
- error(message, level + 1)
- end
- end
- local function proxyError(fn, args, level)
- local level = level + 1
- local results = { pcall(fn, unpack(args)) }
- if not results[1] then
- error(results[2]:sub(8), level)
- else
- table.remove(results, 1)
- return unpack(results)
- end
- end
- local function clean(path)
- return fs.combine(path:gsub("%.%.%.",""):gsub("%.%.",""), "")
- end
- local function split(path)
- local path = clean(path)
- local out = {}
- for part in path:gmatch("([^/]+)") do
- table.insert(out, part)
- end
- return out
- end
- local function isAllowed(path)
- local path = split(path)[1] or "/"
- for i,v in ipairs(allowedRootFolders) do
- if path:find("^"..v.."$") then
- return true
- end
- end
- return false
- end
- function resolve(path)
- local path = clean(path)
- if isAllowed(path) then
- return path
- else
- if not _fs.isDir(datafolder) then
- _fs.delete(datafolder)
- end
- if not _fs.exists(datafolder) then
- _fs.makeDir(datafolder)
- end
- return _fs.combine(datafolder,path)
- end
- end
- -- VFS functions --
- local simpleOverrides = { "exists", "isDir", "isReadOnly", "getDrive", "getSize", "getFreeSpace", "makeDir", "delete" }
- for k,v in pairs(simpleOverrides) do
- vfs[v] = function(p)
- assert(type(p) == "string", "expected string", 2)
- local p = resolve(p)
- return proxyError(_fs[v], {p}, 1)
- end
- end
- function vfs.list(path)
- assert(type(path) == "string", "expected string",2)
- local path = resolve(path)
- local out = proxyError(_fs.list, {path}, 2)
- if clean(path) == datafolder then
- for i,v in ipairs(_fs.list("/")) do
- if isAllowed(v) then
- table.insert(out, v)
- end
- end
- end
- return out
- end
- function vfs.move(p1, p2)
- assert(type(p1) == "string" and type(p2) == "string", "expected string, string", 2)
- local p1, p2 = resolve(p1), resolve(p2)
- return proxyError(_fs.move, {p1, p2}, 2)
- end
- function vfs.copy(p1, p2)
- assert(type(p1) == "string" and type(p2) == "string", "expected string, string", 2)
- local p1, p2 = resolve(p1), resolve(p2)
- return proxyError(_fs.copy, {p1, p2}, 2)
- end
- function vfs.open(path, mode)
- assert(type(path) == "string" and type(mode) == "string", "expected string, string", 2)
- local path = resolve(path)
- return proxyError(_fs.open, {path, mode}, 2)
- end
- local function recurse_spec(results, path, spec)
- local segment = spec:match('([^/]*)'):gsub('/', '')
- local pattern = '^' .. segment:gsub("[%.%[%]%(%)%%%+%-%?%^%$]","%%%1"):gsub("%z","%%z"):gsub("%*","[^/]-") .. '$'
- if vfs.isDir(path) then
- for _, file in ipairs(vfs.list(path)) do
- if file:match(pattern) then
- local f = _fs.combine(path, file)
- if spec == segment then
- table.insert(results, f)
- end
- if vfs.isDir(f) then
- recurse_spec(results, f, spec:sub(#segment + 2))
- end
- end
- end
- end
- end
- function vfs.find(spec)
- assert(type(spec) == "string","expected string",2)
- spec = clean(spec)
- local results = {}
- recurse_spec(results, '', spec)
- return results
- end
- for k,v in pairs(_fs) do
- if not vfs[k] then
- vfs[k] = v
- end
- end
- env = hardcopy(getfenv(0))
- env.fs = vfs
- term.setCursorPos(1,1)
- term.clear()
- term.redirect(term.native())
- setfenv(loadfile("rom/programs/shell"), env)()
- os.shutdown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement