mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 19:25:20 -04:00
added basic support for symbolic links, pretty untested as of yet, though. they're kind of like mounts in that they have to be re-created after a reboot.
This commit is contained in:
parent
9d5f44919b
commit
7f8f216682
22
assets/opencomputers/lua/rom/bin/ln.lua
Normal file
22
assets/opencomputers/lua/rom/bin/ln.lua
Normal file
@ -0,0 +1,22 @@
|
||||
local component = require("component")
|
||||
local fs = require("filesystem")
|
||||
local shell = require("shell")
|
||||
|
||||
local dirs = shell.parse(...)
|
||||
if #dirs == 0 then
|
||||
print("Usage: ln <target> [<name>]")
|
||||
return
|
||||
end
|
||||
|
||||
local target = shell.resolve(dirs[1])
|
||||
local linkpath
|
||||
if #dirs > 1 then
|
||||
linkpath = shell.resolve(dirs[2])
|
||||
else
|
||||
linkpath = fs.concat(shell.getWorkingDirectory(), fs.name(target))
|
||||
end
|
||||
|
||||
local result, reason = fs.link(target, linkpath)
|
||||
if not result then
|
||||
print(reason)
|
||||
end
|
@ -43,7 +43,9 @@ for i = 1, #dirs do
|
||||
end
|
||||
end
|
||||
for _, f in ipairs(lsf) do
|
||||
if f:sub(-4) == ".lua" then
|
||||
if fs.isLink(fs.concat(path, f)) then
|
||||
setColor(0xFFAA00)
|
||||
elseif f:sub(-4) == ".lua" then
|
||||
setColor(0x00FF00)
|
||||
else
|
||||
setColor(0xFFFFFF)
|
||||
|
@ -3,7 +3,7 @@ local unicode = require("unicode")
|
||||
|
||||
local filesystem, fileStream = {}, {}
|
||||
local isAutorunEnabled = true
|
||||
local mtab = {children={}}
|
||||
local mtab = {children={}, links={}}
|
||||
|
||||
local function segments(path)
|
||||
path = path:gsub("\\", "/")
|
||||
@ -31,19 +31,29 @@ local function segments(path)
|
||||
return parts
|
||||
end
|
||||
|
||||
local function findNode(path, create)
|
||||
local function findNode(path, create, depth)
|
||||
checkArg(1, path, "string")
|
||||
depth = depth or 0
|
||||
if depth > 100 then
|
||||
error("link cycle detected")
|
||||
end
|
||||
local parts = segments(path)
|
||||
local node = mtab
|
||||
for i = 1, #parts do
|
||||
if not node.children[parts[i]] then
|
||||
if create then
|
||||
node.children[parts[i]] = {children={}, parent=node}
|
||||
while #parts > 0 do
|
||||
local part = parts[1]
|
||||
if not node.children[part] then
|
||||
if node.links[part] then
|
||||
return findNode(filesystem.concat(node.links[part], table.concat(parts, "/", 2)), create, depth + 1)
|
||||
else
|
||||
return node, table.concat(parts, "/", i)
|
||||
if create then
|
||||
node.children[part] = {children={}, links={}, parent=node}
|
||||
else
|
||||
return node, table.concat(parts, "/")
|
||||
end
|
||||
end
|
||||
end
|
||||
node = node.children[parts[i]]
|
||||
node = node.children[part]
|
||||
table.remove(parts, 1)
|
||||
end
|
||||
return node
|
||||
end
|
||||
@ -111,6 +121,24 @@ function filesystem.get(path)
|
||||
return nil, "no such file system"
|
||||
end
|
||||
|
||||
function filesystem.isLink(path)
|
||||
local node, rest = findNode(filesystem.path(path))
|
||||
return not rest and node.links[filesystem.name(path)] ~= nil
|
||||
end
|
||||
|
||||
function filesystem.link(target, linkpath)
|
||||
checkArg(1, target, "string")
|
||||
checkArg(2, linkpath, "string")
|
||||
|
||||
if filesystem.exists(linkpath) then
|
||||
return nil, "file already exists"
|
||||
end
|
||||
|
||||
local node = findNode(filesystem.path(linkpath), true)
|
||||
node.links[filesystem.name(linkpath)] = target
|
||||
return true
|
||||
end
|
||||
|
||||
function filesystem.mount(fs, path)
|
||||
checkArg(1, fs, "string", "table")
|
||||
if type(fs) == "string" then
|
||||
@ -119,6 +147,10 @@ function filesystem.mount(fs, path)
|
||||
assert(type(fs) == "table", "bad argument #1 (file system proxy or address expected)")
|
||||
checkArg(2, path, "string")
|
||||
|
||||
if path ~= "/" and filesystem.exists(path) then
|
||||
return nil, "file already exists"
|
||||
end
|
||||
|
||||
local node = findNode(path, true)
|
||||
if node.fs then
|
||||
return nil, "another filesystem is already mounted here"
|
||||
@ -217,7 +249,7 @@ end
|
||||
|
||||
function filesystem.exists(path)
|
||||
local node, rest = findNode(path)
|
||||
if not rest then -- virtual directory
|
||||
if not rest or node.links[rest] then -- virtual directory or symbolic link
|
||||
return true
|
||||
end
|
||||
if node.fs then
|
||||
@ -266,9 +298,12 @@ function filesystem.list(path)
|
||||
result = {}
|
||||
end
|
||||
if not rest then
|
||||
for k, _ in pairs(node.children) do
|
||||
for k in pairs(node.children) do
|
||||
table.insert(result, k .. "/")
|
||||
end
|
||||
for k in pairs(node.links) do
|
||||
table.insert(result, k)
|
||||
end
|
||||
end
|
||||
table.sort(result)
|
||||
local i = 0
|
||||
@ -279,6 +314,9 @@ function filesystem.list(path)
|
||||
end
|
||||
|
||||
function filesystem.makeDirectory(path)
|
||||
if filesystem.exists(path) then
|
||||
return nil, "file or directory with that name already exists"
|
||||
end
|
||||
local node, rest = findNode(path)
|
||||
if node.fs and rest then
|
||||
return node.fs.makeDirectory(rest)
|
||||
@ -290,29 +328,49 @@ function filesystem.makeDirectory(path)
|
||||
end
|
||||
|
||||
function filesystem.remove(path)
|
||||
local node, rest = findNode(path)
|
||||
if node.fs and rest then
|
||||
return node.fs.remove(rest)
|
||||
local node, rest = findNode(filesystem.path(path))
|
||||
local name = filesystem.name(path)
|
||||
if node.children[name] then
|
||||
node.children[name] = nil
|
||||
return true
|
||||
elseif node.links[name] then
|
||||
node.links[name] = nil
|
||||
return true
|
||||
else
|
||||
node, rest = findNode(path)
|
||||
if node.fs and rest then
|
||||
return node.fs.remove(rest)
|
||||
end
|
||||
return nil, "no such file or directory"
|
||||
end
|
||||
return nil, "no such non-virtual directory"
|
||||
end
|
||||
|
||||
function filesystem.rename(oldPath, newPath)
|
||||
local oldNode, oldRest = findNode(oldPath)
|
||||
local newNode, newRest = findNode(newPath)
|
||||
if oldNode.fs and oldRest and newNode.fs and newRest then
|
||||
if oldNode.fs.address == newNode.fs.address then
|
||||
return oldNode.fs.rename(oldRest, newRest)
|
||||
else
|
||||
local result, reason = filesystem.copy(oldPath, newPath)
|
||||
if result then
|
||||
return filesystem.remove(oldPath)
|
||||
if filesystem.isLink(oldPath) then
|
||||
local node, rest = findNode(filesystem.path(oldPath))
|
||||
local target = node.links[filesystem.name(oldPath)]
|
||||
local result, reason = filesystem.link(target, newPath)
|
||||
if result then
|
||||
filesystem.remove(oldPath)
|
||||
end
|
||||
return result, reason
|
||||
else
|
||||
local oldNode, oldRest = findNode(oldPath)
|
||||
local newNode, newRest = findNode(newPath)
|
||||
if oldNode.fs and oldRest and newNode.fs and newRest then
|
||||
if oldNode.fs.address == newNode.fs.address then
|
||||
return oldNode.fs.rename(oldRest, newRest)
|
||||
else
|
||||
return nil, reason
|
||||
local result, reason = filesystem.copy(oldPath, newPath)
|
||||
if result then
|
||||
return filesystem.remove(oldPath)
|
||||
else
|
||||
return nil, reason
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil, "trying to read from or write to virtual directory"
|
||||
end
|
||||
return nil, "trying to read from or write to virtual directory"
|
||||
end
|
||||
|
||||
function filesystem.copy(fromPath, toPath)
|
||||
|
Loading…
x
Reference in New Issue
Block a user