Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local parentShell = rawget(_G, "shell")
- local bExit = false
- local sDir = --[[(parentShell and parentShell.dir()) or --]]""
- local sPath = --[[(parentShell and parentShell.path()) or --]]".:/rom/programs"
- local tAliases = --[[(false and parentShell and parentShell.aliases()) or --]]{}
- local tProgramStack = {}
- local shell = {}
- local tEnv = {
- ["shell"] = shell,
- }
- setmetatable(tEnv, {__index = KilOS.sandbox})
- local function runfile( _tEnv, _sPath, ... )
- local tArgs = { ... }
- local fnFile, err = loadfile( _sPath )
- if fnFile then
- local tEnv = _tEnv
- --setmetatable( tEnv, { __index = function(t,k) return _G[k] end } )
- --setmetatable( tEnv, { __index = _G } )
- setfenv( fnFile, tEnv )
- local ok, err = pcall( function()
- fnFile( unpack( tArgs ) )
- end )
- if not ok then
- if err and err ~= "" then
- print( err )
- end
- return false
- end
- return true
- end
- if err and err ~= "" then
- print( err )
- end
- return false
- end
- local function run( _sCommand, ... )
- local sPath = shell.resolveProgram( _sCommand )
- if sPath ~= nil then
- tProgramStack[#tProgramStack + 1] = sPath
- local result = runfile( KilOS.sandbox, sPath, ... )
- tProgramStack[#tProgramStack] = nil
- return result
- else
- return false, "No such program"
- 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
- if str.startsWith(sDir, "/") then
- sDir = sDir:sub(2)
- end
- if not str.endsWith(sDir, "/") then
- sDir = sDir.."/"
- end
- end
- function shell.getDirName()
- local ret = sDir
- if user.getName() then
- if str.startsWith(sDir, "home/"..user.getName().."/") then
- ret = sDir:sub(#user.getName() + 7)
- ret = "~/"..ret
- end
- end
- return ret
- end
- function shell.path()
- return sPath
- end
- function shell.setPath( _sPath )
- sPath = _sPath
- end
- function shell.resolve( _sPath )
- if str.startsWith(_sPath , "~") then
- _sPath = "/home/"..user.getName().._sPath:sub(2)
- end
- if str.startsWith(_sPath , "/~") then
- _sPath = "/home/"..user.getName().._sPath:sub(3)
- end
- 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
- if user.getName() then
- shell.setDir("/home/"..user.getName())
- else
- shell.setDir("/")
- end
- print( KilOS.version() )
- -- If this is the toplevel shell, run the startup programs
- --[[if parentShell == nil then
- -- Run the startup from the ROM first
- local sRomStartup = shell.resolveProgram( "/rom/startup" )
- if sRomStartup then
- shell.run( sRomStartup )
- end
- -- Then run the user created startup, from the disks or the root
- local sUserStartup = shell.resolveProgram( "/startup" )
- for n,sSide in pairs( redstone.getSides() ) do
- if disk.isPresent( sSide ) and disk.hasData( sSide ) then
- local sDiskStartup = shell.resolveProgram( fs.combine(disk.getMountPath( sSide ), "startup") )
- if sDiskStartup then
- sUserStartup = sDiskStartup
- break
- end
- end
- end
- if sUserStartup then
- shell.run( sUserStartup )
- end
- end--]]
- -- Run any programs passed in as arguments
- local tArgs = { ... }
- if #tArgs > 0 then
- shell.run( ... )
- end
- -- Read commands and execute them
- local tCommandHistory = {}
- while not bExit do
- write( shell.getDirName() .. "> " )
- local sLine = read( nil, tCommandHistory )
- table.insert( tCommandHistory, sLine )
- local s, m = runLine( sLine )
- if m ~= "" then
- print(m)
- end
- end
- -- If this is the toplevel shell, run the shutdown program
- if parentShell == nil then
- if shell.resolveProgram( "shutdown" ) then
- shell.run( "shutdown" )
- end
- os.shutdown() -- just in case
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement