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