rbkb 0.6.10

Sign up to get free protection for your applications and to get access to all the features.
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
+