ruckus 0.5.4

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 (59) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/README +0 -0
  4. data/README.markdown +51 -0
  5. data/Rakefile +54 -0
  6. data/VERSION +1 -0
  7. data/lib/ruckus.rb +70 -0
  8. data/lib/ruckus/blob.rb +113 -0
  9. data/lib/ruckus/choice.rb +55 -0
  10. data/lib/ruckus/dfuzz.rb +231 -0
  11. data/lib/ruckus/dictionary.rb +119 -0
  12. data/lib/ruckus/enum.rb +39 -0
  13. data/lib/ruckus/extensions/array.rb +33 -0
  14. data/lib/ruckus/extensions/class.rb +168 -0
  15. data/lib/ruckus/extensions/duplicable.rb +37 -0
  16. data/lib/ruckus/extensions/file.rb +24 -0
  17. data/lib/ruckus/extensions/fixnum.rb +26 -0
  18. data/lib/ruckus/extensions/hash.rb +10 -0
  19. data/lib/ruckus/extensions/integer.rb +26 -0
  20. data/lib/ruckus/extensions/ipaddr.rb +155 -0
  21. data/lib/ruckus/extensions/irb.rb +30 -0
  22. data/lib/ruckus/extensions/math.rb +6 -0
  23. data/lib/ruckus/extensions/module.rb +37 -0
  24. data/lib/ruckus/extensions/numeric.rb +117 -0
  25. data/lib/ruckus/extensions/object.rb +22 -0
  26. data/lib/ruckus/extensions/range.rb +16 -0
  27. data/lib/ruckus/extensions/socket.rb +20 -0
  28. data/lib/ruckus/extensions/string.rb +327 -0
  29. data/lib/ruckus/filter.rb +16 -0
  30. data/lib/ruckus/human_display.rb +79 -0
  31. data/lib/ruckus/ip.rb +38 -0
  32. data/lib/ruckus/mac_addr.rb +31 -0
  33. data/lib/ruckus/mutator.rb +318 -0
  34. data/lib/ruckus/null.rb +24 -0
  35. data/lib/ruckus/number.rb +360 -0
  36. data/lib/ruckus/parsel.rb +363 -0
  37. data/lib/ruckus/selector.rb +92 -0
  38. data/lib/ruckus/str.rb +164 -0
  39. data/lib/ruckus/structure.rb +263 -0
  40. data/lib/ruckus/structure/atcreate.rb +23 -0
  41. data/lib/ruckus/structure/beforebacks.rb +28 -0
  42. data/lib/ruckus/structure/defaults.rb +57 -0
  43. data/lib/ruckus/structure/factory.rb +42 -0
  44. data/lib/ruckus/structure/fixupfields.rb +16 -0
  45. data/lib/ruckus/structure/initializers.rb +14 -0
  46. data/lib/ruckus/structure/relate.rb +34 -0
  47. data/lib/ruckus/structure/replacement.rb +30 -0
  48. data/lib/ruckus/structure/searchmods.rb +33 -0
  49. data/lib/ruckus/structure/structureproxies.rb +28 -0
  50. data/lib/ruckus/structure/validate.rb +12 -0
  51. data/lib/ruckus/structure_shortcuts.rb +109 -0
  52. data/lib/ruckus/time_t.rb +26 -0
  53. data/lib/ruckus/vector.rb +97 -0
  54. data/ruckus.gemspec +104 -0
  55. data/test/test_decides.rb +61 -0
  56. data/test/test_mutator.rb +29 -0
  57. data/test/test_override.rb +23 -0
  58. data/test/test_replace.rb +39 -0
  59. metadata +138 -0
@@ -0,0 +1,10 @@
1
+ class Hash
2
+ module HashExtensions
3
+ # XXX does the same thing as Hash#invert i think?
4
+ def flip
5
+ # XXX not used
6
+ map {|k,v| [v,k]}.to_hash
7
+ end
8
+ end
9
+ include HashExtensions
10
+ end
@@ -0,0 +1,26 @@
1
+ class Integer
2
+ module IntegerExtensions
3
+ # Convert integers to binary strings
4
+ def to_l32; [self].pack "L"; end
5
+ def to_b32; [self].pack "N"; end
6
+ def to_l16; [self].pack "v"; end
7
+ def to_b16; [self].pack "n"; end
8
+ def to_u8; [self].pack "C"; end
9
+
10
+ # Print a number in hex
11
+ def to_hex(pre="0x"); pre + to_s(16); end
12
+
13
+ # Print a number in binary
14
+ def to_b(pre=""); pre + to_s(2); end
15
+
16
+ def ffs
17
+ i = 0
18
+ v = self
19
+ while((v >>= 1) != 0)
20
+ i += 1
21
+ end
22
+ return i
23
+ end
24
+ end
25
+ include IntegerExtensions
26
+ end
@@ -0,0 +1,155 @@
1
+ require 'ipaddr'
2
+
3
+ class IPAddr
4
+ attr_reader :mask_addr
5
+
6
+ module IPAddrExtensions
7
+
8
+ # ---------------------------------------------------------
9
+
10
+ # make an IP address take the int32 value provided
11
+
12
+ def set_int(ip)
13
+ set(ip, Socket::AF_INET)
14
+ end
15
+
16
+ # ---------------------------------------------------------
17
+
18
+ # randomize the "host" part of the IP address (destructive)
19
+
20
+ def random(mask=0xFFFFFFFF)
21
+ r = rand(0xFFFFFFFF) & mask
22
+ i = self.to_i & (~mask)
23
+ self.set_int(i | r)
24
+ end
25
+
26
+ alias_method :random!, :random
27
+
28
+ # ---------------------------------------------------------
29
+
30
+ # convert a string to IP
31
+
32
+ def inet_addr(str)
33
+ in_addr(str)
34
+ end
35
+
36
+ module ClassMethods
37
+ # ---------------------------------------------------------
38
+
39
+ # construct an IPAddr from a dotted quad string or integer
40
+
41
+ def inet_addr(str)
42
+ if str.kind_of? String
43
+ IPAddr.lite(str).to_i
44
+ else
45
+ i = IPAddr.new(0, Socket::AF_INET)
46
+ i.set_int(str)
47
+ return i
48
+ end
49
+ end
50
+
51
+ # ---------------------------------------------------------
52
+ # Convert 255.255.255.0 to 24
53
+ def mask2mlen(mask)
54
+ len = 0
55
+ while len < 32 && mask & 0x80000000 != 0
56
+ mask <<= 1
57
+ mask &= 0xFFFFFFFF
58
+ len += 1
59
+ end
60
+ return len
61
+ end
62
+
63
+ # ---------------------------------------------------------
64
+
65
+ # construct an IPAddr from a dotted quad string without
66
+ # incurring a reverse lookup.
67
+
68
+ def lite(str)
69
+ # XXX self.new(0, Socket::AF_Inet, *args) instead?
70
+ ip = IPAddr.new(0, Socket::AF_INET)
71
+
72
+ parts = str.split "/"
73
+
74
+ ip.set_int(ip.inet_addr(parts[0]))
75
+ ip = ip.mask parts[1] if parts[1]
76
+ return ip
77
+ end
78
+ end
79
+
80
+ def self.included(klass)
81
+ klass.extend(ClassMethods)
82
+ end
83
+ # ---------------------------------------------------------
84
+
85
+ # to_s with a cidr prefix at the end
86
+
87
+ def to_cidr_s
88
+ # XXX not used
89
+ "#{ to_s }/#{ self.class.mask2mlen(@mask_addr) }"
90
+ end
91
+
92
+ # ---------------------------------------------------------
93
+
94
+ # get the mask length
95
+
96
+ def to_mlen
97
+ # XXX not used
98
+ mask = self.to_i
99
+ self.class.mask2mlen(mask)
100
+ end
101
+
102
+ # ---------------------------------------------------------
103
+
104
+ # get the highest address in the range defined by the netmask
105
+
106
+ def top
107
+ # XXX not used
108
+ # XXX should use self.class.inet_addr instead?
109
+ IPAddr.inet_addr(self.to_i | (0xFFFFFFFF & (~self.mask_addr)))
110
+ end
111
+
112
+ # ---------------------------------------------------------
113
+
114
+ # get the lowest address in the range defined by the netmask
115
+
116
+ def bottom
117
+ # XXX not used
118
+ # XXX should use self.class instead of IPAddr
119
+ IPAddr.inet_addr(self.to_i & self.mask_addr)
120
+ end
121
+
122
+ # ---------------------------------------------------------
123
+
124
+ # get a random address from within the range defined by the
125
+ # netmask.
126
+
127
+ def choice
128
+ # XXX not used
129
+ return self.clone if self.mask_addr == 0xFFFFFFFF
130
+
131
+ span = self.top.to_i - self.bottom.to_i
132
+ x = self.clone
133
+ x.set_int(self.bottom.to_i + rand(span))
134
+ return x
135
+ end
136
+
137
+ # ---------------------------------------------------------
138
+
139
+ # test if the address provided is in the range defined by the
140
+ # netmask
141
+
142
+ def contains(i)
143
+ # XXX not used
144
+ # XXX should use self.class instead of IPAddr
145
+ if not i.kind_of? IPAddr
146
+ i = IPAddr.inet_addr i
147
+ end
148
+
149
+ i.to_i >= self.bottom.to_i and i.to_i <= self.top.to_i
150
+ end
151
+
152
+ alias_method :contains?, :contains
153
+ end
154
+ include IPAddrExtensions
155
+ end
@@ -0,0 +1,30 @@
1
+ require 'irb'
2
+
3
+ module IRB
4
+ # Lifted from http://errtheblog.com/posts/9-drop-to-irb
5
+ # Starts an IRB session with a specific binding. To use type:
6
+ # IRB.start_session(binding)
7
+ def self.start_session(binding)
8
+ # XXX not used
9
+ IRB.setup(nil)
10
+
11
+ workspace = WorkSpace.new(binding)
12
+
13
+ if @CONF[:SCRIPT]
14
+ irb = Irb.new(workspace, @CONF[:SCRIPT])
15
+ else
16
+ irb = Irb.new(workspace)
17
+ end
18
+
19
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
20
+ @CONF[:MAIN_CONTEXT] = irb.context
21
+
22
+ trap("SIGINT") do
23
+ irb.signal_handle
24
+ end
25
+
26
+ catch(:IRB_EXIT) do
27
+ irb.eval_input
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,6 @@
1
+ module Math
2
+ # Ick. Why isn't this in the standard library? Ick.
3
+ def log2(x); log(x) / log(2); end
4
+ module_function :log2
5
+ end
6
+
@@ -0,0 +1,37 @@
1
+ class Module
2
+ module ModuleExtensions
3
+ def to_name_hash
4
+ # XXX not used
5
+ @name_hash ||= constants.map {|k| [k.intern, const_get(k.intern)]}.to_hash
6
+ end
7
+
8
+ def to_key_hash
9
+ # XXX not used
10
+ @key_hash ||= constants.map {|k| [const_get(k.intern), k.intern]}.to_hash
11
+ end
12
+
13
+ def flag_dump(i)
14
+ # XXX not used
15
+ @bit_map ||= constants.map do |k|
16
+ [k, const_get(k.intern).ffs]
17
+ end.sort {|x, y| x[1] <=> y[1]}
18
+
19
+ last = 0
20
+ r = ""
21
+ @bit_map.each do |tup|
22
+ if((v = (tup[1] - last)) > 1)
23
+ r << ("." * (v-1))
24
+ end
25
+
26
+ if((i & (1 << tup[1])) != 0)
27
+ r << tup[0][0].chr
28
+ else
29
+ r << tup[0][0].chr.downcase
30
+ end
31
+ last = tup[1]
32
+ end
33
+ return r.reverse
34
+ end
35
+ end
36
+ include ModuleExtensions
37
+ end
@@ -0,0 +1,117 @@
1
+ class Numeric
2
+ module NumericExtensions
3
+ # XXX likely these should be moved to Integer
4
+
5
+ # This HAS TO BE in the library somewhere already, but: give a fixnum,
6
+ # cap it at some number (ie, max(x, y) -> x). 10.cap(9) => 9.
7
+ def cap(limit); self > limit ? limit : self; end
8
+
9
+ def to_x; to_s(16).rjust(8, "0"); end
10
+
11
+ def to_l32
12
+ [self].pack("L")
13
+ end
14
+
15
+ def to_l16
16
+ [self].pack("v")
17
+ end
18
+
19
+ def to_l8
20
+ (self&0xFF).chr
21
+ end
22
+
23
+ # sign extend
24
+ def sx8; ([self].pack "c").unpack("C").first; end
25
+ def sx16; ([self].pack "s").unpack("S").first; end
26
+ def sx32; ([self].pack "l").unpack("L").first; end
27
+
28
+ module ClassMethods
29
+ # Make a bitmask with m-many bits, as an Integer
30
+ def mask_for(m)
31
+ # This is just table lookup for values less than 65
32
+
33
+ @@mask ||= {
34
+ 1 => 0x1,
35
+ 2 => 0x3,
36
+ 3 => 0x7,
37
+ 4 => 0xf,
38
+ 5 => 0x1f,
39
+ 6 => 0x3f,
40
+ 7 => 0x7f,
41
+ 8 => 0xff,
42
+ 9 => 0x1ff,
43
+ 10 => 0x3ff,
44
+ 11 => 0x7ff,
45
+ 12 => 0xfff,
46
+ 13 => 0x1fff,
47
+ 14 => 0x3fff,
48
+ 15 => 0x7fff,
49
+ 16 => 0xffff,
50
+ 17 => 0x1ffff,
51
+ 18 => 0x3ffff,
52
+ 19 => 0x7ffff,
53
+ 20 => 0xfffff,
54
+ 21 => 0x1fffff,
55
+ 22 => 0x3fffff,
56
+ 23 => 0x7fffff,
57
+ 24 => 0xffffff,
58
+ 25 => 0x1ffffff,
59
+ 26 => 0x3ffffff,
60
+ 27 => 0x7ffffff,
61
+ 28 => 0xfffffff,
62
+ 29 => 0x1fffffff,
63
+ 30 => 0x3fffffff,
64
+ 31 => 0x7fffffff,
65
+ 32 => 0xffffffff,
66
+ 33 => 0x1ffffffff,
67
+ 34 => 0x3ffffffff,
68
+ 35 => 0x7ffffffff,
69
+ 36 => 0xfffffffff,
70
+ 37 => 0x1fffffffff,
71
+ 38 => 0x3fffffffff,
72
+ 39 => 0x7fffffffff,
73
+ 40 => 0xffffffffff,
74
+ 41 => 0x1ffffffffff,
75
+ 42 => 0x3ffffffffff,
76
+ 43 => 0x7ffffffffff,
77
+ 44 => 0xfffffffffff,
78
+ 45 => 0x1fffffffffff,
79
+ 46 => 0x3fffffffffff,
80
+ 47 => 0x7fffffffffff,
81
+ 48 => 0xffffffffffff,
82
+ 49 => 0x1ffffffffffff,
83
+ 50 => 0x3ffffffffffff,
84
+ 51 => 0x7ffffffffffff,
85
+ 52 => 0xfffffffffffff,
86
+ 53 => 0x1fffffffffffff,
87
+ 54 => 0x3fffffffffffff,
88
+ 55 => 0x7fffffffffffff,
89
+ 56 => 0xffffffffffffff,
90
+ 57 => 0x1ffffffffffffff,
91
+ 58 => 0x3ffffffffffffff,
92
+ 59 => 0x7ffffffffffffff,
93
+ 60 => 0xfffffffffffffff,
94
+ 61 => 0x1fffffffffffffff,
95
+ 62 => 0x3fffffffffffffff,
96
+ 63 => 0x7fffffffffffffff,
97
+ 64 => 0xffffffffffffffff
98
+ }
99
+
100
+ if (v = @@mask[m])
101
+ return v
102
+ end
103
+
104
+ # Compute it for crazy values.
105
+
106
+ r = 0
107
+ 0.upto(m-1) {|q| r |= (1 << q)}
108
+ return r
109
+ end
110
+ end
111
+
112
+ def self.included(klass)
113
+ klass.extend(ClassMethods)
114
+ end
115
+ end
116
+ include NumericExtensions
117
+ end
@@ -0,0 +1,22 @@
1
+ class Object
2
+ module ObjectExtensions
3
+ # Every object has a "singleton" class, which you can think
4
+ # of as the class (ie, 1.metaclass =~ Fixnum) --- but that you
5
+ # can modify and extend without fucking up the actual class.
6
+
7
+ def metaclass; class << self; self; end; end
8
+ def meta_eval(&blk) metaclass.instance_eval &blk; end
9
+ def meta_def(name, &blk) meta_eval { define_method name, &blk }; end
10
+ def try(meth, *args); send(meth, *args) if respond_to? meth; end
11
+
12
+ def through(meth, *args)
13
+ if respond_to? meth
14
+ send(meth, *args)
15
+ else
16
+ self
17
+ end
18
+ end
19
+ end
20
+ include ObjectExtensions
21
+ end
22
+
@@ -0,0 +1,16 @@
1
+ class Range
2
+ module RangeExtensions
3
+ # again, surprised this isn't in the library
4
+ def each_backwards
5
+ max.to_i.downto(min) {|i| yield i}
6
+ end
7
+
8
+ # Take a random number out of a range
9
+ #
10
+ def choice
11
+ rand(self.last - self.first) + self.first
12
+ end
13
+ alias_method :choose, :choice
14
+ end
15
+ include RangeExtensions
16
+ end
@@ -0,0 +1,20 @@
1
+ class Socket
2
+ module SocketExtensions
3
+ module ClassMethods
4
+ def addr(host, port=nil)
5
+ if not port
6
+ raise "bad!" if not host =~ /(.*):(.*)/
7
+ host = $1
8
+ port = $2
9
+ end
10
+ port = port.to_i
11
+ Socket.pack_sockaddr_in(port, host)
12
+ end
13
+ end
14
+
15
+ def self.included(klass)
16
+ klass.extend(ClassMethods)
17
+ end
18
+ end
19
+ include SocketExtensions
20
+ end