mirror of
https://git.shadowkat.net/izaya/OC-PsychOS2.git
synced 2024-11-14 00:47:00 -05:00
146 lines
3.9 KiB
Lua
146 lines
3.9 KiB
Lua
do
|
|
fs = {}
|
|
local fsmounts = {}
|
|
|
|
-- 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, rfs= fs.segments(path)
|
|
local rc = #segments
|
|
for i = #segments, 1, -1 do
|
|
if fsmounts[table.concat(segments, "/", 1, i)] ~= nil then
|
|
return table.concat(segments, "/", 1, i), table.concat(segments, "/", i+1)
|
|
end
|
|
end
|
|
return "/", table.concat(segments,"/")
|
|
end
|
|
|
|
-- generate some simple functions
|
|
for k,v in pairs({"makeDirectory","exists","isDirectory","list","lastModified","remove","size","spaceUsed","spaceTotal","isReadOnly","getLabel"}) do
|
|
fs[v] = function(path)
|
|
local fsi,path = fs.resolve(path)
|
|
return fsmounts[fsi][v](path)
|
|
end
|
|
end
|
|
|
|
local function fread(self,length)
|
|
if length == "*a" then
|
|
length = math.huge
|
|
end
|
|
if type(length) == "number" then
|
|
local rstr, lstr = "", ""
|
|
repeat
|
|
lstr = fsmounts[self.fs].read(self.fid,math.min(2^16,length-rstr:len())) or ""
|
|
rstr = rstr .. lstr
|
|
until rstr:len() == length or lstr == ""
|
|
return rstr
|
|
elseif type(length) == "string" then
|
|
local buf = ""
|
|
if length == "*l" then
|
|
length = "\n"
|
|
end
|
|
repeat
|
|
local rb = fsmounts[self.fs].read(self.fid,1) or ""
|
|
buf = buf .. rb
|
|
until buf:match(length) or rb == ""
|
|
return buf:match("(.*)"..length)
|
|
end
|
|
return fsmounts[self.fs].read(self.fid,length)
|
|
end
|
|
local function fwrite(self,data)
|
|
fsmounts[self.fs].write(self.fid,data)
|
|
end
|
|
local function fseek(self,dist)
|
|
fsmounts[self.fs].seek(self.fid,dist)
|
|
end
|
|
local function fclose(self)
|
|
fsmounts[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 fsmounts[fsi] then return false end
|
|
local fid = fsmounts[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
|
|
fsmounts[ofsi].rename(opath,dpath)
|
|
return true
|
|
end
|
|
fs.copy(from,to)
|
|
fs.remove(from)
|
|
return true
|
|
end
|
|
|
|
function fs.mount(path,proxy) -- mounts the filesystem *proxy* to the mount point *path* if it is a directory. BYO proxy.
|
|
if fs.isDirectory(path) and not fsmounts[table.concat(fs.segments(path),"/")] then
|
|
fsmounts[table.concat(fs.segments(path),"/")] = proxy
|
|
return true
|
|
end
|
|
return false, "path is not a directory"
|
|
end
|
|
function fs.umount(path)
|
|
local fsi,_ = fs.resolve(path)
|
|
fsmounts[fsi] = nil
|
|
end
|
|
|
|
function fs.mounts() -- returns a table containing the mount points of all mounted filesystems
|
|
local rt = {}
|
|
for k,v in pairs(fsmounts) do
|
|
rt[#rt+1] = k,v.address or "unknown"
|
|
end
|
|
return rt
|
|
end
|
|
|
|
function fs.address(path) -- returns the address of the filesystem at a given path, if applicable; do not expect a sensical response
|
|
local fsi,_ = fs.resolve(path)
|
|
return fsmounts[fsi].address
|
|
end
|
|
function fs.type(path) -- returns the component type of the filesystem at a given path, if applicable
|
|
local fsi,_ = fs.resolve(path)
|
|
return fsmounts[fsi].type
|
|
end
|
|
|
|
fsmounts["/"] = component.proxy(computer.tmpAddress())
|
|
fs.makeDirectory("temp")
|
|
if computer.getBootAddress then
|
|
fs.makeDirectory("boot")
|
|
fs.mount("boot",component.proxy(computer.getBootAddress()))
|
|
end
|
|
|
|
end
|