lib/ronin/ui/command_line/command_line.rb in ronin-0.2.2 vs lib/ronin/ui/command_line/command_line.rb in ronin-0.2.3

- old
+ new

@@ -20,77 +20,97 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #++ # require 'ronin/ui/command_line/exceptions/unknown_command' -require 'ronin/ui/command_line/commands/console' -require 'ronin/ui/console' require 'reverse_require' +require 'extlib' module Ronin module UI module CommandLine + # Directory which stores the commands + COMMANDS_DIR = File.join('ronin','ui','command_line','commands') + + # Name of the default to run + DEFAULT_COMMAND = 'console' + # # Returns the commands registered with the command-line utility. # def CommandLine.commands unless class_variable_defined?('@@ronin_commands') - paths = Gem.find_resources('bin/ronin-*') + pattern = File.join('lib',COMMANDS_DIR,'*.rb') + paths = Gem.find_resources(pattern) - @@ronin_commands = {} + @@ronin_commands = [] paths.each do |path| - next unless File.executable?(path) - name = File.basename(path).gsub(/^ronin-/,'') + name = File.basename(path).gsub(/\.rb$/,'') - @@ronin_commands[name] ||= path + @@ronin_commands << name unless @@ronin_commands.include?(name) end end return @@ronin_commands end # - # Returns +true+ if the a Command with the specified _name_ was - # registered with the command-line utility. + # Returns +true+ if a command exists with the specified _name_, + # returns +false+ otherwise. # def CommandLine.has_command?(name) - CommandLine.commands.has_key?(name.to_s) + CommandLine.commands.include?(name.to_s) end # # Returns the Command registered with the command-line utility # with the specified _name_. # def CommandLine.get_command(name) name = name.to_s - unless CommandLine.has_command?(name) + begin + require File.join(COMMANDS_DIR,name) + rescue LoadError + raise(UnknownCommand,"unable to load the command #{name.dump}",caller) + end + + class_name = name.to_const_string + + unless Commands.const_defined?(class_name) raise(UnknownCommand,"unknown command #{name.dump}",caller) end - return CommandLine.commands[name] + command = Commands.const_get(class_name) + + unless command.respond_to?(:run) + raise(UnknownCommand,"command #{name.dump} must provide a 'run' method",caller) + end + + return command end # # Runs the command-line utility with the given _argv_ Array. If the # first argument is a sub-command name, the command-line utility will # attempt to find and execute the Command with the same name. # def CommandLine.run(*argv) - if (argv.empty? || argv[0][0..0]=='-') - Commands::Console.run(*argv) + if (argv.empty? || argv.first[0..0]=='-') + name = DEFAULT_COMMAND + argv = ARGV else - cmd = argv.first + name = argv.first argv = argv[1..-1] + end - begin - exec(CommandLine.get_command(cmd),*argv) - rescue UnknownCommand => e - STDERR.puts e - exit -1 - end + begin + CommandLine.get_command(name).run(*argv) + rescue UnknownCommand => e + STDERR.puts e + exit -1 end return true end end