245 lines
6.1 KiB
Plaintext
245 lines
6.1 KiB
Plaintext
-- Copyright (C) 2025 ASTRONAND
|
|
-- File open modes
|
|
-- M | H | D
|
|
-- rc | r | Read and close
|
|
-- r | r | Read
|
|
-- w | w | Write
|
|
-- o | w | Overite file
|
|
-- om | m | Overite and modify
|
|
-- rw | m | Read and write
|
|
-- x | f | get function
|
|
|
|
local args=({...})[1]
|
|
local fs={}
|
|
local disks={}
|
|
local mounts={}
|
|
local bootDrive=args.bootDrive
|
|
local auth=args.auth
|
|
local log=args.logging
|
|
|
|
for t, o in component.list() do
|
|
if t=="disk" then
|
|
if o.id==bootDrive.id then
|
|
else disks[o.id]=o end
|
|
end
|
|
end
|
|
|
|
local function resolve(path)
|
|
if string.sub(path,1,1)~="/" then
|
|
path="/"..path
|
|
end
|
|
local drive=bootDrive
|
|
for i,v in pairs(mounts) do
|
|
if string.hasPrefix(path,v) then
|
|
drive=disks[i]
|
|
path=string.getSuffix(path,v)
|
|
break
|
|
end
|
|
end
|
|
return drive, path
|
|
end
|
|
|
|
local function checkPerms(path, mode)
|
|
|
|
end
|
|
|
|
local function getHandle(backing,typ,clear)
|
|
local ret={}
|
|
local close=false
|
|
ret.close=function()
|
|
close=true
|
|
end
|
|
if typ=="r" then
|
|
ret.read=function()
|
|
if close then return "Handle closed" end
|
|
return backing.read()
|
|
end
|
|
ret.lines=function()
|
|
if close then error() end
|
|
local lines=string.split(backing.read(), "\n")
|
|
local i=0
|
|
return function()
|
|
i=i+1
|
|
return lines[i]
|
|
end
|
|
end
|
|
elseif typ=="w" then
|
|
ret.write=function(data)
|
|
if close then return "Handle closed" end
|
|
backing.append(data)
|
|
end
|
|
elseif typ=="m" then
|
|
ret.read=function()
|
|
if close then return "Handle closed" end
|
|
return backing.read()
|
|
end
|
|
ret.lines=function()
|
|
if close then error() end
|
|
local lines=string.split(backing.read(), "\n")
|
|
local i=0
|
|
return function()
|
|
i=i+1
|
|
return lines[i]
|
|
end
|
|
end
|
|
ret.write=function(data)
|
|
if close then return "Handle closed" end
|
|
backing.append(data)
|
|
end
|
|
end
|
|
if clear then
|
|
ret.clear=function()
|
|
if close then return "Handle closed" end
|
|
backing.write()
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
local function open(path, mode, arg, pc)
|
|
if pc then
|
|
checkPerms(path, mode)
|
|
end
|
|
local drive, newPath = resolve(path)
|
|
if drive:directoryExists(newPath) then error("Cannot open directory") end
|
|
if not drive:fileExists(newPath) then error("File does not exist") end
|
|
local backing=drive:open(newPath)
|
|
if mode=="rc" then
|
|
local file=getHandle(backing,"r")
|
|
local text=file.read()
|
|
file.close()
|
|
return text
|
|
elseif mode=="r" then
|
|
return getHandle(backing,"r")
|
|
elseif mode=="w" then
|
|
return getHandle(backing,"w")
|
|
elseif mode=="o" then
|
|
local file=getHandle(backing,"w",true)
|
|
file.clear()
|
|
file.clear=nil
|
|
return file
|
|
elseif mode=="om" then
|
|
local file=getHandle(backing,"m",true)
|
|
file.clear()
|
|
file.clear=nil
|
|
return file
|
|
elseif mode=="rw" then
|
|
return getHandle(backing,"m")
|
|
elseif mode=="x" then
|
|
local file=getHandle(backing,"r")
|
|
local text=file.read()
|
|
file.close()
|
|
return load(text, path, nil, table.deepcopy(_G))
|
|
elseif mode=="xe" then
|
|
local file=getHandle(backing,"r")
|
|
local text=file.read()
|
|
file.close()
|
|
return load(text, path, nil, arg)
|
|
else
|
|
error("Invailid mode")
|
|
end
|
|
end
|
|
|
|
function fs.open(path, mode, arg)
|
|
return open(path, mode, arg, true)
|
|
end
|
|
|
|
function fs.copy(orig, dest)
|
|
local destFile = fs.open(dest,"o")
|
|
local origFile = fs.open(orig, "rc")
|
|
destFile.write(origFile)
|
|
destFile.close()
|
|
end
|
|
|
|
function fs.move(orig, dest)
|
|
local destFile = fs.open(dest,"o")
|
|
local origFile = fs.open(orig, "rc")
|
|
destFile.write(origFile)
|
|
destFile.close()
|
|
fs.delete(orig)
|
|
end
|
|
|
|
-- This fixes the weirdest bug ever
|
|
local isDir = function(path, pc)
|
|
if pc then checkPerms(path, "r") end
|
|
local drive, newPath = resolve(path)
|
|
return drive:directoryExists(newPath)
|
|
end
|
|
|
|
local exists = function(path, pc)
|
|
if pc then checkPerms(path, "r") end
|
|
local drive, newPath = resolve(path)
|
|
return ((drive:directoryExists(newPath)) or (drive:fileExists(newPath)))
|
|
end
|
|
|
|
local delete = function(path, pc)
|
|
if pc then checkPerms(path, "w") end
|
|
local drive, newPath = resolve(path)
|
|
return drive:delete(newPath)
|
|
end
|
|
|
|
local list = function(path, pc)
|
|
if pc then checkPerms(path, "w") end
|
|
local drive, newPath = resolve(path)
|
|
return drive:list(newPath)
|
|
end
|
|
|
|
function fs.list(path)
|
|
return list(path, true)
|
|
end
|
|
|
|
function fs.isDir(path)
|
|
return isDir(path, true)
|
|
end
|
|
|
|
function fs.exists(path)
|
|
return exists(path, true)
|
|
end
|
|
|
|
function fs.delete(path)
|
|
return delete(path, true)
|
|
end
|
|
|
|
function fs.getSudo(key)
|
|
if auth.sudo.isAproved(key) then
|
|
return {
|
|
createVirtDisk=function(virtualDiskName,virtualDiskObj)
|
|
disks[virtualDiskName]=virtualDiskObj
|
|
log.log("Created VirtIO disk named "..virtualDiskName)
|
|
end,
|
|
mount=function(hardwareDir,path)
|
|
mounts[hardwareDir]=path
|
|
log.log("Mounted disk ")
|
|
end,
|
|
unmount=function(hardwareDir)
|
|
mounts[hardwareDir]=nil
|
|
end,
|
|
eject=function(hardwareDir)
|
|
disks[hardwareDir]=nil
|
|
end,
|
|
sfs={
|
|
open=function(path, mode, arg)
|
|
return open(path, mode, arg)
|
|
end,
|
|
delete=function(path)
|
|
return delete(path)
|
|
end,
|
|
copy=fs.copy,
|
|
move=fs.move,
|
|
exists=function(path)
|
|
return exists(path)
|
|
end,
|
|
isDir=function(path)
|
|
return isDir(path)
|
|
end,
|
|
list=function(path)
|
|
return list(path)
|
|
end
|
|
}
|
|
}
|
|
else
|
|
error("sudo request denied")
|
|
end
|
|
end
|
|
|
|
return fs |