Skip to content

Commit 289277c

Browse files
committed
Land rapid7#9516, Support Bash-Style Continuation Lines
2 parents 242f2d3 + 214c137 commit 289277c

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

lib/rex/ui/text/input/readline.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def gets()
8888
# down other background threads. This is important when there are many active
8989
# background jobs, such as when the user is running Karmetasploit
9090
#
91-
def pgets()
91+
def pgets
9292

9393
line = nil
9494
orig = Thread.current.priority

lib/rex/ui/text/shell.rb

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module Shell
2222
module InputShell
2323
attr_accessor :prompt, :output
2424

25-
def pgets()
25+
def pgets
2626

2727
output.print(prompt)
2828
output.flush
@@ -46,6 +46,8 @@ def initialize(prompt, prompt_char = '>', histfile = nil, framework = nil)
4646

4747
# Initialize the prompt
4848
self.init_prompt = prompt
49+
self.cont_prompt = ' > '
50+
self.cont_flag = false
4951
self.prompt_char = prompt_char
5052

5153
self.histfile = histfile
@@ -56,7 +58,8 @@ def initialize(prompt, prompt_char = '>', histfile = nil, framework = nil)
5658

5759
def init_tab_complete
5860
if (self.input and self.input.supports_readline)
59-
self.input = Input::Readline.new(lambda { |str| tab_complete(str) })
61+
# Unless cont_flag because there's no tab complete for continuation lines
62+
self.input = Input::Readline.new(lambda { |str| tab_complete(str) unless cont_flag })
6063
if Readline::HISTORY.length == 0 and histfile and File.exist?(histfile)
6164
File.readlines(histfile).each { |e|
6265
Readline::HISTORY << e.chomp
@@ -185,17 +188,14 @@ def run(&block)
185188
self.init_prompt = input.prompt
186189
end
187190

188-
output.input = input
189-
line = input.pgets()
190-
output.input = nil
191-
log_output(input.prompt)
191+
line = get_input_line
192192

193193
# If a block was passed in, pass the line to it. If it returns true,
194194
# break out of the shell loop.
195195
if (block)
196196
break if (line == nil or block.call(line))
197197
elsif(input.eof? or line == nil)
198-
# If you have sessions active, this will give you a shot to exit gravefully
198+
# If you have sessions active, this will give you a shot to exit gracefully
199199
# If you really are ambitious, 2 eofs will kick this out
200200
self.stop_count += 1
201201
next if(self.stop_count > 1)
@@ -350,6 +350,40 @@ def print(msg='')
350350

351351
protected
352352

353+
#
354+
# Get a single line of input, following continuation directives as necessary.
355+
#
356+
def get_input_line
357+
line = "\\\n"
358+
prompt_needs_reset = false
359+
360+
self.cont_flag = false
361+
while line =~ /(^|[^\\])\\\s*$/
362+
# Strip \ and all the trailing whitespace
363+
line.sub!(/\\\s*/, '')
364+
365+
if line.length > 0
366+
# Using update_prompt will overwrite the primary prompt
367+
input.prompt = output.update_prompt(self.cont_prompt)
368+
self.cont_flag = true
369+
prompt_needs_reset = true
370+
end
371+
372+
output.input = input
373+
line << input.pgets
374+
output.input = nil
375+
log_output(input.prompt)
376+
end
377+
self.cont_flag = false
378+
379+
if prompt_needs_reset
380+
# The continuation prompt was used so reset the prompt
381+
update_prompt
382+
end
383+
384+
line
385+
end
386+
353387
#
354388
# Parse a line into an array of arguments.
355389
#
@@ -389,12 +423,17 @@ def log_output(buf)
389423
end
390424

391425
attr_writer :input, :output # :nodoc:
392-
attr_accessor :stop_flag, :init_prompt # :nodoc:
426+
attr_accessor :stop_flag, :init_prompt, :cont_prompt # :nodoc:
393427
attr_accessor :prompt # :nodoc:
394428
attr_accessor :prompt_char, :tab_complete_proc # :nodoc:
395429
attr_accessor :histfile # :nodoc:
396430
attr_accessor :hist_last_saved # the number of history lines when last saved/loaded
397431
attr_accessor :log_source, :stop_count # :nodoc:
432+
attr_reader :cont_flag # :nodoc:
433+
434+
private
435+
436+
attr_writer :cont_flag # :nodoc:
398437

399438
end
400439

0 commit comments

Comments
 (0)