Files
aceVM/disks/1h/sys/kernel/filesystem.sys
2025-09-29 00:03:57 -04:00

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