175 lines
4.9 KiB
Lua
175 lines
4.9 KiB
Lua
local debug = ...
|
|
|
|
local filesystem = {}
|
|
local component = require("component")
|
|
local computer = require("computer")
|
|
local mounts = {}
|
|
|
|
--false if file, true if dir
|
|
local function isFileOrDir(path)
|
|
return (string.sub(path, -1) == "/")
|
|
end
|
|
local function removeFilename(path) -- this sucks
|
|
local t = {}
|
|
local s = ""
|
|
|
|
for i in string.gmatch(path, "[^/]+") do
|
|
table.insert(t,i)
|
|
end
|
|
|
|
table.remove(t,#t)
|
|
|
|
if #t == 0 then
|
|
return "/"
|
|
end
|
|
for i=1,#t do
|
|
s = s .. t[i] .. "/"
|
|
end
|
|
if s:sub(1,1) ~= "/" then
|
|
s = "/" .. s
|
|
end
|
|
|
|
return s
|
|
end
|
|
local function log(msg,d)
|
|
if d then
|
|
if debug then
|
|
Journal.write(msg)
|
|
end
|
|
elseif not d then
|
|
Journal.write(msg)
|
|
end
|
|
end
|
|
|
|
|
|
-- Mount/node handling
|
|
----------------------------------------------------------------------------------------------------
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
function filesystem.findNode(path,skipFileDirCheck)
|
|
--go through mounts
|
|
-- abc - / 1st iteration, does match
|
|
-- def - /mnt 2nd iteration, matches better
|
|
if not skipFileDirCheck then
|
|
if not isFileOrDir(path) then
|
|
path = removeFilename(path)
|
|
end
|
|
end
|
|
|
|
local candidate = nil
|
|
local lastNum = 0
|
|
for i=1, #mounts do
|
|
local s,e = string.find(path,mounts[i].path)
|
|
log(string.format(" [FILESYSTEM.findNode] s:%s e:%s path:%s candidate:%s lastNum:%s - tagainst %s, is id %s",s,e,path,candidate,lastNum,mounts[i].path,mounts[i].disk.address or "n/a"), true)
|
|
if e == nil then
|
|
e = 0
|
|
end
|
|
if e > lastNum and s == 1 then
|
|
candidate = mounts[i]
|
|
lastNum = e
|
|
end
|
|
end
|
|
|
|
if lastNum == 0 then
|
|
log(" [FILESYSTEM.findNode] failed", true)
|
|
return false, "did not find any matching"
|
|
else
|
|
log(" [FILESYSTEM.findNode] candidate has addr "..candidate.disk.address, true)
|
|
return candidate, nil, lastNum
|
|
end
|
|
end
|
|
|
|
function filesystem.mount(disk, path)
|
|
log(string.format(" [FILESYSTEM] mounting %sas %s", AlignString(disk,7),path),false)
|
|
-- check if disk exists
|
|
|
|
if component.get(disk, "filesystem") then
|
|
table.insert(mounts, {
|
|
["disk"]=component.proxy(disk),
|
|
["path"]=path
|
|
})
|
|
return mounts[#mounts]
|
|
else
|
|
log(string.format(" [FILESYSTEM] drive does not exist", false))
|
|
return nil, "no filesystem at address"
|
|
end
|
|
end
|
|
|
|
-- File operations
|
|
----------------------------------------------------------------------------------------------------
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
function filesystem.open(path, mode)
|
|
local mount,reason,lastNum = filesystem.findNode(path)
|
|
assert(mount,reason)
|
|
local id = mount.disk.open(path:sub(lastNum),mode)
|
|
assert(id, string.format("id is '%s', not a handle, when opening '%s' (actually '%s') as '%s'",id,path,path:sub(lastNum),mode))
|
|
return {["id"]=id,["disk"]=mount}
|
|
end
|
|
|
|
function filesystem.write(handle, data)
|
|
handle.disk.disk.write(handle.id,data)
|
|
end
|
|
|
|
function filesystem.read(handle,count)
|
|
if count == nil then
|
|
count = math.maxinteger or math.huge
|
|
end
|
|
local buffer = ""
|
|
|
|
repeat
|
|
local data = handle.disk.disk.read(handle.id, count)
|
|
buffer = buffer .. (data or "")
|
|
until not data
|
|
|
|
return buffer
|
|
end
|
|
|
|
function filesystem.close(handle)
|
|
return handle.disk.disk.close(handle.id)
|
|
end
|
|
|
|
-- Directory operations
|
|
----------------------------------------------------------------------------------------------------
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
function filesystem.makeDirectory(path)
|
|
local addr,reason,lastNum = filesystem.findNode(path,true)
|
|
assert(addr, reason)
|
|
|
|
return addr.disk.makeDirectory(path:sub(lastNum))
|
|
end
|
|
|
|
-- Misc
|
|
----------------------------------------------------------------------------------------------------
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
function filesystem.exists(path)
|
|
local addr,reason,lastNum = filesystem.findNode(path)
|
|
assert(addr, reason)
|
|
|
|
if addr.disk.isDirectory(path:sub(lastNum)) or
|
|
addr.disk.exists(path:sub(lastNum)) then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function filesystem.loadfile(path, workspace)
|
|
local handle = filesystem.open(path, "r")
|
|
local data = filesystem.read(handle)
|
|
filesystem.close(handle)
|
|
if workspace == nil then
|
|
return load(data, "=" .. path, "bt", _G)
|
|
else
|
|
return load(data, "=" .. path, "bt", workspace)
|
|
end
|
|
end
|
|
|
|
function filesystem.getlisting(path) -- handle.disk.files[path]
|
|
local mount,reason,lastNum = filesystem.findNode(path)
|
|
assert(mount, reason)
|
|
return mount.disk.list(path:sub(lastNum))
|
|
end
|
|
|
|
return filesystem |