v2.4.0 - Added a /special/ folder with files for interacting with unmanaged drives and EEPROMs.
This commit is contained in:
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
local agcfg = {
|
local agcfg = {
|
||||||
["halyde"] = {
|
["halyde"] = {
|
||||||
["maindir"] = "",
|
["maindir"] = "",
|
||||||
["version"] = "2.3.0",
|
["version"] = "2.4.0",
|
||||||
["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.",
|
["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.",
|
||||||
["directories"] = {
|
["directories"] = {
|
||||||
"halyde/apps",
|
"halyde/apps",
|
||||||
@@ -10,7 +10,7 @@ local agcfg = {
|
|||||||
"halyde/core",
|
"halyde/core",
|
||||||
"halyde/drivers",
|
"halyde/drivers",
|
||||||
"halyde/lib",
|
"halyde/lib",
|
||||||
"halyde"
|
"halyde",
|
||||||
"home",
|
"home",
|
||||||
"mnt"
|
"mnt"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
local loadfile = ...
|
local loadfile = ...
|
||||||
local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile)
|
local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile)
|
||||||
|
|
||||||
_G._OSVERSION = "Halyde 2.3.0"
|
_G._OSVERSION = "Halyde 2.4.0"
|
||||||
_G._OSLOGO = ""
|
_G._OSLOGO = ""
|
||||||
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
|
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
|
||||||
repeat
|
repeat
|
||||||
@@ -32,6 +32,7 @@ function _G.import(module, ...)
|
|||||||
tmpdata = handle:read(math.huge or math.maxinteger)
|
tmpdata = handle:read(math.huge or math.maxinteger)
|
||||||
data = data .. (tmpdata or "")
|
data = data .. (tmpdata or "")
|
||||||
until not tmpdata
|
until not tmpdata
|
||||||
|
handle:close()
|
||||||
return(assert(load(data, "="..modulepath))(table.unpack(args)))
|
return(assert(load(data, "="..modulepath))(table.unpack(args)))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ local function findCodeEnd(text,i)
|
|||||||
return v>=min and v<=max
|
return v>=min and v<=max
|
||||||
end
|
end
|
||||||
i=i+2
|
i=i+2
|
||||||
while not inRange(text:byte(i),0x40,0x7F) do i=i+1 end
|
while i<=#text and not inRange(text:byte(i),0x40,0x7F) do i=i+1 end
|
||||||
return i
|
return i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+358
-225
@@ -71,6 +71,12 @@ function filesystem.exists(path) -- check if path exists
|
|||||||
if not address then
|
if not address then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
if absPath:find("^/special/drive/...") then
|
||||||
|
return not not (computer.getBootAddress() and component.get(absPath:sub(16,18)))
|
||||||
|
end
|
||||||
|
if absPath:find("^/special/eeprom/") then
|
||||||
|
return table.find({"init.lua","data.bin","label.txt"},absPath:sub(17))
|
||||||
|
end
|
||||||
return component.invoke(address, "exists", absPath)
|
return component.invoke(address, "exists", absPath)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -106,231 +112,6 @@ local function iterateUnicodeChars(self)
|
|||||||
return unicode.iterate(iterateBytes(self))
|
return unicode.iterate(iterateBytes(self))
|
||||||
end
|
end
|
||||||
|
|
||||||
function filesystem.open(path, mode, buffered) -- opens a file and returns its handle
|
|
||||||
checkArg(1, path, "string")
|
|
||||||
checkArg(2, mode, "string", "nil")
|
|
||||||
checkArg(3, buffered, "boolean", "nil")
|
|
||||||
if not mode then
|
|
||||||
mode = "r"
|
|
||||||
end
|
|
||||||
if not buffered then
|
|
||||||
buffered = true
|
|
||||||
end
|
|
||||||
if not (mode == "r" or mode == "w" or mode == "rb" or mode == "wb" or mode == "a" or mode == "ab") then
|
|
||||||
return nil, "invalid handle type"
|
|
||||||
end
|
|
||||||
local address, absPath = filesystem.absolutePath(path)
|
|
||||||
local handleArgs = {component.invoke(address, "open", absPath, mode)}
|
|
||||||
local handle = handleArgs[1]
|
|
||||||
if not handle then
|
|
||||||
return table.unpack(handleArgs)
|
|
||||||
end
|
|
||||||
handleArgs = nil
|
|
||||||
local properHandle = {}
|
|
||||||
properHandle.handle = handle
|
|
||||||
properHandle.address = address
|
|
||||||
local content = nil
|
|
||||||
local readcursor = 1
|
|
||||||
if buffered and mode:sub(1,1)=="r" then
|
|
||||||
content=""
|
|
||||||
repeat
|
|
||||||
tmpdata = component.invoke(address, "read", handle, math.huge or math.maxinteger)
|
|
||||||
content = content .. (tmpdata or "")
|
|
||||||
until not tmpdata
|
|
||||||
component.invoke(address, "close", handle)
|
|
||||||
end
|
|
||||||
function properHandle.read(self, amount)
|
|
||||||
checkArg(2, amount, "number")
|
|
||||||
if buffered then
|
|
||||||
local limit = string.len(content)+1
|
|
||||||
local out = nil
|
|
||||||
if readcursor<limit then
|
|
||||||
if amount==math.huge then
|
|
||||||
out = string.sub(content,math.min(readcursor,limit))
|
|
||||||
else
|
|
||||||
out = string.sub(content,math.min(readcursor,limit),math.min(readcursor+amount-1,limit))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
readcursor=readcursor+amount
|
|
||||||
if out=="" then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
return out
|
|
||||||
else
|
|
||||||
return component.invoke(self.address, "read", self.handle, amount)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
properHandle.readBytes = readBytes
|
|
||||||
properHandle.readUnicodeChar = readUnicodeChar
|
|
||||||
properHandle.iterateBytes = iterateBytes
|
|
||||||
properHandle.iterateUnicodeChars = iterateUnicodeChars
|
|
||||||
function properHandle.write(self, data)
|
|
||||||
checkArg(2, data, "string")
|
|
||||||
return component.invoke(self.address, "write", self.handle, data)
|
|
||||||
end
|
|
||||||
function properHandle.close(self)
|
|
||||||
if buffered then
|
|
||||||
content = nil
|
|
||||||
else
|
|
||||||
return component.invoke(self.address, "close", self.handle)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return properHandle
|
|
||||||
end
|
|
||||||
|
|
||||||
function filesystem.list(path)
|
|
||||||
checkArg(1, path, "string")
|
|
||||||
path = filesystem.canonical(path)
|
|
||||||
if path == "/mnt" then
|
|
||||||
-- list drives
|
|
||||||
local returnTable = {}
|
|
||||||
local tmpAddress = computer.tmpAddress()
|
|
||||||
for address, _ in component.list("filesystem") do
|
|
||||||
if address~=tmpAddress then
|
|
||||||
table.insert(returnTable, address:sub(1, 3) .. "/")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return returnTable
|
|
||||||
else
|
|
||||||
local address, absPath = filesystem.absolutePath(path)
|
|
||||||
if not address then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return component.invoke(address, "list", absPath)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function filesystem.size(path)
|
|
||||||
checkArg(1, path, "string")
|
|
||||||
local address, absPath = filesystem.absolutePath(path)
|
|
||||||
if not address then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return component.invoke(address, "size", absPath)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function getRecursiveList(address,absPath)
|
|
||||||
local list = component.invoke(address,"list",absPath)
|
|
||||||
local dirList = {}
|
|
||||||
local listChanged = true
|
|
||||||
while listChanged do
|
|
||||||
listChanged = false
|
|
||||||
for i=1,#list do
|
|
||||||
if component.invoke(address, "isDirectory", absPath.."/"..list[i]) then
|
|
||||||
listChanged = true
|
|
||||||
local dir = list[i]
|
|
||||||
if dir:sub(-1)=="/" then dir=dir:sub(1,-2) end
|
|
||||||
table.insert(dirList,dir)
|
|
||||||
table.remove(list,i)
|
|
||||||
local subDir = component.invoke(address,"list",absPath.."/"..dir)
|
|
||||||
for j=1,#subDir do table.insert(list,dir.."/"..subDir[j]) end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return list,dirList
|
|
||||||
end
|
|
||||||
|
|
||||||
local function copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
|
|
||||||
if fromAbsPath:sub(-1)=="/" then fromAbsPath=fromAbsPath:sub(1,-2) end
|
|
||||||
if toAbsPath:sub(-1)=="/" then toAbsPath=toAbsPath:sub(1,-2) end
|
|
||||||
component.invoke(toAddress,"makeDirectory",toAbsPath)
|
|
||||||
local fileList,dirList = getRecursiveList(fromAddress,fromAbsPath)
|
|
||||||
for i=1,#dirList do
|
|
||||||
component.invoke(toAddress,"makeDirectory",toAbsPath.."/"..dirList[i])
|
|
||||||
end
|
|
||||||
for i=1,#fileList do
|
|
||||||
local fromFile, toFile = fromAbsPath.."/"..fileList[i], toAbsPath.."/"..fileList[i]
|
|
||||||
local handle = component.invoke(fromAddress, "open", fromFile, "r")
|
|
||||||
local data, tmpdata = "", nil
|
|
||||||
repeat
|
|
||||||
tmpdata = component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
|
|
||||||
data = data .. (tmpdata or "")
|
|
||||||
until not tmpdata
|
|
||||||
tmpdata = component.invoke(fromAddress, "close", handle)
|
|
||||||
local handle = component.invoke(toAddress, "open", toFile, "w")
|
|
||||||
component.invoke(toAddress, "write", handle, data)
|
|
||||||
component.invoke(toAddress, "close", handle)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function filesystem.rename(fromPath, toPath)
|
|
||||||
checkArg(1, fromPath, "string")
|
|
||||||
checkArg(2, toPath, "string")
|
|
||||||
local fromAddress, fromAbsPath = filesystem.absolutePath(fromPath)
|
|
||||||
local toAddress, toAbsPath = filesystem.absolutePath(toPath)
|
|
||||||
if not fromAddress or not toAddress then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
if fromAddress == toAddress then
|
|
||||||
return component.invoke(fromAddress, "rename", fromAbsPath, toAbsPath)
|
|
||||||
elseif component.invoke(fromAddress, "isDirectory", fromAbsPath) then
|
|
||||||
copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
|
|
||||||
component.invoke(fromAddress,"remove", fromAbsPath)
|
|
||||||
else
|
|
||||||
local handle, data, tmpdata = component.invoke(fromAddress, "open", fromAbsPath, "r"), "", nil
|
|
||||||
repeat
|
|
||||||
tmpdata = component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
|
|
||||||
data = data .. (tmpdata or "")
|
|
||||||
until not tmpdata
|
|
||||||
tmpdata = component.invoke(fromAddress, "close", handle)
|
|
||||||
local handle = component.invoke(toAddress, "open", toAbsPath, "w")
|
|
||||||
component.invoke(toAddress, "write", handle, data)
|
|
||||||
component.invoke(toAddress, "close", handle)
|
|
||||||
component.invoke(fromAddress, "remove", fromAbsPath)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function filesystem.copy(fromPath, toPath)
|
|
||||||
checkArg(1, fromPath, "string")
|
|
||||||
checkArg(2, toPath, "string")
|
|
||||||
local fromAddress, fromAbsPath = filesystem.absolutePath(fromPath)
|
|
||||||
local toAddress, toAbsPath = filesystem.absolutePath(toPath)
|
|
||||||
if not fromAddress or not toAddress then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
if component.invoke(fromAddress, "isDirectory", fromAbsPath) then
|
|
||||||
copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
|
|
||||||
else
|
|
||||||
local handle = component.invoke(fromAddress, "open", fromAbsPath, "r")
|
|
||||||
local data, tmpdata = "", nil
|
|
||||||
repeat
|
|
||||||
tmpdata = component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
|
|
||||||
data = data .. (tmpdata or "")
|
|
||||||
until not tmpdata
|
|
||||||
tmpdata = component.invoke(fromAddress, "close", handle)
|
|
||||||
local handle = component.invoke(toAddress, "open", toAbsPath, "w")
|
|
||||||
component.invoke(toAddress, "write", handle, data)
|
|
||||||
component.invoke(toAddress, "close", handle)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function filesystem.isDirectory(path)
|
|
||||||
checkArg(1, path, "string")
|
|
||||||
local address, absPath = filesystem.absolutePath(path)
|
|
||||||
if not address then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return component.invoke(address, "isDirectory", absPath)
|
|
||||||
end
|
|
||||||
|
|
||||||
function filesystem.remove(path)
|
|
||||||
checkArg(1, path, "string")
|
|
||||||
local address, absPath = filesystem.absolutePath(path)
|
|
||||||
if not address then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return component.invoke(address, "remove", absPath)
|
|
||||||
end
|
|
||||||
|
|
||||||
function filesystem.makeDirectory(path)
|
|
||||||
checkArg(1, path, "string")
|
|
||||||
local address, absPath = filesystem.absolutePath(path)
|
|
||||||
if not address then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return component.invoke(address, "makeDirectory", absPath)
|
|
||||||
end
|
|
||||||
|
|
||||||
function filesystem.makeReadStream(content)
|
function filesystem.makeReadStream(content)
|
||||||
local properHandle = {}
|
local properHandle = {}
|
||||||
local readcursor = 1
|
local readcursor = 1
|
||||||
@@ -364,4 +145,356 @@ function filesystem.makeReadStream(content)
|
|||||||
return properHandle
|
return properHandle
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function filesystem.open(path, mode, buffered) -- opens a file and returns its handle
|
||||||
|
checkArg(1, path, "string")
|
||||||
|
checkArg(2, mode, "string", "nil")
|
||||||
|
checkArg(3, buffered, "boolean", "nil")
|
||||||
|
if not mode then
|
||||||
|
mode = "r"
|
||||||
|
end
|
||||||
|
if buffered == nil then
|
||||||
|
buffered = true
|
||||||
|
end
|
||||||
|
if not (mode == "r" or mode == "w" or mode == "rb" or mode == "wb" or mode == "a" or mode == "ab") then
|
||||||
|
return nil, "invalid handle type"
|
||||||
|
end
|
||||||
|
if path:find("^/special") and not filesystem.exists(path) then
|
||||||
|
return nil, "/special does not allow creating files"
|
||||||
|
end
|
||||||
|
local address, absPath = filesystem.absolutePath(path)
|
||||||
|
local unmanagedDrive = address==computer.getBootAddress() and absPath:find("^/special/drive")
|
||||||
|
local unmanagedProxy, sectorSize, sectorCount, handle
|
||||||
|
if unmanagedDrive then
|
||||||
|
unmanagedProxy = component.proxy(component.get(absPath:sub(16,18)))
|
||||||
|
sectorSize = unmanagedProxy.getSectorSize()
|
||||||
|
sectorCount = math.ceil(unmanagedProxy.getCapacity()/sectorSize)
|
||||||
|
elseif not (address==computer.getBootAddress() and absPath:find("^/special/")) then
|
||||||
|
local handleArgs = {component.invoke(address, "open", absPath, mode)}
|
||||||
|
handle = handleArgs[1]
|
||||||
|
if not handle then
|
||||||
|
return table.unpack(handleArgs)
|
||||||
|
end
|
||||||
|
handleArgs = nil
|
||||||
|
end
|
||||||
|
local properHandle = {}
|
||||||
|
properHandle.handle = handle
|
||||||
|
properHandle.address = address
|
||||||
|
local content = nil
|
||||||
|
local readcursor = 1
|
||||||
|
if buffered and mode:sub(1,1)=="r" then
|
||||||
|
content=""
|
||||||
|
repeat
|
||||||
|
tmpdata = component.invoke(address, "read", handle, math.huge or math.maxinteger)
|
||||||
|
content = content .. (tmpdata or "")
|
||||||
|
until not tmpdata
|
||||||
|
component.invoke(address, "close", handle)
|
||||||
|
end
|
||||||
|
function properHandle.read(self, amount)
|
||||||
|
checkArg(2, amount, "number")
|
||||||
|
if unmanagedDrive then
|
||||||
|
local sectorIdx = ((readcursor-1)//sectorSize)+1
|
||||||
|
if sectorIdx>sectorCount then return nil end
|
||||||
|
local sector = unmanagedProxy.readSector(sectorIdx)
|
||||||
|
local data = sector:sub(((readcursor-1)%sectorSize)+1,((readcursor+math.min(amount,sectorSize)-2)%sectorSize)+1)
|
||||||
|
readcursor=readcursor+#data
|
||||||
|
if data=="" then return nil end
|
||||||
|
return data
|
||||||
|
else
|
||||||
|
if buffered then
|
||||||
|
local limit = string.len(content)+1
|
||||||
|
local out = nil
|
||||||
|
if readcursor<limit then
|
||||||
|
if amount==math.huge then
|
||||||
|
out = string.sub(content,math.min(readcursor,limit))
|
||||||
|
else
|
||||||
|
out = string.sub(content,math.min(readcursor,limit),math.min(readcursor+amount-1,limit))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
readcursor=readcursor+amount
|
||||||
|
if out=="" then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
else
|
||||||
|
return component.invoke(self.address, "read", self.handle, amount)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
properHandle.readBytes = readBytes
|
||||||
|
properHandle.readUnicodeChar = readUnicodeChar
|
||||||
|
properHandle.iterateBytes = iterateBytes
|
||||||
|
properHandle.iterateUnicodeChars = iterateUnicodeChars
|
||||||
|
function properHandle.write(self, data)
|
||||||
|
checkArg(2, data, "string")
|
||||||
|
if unmanagedDrive then
|
||||||
|
local startSector = ((readcursor-1)//sectorSize)+1
|
||||||
|
if startSector>sectorCount then return nil, "not enough space" end
|
||||||
|
local startSByte = ((readcursor-1)%sectorSize)+1
|
||||||
|
local sect = unmanagedProxy.readSector(startSector)
|
||||||
|
unmanagedProxy.writeSector(startSector,sect:sub(1,startSByte-1)..data:sub(1,sectorSize-startSByte+1))
|
||||||
|
for i=2,(#data+startSByte)//sectorSize do
|
||||||
|
if startSector+i-1>sectorCount then return nil, "not enough space" end
|
||||||
|
unmanagedProxy.writeSector(startSector+i-1,data:sub(startSByte+sectorSize*(i-1),startSByte+sectorSize*i-1))
|
||||||
|
end
|
||||||
|
readcursor=readcursor+#data
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return component.invoke(self.address, "write", self.handle, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function properHandle.close(self)
|
||||||
|
if buffered then
|
||||||
|
content = nil
|
||||||
|
else
|
||||||
|
return component.invoke(self.address, "close", self.handle)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if address==computer.getBootAddress() then
|
||||||
|
local eeprom
|
||||||
|
pcall(function()
|
||||||
|
eeprom = component.eeprom
|
||||||
|
end)
|
||||||
|
if eeprom then
|
||||||
|
local getFunc, setFunc
|
||||||
|
if absPath=="/special/eeprom/init.lua" then
|
||||||
|
getFunc,setFunc = "get","set"
|
||||||
|
elseif absPath=="/special/eeprom/data.bin" then
|
||||||
|
getFunc,setFunc = "getData","setData"
|
||||||
|
elseif absPath=="/special/eeprom/label.txt" then
|
||||||
|
getFunc,setFunc = "getLabel","setLabel"
|
||||||
|
end
|
||||||
|
if mode:sub(1,1)=="r" and getFunc then
|
||||||
|
local stream = filesystem.makeReadStream(eeprom[getFunc]() or "")
|
||||||
|
properHandle.read = stream.read
|
||||||
|
properHandle.close = stream.close
|
||||||
|
elseif mode:sub(1,1)=="w" and setFunc then
|
||||||
|
local content = ""
|
||||||
|
function properHandle.write(self, data)
|
||||||
|
checkArg(2, data, "string")
|
||||||
|
content=content..data
|
||||||
|
end
|
||||||
|
function properHandle.close(self)
|
||||||
|
return eeprom[setFunc](content)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return properHandle
|
||||||
|
end
|
||||||
|
|
||||||
|
function filesystem.list(path)
|
||||||
|
checkArg(1, path, "string")
|
||||||
|
path = filesystem.canonical(path)
|
||||||
|
if path == "/mnt" then
|
||||||
|
-- list drives
|
||||||
|
local returnTable = {}
|
||||||
|
local tmpAddress = computer.tmpAddress()
|
||||||
|
for address, _ in component.list("filesystem") do
|
||||||
|
if address~=tmpAddress then
|
||||||
|
table.insert(returnTable, address:sub(1, 3) .. "/")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return returnTable
|
||||||
|
elseif path == "/special/drive" then
|
||||||
|
local returnTable = {}
|
||||||
|
local tmpAddress = computer.tmpAddress()
|
||||||
|
for address, _ in component.list("drive") do
|
||||||
|
if address~=tmpAddress then
|
||||||
|
table.insert(returnTable, address:sub(1, 3))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return returnTable
|
||||||
|
elseif path=="/special/eeprom" then
|
||||||
|
return {"init.lua","data.bin","label.txt"}
|
||||||
|
else
|
||||||
|
local address, absPath = filesystem.absolutePath(path)
|
||||||
|
if not address then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return component.invoke(address, "list", absPath)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function filesystem.size(path)
|
||||||
|
checkArg(1, path, "string")
|
||||||
|
local address, absPath = filesystem.absolutePath(path)
|
||||||
|
if not address then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if address==computer.getBootAddress() then
|
||||||
|
if absPath:find("^/special/drive") then
|
||||||
|
local drive = component.get(absPath:sub(16,18))
|
||||||
|
if not drive then return false end
|
||||||
|
return component.invoke(drive,"getCapacity")
|
||||||
|
elseif absPath:find("^/special/eeprom") then
|
||||||
|
local eeprom
|
||||||
|
pcall(function()
|
||||||
|
eeprom = component.eeprom
|
||||||
|
end)
|
||||||
|
if eeprom then
|
||||||
|
local getFunc
|
||||||
|
if absPath=="/special/eeprom/init.lua" then
|
||||||
|
getFunc = "get"
|
||||||
|
elseif absPath=="/special/eeprom/data.bin" then
|
||||||
|
getFunc = "getData"
|
||||||
|
elseif absPath=="/special/eeprom/label.txt" then
|
||||||
|
getFunc = "getLabel"
|
||||||
|
end
|
||||||
|
return #(eeprom[getFunc]())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return component.invoke(address, "size", absPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getRecursiveList(address,absPath)
|
||||||
|
local list = component.invoke(address,"list",absPath)
|
||||||
|
local dirList = {}
|
||||||
|
local listChanged = true
|
||||||
|
while listChanged do
|
||||||
|
listChanged = false
|
||||||
|
for i=1,#list do
|
||||||
|
if component.invoke(address, "isDirectory", absPath.."/"..list[i]) then
|
||||||
|
listChanged = true
|
||||||
|
local dir = list[i]
|
||||||
|
if dir:sub(-1)=="/" then dir=dir:sub(1,-2) end
|
||||||
|
table.insert(dirList,dir)
|
||||||
|
table.remove(list,i)
|
||||||
|
local subDir = component.invoke(address,"list",absPath.."/"..dir)
|
||||||
|
for j=1,#subDir do table.insert(list,dir.."/"..subDir[j]) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return list,dirList
|
||||||
|
end
|
||||||
|
|
||||||
|
local function copyContent(fromHandle,toHandle)
|
||||||
|
if not (fromHandle and toHandle) then return end
|
||||||
|
local memory = math.floor(computer.freeMemory()*0.8)
|
||||||
|
local tmpdata
|
||||||
|
while true do
|
||||||
|
tmpdata = fromHandle:read(memory)
|
||||||
|
if not tmpdata then break end
|
||||||
|
local status,reason = toHandle:write(tmpdata)
|
||||||
|
if status~=true then break end
|
||||||
|
end
|
||||||
|
fromHandle:close()
|
||||||
|
toHandle:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
|
||||||
|
-- TODO: make this use copyContent
|
||||||
|
if fromAbsPath:sub(-1)=="/" then fromAbsPath=fromAbsPath:sub(1,-2) end
|
||||||
|
if toAbsPath:sub(-1)=="/" then toAbsPath=toAbsPath:sub(1,-2) end
|
||||||
|
component.invoke(toAddress,"makeDirectory",toAbsPath)
|
||||||
|
local fileList,dirList = getRecursiveList(fromAddress,fromAbsPath)
|
||||||
|
for i=1,#dirList do
|
||||||
|
component.invoke(toAddress,"makeDirectory",toAbsPath.."/"..dirList[i])
|
||||||
|
end
|
||||||
|
for i=1,#fileList do
|
||||||
|
local fromFile, toFile = fromAbsPath.."/"..fileList[i], toAbsPath.."/"..fileList[i]
|
||||||
|
--[[ local handle = component.invoke(fromAddress, "open", fromFile, "r")
|
||||||
|
local data, tmpdata = "", nil
|
||||||
|
repeat
|
||||||
|
tmpdata = component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
|
||||||
|
data = data .. (tmpdata or "")
|
||||||
|
until not tmpdata
|
||||||
|
tmpdata = component.invoke(fromAddress, "close", handle)
|
||||||
|
local handle = component.invoke(toAddress, "open", toFile, "w")
|
||||||
|
component.invoke(toAddress, "write", handle, data)
|
||||||
|
component.invoke(toAddress, "close", handle) ]]
|
||||||
|
local fromHandle = component.invoke(fromAddress, "open", fromFile, "r")
|
||||||
|
local toHandle = component.invoke(toAddress, "open", toFile, "w")
|
||||||
|
copyContent({
|
||||||
|
["read"]=function(...) return component.invoke(fromAddress, "read", handle, ...) end,
|
||||||
|
["close"]=function(...) return component.invoke(fromAddress, "close", handle, ...) end
|
||||||
|
},{
|
||||||
|
["write"]=function(...) return component.invoke(fromAddress, "write", handle, ...) end,
|
||||||
|
["close"]=function(...) return component.invoke(fromAddress, "close", handle, ...) end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function filesystem.isDirectory(path)
|
||||||
|
checkArg(1, path, "string")
|
||||||
|
local address, absPath = filesystem.absolutePath(path)
|
||||||
|
if not address then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return component.invoke(address, "isDirectory", absPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
function filesystem.rename(fromPath, toPath)
|
||||||
|
checkArg(1, fromPath, "string")
|
||||||
|
checkArg(2, toPath, "string")
|
||||||
|
local fromAddress, fromAbsPath = filesystem.absolutePath(fromPath)
|
||||||
|
local toAddress, toAbsPath = filesystem.absolutePath(toPath)
|
||||||
|
if not fromAddress or not toAddress then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if fromAddress == toAddress then
|
||||||
|
return component.invoke(fromAddress, "rename", fromAbsPath, toAbsPath)
|
||||||
|
elseif filesystem.isDirectory(fromPath) then -- component.invoke(fromAddress, "isDirectory", fromAbsPath) then
|
||||||
|
copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
|
||||||
|
filesystem.remove(fromPath) -- component.invoke(fromAddress,"remove", fromAbsPath)
|
||||||
|
else
|
||||||
|
local handle, data, tmpdata = filesystem.open(fromPath), "", nil -- component.invoke(fromAddress, "open", fromAbsPath, "r"), "", nil
|
||||||
|
repeat
|
||||||
|
tmpdata = handle:read(math.huge or math.maxinteger) -- component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
|
||||||
|
data = data .. (tmpdata or "")
|
||||||
|
until not tmpdata
|
||||||
|
tmpdata = handle:close() -- component.invoke(fromAddress, "close", handle)
|
||||||
|
local handle = filesystem.open(toPath) -- component.invoke(toAddress, "open", toAbsPath, "w")
|
||||||
|
handle:write(data) -- component.invoke(toAddress, "write", handle, data)
|
||||||
|
handle:close() -- component.invoke(toAddress, "close", handle)
|
||||||
|
filesystem.remove(fromPath) -- component.invoke(fromAddress, "remove", fromAbsPath)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function filesystem.copy(fromPath, toPath)
|
||||||
|
checkArg(1, fromPath, "string")
|
||||||
|
checkArg(2, toPath, "string")
|
||||||
|
local fromAddress, fromAbsPath = filesystem.absolutePath(fromPath)
|
||||||
|
local toAddress, toAbsPath = filesystem.absolutePath(toPath)
|
||||||
|
if not fromAddress or not toAddress then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if filesystem.isDirectory(fromPath) then -- component.invoke(fromAddress, "isDirectory", fromAbsPath)
|
||||||
|
copyRecursive(fromAddress,fromAbsPath,toAddress,toAbsPath)
|
||||||
|
else
|
||||||
|
--[[ local handle = filesystem.open(fromPath,"r")
|
||||||
|
local data, tmpdata = "", nil
|
||||||
|
repeat
|
||||||
|
tmpdata = handle:read(math.huge or math.maxinteger)
|
||||||
|
data = data .. (tmpdata or "")
|
||||||
|
until not tmpdata
|
||||||
|
tmpdata = handle:close()
|
||||||
|
local handle = filesystem.open(toPath,"w")
|
||||||
|
handle:write(data)
|
||||||
|
handle:close() ]]
|
||||||
|
copyContent(filesystem.open(fromPath,"r"),filesystem.open(toPath,"w"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function filesystem.remove(path)
|
||||||
|
checkArg(1, path, "string")
|
||||||
|
local address, absPath = filesystem.absolutePath(path)
|
||||||
|
if not address then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if absPath:find("^/special") then return false end
|
||||||
|
if absPath:find("^/tmp") then return false end
|
||||||
|
if absPath:find("^/mnt") then return false end
|
||||||
|
return component.invoke(address, "remove", absPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
function filesystem.makeDirectory(path)
|
||||||
|
checkArg(1, path, "string")
|
||||||
|
local address, absPath = filesystem.absolutePath(path)
|
||||||
|
if not address then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return component.invoke(address, "makeDirectory", absPath)
|
||||||
|
end
|
||||||
|
|
||||||
return(filesystem)
|
return(filesystem)
|
||||||
|
|||||||
@@ -39,10 +39,15 @@ if not result then
|
|||||||
gpu.set(2,i,line)
|
gpu.set(2,i,line)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
if computer~=nil then
|
||||||
gpu.set(2,i+1, "Press any key to restart.")
|
gpu.set(2,i+1, "Press any key to restart.")
|
||||||
local evname
|
local evname
|
||||||
repeat
|
repeat
|
||||||
evname = computer.pullSignal()
|
evname = computer.pullSignal()
|
||||||
until evname == "key_down"
|
until evname == "key_down"
|
||||||
computer.shutdown(true)
|
computer.shutdown(true)
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user