rbkb 0.6.10

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.
Files changed (101) hide show
  1. data/History.txt +74 -0
  2. data/README.rdoc +149 -0
  3. data/Rakefile +47 -0
  4. data/bin/b64 +5 -0
  5. data/bin/bgrep +5 -0
  6. data/bin/blit +5 -0
  7. data/bin/c +5 -0
  8. data/bin/crc32 +5 -0
  9. data/bin/d64 +5 -0
  10. data/bin/dedump +5 -0
  11. data/bin/feed +5 -0
  12. data/bin/hexify +5 -0
  13. data/bin/len +5 -0
  14. data/bin/plugsrv +271 -0
  15. data/bin/rex +10 -0
  16. data/bin/rstrings +5 -0
  17. data/bin/slice +5 -0
  18. data/bin/telson +5 -0
  19. data/bin/unhexify +5 -0
  20. data/bin/urldec +5 -0
  21. data/bin/urlenc +5 -0
  22. data/bin/xor +5 -0
  23. data/cli_usage.rdoc +285 -0
  24. data/doctor-bag.jpg +0 -0
  25. data/lib/rbkb.rb +51 -0
  26. data/lib/rbkb/cli.rb +219 -0
  27. data/lib/rbkb/cli/b64.rb +35 -0
  28. data/lib/rbkb/cli/bgrep.rb +86 -0
  29. data/lib/rbkb/cli/blit.rb +89 -0
  30. data/lib/rbkb/cli/chars.rb +24 -0
  31. data/lib/rbkb/cli/crc32.rb +35 -0
  32. data/lib/rbkb/cli/d64.rb +28 -0
  33. data/lib/rbkb/cli/dedump.rb +52 -0
  34. data/lib/rbkb/cli/feed.rb +229 -0
  35. data/lib/rbkb/cli/hexify.rb +65 -0
  36. data/lib/rbkb/cli/len.rb +76 -0
  37. data/lib/rbkb/cli/rstrings.rb +108 -0
  38. data/lib/rbkb/cli/slice.rb +47 -0
  39. data/lib/rbkb/cli/telson.rb +87 -0
  40. data/lib/rbkb/cli/unhexify.rb +50 -0
  41. data/lib/rbkb/cli/urldec.rb +35 -0
  42. data/lib/rbkb/cli/urlenc.rb +35 -0
  43. data/lib/rbkb/cli/xor.rb +43 -0
  44. data/lib/rbkb/extends.rb +725 -0
  45. data/lib/rbkb/http.rb +21 -0
  46. data/lib/rbkb/http/base.rb +172 -0
  47. data/lib/rbkb/http/body.rb +214 -0
  48. data/lib/rbkb/http/common.rb +74 -0
  49. data/lib/rbkb/http/headers.rb +370 -0
  50. data/lib/rbkb/http/parameters.rb +104 -0
  51. data/lib/rbkb/http/request.rb +58 -0
  52. data/lib/rbkb/http/response.rb +86 -0
  53. data/lib/rbkb/plug.rb +9 -0
  54. data/lib/rbkb/plug/blit.rb +222 -0
  55. data/lib/rbkb/plug/cli.rb +83 -0
  56. data/lib/rbkb/plug/feed_import.rb +74 -0
  57. data/lib/rbkb/plug/peer.rb +67 -0
  58. data/lib/rbkb/plug/plug.rb +215 -0
  59. data/lib/rbkb/plug/proxy.rb +26 -0
  60. data/lib/rbkb/plug/unix_domain.rb +75 -0
  61. data/lib_usage.rdoc +176 -0
  62. data/rbkb.gemspec +38 -0
  63. data/spec/rbkb_spec.rb +7 -0
  64. data/spec/spec_helper.rb +16 -0
  65. data/tasks/ann.rake +80 -0
  66. data/tasks/bones.rake +20 -0
  67. data/tasks/gem.rake +201 -0
  68. data/tasks/git.rake +40 -0
  69. data/tasks/notes.rake +27 -0
  70. data/tasks/post_load.rake +34 -0
  71. data/tasks/rdoc.rake +51 -0
  72. data/tasks/rubyforge.rake +55 -0
  73. data/tasks/setup.rb +292 -0
  74. data/tasks/spec.rake +54 -0
  75. data/tasks/svn.rake +47 -0
  76. data/tasks/test.rake +40 -0
  77. data/test/test_cli_b64.rb +35 -0
  78. data/test/test_cli_bgrep.rb +137 -0
  79. data/test/test_cli_blit.rb +11 -0
  80. data/test/test_cli_chars.rb +21 -0
  81. data/test/test_cli_crc32.rb +108 -0
  82. data/test/test_cli_d64.rb +22 -0
  83. data/test/test_cli_dedump.rb +118 -0
  84. data/test/test_cli_feed.rb +11 -0
  85. data/test/test_cli_helper.rb +96 -0
  86. data/test/test_cli_hexify.rb +63 -0
  87. data/test/test_cli_len.rb +96 -0
  88. data/test/test_cli_rstrings.rb +15 -0
  89. data/test/test_cli_slice.rb +73 -0
  90. data/test/test_cli_telson.rb +11 -0
  91. data/test/test_cli_unhexify.rb +43 -0
  92. data/test/test_cli_urldec.rb +50 -0
  93. data/test/test_cli_urlenc.rb +44 -0
  94. data/test/test_cli_xor.rb +71 -0
  95. data/test/test_helper.rb +5 -0
  96. data/test/test_http.rb +27 -0
  97. data/test/test_http_helper.rb +60 -0
  98. data/test/test_http_request.rb +136 -0
  99. data/test/test_http_response.rb +222 -0
  100. data/test/test_rbkb.rb +19 -0
  101. metadata +238 -0
data/bin/rex ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # lazy form of ruby -e "xxxx". All commandline arguments get smeared to
4
+ # pure ruby.
5
+
6
+ require 'pp'
7
+ require 'rbkb'
8
+
9
+ eval ARGV.join(' ');
10
+
data/bin/rstrings ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rbkb/cli/rstrings"
4
+
5
+ Rbkb::Cli::Rstrings.run()
data/bin/slice ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rbkb/cli/slice"
4
+
5
+ Rbkb::Cli::Slice.run()
data/bin/telson ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rbkb/cli/telson"
4
+
5
+ Rbkb::Cli::Telson.run()
data/bin/unhexify ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rbkb/cli/unhexify"
4
+
5
+ Rbkb::Cli::Unhexify.run()
data/bin/urldec ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rbkb/cli/urldec"
4
+
5
+ Rbkb::Cli::Urldec.run()
data/bin/urlenc ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rbkb/cli/urlenc"
4
+
5
+ Rbkb::Cli::Urlenc.run()
data/bin/xor ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rbkb/cli/xor"
4
+
5
+ Rbkb::Cli::Xor.run()
data/cli_usage.rdoc ADDED
@@ -0,0 +1,285 @@
1
+ == Command Line Tools
2
+
3
+ Below is a list of the command line utilities with short descriptions and
4
+ usage information. Examples to come.
5
+
6
+ === b64
7
+
8
+ Base64 encode data supplied via an argument, file, or standard input.
9
+
10
+ Usage: b64 [options] <data | blank for stdin>
11
+ -h, --help Show this message
12
+ -v, --version Show version and exit
13
+ -f, --file FILENAME Input from FILENAME
14
+ -l, --length LEN Output LEN chars per line
15
+
16
+
17
+ === bgrep
18
+
19
+ Binary grep. Prints 'inspected' matches and offset information.
20
+
21
+ Usage: bgrep [options] <subject> <file | blank for stdin>
22
+ -h, --help Show this message
23
+ -v, --version Show version and exit
24
+ -x, --[no-]hex Specify subject as hex (default: false)
25
+ -r, --[no-]regex Specify subject as regex (default: false)
26
+ -a, --align=BYTES Only match on alignment boundary
27
+ -n, --[no-]filename Suppress prefixing of filenames.
28
+
29
+
30
+ === blit
31
+
32
+ Sends data through any plugboard that implements a Plug::Blit listener for
33
+ out-of band input.
34
+
35
+ See also: telson
36
+
37
+ Usage: blit [options] <data | blank for stdin>
38
+ -h, --help Show this message
39
+ -v, --version Show version and exit
40
+ -f, --file FILENAME Input from FILENAME
41
+ -t, --trans-protocol=PROTO Blit transport protocol TCP/UDP
42
+ -b, --blitsrv=ADDR:PORT Where to send blit messages
43
+ -i, --peer-index=IDX Index for remote peer to receive
44
+ -l, --list-peers Lists the peer array for the target
45
+ -k, --kill Stops the remote event loop.
46
+
47
+
48
+ === c
49
+
50
+ Prints a character n-times.
51
+
52
+ Usage: c 100 A; # print 100 A's'
53
+
54
+
55
+ === crc32
56
+
57
+ Generates a crc32 checksum for data provided via stdin or file
58
+
59
+ Usage: crc32 [options]
60
+ -h, --help Show this message
61
+ -v, --version Show version and exit
62
+ -f, --file FILENAME Input from FILENAME
63
+ -r, --range=START[:END] Start and optional end range
64
+ -x, --hexrange=START[:END] same, but in hex
65
+
66
+
67
+ === d64
68
+
69
+ Base64 decode an encoded chunk supplied via argument, file, or standard input.
70
+
71
+ Usage: d64 [options] <data | blank for stdin>
72
+ -h, --help Show this message
73
+ -v, --version Show version and exit
74
+ -f, --file FILENAME Input from FILENAME
75
+
76
+
77
+ === dedump
78
+
79
+ Reverses a hexdump back to raw data. Designed to work with hexdumps created
80
+ by Unix utilities like 'xxd' as well as 'hexdump -C'.
81
+
82
+ Usage: dedump [options] <input-file | blank for stdin>
83
+ -h, --help Show this message
84
+ -v, --version Show version and exit
85
+ -l, --length LEN Bytes per line in hexdump (default: 16)
86
+
87
+
88
+ === feed
89
+
90
+ This is a plug-board message feeder from static data sources.
91
+ The "feed" handles messages opaquely and just plays them as a server or
92
+ client in the given sequence.
93
+
94
+ Feed can do the following things with minimum fuss:
95
+ * Import messages from files, yaml, or pcap
96
+ * Inject custom/modified messages with "blit"
97
+ * Run as a server or client using UDP or TCP
98
+ * Bootstrap protocols without a lot of work up front
99
+ * Skip uninteresting messages and focus attention on the fun ones.
100
+ * Replay conversations for relatively unfamiliar protocols.
101
+ * Observe client/server behaviors using different messages at
102
+ various phases of a conversation.
103
+
104
+ Usage: feed [options] host:port
105
+ -h, --help Show this message
106
+ -v, --version Show version and exit
107
+ -o, --output=FILE Output to file
108
+ -l, --listen=(ADDR:?)PORT Server - on port (and addr?)
109
+ -s, --source=(ADDR:?)PORT Bind client on port and addr
110
+ -b, --blit=(ADDR:)?PORT Where to listen for blit
111
+ -i, --[no-]initiate Send the first message on connect
112
+ -e, --[no-]end End connection when feed is exhausted
113
+ --[no-]step 'Continue' prompt between messages
114
+ -u, --udp Use UDP instead of TCP
115
+ -r, --reconnect Attempt to reconnect endlessly.
116
+ -q, --quiet Suppress verbose messages/dumps
117
+ -Q, --squelch-exhausted Squelch 'FEED EXHAUSTED' messages
118
+ Sources: (can be combined)
119
+ -f, --from-files=GLOB Import messages from raw files
120
+ -x, --from-hex=FILE Import messages from hexdumps
121
+ -y, --from-yaml=FILE Import messages from yaml
122
+ -p, --from-pcap=FILE[:FILTER] Import messages from pcap
123
+
124
+
125
+
126
+ === hexify
127
+
128
+ Converts a string or raw data to hex characters. Input can be supplied via
129
+ stdin, a string argument, or a file (with -f).
130
+
131
+ Usage: hexify [options] <data | blank for stdin>
132
+ -h, --help Show this message
133
+ -v, --version Show version and exit
134
+ -f, --file FILENAME Input from FILENAME
135
+ -l, --length LEN Hexify in lines of LEN bytes
136
+ -d, --delim=DELIMITER DELIMITER between each byte
137
+ -p, --prefix=PREFIX PREFIX before each byte
138
+ -s, --suffix=SUFFIX SUFFIX after each byte
139
+
140
+
141
+ === len
142
+
143
+ Takes input from a blob of data and output it with its binary length prepended.
144
+
145
+ Usage: len [options] <data | blank for stdin>
146
+ -h, --help Show this message
147
+ -v, --version Show version and exit
148
+ -f, --file FILENAME Input from FILENAME
149
+ -n, --nudge INT Add integer to length
150
+ -s, --size=SIZE Size of length field in bytes
151
+ -x, --[no-]swap Swap endianness. Default=big
152
+ -t, --[no-]total Include size word in size
153
+ -l, --length=LEN Ignore all else and use LEN
154
+
155
+
156
+ === plugsrv
157
+
158
+ A blit-able reverse TCP proxy. Displays traffic hexdumps.
159
+
160
+ Usage: plugsrv [options] target:tport[@[laddr:]lport]
161
+ <target:tport> = the address of the target service
162
+ <@laddr:lport> = optional address and port to listen on
163
+
164
+ Options:
165
+ -o, --output FILE send output to a file
166
+ -l, --listen ADDR:PORT optional listener address:port
167
+ (default: 0.0.0.0:<tport>)
168
+ -q, --[no-]quiet Suppress/Enable conversation dumps.
169
+ -b, --blit ADDR:PORT specify blit listener [address:]port
170
+ (default: 127.0.0.1:25195)
171
+ --[no-]target-tls enable/disable TLS to target
172
+ --[no-]server-tls enable/disable TLS to clients
173
+ -h, --help Show this message
174
+
175
+
176
+ === rex
177
+
178
+ Lazy shortcut for ruby -e "..."
179
+
180
+ All commandline arguments get smeared into a ruby statement via 'eval()'.
181
+
182
+
183
+ === rstrings
184
+
185
+ A utility much like Unix 'strings' -- implemented in ruby.
186
+
187
+ Usage: rstrings [options] <file | blank for stdin>
188
+ -h, --help Show this message
189
+ -v, --version Show version and exit
190
+ -s, --start=OFFSET Start at offset
191
+ -e, --end=OFFSET End at offset
192
+ -t, --encoding-type=TYPE Encoding: ascii/unicode/both (default=both)
193
+ -l, --min-length=NUM Minimum length of strings (default=6)
194
+ -a, --align=ALIGNMENT Match only on alignment (default=none)
195
+
196
+
197
+ === slice
198
+
199
+ Returns a slice from input. Just a shell interface to a string slice operation.
200
+
201
+ Usage: slice [options] start (no args when using -r|-x)
202
+ -h, --help Show this message
203
+ -v, --version Show version and exit
204
+ -f, --file FILENAME Input from FILENAME
205
+ -r, --range=START[:END] Start and optional end range
206
+ -x, --hexrange=START[:END] same, but in hex
207
+
208
+
209
+ === telson
210
+
211
+ This is an implementation of the original blackbag "telson" using ruby and
212
+ eventmachine.
213
+
214
+ Telson is for doing the following things with minimum fuss:
215
+
216
+ * Run as a stubbed network client using UDP or TCP
217
+ * Use blit to communicate with the other side.
218
+ * Debug network protocols
219
+ * Observe client/server behaviors using different messages at various phases
220
+ of a conversation.
221
+
222
+ Usage: telson [options] host:port
223
+ -h, --help Show this message
224
+ -v, --version Show version and exit
225
+ -o, --output=FILE Output to file
226
+ -q, --quiet Turn off verbose logging
227
+ -d, --dump-format=hex/raw Output conversations in hexdump or raw
228
+ -b, --blit=ADDR:PORT Where to listen for blit
229
+ -u, --udp UDP mode
230
+ -S, --start-tls Initiate TLS
231
+ -r, --reconnect Attempt to reconnect endlessly.
232
+ -s, --source=(ADDR:?)PORT Bind client on port and addr
233
+
234
+
235
+ === unhexify
236
+
237
+ unhexify converts a string of hex bytes back to raw data. Input can be
238
+ supplied via stdin, a hex-string argument, or a file containing hex (use -f).
239
+
240
+ Usage: unhexify [options] <data | blank for stdin>
241
+ -h, --help Show this message
242
+ -v, --version Show version and exit
243
+ -f, --file FILENAME Input from FILENAME
244
+ -d, --delim DELIMITER DELIMITER regex between hex chunks
245
+
246
+
247
+ === urldec
248
+
249
+ Decodes a url percent-encoded string.
250
+ Input from stdin, file, or command-line argument.
251
+
252
+ Usage: urldec [options] <data | blank for stdin>
253
+ -h, --help Show this message
254
+ -v, --version Show version and exit
255
+ -f, --file FILENAME Input from FILENAME
256
+ -p, --[no-]plus Convert '+' to space (default is true)
257
+
258
+
259
+ === urlenc
260
+
261
+ Encodes data as a url percent-encoded string.
262
+ Input from stdin, file, or command-line argument.
263
+
264
+ Usage: urlenc [options] <data | blank for stdin>
265
+ -h, --help Show this message
266
+ -v, --version Show version and exit
267
+ -f, --file FILENAME Input from FILENAME
268
+ -p, --[no-]plus Convert spaces to '+' (default is false)
269
+
270
+
271
+ === xor
272
+
273
+ Repeating string xor. Takes input and XOR's it against a string.
274
+ String can be provided in hex.
275
+
276
+ Usage: xor [options] -k|-s <key> <data | stdin>
277
+ -h, --help Show this message
278
+ -v, --version Show version and exit
279
+ -f, --file FILENAME Input from FILENAME
280
+
281
+ Key options (one of the following is required):
282
+ -s, --strkey STRING xor against bare STRING
283
+ -x, --hexkey HEXSTR xor against decoded HEXSTR
284
+
285
+
data/doctor-bag.jpg ADDED
Binary file
data/lib/rbkb.rb ADDED
@@ -0,0 +1,51 @@
1
+
2
+ module Rbkb
3
+
4
+ # :stopdoc:
5
+ VERSION = '0.6.10'
6
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
+ # :startdoc:
9
+
10
+ # Returns the version string for the library.
11
+ #
12
+ def self.version
13
+ VERSION
14
+ end
15
+
16
+ # Returns the library path for the module. If any arguments are given,
17
+ # they will be joined to the end of the libray path using
18
+ # <tt>File.join</tt>.
19
+ #
20
+ def self.libpath( *args )
21
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
22
+ end
23
+
24
+ # Returns the lpath for the module. If any arguments are given,
25
+ # they will be joined to the end of the path using
26
+ # <tt>File.join</tt>.
27
+ #
28
+ def self.path( *args )
29
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
30
+ end
31
+
32
+ # Utility method used to require all files ending in .rb that lie in the
33
+ # directory below this file that has the same name as the filename passed
34
+ # in. Optionally, a specific _directory_ name can be passed in such that
35
+ # the _filename_ does not have to be equivalent to the directory.
36
+ #
37
+ def self.require_all_libs_relative_to( fname, dir = nil )
38
+ dir ||= ::File.basename(fname, '.*')
39
+ search_me = ::File.expand_path(
40
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
41
+
42
+ Dir.glob(search_me).sort.each {|rb| require rb}
43
+ end
44
+
45
+ end # module Rbkb
46
+
47
+ #Rbkb.require_all_libs_relative_to(__FILE__)
48
+
49
+ require 'rbkb/extends'
50
+
51
+ # EOF
data/lib/rbkb/cli.rb ADDED
@@ -0,0 +1,219 @@
1
+ require 'rbkb'
2
+ require 'optparse'
3
+
4
+ # Copyright 2009 emonti at matasano.com
5
+ # See README.rdoc for license information
6
+ #
7
+ module Rbkb::Cli
8
+
9
+ # Rbkb::Cli::Executable is an abstract class for creating command line
10
+ # executables using the Ruby Black Bag framework.
11
+ class Executable
12
+
13
+ def self.run(param={})
14
+ new(param).go
15
+ end
16
+
17
+ attr_accessor :stdout, :stderr, :stdin, :argv, :opts, :oparse
18
+ attr_reader :exit_status
19
+
20
+ # Instantiates a new Executable object.
21
+ #
22
+ # The 'param' argument is a named value hash. The following keys are
23
+ # significant:
24
+ #
25
+ # :argv - An array of cli arguments (default ARGV)
26
+ # :opts - executable/function options for use when running 'go'
27
+ # :stdout, - IO redirection (mostly for unit tests)
28
+ # :stderr,
29
+ # :stdin
30
+ #
31
+ #
32
+ # The above keys are deleted from the 'param' hash and stored as instance
33
+ # variables with attr_accessors. All other parameters are ignored.
34
+ def initialize(param={})
35
+ @argv ||= param.delete(:argv) || ARGV
36
+ @stdout ||= param.delete(:stdout) || STDOUT
37
+ @stderr ||= param.delete(:stderr) || STDERR
38
+ @stdin ||= param.delete(:stdin) || STDIN
39
+ @opts ||= param.delete(:opts) || {}
40
+ @parser_got_range=nil
41
+ yield self if block_given?
42
+ make_parser()
43
+ end
44
+
45
+
46
+ # Wrapper for Kernel.exit() so we can unit test cli tools
47
+ def exit(ret)
48
+ @exit_status = ret
49
+ if defined? Rbkb::Cli::TESTING
50
+ throw(((ret==0)? :exit_zero : :exit_err), ret)
51
+ else
52
+ Kernel.exit(ret)
53
+ end
54
+ end
55
+
56
+
57
+ # This method exits with a message on stderr
58
+ def bail(msg)
59
+ @stderr.puts msg if msg
60
+ self.exit(1)
61
+ end
62
+
63
+
64
+ # This method wraps a 'bail' with a basic argument error mesage and hint
65
+ # for the '-h or --help' flag
66
+ # The 'arg_err' parameter is a string with the erroneous arguments
67
+ def bail_args(arg_err)
68
+ bail "Error: bad arguments - #{arg_err}\n Hint: Use -h or --help"
69
+ end
70
+
71
+
72
+ # Prepares an OptionsParser object with blackbag standard options
73
+ # This is called from within initialize() and should be overridden in
74
+ # inherited classes to add additional OptionParser-based parsers.
75
+ #
76
+ # See parse for actual parsing.
77
+ def make_parser
78
+ @oparse ||= OptionParser.new
79
+ @oparse.banner = "Usage: #{File.basename $0} [options]"
80
+
81
+ @oparse.on("-h", "--help", "Show this message") do
82
+ bail(@oparse)
83
+ end
84
+
85
+ @oparse.on("-v", "--version", "Show version and exit") do
86
+ @stdout.puts("Ruby BlackBag version #{Rbkb::VERSION}")
87
+ self.exit(0)
88
+ end
89
+
90
+ return @oparse
91
+ end
92
+
93
+
94
+ # Abstract argument parser. Override this method with super() from
95
+ # inherited executables. The base method just calls OptionParser.parse!
96
+ # on the internal @oparse object.
97
+ def parse
98
+ # parse flag arguments
99
+ @oparse.parse!(@argv) rescue(bail_args($!))
100
+ @parsed=true
101
+
102
+ # the overriding class may implement additional arguments from here
103
+ end
104
+
105
+
106
+ # Abstract 'runner'. Override this method with super() from inherited
107
+ # executables. The base method just slurps in an optional argv and
108
+ # runs 'parse' if it hasn't already
109
+ def go(argv=nil)
110
+ @exit_status = nil
111
+ @argv = argv if argv
112
+
113
+ parse
114
+
115
+ # the overriding class implements actual functionality beyond here
116
+ end
117
+
118
+
119
+ private
120
+
121
+ # Wraps a file read with a standard bail error message
122
+ def do_file_read(f)
123
+ File.read(f) rescue(bail "File Read Error: #{$!}")
124
+ end
125
+
126
+
127
+ # Implements a basic input file argument. File reading is handled
128
+ # by do_file_read().
129
+ #
130
+ # Takes one argument, which is the @opts hash keyname to store
131
+ # the file data into.
132
+ # (Used commonly throughout several executables)
133
+ def add_std_file_opt(inkey)
134
+ @oparse.on("-f", "--file FILENAME", "Input from FILENAME") do |f|
135
+ @opts[inkey] = do_file_read(f)
136
+ end
137
+ return @oparse
138
+ end
139
+
140
+
141
+ # Implements numeric and hex range options via '-r' and '-x'
142
+ #
143
+ # Takes two arguments which are the @opts hash key names for
144
+ # first and last parameters.
145
+ #
146
+ # (Used commonly throughout several executables)
147
+ def add_range_opts(fkey, lkey)
148
+ @oparse.on("-r", "--range=START[:END]",
149
+ "Start and optional end range") do |r|
150
+
151
+ raise "-x and -r are mutually exclusive" if @parser_got_range
152
+ @parser_got_range=true
153
+
154
+ unless m=/^(-?[0-9]+)(?::(-?[0-9]+))?$/.match(r)
155
+ raise "invalid range #{r.inspect}"
156
+ end
157
+
158
+ @opts[fkey] = $1.to_i
159
+ @opts[lkey] = $2.to_i if $2
160
+ end
161
+
162
+ @oparse.on("-x", "--hexrange=START[:END]",
163
+ "Start and optional end range in hex") do |r|
164
+
165
+ raise "-x and -r are mutually exclusive" if @parser_got_range
166
+ @parser_got_range=true
167
+
168
+ unless m=/^(-?[0-9a-f]+)(?::(-?[0-9a-f]+))?$/i.match(r)
169
+ raise "invalid range #{r.inspect}"
170
+ end
171
+
172
+ @opts[fkey] =
173
+ if ($1[0,1] == '-')
174
+ ($1[1..-1]).hex_to_num * -1
175
+ else
176
+ $1.hex_to_num
177
+ end
178
+
179
+ if $2
180
+ @opts[lkey] =
181
+ if($2[0,1] == '-')
182
+ $2[1..-1].hex_to_num * -1
183
+ else
184
+ $2.hex_to_num
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+
191
+ # Conditionally parses a string argument. Uses 'key' to first check for
192
+ # then store it in @opts hash if it is not yet there.
193
+ # (Used commonly throughout several executables)
194
+ def parse_string_argument(key)
195
+ if @opts[key].nil? and s=@argv.shift
196
+ @opts[key] = s.dup
197
+ end
198
+ end
199
+
200
+
201
+ # Conditionally parses a file argument. Uses 'key' to first check for
202
+ # then store it in @opts hash if it is not yet there.
203
+ # (Used commonly throughout several executables)
204
+ def parse_file_argument(key)
205
+ if @opts[key].nil? and f=@argv.shift
206
+ @opts[key] = do_file_read(f)
207
+ end
208
+ end
209
+
210
+ # For use at the end of a parser - calls bail_args with remaining
211
+ # arguments if there are extra arguments.
212
+ # (Used commonly throughout several executables)
213
+ def parse_catchall
214
+ bail_args(@argv.join(' ')) if(@argv.length != 0)
215
+ end
216
+
217
+ end
218
+ end
219
+