Advertisement
Guest User

q

a guest
Apr 22nd, 2015
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.62 KB | None | 0 0
  1. local datafolder = ".data"
  2. local allowedRootFolders = {
  3.     "rom",
  4.     "disk[%d+]?"
  5. }
  6.  
  7. local _fs = fs
  8. vfs = {}
  9.  
  10. local function hardcopy(tbl)
  11.     for k,v in pairs(tbl) do
  12.         if type(v) == "table" then
  13.             if v == tbl then
  14.                 tbl[k] = tbl
  15.             else
  16.                 tbl[k] = hardcopy(v)
  17.             end
  18.         else
  19.             tbl[k] = v
  20.         end
  21.     end
  22.     return tbl
  23. end
  24.  
  25. local function assert(case, message, level)
  26.     if not case then
  27.         error(message, level + 1)
  28.     end
  29. end
  30.  
  31. local function proxyError(fn, args, level)
  32.     local level = level + 1
  33.     local results = { pcall(fn, unpack(args)) }
  34.     if not results[1] then
  35.         error(results[2]:sub(8), level)
  36.     else
  37.         table.remove(results, 1)
  38.         return unpack(results)
  39.     end
  40. end
  41.  
  42. local function clean(path)
  43.     return fs.combine(path:gsub("%.%.%.",""):gsub("%.%.",""), "")
  44. end
  45.  
  46. local function split(path)
  47.     local path = clean(path)
  48.     local out = {}
  49.     for part in path:gmatch("([^/]+)") do
  50.         table.insert(out, part)
  51.     end
  52.     return out
  53. end
  54.  
  55. local function isAllowed(path)
  56.     local path = split(path)[1] or "/"
  57.     for i,v in ipairs(allowedRootFolders) do
  58.         if path:find("^"..v.."$") then
  59.             return true
  60.         end
  61.     end
  62.     return false
  63. end
  64.  
  65. function resolve(path)
  66.     local path = clean(path)
  67.     if isAllowed(path) then
  68.         return path
  69.     else
  70.         if not _fs.isDir(datafolder) then
  71.             _fs.delete(datafolder)
  72.         end
  73.         if not _fs.exists(datafolder) then
  74.             _fs.makeDir(datafolder)
  75.         end
  76.         return _fs.combine(datafolder,path)
  77.     end
  78. end
  79.  
  80. -- VFS functions --
  81.  
  82. local simpleOverrides = { "exists", "isDir", "isReadOnly", "getDrive", "getSize", "getFreeSpace", "makeDir", "delete" }
  83.  
  84. for k,v in pairs(simpleOverrides) do
  85.     vfs[v] = function(p)
  86.         assert(type(p) == "string", "expected string", 2)
  87.         local p = resolve(p)
  88.  
  89.         return proxyError(_fs[v], {p}, 1)
  90.     end
  91. end
  92.  
  93. function vfs.list(path)
  94.     assert(type(path) == "string", "expected string",2)
  95.     local path = resolve(path)
  96.  
  97.     local out = proxyError(_fs.list, {path}, 2)
  98.     if clean(path) == datafolder then
  99.         for i,v in ipairs(_fs.list("/")) do
  100.             if isAllowed(v) then
  101.                 table.insert(out, v)
  102.             end
  103.         end
  104.     end
  105.     return out
  106. end
  107.  
  108. function vfs.move(p1, p2)
  109.     assert(type(p1) == "string" and type(p2) == "string", "expected string, string", 2)
  110.     local p1, p2 = resolve(p1), resolve(p2)
  111.  
  112.     return proxyError(_fs.move, {p1, p2}, 2)
  113. end
  114.  
  115. function vfs.copy(p1, p2)
  116.     assert(type(p1) == "string" and type(p2) == "string", "expected string, string", 2)
  117.     local p1, p2 = resolve(p1), resolve(p2)
  118.    
  119.     return proxyError(_fs.copy, {p1, p2}, 2)
  120. end
  121.  
  122. function vfs.open(path, mode)
  123.     assert(type(path) == "string" and type(mode) == "string", "expected string, string", 2)
  124.     local path = resolve(path)
  125.  
  126.     return proxyError(_fs.open, {path, mode}, 2)
  127. end
  128.  
  129. local function recurse_spec(results, path, spec)
  130.     local segment = spec:match('([^/]*)'):gsub('/', '')
  131.     local pattern = '^' .. segment:gsub("[%.%[%]%(%)%%%+%-%?%^%$]","%%%1"):gsub("%z","%%z"):gsub("%*","[^/]-") .. '$'
  132.  
  133.     if vfs.isDir(path) then
  134.         for _, file in ipairs(vfs.list(path)) do
  135.             if file:match(pattern) then
  136.                 local f = _fs.combine(path, file)
  137.  
  138.                 if spec == segment then
  139.                     table.insert(results, f)
  140.                 end
  141.                 if vfs.isDir(f) then
  142.                     recurse_spec(results, f, spec:sub(#segment + 2))
  143.                 end
  144.             end
  145.         end
  146.     end
  147. end
  148.  
  149. function vfs.find(spec)
  150.     assert(type(spec) == "string","expected string",2)
  151.     spec = clean(spec)
  152.     local results = {}
  153.     recurse_spec(results, '', spec)
  154.     return results
  155. end
  156.  
  157. for k,v in pairs(_fs) do
  158.     if not vfs[k] then
  159.         vfs[k] = v
  160.     end
  161. end
  162.  
  163. env = hardcopy(getfenv(0))
  164. env.fs = vfs
  165. term.setCursorPos(1,1)
  166. term.clear()
  167. term.redirect(term.native())
  168. setfenv(loadfile("rom/programs/shell"), env)()
  169. os.shutdown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement