Tab completion changes, start of completion routines
git-svn-id: file:///home/svn/incoming/trunk@3061 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
2dc8cd66d3
commit
cad67cec49
|
@ -581,7 +581,7 @@ class Core
|
|||
|
||||
print_line("#{name} => #{value}")
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Sets the supplied variables in the global datastore.
|
||||
#
|
||||
|
@ -636,7 +636,18 @@ class Core
|
|||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Tab completion for the show command
|
||||
#
|
||||
def cmd_show_tabs(str, words)
|
||||
res = %w{all encoders nops exploits payloads recon plugins}
|
||||
if (active_module)
|
||||
res.concat(%w{ options advanced })
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
#
|
||||
# Unloads a plugin by its name.
|
||||
#
|
||||
|
@ -659,6 +670,13 @@ class Core
|
|||
end
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Tab completion for the unload command
|
||||
#
|
||||
def cmd_unload_tabs(str, words)
|
||||
framework.plugins.each { k.name }
|
||||
end
|
||||
|
||||
#
|
||||
# Unsets a value if it's been set.
|
||||
|
@ -700,7 +718,15 @@ class Core
|
|||
datastore.delete(val)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Tab completion for the unset command
|
||||
#
|
||||
def cmd_unset_tabs(str, words)
|
||||
datastore = active_module ? active_module.datastore : self.framework.datastore
|
||||
datastore.keys
|
||||
end
|
||||
|
||||
#
|
||||
# Unsets variables in the global data store.
|
||||
#
|
||||
|
@ -709,7 +735,14 @@ class Core
|
|||
|
||||
cmd_unset(*args)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Tab completion for the unsetg command
|
||||
#
|
||||
def cmd_unsetg_tabs(str, words)
|
||||
self.framework.datastore.keys
|
||||
end
|
||||
|
||||
#
|
||||
# Uses a module.
|
||||
#
|
||||
|
@ -771,7 +804,19 @@ class Core
|
|||
# Update the command prompt
|
||||
driver.update_prompt("#{mod.type}(#{mod.refname}) ")
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Tab completion for the use command
|
||||
#
|
||||
def cmd_use_tabs(str, words)
|
||||
res = []
|
||||
framework.modules.each_module { |refname, mod|
|
||||
res << refname
|
||||
res << mod.fullname
|
||||
}
|
||||
return res
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the revision of the console library
|
||||
#
|
||||
|
@ -791,6 +836,27 @@ class Core
|
|||
recalculate_tab_complete
|
||||
end
|
||||
|
||||
#
|
||||
# Provide command-specific tab completion
|
||||
#
|
||||
def tab_complete_helper(str, words)
|
||||
items = []
|
||||
|
||||
# Is the user trying to tab complete one of our commands?
|
||||
if (commands.include?(words[0]))
|
||||
if (self.respond_to?('cmd_'+words[0]+'_tabs'))
|
||||
res = self.send('cmd_'+words[0]+'_tabs', str, words)
|
||||
return nil if res.nil?
|
||||
items.concat(res)
|
||||
else
|
||||
# Avoid the default completion list for known commands
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
return items
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
|
@ -798,11 +864,7 @@ protected
|
|||
#
|
||||
def recalculate_tab_complete
|
||||
self.tab_complete_items = []
|
||||
|
||||
framework.modules.each_module { |refname, mod|
|
||||
self.tab_complete_items << refname
|
||||
self.tab_complete_items << mod.fullname
|
||||
}
|
||||
# wont be needed much longer
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -66,6 +66,9 @@ class Driver < Msf::Ui::Driver
|
|||
|
||||
# Process the resource script
|
||||
process_rc_file
|
||||
|
||||
# Initialize the tab completion array
|
||||
self.tab_words = []
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -201,6 +204,7 @@ class Driver < Msf::Ui::Driver
|
|||
protected
|
||||
|
||||
attr_writer :framework # :nodoc:
|
||||
attr_accessor :tab_words # :nodoc:
|
||||
|
||||
##
|
||||
#
|
||||
|
@ -260,6 +264,31 @@ protected
|
|||
set_log_level(Rex::LogSource, val)
|
||||
set_log_level(Msf::LogSource, val)
|
||||
end
|
||||
|
||||
#
|
||||
# This method accepts the entire line of text from the Readline
|
||||
# routine, stores all completed words, and passes the partial
|
||||
# word to the real tab completion function. This works around
|
||||
# a design problem in the Readline module and depends on the
|
||||
# Readline.basic_word_break_characters variable being set to \x00
|
||||
#
|
||||
def tab_complete(str)
|
||||
# Check trailing whitespace so we can tell 'x' from 'x '
|
||||
str_match = str.match(/\s+$/)
|
||||
str_trail = (str_match.nil?) ? '' : str_match[0]
|
||||
|
||||
# Split the line up by whitespace into words
|
||||
str_words = str.split(/[\s\t\n]/)
|
||||
|
||||
# Append an empty word if we had trailing whitespace
|
||||
str_words << '' if str_trail.length > 0
|
||||
|
||||
# Place the word list into an instance variable
|
||||
self.tab_words = str_words
|
||||
|
||||
# Pop the last word and pass it to the parent
|
||||
super(self.tab_words.pop)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -95,24 +95,46 @@ module DispatcherShell
|
|||
|
||||
#
|
||||
# Performs tab completion on shell input if supported.
|
||||
# Current words can be found in self.tab_words
|
||||
#
|
||||
def tab_complete(str)
|
||||
items = []
|
||||
|
||||
|
||||
# puts "Words(#{tab_words.join(", ")}) Partial='#{str}'"
|
||||
|
||||
# Next, try to match internal command or value completion
|
||||
# Enumerate each entry in the dispatcher stack
|
||||
dispatcher_stack.each { |dispatcher|
|
||||
# If it supports commands, query them all
|
||||
if (dispatcher.respond_to?('commands'))
|
||||
|
||||
# If no command is set and it supports commands, add them all
|
||||
if (tab_words.empty? and dispatcher.respond_to?('commands'))
|
||||
items.concat(dispatcher.commands.to_a.map { |x| x[0] })
|
||||
end
|
||||
|
||||
# XXX - This should now be obsolete!
|
||||
# If the dispatcher has custom tab completion items, use them
|
||||
items.concat(dispatcher.tab_complete_items || [])
|
||||
# items.concat(dispatcher.tab_complete_items || [])
|
||||
|
||||
# If the dispatcher exports a tab completion function, use it
|
||||
if(dispatcher.respond_to?('tab_complete_helper'))
|
||||
res = dispatcher.tab_complete_helper(str, tab_words)
|
||||
|
||||
if (res.nil?)
|
||||
# A nil response indicates no optional arguments
|
||||
return [''] if items.empty?
|
||||
else
|
||||
# Otherwise we add the completion items to the list
|
||||
items.concat(res)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
# Match based on the partial word
|
||||
items.find_all { |e|
|
||||
e =~ /^#{str}/
|
||||
# Prepend the rest of the command (or it gets replaced!)
|
||||
}.map { |e|
|
||||
tab_words.dup.push(e).join(' ')
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -21,10 +21,11 @@ begin
|
|||
#
|
||||
def initialize(tab_complete_proc = nil)
|
||||
if (tab_complete_proc)
|
||||
::Readline.basic_word_break_characters = "\x00"
|
||||
::Readline.completion_proc = tab_complete_proc
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Regular old gets, reads a line of input and returns it to the caller.
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue