Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function createVFSInstance(oldFS)
- local vfs = {}
- --[[
- Structure of a FS object:
- {
- function isReadOnly(self, path)
- function exists(self, path)
- function open(self, path, mode)
- function isDir(self, path) -- optional, defaults to false
- function list(self, path) -- optional, defaults to throwing error
- function getDrive(self, path) -- optional, defaults to "unknown"
- function mkdir(self, path) -- optional, defaults to throwing error
- function delete(self, path) -- optional, defaults to throwing error
- function getSize(self, path) -- optional, defaults to always 512
- function move(self, from1, from2) -- optional
- function copy(self, from1, from2) -- optional
- function getFreeSpace(self, path) -- optional, defaults to 2MiB
- }
- ]]
- local _registeredFS = {}
- -- factory is a function(mountPoint, options) that returns a FS object
- function vfs.registerFS(name, factory)
- assert(type(name) == "string", "name must be a string")
- assert(type(factory) == "function", "factory must be a function")
- if _registeredFS[name] then
- print("Warning: Re-registering filesystem type "..name)
- print("Existing mounted filesystems will not be affected.")
- end
- _registeredFS[name] = factory
- end
- local _mountPoints = {}
- -- fsType is the name of a FS previously registered with vfs.registerFS
- function vfs.mount(mountPoint, fsType, options)
- assert(mountPoint:sub(mountPoint:len()) == "/", "mount point must end with a slash")
- assert(_mountPoints[mountPoint] == nil, "already mounted")
- assert(_registeredFS[fsType] ~= nil, "unknown fs type "..tostring(fsType))
- _mountPoints[mountPoint] = _registeredFS[fsType](mountPoint, options)
- end
- function vfs.unmount(mountPoint)
- _mountPoints[mountPoint] = nil
- end
- -- returns FS, FS-relative-path
- function vfs._resolve(path)
- if path:sub(1,1) ~= "/" then
- path = "/" .. path
- end
- if _mountPoints[path .. "/"] then
- return _mountPoints[path .. "/"], "/"
- end
- if _mountPoints[path] then
- return _mountPoints[path], "/"
- end
- local best = ""
- for k,v in pairs(_mountPoints) do
- --print(path," ",k," ",path:sub(1,k:len())," ",best)
- if path:sub(1, k:len()) == k and k:len() > best:len() then
- best = k
- end
- end
- return _mountPoints[best], "/" .. path:sub(best:len() + 1)
- end
- vfs.oldFS = oldFS
- local fs = {}
- function fs.combine(basePath, localPath)
- return oldFS.combine(basePath, localPath)
- end
- function fs.isReadOnly(path)
- local fs, rel = vfs._resolve(path)
- if not fs then return true end
- return fs:isReadOnly(rel)
- end
- function fs.getSize(path)
- local fs, rel = vfs._resolve(path)
- if not fs then return 0 end
- if fs.getSize then return fs:getSize(path) else return 512 end
- end
- function fs.move(p1, p2)
- local fs1, rel1 = vfs._resolve(p1)
- local fs2, rel2 = vfs._resolve(p2)
- if not fs1 then error("doesn't exist: "..fs1) end
- if not fs2 then error("Fuck!") end
- if fs2:exists(rel2) then
- error("already exists: "..p2)
- end
- if fs1 == fs2 and fs1.move then
- fs1:move(rel1, rel2)
- elseif fs1:exists(rel1) then
- fs.copy(p1, p2)
- fs.delete(p1)
- end
- end
- function fs.exists(path)
- local fs, rel = vfs._resolve(path)
- if not fs then return false end
- return fs:exists(rel)
- end
- local function copyFile(p1, p2)
- local f = fs.open(p1, "r")
- local d = f.readAll()
- f.close()
- f = fs.open(p2, "w")
- f.write(d)
- f.close()
- end
- local function copyDir(p1, p2)
- if not fs.exists(p2) then fs.makeDir(p2) end
- for k,v in ipairs(fs.list(p1)) do
- local p = fs.combine(p1, v)
- if fs.isDir(p) then
- copyDir(p, fs.combine(p2, v))
- else
- copyFile(p, fs.combine(p2, v))
- end
- end
- end
- function fs.copy(p1, p2)
- local fs1, rel1 = vfs._resolve(p1)
- local fs2, rel2 = vfs._resolve(p2)
- if not fs1 or not fs1:exists(rel1) then error("doesn't exist: "..p1) end
- if fs2:exists(rel2) then
- error("already exists: "..p2)
- end
- if fs1 == fs2 and fs1.copy then
- fs1:copy(rel1, rel2)
- elseif fs.isDir(p1) then
- copyDir(p1, p2)
- else
- copyFile(p1, p2)
- end
- end
- function fs.getFreeSpace(path)
- local fs, rel = vfs._resolve(path)
- if not fs then return 0 end
- if not fs.getFreeSpace then return 2097152 end
- return fs:getFreeSpace(rel)
- end
- function fs.makeDir(path)
- local fs, rel = vfs._resolve(path)
- if not fs or not fs.mkdir then error("Not supported on this device") end
- if fs:exists(rel) then error("Already exists: "..path) end
- fs:mkdir(rel)
- end
- function fs.delete(path)
- local fs, rel = vfs._resolve(path)
- if not fs or not fs.delete then error("Not supported on this device") end
- fs:delete(rel)
- end
- function fs.open(path, mode)
- local fs, rel = vfs._resolve(path)
- if not fs then return nil end
- return fs:open(rel, mode)
- end
- local function tablefind(t, v)
- for _,v2 in ipairs(t) do
- if v2 == v then return true end
- end
- end
- function fs.list(path)
- if not fs.isDir(path) then error("Not a directory",2) end
- local fs, rel = vfs._resolve(path)
- if not fs.list then error("Not supported on this device") end
- local rv
- if fs == nil then
- rv = {}
- else
- rv = fs:list(rel)
- end
- -- add mount points to list
- while path:sub(path:len()) == "/" do path = path:sub(1, path:len() - 1) end
- path = path .. "/"
- for k,v in pairs(_mountPoints) do
- if k:sub(1, path:len()) == path and k ~= path then
- local after = k:sub(path:len() + 1)
- after = after:sub(1, after:len() - 1)
- if after:find("/") == nil and not tablefind(rv, after) then
- table.insert(rv, after)
- end
- end
- end
- return rv
- end
- function fs.getDrive(path)
- local fs, rel = vfs._resolve(path)
- if not fs.getDrive then return "unknown" end
- return fs:getDrive(rel)
- end
- function fs.getName(path)
- return oldFS.getName(path)
- end
- function fs.isDir(path)
- local fs, rel = vfs._resolve(path)
- if not fs.isDir then return false end
- return fs:isDir(rel)
- end
- local fs_craftos = {
- isReadOnly = function(self, path) return oldFS.isReadOnly(self.prefix .. path) end,
- exists = function(self, path) return oldFS.exists(self.prefix .. path) end,
- open = function(self, path, mode) return oldFS.open(self.prefix .. path, mode) end,
- isDir = function(self, path) return oldFS.isDir(self.prefix .. path) end,
- list = function(self, path) return oldFS.list(self.prefix .. path) end,
- getDrive = function(self, path) return oldFS.getDrive(self.prefix .. path) end,
- mkdir = function(self, path) return oldFS.makeDir(self.prefix .. path) end,
- delete = function(self, path) return oldFS.delete(self.prefix .. path) end,
- getSize = function(self, path) return oldFS.getSize(self.prefix .. path) end,
- getFreeSpace = function(self, path) return oldFS.getFreeSpace(self.prefix .. path) end,
- move = function(self, path1, path2) return oldFS.move(self.prefix .. path1, self.prefix .. path2) end,
- copy = function(self, path1, path2) return oldFS.copy(self.prefix .. path1, self.prefix .. path2) end,
- }
- vfs.registerFS("craftos", function(mount, opts)
- local t = {prefix=opts.prefix or ""}
- setmetatable(t, {__index=fs_craftos})
- return t
- end)
- vfs.mount("/", "craftos", {})
- return vfs, fs
- end
- local vfs, fs = createVFSInstance(fs)
- rawset(_G, "vfs", vfs)
- rawset(_G, "fs", fs)
- vfs.createVFSInstance = createVFSInstance
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement