spinal_tap 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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