ronin 0.0.9

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