ronin 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/History.txt +50 -0
  2. data/Manifest.txt +31 -19
  3. data/README.txt +27 -19
  4. data/Rakefile +1 -1
  5. data/TODO.txt +1 -7
  6. data/lib/ronin.rb +1 -11
  7. data/lib/ronin/database/database.rb +1 -1
  8. data/lib/ronin/{cache/config.rb → environment.rb} +10 -8
  9. data/lib/ronin/formatting.rb +0 -1
  10. data/lib/ronin/formatting/extensions.rb +0 -1
  11. data/lib/ronin/formatting/extensions/binary/integer.rb +10 -0
  12. data/lib/ronin/formatting/extensions/binary/string.rb +11 -0
  13. data/lib/ronin/formatting/extensions/http/string.rb +1 -1
  14. data/lib/ronin/network/extensions/http/net.rb +8 -0
  15. data/lib/ronin/objectify/objectify.rb +0 -47
  16. data/lib/ronin/os.rb +89 -0
  17. data/lib/ronin/platform.rb +4 -77
  18. data/lib/ronin/{cache → platform}/exceptions.rb +2 -2
  19. data/lib/ronin/{cache → platform}/exceptions/extension_not_found.rb +1 -1
  20. data/lib/ronin/{cache → platform}/exceptions/overlay_cached.rb +1 -1
  21. data/lib/ronin/{cache → platform}/exceptions/overlay_not_found.rb +1 -1
  22. data/lib/ronin/{cache → platform}/extension.rb +68 -177
  23. data/lib/ronin/{cache → platform}/extension_cache.rb +9 -7
  24. data/lib/ronin/{cache → platform}/maintainer.rb +1 -1
  25. data/lib/ronin/platform/object_cache.rb +94 -0
  26. data/lib/ronin/platform/overlay.rb +274 -0
  27. data/lib/ronin/platform/overlay_cache.rb +318 -0
  28. data/lib/ronin/platform/platform.rb +195 -0
  29. data/lib/ronin/{cache → platform}/ronin.rb +7 -6
  30. data/lib/ronin/target.rb +5 -5
  31. data/lib/ronin/ui.rb +4 -1
  32. data/lib/ronin/ui/command_line/command_line.rb +0 -1
  33. data/lib/ronin/ui/command_line/commands/add.rb +21 -6
  34. data/lib/ronin/ui/command_line/commands/default.rb +6 -1
  35. data/lib/ronin/ui/command_line/commands/extension.rb +3 -3
  36. data/lib/ronin/ui/command_line/commands/install.rb +16 -5
  37. data/lib/ronin/ui/command_line/commands/list.rb +31 -8
  38. data/lib/ronin/ui/command_line/commands/overlay.rb +10 -9
  39. data/lib/ronin/ui/command_line/commands/remove.rb +16 -5
  40. data/lib/ronin/ui/command_line/commands/uninstall.rb +16 -5
  41. data/lib/ronin/ui/command_line/commands/update.rb +16 -3
  42. data/lib/ronin/ui/console.rb +81 -77
  43. data/lib/ronin/ui/diagnostics.rb +73 -0
  44. data/lib/ronin/version.rb +1 -1
  45. data/spec/chars/chars_spec.rb +1 -3
  46. data/spec/formatting/binary/integer_spec.rb +48 -36
  47. data/spec/formatting/binary/string_spec.rb +66 -4
  48. data/spec/os_spec.rb +24 -0
  49. data/spec/platform/extension_cache_spec.rb +42 -0
  50. data/spec/platform/extension_spec.rb +62 -0
  51. data/spec/platform/helpers/overlays.rb +18 -0
  52. data/spec/platform/helpers/overlays.yaml.erb +10 -0
  53. data/spec/platform/helpers/overlays/hello/hello/extension.rb +7 -0
  54. data/spec/platform/helpers/overlays/hello/ronin.xml +26 -0
  55. data/spec/platform/helpers/overlays/test1/ronin.xml +26 -0
  56. data/spec/platform/helpers/overlays/test1/test/extension.rb +7 -0
  57. data/spec/platform/helpers/overlays/test2/ronin.xml +26 -0
  58. data/spec/platform/helpers/overlays/test2/test/extension.rb +7 -0
  59. data/spec/platform/overlay_cache_spec.rb +63 -0
  60. data/spec/platform/platform_spec.rb +14 -0
  61. data/spec/platform/ronin_spec.rb +22 -0
  62. data/spec/target_spec.rb +1 -1
  63. data/spec/ui/diagnostics_spec.rb +17 -0
  64. metadata +34 -22
  65. data/lib/ronin/cache.rb +0 -27
  66. data/lib/ronin/cache/cache.rb +0 -78
  67. data/lib/ronin/cache/overlay.rb +0 -470
  68. data/lib/ronin/cache/overlay_cache.rb +0 -216
  69. data/lib/ronin/formatting/extensions/html.rb +0 -24
  70. data/lib/ronin/formatting/extensions/html/string.rb +0 -75
  71. data/lib/ronin/formatting/html.rb +0 -24
  72. data/spec/formatting/html_spec.rb +0 -46
  73. data/spec/platform_spec.rb +0 -24
@@ -21,11 +21,11 @@
21
21
  #++
22
22
  #
23
23
 
24
- require 'ronin/cache/extension'
25
- require 'ronin/cache/exceptions/extension_not_found'
24
+ require 'ronin/platform/extension'
25
+ require 'ronin/platform/exceptions/extension_not_found'
26
26
 
27
27
  module Ronin
28
- module Cache
28
+ module Platform
29
29
  class ExtensionCache < Hash
30
30
 
31
31
  #
@@ -34,11 +34,13 @@ module Ronin
34
34
  #
35
35
  def initialize(&block)
36
36
  super() do |hash,key|
37
- hash[name] = load_extension(key.to_s)
37
+ name = key.to_s
38
+
39
+ hash[name] = load_extension(name)
38
40
  end
39
41
 
40
42
  at_exit do
41
- each_extension { |ext| ext.perform_teardown }
43
+ each_extension { |ext| ext.teardown! }
42
44
  end
43
45
 
44
46
  block.call(self) if block
@@ -72,12 +74,12 @@ module Ronin
72
74
  def load_extension(name,&block)
73
75
  name = name.to_s
74
76
 
75
- unless Extension.exists?(name)
77
+ unless Platform.overlays.has_extension?(name)
76
78
  raise(ExtensionNotFound,"extension #{name.dump} does not eixst",caller)
77
79
  end
78
80
 
79
81
  return Extension.load(name) do |ext|
80
- ext.perform_setup
82
+ ext.setup!
81
83
 
82
84
  block.call(ext) if block
83
85
  end
@@ -22,7 +22,7 @@
22
22
  #
23
23
 
24
24
  module Ronin
25
- module Cache
25
+ module Platform
26
26
  class Maintainer
27
27
 
28
28
  # Name of the maintainer
@@ -0,0 +1,94 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ronin/objectify'
25
+
26
+ module Ronin
27
+ module Platform
28
+ module ObjectCache
29
+ #
30
+ # Returns all paths within the specified _directory_ pointing
31
+ # to object files.
32
+ #
33
+ def ObjectCache.paths(directory)
34
+ Dir[File.join(directory,'**','*.rb')]
35
+ end
36
+
37
+ #
38
+ # Finds all cached objects, passing each to the given _block_.
39
+ #
40
+ def ObjectCache.each(directory=nil,&block)
41
+ attributes = {}
42
+
43
+ if directory
44
+ attributes.merge!(:object_path.like => File.join(directory,'%'))
45
+ end
46
+
47
+ Objectify.object_contexts.each_value do |base|
48
+ base.all(attributes).each(&block)
49
+ end
50
+
51
+ return true
52
+ end
53
+
54
+ #
55
+ # Cache all objects loaded from the paths within the specified
56
+ # _directory_.
57
+ #
58
+ def ObjectCache.cache(directory)
59
+ ObjectCache.paths(directory).each do |path|
60
+ Objectify.cache_objects(path)
61
+ end
62
+
63
+ return true
64
+ end
65
+
66
+ #
67
+ # Mirror all objects that were previously cached from paths within
68
+ # the specified _directory_. Also cache objects which have yet to
69
+ # be cached.
70
+ #
71
+ def ObjectCache.mirror(directory)
72
+ new_paths = ObjectCache.paths(directory)
73
+
74
+ ObjectCache.each(directory) do |obj|
75
+ new_paths.delete(obj.object_path)
76
+
77
+ obj.mirror
78
+ end
79
+
80
+ # cache the remaining new paths
81
+ new_paths.each { |path| Objectify.cache_objects(path) }
82
+ return true
83
+ end
84
+
85
+ #
86
+ # Deletes all cached objects that existed in the specified _directory_.
87
+ #
88
+ def ObjectCache.expunge(directory)
89
+ ObjectCache.each(directory) { |obj| obj.destroy }
90
+ return true
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,274 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ronin/platform/exceptions/extension_not_found'
25
+ require 'ronin/platform/maintainer'
26
+ require 'ronin/platform/extension'
27
+
28
+ require 'rexml/document'
29
+ require 'repertoire'
30
+
31
+ module Ronin
32
+ module Platform
33
+ class Overlay < Repertoire::Repository
34
+
35
+ # Overlay metadata XML file name
36
+ METADATA_FILE = 'ronin.xml'
37
+
38
+ # Overlay lib directory
39
+ LIB_DIR = 'lib'
40
+
41
+ # Overlay objects directory
42
+ OBJECTS_DIR = 'objects'
43
+
44
+ # Local path to the overlay
45
+ attr_reader :path
46
+
47
+ # Name of the overlay
48
+ attr_reader :name
49
+
50
+ # URI that the overlay was installed from
51
+ attr_reader :uri
52
+
53
+ # Title of the overlay
54
+ attr_reader :title
55
+
56
+ # License that the overlay contents is under
57
+ attr_reader :license
58
+
59
+ # Source URI of the overlay
60
+ attr_reader :source
61
+
62
+ # Source View URI of the overlay
63
+ attr_reader :source_view
64
+
65
+ # Website URI for the overlay
66
+ attr_reader :website
67
+
68
+ # Maintainers of the overlay
69
+ attr_reader :maintainers
70
+
71
+ # Description
72
+ attr_reader :description
73
+
74
+ # The objects directory
75
+ attr_reader :objects_dir
76
+
77
+ #
78
+ # Creates a new Overlay object with the specified _path_, _media_type_
79
+ # and _uri_.
80
+ #
81
+ def initialize(path,media_type=nil,uri=nil,&block)
82
+ @path = File.expand_path(path)
83
+ @name = File.basename(@path)
84
+ @objects_dir = File.join(@path,OBJECTS_DIR)
85
+ @uri = uri
86
+
87
+ super(@path,Repertoire::Media.types[media_type])
88
+
89
+ initialize_metadata(&block)
90
+ end
91
+
92
+ #
93
+ # Media type of the overlay.
94
+ #
95
+ def media_type
96
+ if @media
97
+ return @media.name
98
+ else
99
+ return nil
100
+ end
101
+ end
102
+
103
+ #
104
+ # Returns the paths of all extensions within the overlay.
105
+ #
106
+ def extension_paths
107
+ directories.reject do |dir|
108
+ name = File.basename(dir)
109
+
110
+ (name == OBJECTS_DIR) || (name == LIB_DIR)
111
+ end
112
+ end
113
+
114
+ #
115
+ # Returns the names of all extensions within the overlay.
116
+ #
117
+ def extensions
118
+ extension_paths.map { |dir| File.basename(dir) }
119
+ end
120
+
121
+ #
122
+ # Returns +true+ if the overlay contains the extension with the
123
+ # specified _name_, returns +false+ otherwise.
124
+ #
125
+ def has_extension?(name)
126
+ name = File.basename(name.to_s)
127
+
128
+ return false if name == OBJECTS_DIR
129
+ return File.directory?(File.join(@path,name))
130
+ end
131
+
132
+ #
133
+ # Returns the <tt>lib/</tt> directories of the extensions within
134
+ # the overlay.
135
+ #
136
+ def lib_dirs
137
+ dirs = []
138
+
139
+ find_directory = lambda { |path|
140
+ dirs << path if File.directory?(path)
141
+ }
142
+
143
+ find_directory.call(File.join(@path,LIB_DIR))
144
+
145
+ extension_paths.each do |path|
146
+ find_directory.call(File.join(path,Extension::LIB_DIR))
147
+ end
148
+
149
+ return dirs
150
+ end
151
+
152
+ #
153
+ # Activates the overlay by adding the lib_dirs to the
154
+ # <tt>$LOAD_PATH</tt>.
155
+ #
156
+ def activate!
157
+ lib_dirs.each do |path|
158
+ $LOAD_PATH << path unless $LOAD_PATH.include?(path)
159
+ end
160
+
161
+ return true
162
+ end
163
+
164
+ #
165
+ # Deactivates the overlay by removing the lib_dirs to the
166
+ # <tt>$LOAD_PATH</tt>.
167
+ #
168
+ def deactive!
169
+ paths = lib_dirs
170
+
171
+ $LOAD_PATH.reject! { |path| paths.include?(path) }
172
+ return true
173
+ end
174
+
175
+ #
176
+ # Updates the overlay and reloads it's metadata. If a _block_
177
+ # is given it will be called after the overlay has been updated.
178
+ #
179
+ def update(&block)
180
+ if media_type
181
+ Repertoire.update(:media => media_type, :path => @path, :uri => @uri)
182
+ end
183
+
184
+ return initialize_metadata(&block)
185
+ end
186
+
187
+ #
188
+ # Deletes the overlay then removes it from the overlay cache.
189
+ # If a _block_ is given, it will be passed the overlay after it
190
+ # has been uninstalled.
191
+ #
192
+ def uninstall(&block)
193
+ Repertoire.delete(@path)
194
+
195
+ block.call(self) if block
196
+ return self
197
+ end
198
+
199
+ #
200
+ # Returns the +name+ of the Overlay.
201
+ #
202
+ def to_s
203
+ @name.to_s
204
+ end
205
+
206
+ protected
207
+
208
+ #
209
+ # Loads the overlay metadata from the METADATA_FILE within the
210
+ # overlay +path+. If a _block_ is given, it will be passed the
211
+ # overlay after the metadata has been loaded.
212
+ #
213
+ def initialize_metadata(&block)
214
+ metadata_path = File.join(@path,METADATA_FILE)
215
+
216
+ # set to default values
217
+ @title = @name
218
+ @license = nil
219
+
220
+ @source = @uri
221
+ @source_view = @source
222
+ @website = @source_view
223
+
224
+ @maintainers = []
225
+ @description = nil
226
+
227
+ if File.file?(metadata_path)
228
+ doc = REXML::Document.new(open(metadata_path))
229
+ overlay = doc.elements['/ronin-overlay']
230
+
231
+ overlay.each_element('title[.]:first') do |title|
232
+ @title = title.text.strip
233
+ end
234
+
235
+ overlay.each_element('license[.]:first') do |license|
236
+ @license = license.text.strip
237
+ end
238
+
239
+ overlay.each_element('source[.]:first') do |source|
240
+ @source = source.text.strip
241
+ end
242
+
243
+ overlay.each_element('source-view[.]:first') do |source_view|
244
+ @source_view = source_view.text.strip
245
+ end
246
+
247
+ overlay.each_element('website[.]:first') do |website|
248
+ @website = website.text.strip
249
+ end
250
+
251
+ overlay.each_element('maintainers/maintainer') do |maintainer|
252
+ if (name = maintainer.text('name'))
253
+ name.strip!
254
+ end
255
+
256
+ if (email = maintainer.text('email'))
257
+ email.strip!
258
+ end
259
+
260
+ @maintainers << Maintainer.new(name,email)
261
+ end
262
+
263
+ overlay.each_element('description[.]:first') do |description|
264
+ @description = description.text.strip
265
+ end
266
+ end
267
+
268
+ block.call(self) if block
269
+ return self
270
+ end
271
+
272
+ end
273
+ end
274
+ end
@@ -0,0 +1,318 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ronin/platform/exceptions/overlay_cached'
25
+ require 'ronin/platform/exceptions/overlay_not_found'
26
+ require 'ronin/platform/overlay'
27
+ require 'ronin/config'
28
+
29
+ require 'yaml'
30
+
31
+ module Ronin
32
+ module Platform
33
+ class OverlayCache < Hash
34
+
35
+ # Default overlay cache directory
36
+ CACHE_DIR = File.join(Ronin::Config::PATH,'overlays')
37
+
38
+ # Name of the overlay cache file
39
+ CACHE_FILE = File.join(Ronin::Config::PATH,'overlays.yaml')
40
+
41
+ # Path of cache file
42
+ attr_reader :path
43
+
44
+ #
45
+ # Create a new OverlayCache object with the specified _path_. The
46
+ # _path_ defaults to <tt>CACHE_FILE</tt>. If a _block_ is given,
47
+ # it will be passed the newly created OverlayCache object.
48
+ #
49
+ def initialize(path=CACHE_FILE,&block)
50
+ super()
51
+
52
+ @path = path
53
+ @dirty = false
54
+
55
+ if File.file?(@path)
56
+ descriptions = YAML.load(File.read(@path))
57
+
58
+ if descriptions.kind_of?(Array)
59
+ descriptions.each do |overlay|
60
+ if overlay.kind_of?(Hash)
61
+ overlay = Overlay.new(
62
+ overlay[:path],
63
+ overlay[:media],
64
+ overlay[:uri]
65
+ )
66
+
67
+ self[overlay.name] = overlay
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ at_exit(&method(:save))
74
+
75
+ block.call(self) if block
76
+ end
77
+
78
+ #
79
+ # Returns +true+ if the overlay cache has been modified, returns
80
+ # +false+ otherwise.
81
+ #
82
+ def dirty?
83
+ @dirty == true
84
+ end
85
+
86
+ alias names keys
87
+ alias overlays values
88
+ alias each_overlay each_value
89
+
90
+ #
91
+ # Returns the Ovlerays which match the specified _block_.
92
+ #
93
+ # cache.with do |overlay|
94
+ # overlay.author == 'the dude'
95
+ # end
96
+ #
97
+ def with(&block)
98
+ values.select(&block)
99
+ end
100
+
101
+ #
102
+ # Returns +true+ if the cache contains the Overlay with the
103
+ # matching _name_, returns +false+ otherwise.
104
+ #
105
+ def has?(name)
106
+ has_key?(name.to_s)
107
+ end
108
+
109
+ #
110
+ # Returns the Overlay with the matching _name_.
111
+ #
112
+ def get(name)
113
+ name = name.to_s
114
+
115
+ unless has?(name)
116
+ raise(OverlayNotFound,"overlay #{name.dump} is not present in cache #{self.to_s.dump}",caller)
117
+ end
118
+
119
+ return self[name]
120
+ end
121
+
122
+ #
123
+ # Returns the paths of the Overlays contained in the cache.
124
+ #
125
+ def paths
126
+ overlays.map { |overlay| overlay.path }
127
+ end
128
+
129
+ #
130
+ # Returns +true+ if the extension with the specified _name_ exists
131
+ # within any of the overlays in the overlay cache, returns +false+
132
+ # otherwise.
133
+ #
134
+ def has_extension?(name)
135
+ each_overlay do |overlay|
136
+ return true if overlay.extensions.include?(name)
137
+ end
138
+
139
+ return false
140
+ end
141
+
142
+ #
143
+ # Returns the names of all extensions within the overlay cache.
144
+ #
145
+ def extensions
146
+ ext_names = []
147
+
148
+ each_overlay do |overlay|
149
+ overlay.extensions.each do |name|
150
+ ext_names << name unless ext_names.include?(name)
151
+ end
152
+ end
153
+
154
+ return ext_names
155
+ end
156
+
157
+ #
158
+ # Returns the paths of all extensions with the specified _name_.
159
+ #
160
+ def extension_paths(name)
161
+ ext_paths = []
162
+
163
+ each_overlay do |overlay|
164
+ overlay.extension_paths.each do |path|
165
+ ext_paths << path if File.basename(path) == name
166
+ end
167
+ end
168
+
169
+ return ext_paths
170
+ end
171
+
172
+ #
173
+ # Adds the specified _overlay_ with the specified _name_ to the
174
+ # overlay cache.
175
+ #
176
+ def []=(name,overlay)
177
+ super(name.to_s,overlay)
178
+
179
+ overlay.activate!
180
+ return overlay
181
+ end
182
+
183
+ #
184
+ # Adds the _overlay_ to the cache. If a _block_ is given, it will
185
+ # be passed the cache after the _overlay_ is added. The _overlay_
186
+ # will be returned.
187
+ #
188
+ # cache.add(overlay)
189
+ # # => #<Ronin::Platform::Overlay: ...>
190
+ #
191
+ # cache.add(overlay) do |cache|
192
+ # puts "Overlay #{overlay} added"
193
+ # end
194
+ #
195
+ def add(overlay,&block)
196
+ name = overlay.name.to_s
197
+
198
+ if has?(name)
199
+ raise(OverlayCached,"overlay #{name.dump} already present in the cache #{self.to_s.dump}",caller)
200
+ end
201
+
202
+ self[overlay.name.to_s] = overlay
203
+ dirty!
204
+
205
+ block.call(self) if block
206
+ return self
207
+ end
208
+
209
+ #
210
+ # Updates all the cached Overlays. If a _block_ is given it will
211
+ # be passed the overlays as they are updated.
212
+ #
213
+ # update
214
+ # # => #<Ronin::Platform::OverlayCache: ...>
215
+ #
216
+ # update do |overlay|
217
+ # puts "#{overaly} is updated"
218
+ # end
219
+ #
220
+ def update(&block)
221
+ overlays.each do |overlay|
222
+ overlay.deactive!
223
+ overlay.update(&block)
224
+ overlay.active!
225
+ end
226
+
227
+ return self
228
+ end
229
+
230
+ #
231
+ # Removes the overlay with the specified _name_ from the cache. If a
232
+ # _block_ is given, it will be passed the removed overlay. The cache
233
+ # will be returned, after the overlay is removed.
234
+ #
235
+ # cache.remove('hello_word')
236
+ # # => #<Ronin::Platform::Overlay: ...>
237
+ #
238
+ # cache.remove('hello_word') do |overlay|
239
+ # puts "Overlay #{overlay} removed"
240
+ # end
241
+ #
242
+ def remove(name,&block)
243
+ name = name.to_s
244
+
245
+ overlay = get(name)
246
+ overlay.deactive!
247
+
248
+ delete_if { |key,value| key == name }
249
+ dirty!
250
+
251
+ block.call(overlay) if block
252
+ return self
253
+ end
254
+
255
+ #
256
+ # Uninstalls the overlay with the specified _name_. If a _block_
257
+ # is given, it will be passed the uninstalled overlay. The cache
258
+ # will be returned, after the overlay is removed.
259
+ #
260
+ # cache.uninstall('hello_word')
261
+ # # => #<Ronin::Platform::Overlay: ...>
262
+ #
263
+ # cache.uninstall('hello_word') do |overlay|
264
+ # puts "Overlay #{overlay} uninstalled"
265
+ # end
266
+ #
267
+ def uninstall(name,&block)
268
+ remove do |overlay|
269
+ overlay.uninstall(&block)
270
+ end
271
+ end
272
+
273
+ #
274
+ # Saves the overlay cache.
275
+ #
276
+ def save
277
+ return false unless dirty?
278
+
279
+ parent_directory = File.dirname(@path)
280
+
281
+ unless File.directory?(parent_directory)
282
+ FileUtils.mkdir_p(parent_directory)
283
+ end
284
+
285
+ File.open(@path,'w') do |output|
286
+ descriptions = overlays.map do |overlay|
287
+ {
288
+ :path => overlay.path,
289
+ :media => overlay.media_type,
290
+ :uri => overlay.uri
291
+ }
292
+ end
293
+
294
+ YAML.dump(descriptions,output)
295
+ end
296
+
297
+ return true
298
+ end
299
+
300
+ #
301
+ # Returns the +path+ of the cache.
302
+ #
303
+ def to_s
304
+ @path.to_s
305
+ end
306
+
307
+ protected
308
+
309
+ #
310
+ # Marks the overlay cache as dirty.
311
+ #
312
+ def dirty!
313
+ @dirty = true
314
+ end
315
+
316
+ end
317
+ end
318
+ end