ronin 0.0.9

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 (157) hide show
  1. data/COPYING.txt +339 -0
  2. data/History.txt +34 -0
  3. data/Manifest.txt +157 -0
  4. data/README.txt +131 -0
  5. data/Rakefile +23 -0
  6. data/TODO.txt +6 -0
  7. data/bin/ronin +12 -0
  8. data/lib/ronin.rb +35 -0
  9. data/lib/ronin/arch.rb +86 -0
  10. data/lib/ronin/author.rb +88 -0
  11. data/lib/ronin/cache.rb +27 -0
  12. data/lib/ronin/cache/config.rb +34 -0
  13. data/lib/ronin/cache/exceptions.rb +25 -0
  14. data/lib/ronin/cache/exceptions/extension_not_found.rb +29 -0
  15. data/lib/ronin/cache/exceptions/overlay_cached.rb +29 -0
  16. data/lib/ronin/cache/exceptions/overlay_not_found.rb +29 -0
  17. data/lib/ronin/cache/extension.rb +706 -0
  18. data/lib/ronin/cache/extension_cache.rb +108 -0
  19. data/lib/ronin/cache/overlay.rb +418 -0
  20. data/lib/ronin/cache/overlay_cache.rb +228 -0
  21. data/lib/ronin/cache/ronin.rb +50 -0
  22. data/lib/ronin/chars.rb +25 -0
  23. data/lib/ronin/chars/char_set.rb +121 -0
  24. data/lib/ronin/chars/chars.rb +180 -0
  25. data/lib/ronin/config.rb +31 -0
  26. data/lib/ronin/console.rb +127 -0
  27. data/lib/ronin/context.rb +233 -0
  28. data/lib/ronin/database.rb +122 -0
  29. data/lib/ronin/environment.rb +39 -0
  30. data/lib/ronin/exceptions/context_not_found.rb +27 -0
  31. data/lib/ronin/exceptions/invalid_database_config.rb +27 -0
  32. data/lib/ronin/exceptions/object_context_not_found.rb +27 -0
  33. data/lib/ronin/exceptions/unknown_context.rb +27 -0
  34. data/lib/ronin/exceptions/unknown_object_context.rb +27 -0
  35. data/lib/ronin/extensions.rb +28 -0
  36. data/lib/ronin/extensions/hash.rb +62 -0
  37. data/lib/ronin/extensions/kernel.rb +34 -0
  38. data/lib/ronin/extensions/meta.rb +24 -0
  39. data/lib/ronin/extensions/meta/object.rb +24 -0
  40. data/lib/ronin/extensions/string.rb +37 -0
  41. data/lib/ronin/extensions/uri.rb +24 -0
  42. data/lib/ronin/extensions/uri/http.rb +78 -0
  43. data/lib/ronin/extensions/uri/query_params.rb +97 -0
  44. data/lib/ronin/formatting.rb +29 -0
  45. data/lib/ronin/formatting/binary.rb +24 -0
  46. data/lib/ronin/formatting/digest.rb +24 -0
  47. data/lib/ronin/formatting/extensions.rb +26 -0
  48. data/lib/ronin/formatting/extensions/binary.rb +25 -0
  49. data/lib/ronin/formatting/extensions/binary/integer.rb +59 -0
  50. data/lib/ronin/formatting/extensions/binary/string.rb +73 -0
  51. data/lib/ronin/formatting/extensions/digest.rb +24 -0
  52. data/lib/ronin/formatting/extensions/digest/string.rb +65 -0
  53. data/lib/ronin/formatting/extensions/html.rb +24 -0
  54. data/lib/ronin/formatting/extensions/html/string.rb +75 -0
  55. data/lib/ronin/formatting/extensions/http.rb +24 -0
  56. data/lib/ronin/formatting/extensions/http/string.rb +69 -0
  57. data/lib/ronin/formatting/extensions/text.rb +24 -0
  58. data/lib/ronin/formatting/extensions/text/string.rb +96 -0
  59. data/lib/ronin/formatting/html.rb +24 -0
  60. data/lib/ronin/formatting/http.rb +24 -0
  61. data/lib/ronin/formatting/text.rb +24 -0
  62. data/lib/ronin/license.rb +87 -0
  63. data/lib/ronin/model.rb +44 -0
  64. data/lib/ronin/models.rb +34 -0
  65. data/lib/ronin/network.rb +31 -0
  66. data/lib/ronin/network/esmtp.rb +24 -0
  67. data/lib/ronin/network/extensions.rb +31 -0
  68. data/lib/ronin/network/extensions/esmtp.rb +24 -0
  69. data/lib/ronin/network/extensions/esmtp/net.rb +68 -0
  70. data/lib/ronin/network/extensions/http.rb +24 -0
  71. data/lib/ronin/network/extensions/http/net.rb +303 -0
  72. data/lib/ronin/network/extensions/imap.rb +24 -0
  73. data/lib/ronin/network/extensions/imap/net.rb +92 -0
  74. data/lib/ronin/network/extensions/pop3.rb +24 -0
  75. data/lib/ronin/network/extensions/pop3/net.rb +65 -0
  76. data/lib/ronin/network/extensions/smtp.rb +24 -0
  77. data/lib/ronin/network/extensions/smtp/net.rb +80 -0
  78. data/lib/ronin/network/extensions/tcp.rb +24 -0
  79. data/lib/ronin/network/extensions/tcp/net.rb +94 -0
  80. data/lib/ronin/network/extensions/telnet.rb +24 -0
  81. data/lib/ronin/network/extensions/telnet/net.rb +132 -0
  82. data/lib/ronin/network/extensions/udp.rb +24 -0
  83. data/lib/ronin/network/extensions/udp/net.rb +99 -0
  84. data/lib/ronin/network/http.rb +128 -0
  85. data/lib/ronin/network/http/exceptions.rb +24 -0
  86. data/lib/ronin/network/http/exceptions/unknown_request.rb +31 -0
  87. data/lib/ronin/network/imap.rb +47 -0
  88. data/lib/ronin/network/pop3.rb +47 -0
  89. data/lib/ronin/network/smtp.rb +26 -0
  90. data/lib/ronin/network/smtp/email.rb +126 -0
  91. data/lib/ronin/network/smtp/smtp.rb +55 -0
  92. data/lib/ronin/network/tcp.rb +24 -0
  93. data/lib/ronin/network/telnet.rb +95 -0
  94. data/lib/ronin/network/udp.rb +24 -0
  95. data/lib/ronin/object_context.rb +257 -0
  96. data/lib/ronin/objects.rb +29 -0
  97. data/lib/ronin/parameters.rb +27 -0
  98. data/lib/ronin/parameters/class_param.rb +45 -0
  99. data/lib/ronin/parameters/exceptions.rb +25 -0
  100. data/lib/ronin/parameters/exceptions/missing_param.rb +29 -0
  101. data/lib/ronin/parameters/exceptions/param_not_found.rb +29 -0
  102. data/lib/ronin/parameters/instance_param.rb +57 -0
  103. data/lib/ronin/parameters/param.rb +45 -0
  104. data/lib/ronin/parameters/parameters.rb +275 -0
  105. data/lib/ronin/path.rb +70 -0
  106. data/lib/ronin/pending_context.rb +42 -0
  107. data/lib/ronin/persistence.rb +32 -0
  108. data/lib/ronin/platform.rb +95 -0
  109. data/lib/ronin/product.rb +56 -0
  110. data/lib/ronin/ronin.rb +49 -0
  111. data/lib/ronin/rpc.rb +27 -0
  112. data/lib/ronin/rpc/call.rb +75 -0
  113. data/lib/ronin/rpc/client.rb +91 -0
  114. data/lib/ronin/rpc/console.rb +79 -0
  115. data/lib/ronin/rpc/exceptions.rb +25 -0
  116. data/lib/ronin/rpc/exceptions/not_implemented.rb +29 -0
  117. data/lib/ronin/rpc/exceptions/response_missing.rb +29 -0
  118. data/lib/ronin/rpc/interactive.rb +55 -0
  119. data/lib/ronin/rpc/interactive_console.rb +58 -0
  120. data/lib/ronin/rpc/interactive_shell.rb +59 -0
  121. data/lib/ronin/rpc/response.rb +57 -0
  122. data/lib/ronin/rpc/service.rb +69 -0
  123. data/lib/ronin/rpc/shell.rb +66 -0
  124. data/lib/ronin/runner.rb +24 -0
  125. data/lib/ronin/runner/program.rb +26 -0
  126. data/lib/ronin/runner/program/command.rb +204 -0
  127. data/lib/ronin/runner/program/commands.rb +33 -0
  128. data/lib/ronin/runner/program/commands/add.rb +73 -0
  129. data/lib/ronin/runner/program/commands/help.rb +52 -0
  130. data/lib/ronin/runner/program/commands/install.rb +65 -0
  131. data/lib/ronin/runner/program/commands/list.rb +81 -0
  132. data/lib/ronin/runner/program/commands/remove.rb +57 -0
  133. data/lib/ronin/runner/program/commands/uninstall.rb +57 -0
  134. data/lib/ronin/runner/program/commands/update.rb +55 -0
  135. data/lib/ronin/runner/program/exceptions.rb +24 -0
  136. data/lib/ronin/runner/program/exceptions/unknown_command.rb +31 -0
  137. data/lib/ronin/runner/program/options.rb +205 -0
  138. data/lib/ronin/runner/program/program.rb +173 -0
  139. data/lib/ronin/runner/program/runner.rb +35 -0
  140. data/lib/ronin/sessions.rb +32 -0
  141. data/lib/ronin/sessions/esmtp.rb +76 -0
  142. data/lib/ronin/sessions/imap.rb +73 -0
  143. data/lib/ronin/sessions/pop3.rb +70 -0
  144. data/lib/ronin/sessions/session.rb +52 -0
  145. data/lib/ronin/sessions/smtp.rb +76 -0
  146. data/lib/ronin/sessions/tcp.rb +111 -0
  147. data/lib/ronin/sessions/telnet.rb +76 -0
  148. data/lib/ronin/sessions/udp.rb +99 -0
  149. data/lib/ronin/sessions/web.rb +83 -0
  150. data/lib/ronin/shell.rb +81 -0
  151. data/lib/ronin/target.rb +40 -0
  152. data/lib/ronin/version.rb +27 -0
  153. data/lib/ronin/web.rb +24 -0
  154. data/lib/ronin/web/web.rb +265 -0
  155. data/spec/spec_helper.rb +9 -0
  156. data/tasks/spec.rb +7 -0
  157. metadata +324 -0
@@ -0,0 +1,31 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2008 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 'fileutils'
25
+
26
+ module Ronin
27
+ module Config
28
+ # Ronin home directory
29
+ PATH = FileUtils.mkdir_p(File.join(ENV['HOME'],'.ronin'))
30
+ end
31
+ end
@@ -0,0 +1,127 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2008 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/config'
25
+
26
+ require 'irb'
27
+ require 'irb/completion'
28
+
29
+ module Ronin
30
+ module Console
31
+ #
32
+ # Returns the default Console prompt style
33
+ #
34
+ def Console.prompt
35
+ @@console_prompt ||= :SIMPLE
36
+ end
37
+
38
+ #
39
+ # Sets the default Console prompt style to the specified _style_.
40
+ #
41
+ def Console.prompt=(style)
42
+ @@console_prompt = style
43
+ end
44
+
45
+ #
46
+ # Returns the default Console indent setting.
47
+ #
48
+ def Console.indent
49
+ @@console_indent ||= true
50
+ end
51
+
52
+ #
53
+ # Sets the default Console indent setting.
54
+ #
55
+ def Console.indent=(value)
56
+ @@console_indent = value
57
+ end
58
+
59
+ #
60
+ # Returns the Array of files to require when the Console starts.
61
+ #
62
+ def Console.auto_load
63
+ @@console_auto_load ||= []
64
+ end
65
+
66
+ #
67
+ # Calls the specified _block_ from within the Console after it is
68
+ # started.
69
+ #
70
+ def Console.setup(&block)
71
+ Console.setup_blocks << block if block
72
+ end
73
+
74
+ #
75
+ # Starts a Console with the given _script_. If a _block_ is given, it
76
+ # will be called from within the Console.
77
+ #
78
+ def Console.start(script=nil,&block)
79
+ IRB.setup(script)
80
+
81
+ IRB.conf[:IRB_NAME] = 'ronin'
82
+ IRB.conf[:PROMPT_MODE] = Console.prompt
83
+ IRB.conf[:AUTO_INDENT] = Console.indent
84
+ IRB.conf[:LOAD_MODULES] = Console.auto_load
85
+
86
+ irb = IRB::Irb.new(nil,script)
87
+
88
+ # configure the irb workspace
89
+ irb.context.main.instance_eval do
90
+ require 'ronin'
91
+ require 'pp'
92
+
93
+ include Ronin
94
+ end
95
+
96
+ Console.setup_blocks.each do |setup_block|
97
+ irb.context.main.instance_eval(&setup_block)
98
+ end
99
+
100
+ # Load console configuration block is given
101
+ irb.context.main.instance_eval(&block) if block
102
+
103
+ IRB.conf[:MAIN_CONTEXT] = irb.context
104
+
105
+ trap('SIGINT') do
106
+ irb.signal_handle
107
+ end
108
+
109
+ catch(:IRB_EXIT) do
110
+ irb.eval_input
111
+ end
112
+
113
+ print "\n"
114
+ return nil
115
+ end
116
+
117
+ protected
118
+
119
+ #
120
+ # Returns the Array of setup_blocks to run within the Console after it
121
+ # is started.
122
+ #
123
+ def Console.setup_blocks
124
+ @@console_setup_blocks ||= []
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,233 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2008 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/exceptions/unknown_context'
25
+ require 'ronin/exceptions/context_not_found'
26
+ require 'ronin/pending_context'
27
+ require 'ronin/extensions/meta'
28
+
29
+ module Ronin
30
+ module Context
31
+ def self.included(base)
32
+ base.metaclass_def(:contextify) do |name|
33
+ Context.contexts[name.to_sym] = self
34
+
35
+ meta_def(:context_name) { name }
36
+
37
+ class_def(:context_name) { name }
38
+
39
+ meta_def(:load_context) do |path,*args|
40
+ Context.load_context(path,self.context_name,*args)
41
+ end
42
+
43
+ # define the top-level context wrappers
44
+ Kernel.module_eval %{
45
+ def ronin_#{name}(*args,&block)
46
+ if (args.empty? && Ronin::Context.is_pending?)
47
+ Ronin::Context.pending.blocks[:#{name}] = block
48
+ return nil
49
+ else
50
+ new_context = #{self}.new(*args)
51
+ new_context.instance_eval(&block) if block
52
+ return new_context
53
+ end
54
+ end
55
+ }
56
+
57
+ # define the Ronin-level context loader
58
+ Ronin.module_eval %{
59
+ def ronin_load_#{name}(path,*args,&block)
60
+ new_context = #{self}.load_context(path,*args)
61
+
62
+ block.call(new_context) if block
63
+ return new_context
64
+ end
65
+ }
66
+ end
67
+ end
68
+
69
+ #
70
+ # Returns a Hash of all defined contexts.
71
+ #
72
+ def Context.contexts
73
+ @@ronin_contexts ||= {}
74
+ end
75
+
76
+ #
77
+ # Returns +true+ if there is a context defined with the specified
78
+ # _name_, returns +false+ otherwise.
79
+ #
80
+ def Context.is_context?(name)
81
+ Context.contexts.has_key?(name.to_sym)
82
+ end
83
+
84
+ #
85
+ # Converts the name of the _base_ class to a context name, returning
86
+ # it in +String+ form.
87
+ #
88
+ # Context.namify(Ronin::Resources) # => "ronin_resources"
89
+ #
90
+ # Context.namify(Analysis::Audio) # => "ronin_analysis_audio"
91
+ #
92
+ def Context.namify(base)
93
+ # similar to the way Og tableizes Class names
94
+ base.to_s.downcase.gsub(/::/,'_').gsub(/^ronin_/,'').to_sym
95
+ end
96
+
97
+ #
98
+ # Returns the Array of contexts which are waiting to be loaded.
99
+ #
100
+ def Context.waiting
101
+ @@ronin_waiting_contexts ||= []
102
+ end
103
+
104
+ #
105
+ # Returns the pending context being loaded.
106
+ #
107
+ def Context.pending
108
+ Context.waiting.first
109
+ end
110
+
111
+ #
112
+ # Returns +true+ if there is a pending context present, returns
113
+ # +false+ otherwise.
114
+ #
115
+ def Context.is_pending?
116
+ !(Context.waiting.empty?)
117
+ end
118
+
119
+ #
120
+ # Returns the first pending context with the specified _path_.
121
+ #
122
+ def Context.loading(path)
123
+ Context.waiting.each do |pending|
124
+ if pending.path == path
125
+ return pending
126
+ end
127
+ end
128
+
129
+ return nil
130
+ end
131
+
132
+ #
133
+ # Returns +true+ if the pending context with the specified _path_
134
+ # is present, returns +false+ otherwise.
135
+ #
136
+ def Context.is_loading?(path)
137
+ !(Context.loading(path).nil?)
138
+ end
139
+
140
+ #
141
+ # Loads all context blocks from the specified _path_, returning a
142
+ # PendingContext object containing the context blocks.
143
+ #
144
+ def Context.load_blocks(path,&block)
145
+ path = File.expand_path(path)
146
+
147
+ unless File.file?(path)
148
+ raise(ContextNotFound,"context #{path.dump} doest not exist",caller)
149
+ end
150
+
151
+ # prevent circular loading of contexts
152
+ unless Context.is_pending?
153
+ # push on the new pending context
154
+ Context.waiting.unshift(PendingContext.new(path))
155
+
156
+ load(path)
157
+ end
158
+
159
+ # pop off and return the pending context
160
+ pending_context = Context.waiting.shift
161
+
162
+ block.call(pending_context) if block
163
+ return pending_context
164
+ end
165
+
166
+ #
167
+ # Loads the context block of the specified _name_ from the specified
168
+ # _path_, returning the context block. If a _block_ is given it will
169
+ # be passed the loaded context block.
170
+ #
171
+ # Context.load_block('/path/to/my_exploit.rb',:exploit) # => Proc
172
+ #
173
+ # Context.load_block('/path/to/my_shellcode.rb',:shellcode)
174
+ # do |block|
175
+ # ...
176
+ # end
177
+ #
178
+ def Context.load_block(name,path,&block)
179
+ context_block = Context.load_blocks(path).blocks[name.to_sym]
180
+
181
+ block.call(context_block) if block
182
+ return context_block
183
+ end
184
+
185
+ #
186
+ # Loads the context of the specified _name_ and from the specified
187
+ # _path_ with the given _args_. If no contexts were defined with the
188
+ # specified _name_, an UnknownContext exception will be raised.
189
+ #
190
+ # Context.load_context(:note,'/path/to/my_notes.rb') # => Note
191
+ #
192
+ def Context.load_context(name,path,*args)
193
+ name = name.to_sym
194
+
195
+ unless Context.is_context?(name)
196
+ raise(UnknownContext,"unknown context '#{name}'",caller)
197
+ end
198
+
199
+ new_context = Context.contexts[name].new(*args)
200
+
201
+ Context.load_block(name,path) do |context_block|
202
+ new_context.instance_eval(&context_block) if context_block
203
+ end
204
+
205
+ return new_context
206
+ end
207
+
208
+ #
209
+ # Loads all contexts from the specified _path_ returning an +Array+
210
+ # of loaded contexts. If a _block_ is given, it will be passed
211
+ # each loaded context.
212
+ #
213
+ # Context.load_contexts('/path/to/misc_contexts.rb') # => [...]
214
+ #
215
+ def Context.load_contexts(path,&block)
216
+ new_objs = []
217
+
218
+ Context.load_blocks(path) do |pending|
219
+ pending.blocks.each do |name,context_block|
220
+ if Context.is_context?(name)
221
+ new_obj = Context.contexts[name].new
222
+ new_obj.instance_eval(&context_block)
223
+
224
+ new_objs << new_obj
225
+ end
226
+ end
227
+ end
228
+
229
+ new_objs.each(&block) if block
230
+ return new_objs
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,122 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2008 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/exceptions/invalid_database_config'
25
+ require 'ronin/extensions/kernel'
26
+ require 'ronin/config'
27
+
28
+ require 'yaml'
29
+ require 'dm-core'
30
+
31
+ module Ronin
32
+ module Database
33
+ # Database configuration file
34
+ CONFIG_FILE = File.join(Config::PATH,'database.yml')
35
+
36
+ # Database log file
37
+ DEFAULT_LOG_PATH = File.join(Config::PATH,'database.log')
38
+
39
+ # Database log level
40
+ DEFAULT_LOG_LEVEL = :info
41
+
42
+ # Default configuration of the database
43
+ DEFAULT_CONFIG = {
44
+ :adapter => :sqlite3,
45
+ :database => File.join(Config::PATH,'ronin.db')
46
+ }
47
+
48
+ #
49
+ # Returns the Database configuration that is stored in the
50
+ # +CONFIG_FILE+. Defaults to +DEFAULT_CONFIG+ if +CONFIG_FILE+ does not
51
+ # exist.
52
+ #
53
+ def Database.config
54
+ unless (class_variable_defined?('@@ronin_database_config'))
55
+ @@ronin_database_config = DEFAULT_CONFIG
56
+
57
+ if File.file?(CONFIG_FILE)
58
+ conf = YAML.load(CONFIG_FILE)
59
+
60
+ unless (conf.kind_of?(Hash) || conf.kind_of?(String))
61
+ raise(InvalidDatabaseConfig,"#{CONFIG_FILE} must contain either a Hash or a String",caller)
62
+ end
63
+
64
+ @@ronin_database_config = conf
65
+ end
66
+ end
67
+
68
+ return @@ronin_database_config ||= DEFAULT_CONFIG
69
+ end
70
+
71
+ #
72
+ # Sets the Database configuration to the specified _configuration_.
73
+ #
74
+ def Database.config=(configuration)
75
+ @@ronin_database_config = configuration
76
+ end
77
+
78
+ #
79
+ # Setup the Database log with the given _options_.
80
+ #
81
+ # _options_ may contain the following keys:
82
+ # <tt>:path</tt>:: The path of the log file. Defaults to
83
+ # +DEFAULT_LOG_PATH+.
84
+ # <tt>:stream</tt>:: The stream to use for the log.
85
+ # <tt>:level</tt>:: The level of messages to log.
86
+ #
87
+ def Database.setup_log(options={})
88
+ path = (options[:path] || DEFAULT_LOG_PATH)
89
+ stream = (options[:stream] || File.new(path,'w+'))
90
+ level = (options[:level] || DEFAULT_LOG_LEVEL)
91
+
92
+ DataMapper::Logger.new(stream,level)
93
+ return nil
94
+ end
95
+
96
+ #
97
+ # Sets up the Database with the given _configuration_. If
98
+ # _configuration is not given, +DEFAULT_CONFIG+ will be used to setup
99
+ # the Database.
100
+ #
101
+ def Database.setup(configuration=Database.config,&block)
102
+ Database.setup_log
103
+ DataMapper.setup(:default, configuration)
104
+
105
+ block.call if block
106
+
107
+ # sourced from http://gist.github.com/3010
108
+ # in order to fix a has-many lazy-loading bug
109
+ # in dm-core <= 0.9.4
110
+ descendants = DataMapper::Resource.descendants.dup
111
+ descendants.each do |model|
112
+ descendants.merge(model.descendants) if model.respond_to?(:descendants)
113
+ end
114
+ descendants.each do |model|
115
+ model.relationships.each_value { |r| r.child_key if r.child_model == model }
116
+ end
117
+
118
+ DataMapper.auto_upgrade!
119
+ return nil
120
+ end
121
+ end
122
+ end