OC-PsychOS2/module/fs.lua

135 lines
3.1 KiB
Lua

fs = {}
fs.mounts = {}
-- basics
function fs.segments(path) -- splits *path* on each /
local segments = {}
for segment in path:gmatch("[^/]+") do
segments[#segments+1] = segment
end
return segments
end
function fs.resolve(path) -- resolves *path* to a specific filesystem mount and path
if not path or path == "." then path = os.getenv("PWD") end
if path:sub(1,1) ~= "/" then path=(os.getenv("PWD") or "").."/"..path end
local segments, rpath = fs.segments(path), "/"
for i = 2, #segments do
rpath = rpath .. segments[i] .. "/"
end
rpath = rpath:match("(.+)/") or rpath
return segments[1] or "root",rpath
end
-- generate some simple functions
for k,v in pairs({"makeDirectory","exists","isDirectory","list","lastModified","remove","size","spaceUsed","isReadOnly","getLabel"}) do
fs[v] = function(path)
local fsi,path = fs.resolve(path)
return fs.mounts[fsi][v](path)
end
end
local function fread(self,length)
length = length or "*l"
if length == "*a" then
length = math.huge
elseif length == "*l" then
local rstr, lstr = "", ""
while true do
lstr = fs.mounts[self.fs].read(self.fid,1)
if lstr == "\n" or not lstr then
break
end
rstr = rstr .. lstr
end
return rstr
end
if type(length) == "number" then
local rstr, lstr = "", ""
repeat
lstr = fs.mounts[self.fs].read(self.fid,math.min(2^16,length-rstr:len())) or ""
rstr = rstr .. lstr
until rstr:len() == length or lstr == ""
return rstr
end
return fs.mounts[self.fs].read(self.fid,length)
end
local function fwrite(self,data)
fs.mounts[self.fs].write(self.fid,data)
end
local function fseek(self,dist)
fs.mounts[self.fs].seek(self.fid,dist)
end
local function fclose(self)
fs.mounts[self.fs].close(self.fid)
end
function fs.open(path,mode) -- opens file *path* with mode *mode*
mode = mode or "rb"
local fsi,path = fs.resolve(path)
if not fs.mounts[fsi] then return false end
local fid = fs.mounts[fsi].open(path,mode)
if fid then
local fobj = {["fs"]=fsi,["fid"]=fid,["seek"]=fseek,["close"]=fclose}
if mode:find("r") then
fobj.read = fread
end
if mode:find("w") then
fobj.write = fwrite
end
return fobj
end
return false
end
function fs.copy(from,to) -- copies a file from *from* to *to*
local of = fs.open(from,"rb")
local df = fs.open(to,"wb")
if not of or not df then
return false
end
df:write(of:read("*a"))
df:close()
of:close()
end
function fs.rename(from,to) -- moves file *from* to *to*
local ofsi, opath = fs.resolve(from)
local dfsi, dpath = fs.resolve(to)
if ofsi == dfsi then
fs.mounts[ofsi].rename(opath,dpath)
return true
end
fs.copy(from,to)
fs.remove(from)
return true
end
fs.mounts.temp = component.proxy(computer.tmpAddress())
if computer.getBootAddress then
fs.mounts.boot = component.proxy(computer.getBootAddress())
end
for addr, _ in component.list("filesystem") do
fs.mounts[addr:sub(1,3)] = component.proxy(addr)
end
local function rf()
return false
end
fs.mounts.root = {}
for k,v in pairs(fs.mounts.temp) do
fs.mounts.root[k] = rf
end
function fs.mounts.root.list()
local t = {}
for k,v in pairs(fs.mounts) do
t[#t+1] = k
end
t.n = #t
return t
end
function fs.mounts.root.isReadOnly()
return true
end