spinal_tap 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,137 @@
1
1
  module SpinalTap
2
2
 
3
3
  module ClientHelpers
4
- def prompt
5
- write('> ')
4
+ def setup(server)
5
+ @server = server
6
+
7
+ @buffer = ''
8
+ @cursor_pos = 1
9
+ @history = []
10
+ @history_pos = 0
11
+
12
+ setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
13
+
14
+ suppress_go_ahead = [255, 251, 3].pack('C3')
15
+ write(suppress_go_ahead)
16
+
17
+ echo = [255, 251, 1].pack('C3')
18
+ write(echo)
19
+
20
+ 6.times { getc }
21
+ end
22
+
23
+ def process_loop
24
+ while (line = read_parsed_line)
25
+ command = line[:command]
26
+ args = line[:args]
27
+
28
+ case command
29
+ when 'help' then exec_help
30
+ when 'eval' then exec_eval(args.join(' '))
31
+ when 'quit'
32
+ close
33
+ break
34
+ else
35
+ write("Unknown command\r\n")
36
+ end
37
+ end
38
+ ensure
39
+ close unless closed?
40
+ @server.unregister(Thread.current)
41
+ end
42
+
43
+ def read_parsed_line
44
+ @buffer = ''
45
+ @cursor_pos = 1
46
+
47
+ redraw_cmd_line
48
+
49
+ while byte = getbyte
50
+ byte_s = '' << byte
51
+
52
+ # Delete Char.
53
+ if byte == 127
54
+ if @buffer.length > 0 && @cursor_pos > 1
55
+ @cursor_pos -= 1
56
+ @buffer.slice!(@cursor_pos - 1)
57
+ end
58
+
59
+ # Null Char.
60
+ elsif byte == 0
61
+ next
62
+
63
+ # Escape Char.
64
+ elsif byte == 27
65
+ if (byte = getbyte) == 91 # [ Char.
66
+ case getbyte
67
+ when 65 # A Char - Up Arrow.
68
+ if @history_pos > 0
69
+ @history_pos -= 1
70
+ @buffer = @history[@history_pos].to_s
71
+ end
72
+ when 66 # B Char - Down Arrow.
73
+ if @history_pos < @history.length
74
+ @history_pos += 1
75
+ @buffer = @history[@history_pos].to_s
76
+ end
77
+ when 67 # C Char - Right Arrow.
78
+ if @cursor_pos < @buffer.length
79
+ @cursor_pos += 1
80
+ end
81
+ when 68 # D Char - Left Arrow.
82
+ if @cursor_pos > 0
83
+ @cursor_pos -= 1
84
+ end
85
+ end
86
+ end
87
+
88
+ # Carriage Return Char.
89
+ elsif byte == 13
90
+ write("\r\n")
91
+
92
+ tokens = @buffer.split(' ')
93
+ command = tokens.first
94
+ args = tokens[1..-1]
95
+
96
+ if @buffer.length > 0
97
+ @history.push(@buffer)
98
+ @history_pos = @history.length
99
+ end
100
+
101
+ return {:command => command, :args => args}
102
+
103
+ # Other Chars.
104
+ elsif byte >= 32 && byte <= 126
105
+ @buffer.insert(@cursor_pos - 1, byte_s)
106
+ @cursor_pos += 1
107
+
108
+ # Ignore all other special characters.
109
+ else
110
+ end
111
+
112
+ redraw_cmd_line
113
+ end
114
+ end
115
+
116
+ def redraw_cmd_line
117
+ write("\e[2K\r>\e[s #{@buffer}\e[u\e[#{@cursor_pos}C")
118
+ end
119
+
120
+ def exec_help
121
+ write("Commands: help quit eval\r\n")
122
+ end
123
+
124
+ def exec_eval(code)
125
+ begin
126
+ result = eval(code)
127
+ write("=> #{result.to_s}\r\n")
128
+ rescue Exception => e
129
+ write(exception_to_s(e))
130
+ end
131
+ end
132
+
133
+ def exception_to_s(e)
134
+ "#{e.message}\r\n#{e.backtrace.join("\r\n")}"
6
135
  end
7
136
  end
8
137
 
@@ -1,4 +1,5 @@
1
1
  require 'socket'
2
+ require 'debugger'
2
3
 
3
4
  module SpinalTap
4
5
 
@@ -7,7 +8,7 @@ module SpinalTap
7
8
  @host = params[:host] || '127.0.0.1'
8
9
  @port = params[:port] || 9000
9
10
 
10
- @run = false
11
+ @running = false
11
12
  @workers = {}
12
13
  @workers_lock = Mutex.new
13
14
  end
@@ -23,16 +24,14 @@ module SpinalTap
23
24
  while true
24
25
  Thread.new(@server_sock.accept) do |client|
25
26
  begin
26
- @workers_lock.synchronize do
27
- @workers[Thread.current] = client
28
- end
27
+ register(Thread.current, client)
29
28
 
30
- client.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
31
29
  client.extend(SpinalTap::ClientHelpers)
30
+ client.setup(self)
31
+ client.process_loop
32
32
 
33
- process(client)
34
33
  rescue Exception => e
35
- puts("WORKER DIED: #{exception_to_s(e)}")
34
+ puts("WORKER DIED: #{e.message}\n#{e.backtrace.join("\n")}")
36
35
  end
37
36
  end
38
37
  end
@@ -56,53 +55,17 @@ module SpinalTap
56
55
  end
57
56
  end
58
57
 
59
- private
60
-
61
- def process(client)
62
- client.prompt
63
-
64
- while(line = client.gets)
65
- line.chomp!
66
-
67
- tokens = line.split(' ')
68
- command = tokens.first
69
-
70
- case command
71
- when 'help' then exec_help(client)
72
- when 'eval' then exec_eval(client, tokens[1..-1].join(' '))
73
- when 'quit'
74
- client.close
75
- break
76
- else
77
- client.puts('Unknown command')
78
- end
79
-
80
- client.prompt
81
- end
82
-
83
- ensure
84
- client.close unless client.closed?
85
-
58
+ def register(thread, client)
86
59
  @workers_lock.synchronize do
87
- @workers.delete(Thread.current)
60
+ @workers[thread] = client
88
61
  end
89
62
  end
90
63
 
91
- def exec_help(client)
92
- client.puts('Commands: help quit eval')
93
- end
94
-
95
- def exec_eval(client, code)
96
- begin
97
- result = eval(code)
98
- client.puts(result.to_s)
99
- rescue Exception => e
100
- client.puts(exception_to_s(e))
64
+ def unregister(thread)
65
+ @workers_lock.synchronize do
66
+ @workers.delete(thread)
101
67
  end
102
68
  end
103
69
 
104
- def exception_to_s(e)
105
- "#{e.message}\r\n#{e.backtrace.join("\r\n")}"
106
- end
107
70
  end
108
71
  end
@@ -1,3 +1,3 @@
1
1
  module SpinalTap
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
data/spinal_tap.gemspec CHANGED
@@ -20,4 +20,5 @@ Gem::Specification.new do |gem|
20
20
  gem.add_development_dependency('guard', ['= 1.2.3'])
21
21
  gem.add_development_dependency('guard-rspec', ['= 1.2.0'])
22
22
  gem.add_development_dependency('growl', ['= 1.0.3'])
23
+ gem.add_development_dependency('debugger', ['>= 1.1.4'])
23
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spinal_tap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-10 00:00:00.000000000 Z
12
+ date: 2012-07-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - '='
92
92
  - !ruby/object:Gem::Version
93
93
  version: 1.0.3
94
+ - !ruby/object:Gem::Dependency
95
+ name: debugger
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.1.4
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: 1.1.4
94
110
  description: Backdoor into your long running ruby processes.
95
111
  email:
96
112
  - chad@remesch.com
@@ -124,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
140
  version: '0'
125
141
  segments:
126
142
  - 0
127
- hash: 4269159806787806500
143
+ hash: 3767051084925650736
128
144
  required_rubygems_version: !ruby/object:Gem::Requirement
129
145
  none: false
130
146
  requirements:
@@ -133,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
149
  version: '0'
134
150
  segments:
135
151
  - 0
136
- hash: 4269159806787806500
152
+ hash: 3767051084925650736
137
153
  requirements: []
138
154
  rubyforge_project:
139
155
  rubygems_version: 1.8.24