Advertisement
Stiepen

shell.lua

Oct 13th, 2012
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.05 KB | None | 0 0
  1.  
  2. local parentShell = rawget(_G, "shell")
  3.  
  4. local bExit = false
  5. local sDir = --[[(parentShell and parentShell.dir()) or --]]""
  6. local sPath = --[[(parentShell and parentShell.path()) or --]]".:/rom/programs"
  7. local tAliases = --[[(false and parentShell and parentShell.aliases()) or --]]{}
  8. local tProgramStack = {}
  9.  
  10. local shell = {}
  11. local tEnv = {
  12. ["shell"] = shell,
  13. }
  14.  
  15. setmetatable(tEnv, {__index = KilOS.sandbox})
  16.  
  17. local function runfile( _tEnv, _sPath, ... )
  18. local tArgs = { ... }
  19. local fnFile, err = loadfile( _sPath )
  20. if fnFile then
  21. local tEnv = _tEnv
  22. --setmetatable( tEnv, { __index = function(t,k) return _G[k] end } )
  23. --setmetatable( tEnv, { __index = _G } )
  24. setfenv( fnFile, tEnv )
  25. local ok, err = pcall( function()
  26. fnFile( unpack( tArgs ) )
  27. end )
  28. if not ok then
  29. if err and err ~= "" then
  30. print( err )
  31. end
  32. return false
  33. end
  34. return true
  35. end
  36. if err and err ~= "" then
  37. print( err )
  38. end
  39. return false
  40. end
  41.  
  42. local function run( _sCommand, ... )
  43. local sPath = shell.resolveProgram( _sCommand )
  44. if sPath ~= nil then
  45. tProgramStack[#tProgramStack + 1] = sPath
  46. local result = runfile( KilOS.sandbox, sPath, ... )
  47. tProgramStack[#tProgramStack] = nil
  48. return result
  49. else
  50. return false, "No such program"
  51. end
  52. end
  53.  
  54. local function runLine( _sLine )
  55. local tWords = {}
  56. for match in string.gmatch( _sLine, "[^ \t]+" ) do
  57. table.insert( tWords, match )
  58. end
  59.  
  60. local sCommand = tWords[1]
  61. if sCommand then
  62. return run( sCommand, unpack( tWords, 2 ) )
  63. end
  64. return false
  65. end
  66.  
  67. -- Install shell API
  68. function shell.run( ... )
  69. return runLine( table.concat( { ... }, " " ) )
  70. end
  71.  
  72. function shell.exit()
  73. bExit = true
  74. end
  75.  
  76. function shell.dir()
  77. return sDir
  78. end
  79.  
  80. function shell.setDir( _sDir )
  81. sDir = _sDir
  82. if str.startsWith(sDir, "/") then
  83. sDir = sDir:sub(2)
  84. end
  85. if not str.endsWith(sDir, "/") then
  86. sDir = sDir.."/"
  87. end
  88. end
  89.  
  90. function shell.getDirName()
  91. local ret = sDir
  92. if user.getName() then
  93. if str.startsWith(sDir, "home/"..user.getName().."/") then
  94. ret = sDir:sub(#user.getName() + 7)
  95. ret = "~/"..ret
  96. end
  97. end
  98. return ret
  99. end
  100.  
  101. function shell.path()
  102. return sPath
  103. end
  104.  
  105. function shell.setPath( _sPath )
  106. sPath = _sPath
  107. end
  108.  
  109. function shell.resolve( _sPath )
  110. if str.startsWith(_sPath , "~") then
  111. _sPath = "/home/"..user.getName().._sPath:sub(2)
  112. end
  113. if str.startsWith(_sPath , "/~") then
  114. _sPath = "/home/"..user.getName().._sPath:sub(3)
  115. end
  116. local sStartChar = string.sub( _sPath, 1, 1 )
  117. if sStartChar == "/" or sStartChar == "\\" then
  118. return fs.combine( "", _sPath )
  119. else
  120. return fs.combine( sDir, _sPath )
  121. end
  122. end
  123.  
  124. function shell.resolveProgram( _sCommand )
  125. -- Substitute aliases firsts
  126. if tAliases[ _sCommand ] ~= nil then
  127. _sCommand = tAliases[ _sCommand ]
  128. end
  129.  
  130. -- If the path is a global path, use it directly
  131. local sStartChar = string.sub( _sCommand, 1, 1 )
  132. if sStartChar == "/" or sStartChar == "\\" then
  133. local sPath = fs.combine( "", _sCommand )
  134. if fs.exists( sPath ) and not fs.isDir( sPath ) then
  135. return sPath
  136. end
  137. return nil
  138. end
  139.  
  140. -- Otherwise, look on the path variable
  141. for sPath in string.gmatch(sPath, "[^:]+") do
  142. sPath = fs.combine( shell.resolve( sPath ), _sCommand )
  143. if fs.exists( sPath ) and not fs.isDir( sPath ) then
  144. return sPath
  145. end
  146. end
  147.  
  148. -- Not found
  149. return nil
  150. end
  151.  
  152. function shell.programs( _bIncludeHidden )
  153. local tItems = {}
  154.  
  155. -- Add programs from the path
  156. for sPath in string.gmatch(sPath, "[^:]+") do
  157. sPath = shell.resolve( sPath )
  158. if fs.isDir( sPath ) then
  159. local tList = fs.list( sPath )
  160. for n,sFile in pairs( tList ) do
  161. if not fs.isDir( fs.combine( sPath, sFile ) ) and
  162. (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
  163. tItems[ sFile ] = true
  164. end
  165. end
  166. end
  167. end
  168.  
  169. -- Sort and return
  170. local tItemList = {}
  171. for sItem, b in pairs( tItems ) do
  172. table.insert( tItemList, sItem )
  173. end
  174. table.sort( tItemList )
  175. return tItemList
  176. end
  177.  
  178. function shell.getRunningProgram()
  179. if #tProgramStack > 0 then
  180. return tProgramStack[#tProgramStack]
  181. end
  182. return nil
  183. end
  184.  
  185. function shell.setAlias( _sCommand, _sProgram )
  186. tAliases[ _sCommand ] = _sProgram
  187. end
  188.  
  189. function shell.clearAlias( _sCommand )
  190. tAliases[ _sCommand ] = nil
  191. end
  192.  
  193. function shell.aliases()
  194. -- Add aliases
  195. local tCopy = {}
  196. for sAlias, sCommand in pairs( tAliases ) do
  197. tCopy[sAlias] = sCommand
  198. end
  199. return tCopy
  200. end
  201.  
  202. if user.getName() then
  203. shell.setDir("/home/"..user.getName())
  204. else
  205. shell.setDir("/")
  206. end
  207.  
  208. print( KilOS.version() )
  209.  
  210. -- If this is the toplevel shell, run the startup programs
  211. --[[if parentShell == nil then
  212. -- Run the startup from the ROM first
  213. local sRomStartup = shell.resolveProgram( "/rom/startup" )
  214. if sRomStartup then
  215. shell.run( sRomStartup )
  216. end
  217.  
  218. -- Then run the user created startup, from the disks or the root
  219. local sUserStartup = shell.resolveProgram( "/startup" )
  220. for n,sSide in pairs( redstone.getSides() ) do
  221. if disk.isPresent( sSide ) and disk.hasData( sSide ) then
  222. local sDiskStartup = shell.resolveProgram( fs.combine(disk.getMountPath( sSide ), "startup") )
  223. if sDiskStartup then
  224. sUserStartup = sDiskStartup
  225. break
  226. end
  227. end
  228. end
  229.  
  230. if sUserStartup then
  231. shell.run( sUserStartup )
  232. end
  233. end--]]
  234.  
  235. -- Run any programs passed in as arguments
  236. local tArgs = { ... }
  237. if #tArgs > 0 then
  238. shell.run( ... )
  239. end
  240.  
  241. -- Read commands and execute them
  242. local tCommandHistory = {}
  243. while not bExit do
  244. write( shell.getDirName() .. "> " )
  245.  
  246. local sLine = read( nil, tCommandHistory )
  247. table.insert( tCommandHistory, sLine )
  248. local s, m = runLine( sLine )
  249. if m ~= "" then
  250. print(m)
  251. end
  252. end
  253.  
  254. -- If this is the toplevel shell, run the shutdown program
  255. if parentShell == nil then
  256. if shell.resolveProgram( "shutdown" ) then
  257. shell.run( "shutdown" )
  258. end
  259. os.shutdown() -- just in case
  260. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement