This repository has been archived on 2024-04-19. You can view files and clone it, but cannot push or open issues or pull requests.
FREAX/bin/sh
2022-07-18 19:33:40 +02:00

256 lines
No EOL
5.6 KiB
Text

local tArgs = {...}
local parentShell = shell
local bExit = false
local sDir = (parentShell and parentShell.dir()) or ""
local sPath = (parentShell and parentShell.path()) or ".:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
local tAliases = (parentShell and parentShell.aliases()) or {}
local tProgramStack = {}
local shell = {}
local tEnv = {
["shell"] = shell,
}
local function findArg(arg)
for _,v in ipairs(tArgs) do
if v == arg then
return true
end
end
return false
end
-- Colours
local promptColour, textColour, bgColour
if term.isColour() then
promptColour = colours.yellow
textColour = colours.white
bgColour = colours.black
else
promptColour = colours.white
textColour = colours.white
bgColour = colours.black
end
local function run( _sCommand, ... )
local sPath = shell.resolveProgram( _sCommand )
if sPath ~= nil then
tProgramStack[#tProgramStack + 1] = sPath
local result = os.run( tEnv, sPath, ... )
tProgramStack[#tProgramStack] = nil
return result
else
printError( "No such program" )
printError( _sCommand .. ": Command not found" )
return false
end
end
local function runLine( _sLine )
local tWords = {}
for match in string.gmatch( _sLine, "[^ \t]+" ) do
table.insert( tWords, match )
end
local sCommand = tWords[1]
if sCommand then
return run( sCommand, unpack( tWords, 2 ) )
end
return false
end
-- Install shell API
function shell.run( ... )
return runLine( table.concat( { ... }, " " ) )
end
function shell.exit()
bExit = true
end
function shell.dir()
return sDir
end
function shell.setDir( _sDir )
sDir = _sDir
end
function shell.path()
return sPath
end
function shell.setPath( _sPath )
sPath = _sPath
end
function shell.resolve( _sPath )
local sStartChar = string.sub( _sPath, 1, 1 )
if sStartChar == "/" or sStartChar == "\\" then
return fs.combine( "", _sPath )
else
return fs.combine( sDir, _sPath )
end
end
function shell.resolveProgram( _sCommand )
-- Substitute aliases firsts
if tAliases[ _sCommand ] ~= nil then
_sCommand = tAliases[ _sCommand ]
end
-- If the path is a global path, use it directly
local sStartChar = string.sub( _sCommand, 1, 1 )
if sStartChar == "/" or sStartChar == "\\" then
local sPath = fs.combine( "", _sCommand )
if fs.exists( sPath ) and not fs.isDir( sPath ) then
return sPath
end
return nil
end
-- Otherwise, look on the path variable
for sPath in string.gmatch(sPath, "[^:]+") do
sPath = fs.combine( shell.resolve( sPath ), _sCommand )
if fs.exists( sPath ) and not fs.isDir( sPath ) then
return sPath
end
end
-- Not found
return nil
end
function shell.programs( _bIncludeHidden )
local tItems = {}
-- Add programs from the path
for sPath in string.gmatch(sPath, "[^:]+") do
sPath = shell.resolve( sPath )
if fs.isDir( sPath ) then
local tList = fs.list( sPath )
for n,sFile in pairs( tList ) do
if not fs.isDir( fs.combine( sPath, sFile ) ) and
(_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
tItems[ sFile ] = true
end
end
end
end
-- Sort and return
local tItemList = {}
for sItem, b in pairs( tItems ) do
table.insert( tItemList, sItem )
end
table.sort( tItemList )
return tItemList
end
function shell.getRunningProgram()
if #tProgramStack > 0 then
return tProgramStack[#tProgramStack]
end
return nil
end
function shell.setAlias( _sCommand, _sProgram )
tAliases[ _sCommand ] = _sProgram
end
function shell.clearAlias( _sCommand )
tAliases[ _sCommand ] = nil
end
function shell.aliases()
-- Add aliases
local tCopy = {}
for sAlias, sCommand in pairs( tAliases ) do
tCopy[sAlias] = sCommand
end
return tCopy
end
-- Custom shell API functions
function shell.executeScript(path)
if not fs.exists(path) or fs.isDir(path) then
return "File or directory not found"
else
local t = luaex.iterateFileLines(path)
if string.find(t[1], "@ @ !! FREAX SCRIPT HEADER") or t[1] == "@ @ !! FREAX SCRIPT HEADER" then
for _,cmd in pairs(t) do
shell.run(cmd)
end
else
return "Couldn't find script header"
end
end
end
function shell.getActiveUserShell()
if fs.exists("/etc/passwd/.shadow/".._G["_activeUser"]..".usr") then
local ud = dofile("/etc/passwd/.shadow/".._G["_activeUser"]..".usr")
return ud.shell or "/bin/sh"
else
return "/bin/sh"
end
end
-- Run custom shells
if findArg("--force") or findArg("-f") then
kernel.writeMessage("Ignoring shell settings")
elseif shell.getActiveUserShell() ~= "/bin/sh" then
shell.run(shell.getActiveUserShell())
kernel.shutdown(false)
end
term.setBackgroundColor( bgColour )
term.setTextColour( textColour )
local label = os.getComputerLabel() or os.getComputerID()
-- Read commands and execute them
local tCommandHistory = {}
while not bExit do
term.setBackgroundColor( bgColour )
if security.getSU() then
if security.getActiveUserStatus() then
term.setTextColour( colours.lime )
else
term.setTextColour( colours.orange )
end
else
term.setTextColour( colours.cyan )
end
write( _activeUser )
term.setTextColour( colours.lightGrey )
write( "@" )
term.setTextColour( colours.lightBlue )
write( label )
term.setTextColour( colours.lightGrey )
write( "/" )
term.setTextColour( colours.lightBlue )
write( shell.dir() )
if security.getSU() then
if security.getActiveUserStatus() then
term.setTextColour( colours.lime )
else
term.setTextColour( colours.orange )
end
write( " # " )
else
term.setTextColour( colours.cyan )
write( " $ " )
end
term.setTextColour( textColour )
local sLine = read( nil, tCommandHistory )
table.insert( tCommandHistory, sLine )
runLine( sLine )
end
-- Custom shutdown code goes here