Permalink
Browse files

added webrat test app bundled gems

  • Loading branch information...
1 parent 4f5a24c commit c04a6856b65cca155e1dcd09c98cfe3f95cefb8e @mattetti mattetti committed Nov 8, 2008
Showing with 19,732 additions and 1 deletion.
  1. +1 −1 .gitignore
  2. +3 −0 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/ChangeLog
  3. +57 −0 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/README.txt
  4. +48 −0 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/abstract.gemspec
  5. +75 −0 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/lib/abstract.rb
  6. +1,331 −0 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/setup.rb
  7. +91 −0 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/test/test.rb
  8. +14 −0 merb-core/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/CHANGELOG
  9. +55 −0 merb-core/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/LICENSE
  10. +6 −0 merb-core/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/Manifest
  11. +40 −0 merb-core/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/README
  12. +44 −0 ...e/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/cgi_multipart_eof_fix.gemspec
  13. +127 −0 ...re/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/lib/cgi_multipart_eof_fix.rb
  14. +59 −0 ...c/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/test/test_cgi_multipart_eof_fix.rb
  15. +29 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/LICENSE
  16. +223 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/README
  17. +84 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/Rakefile
  18. +126 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/Releases
  19. +6 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/TODO
  20. +56 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/call/call.rb
  21. +55 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/call/call_monitor.rb
  22. +20 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/daemonize/daemonize.rb
  23. +17 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_crash.rb
  24. +16 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_exec.rb
  25. +15 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_exit.rb
  26. +17 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_keep_pid_files.rb
  27. +16 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_monitor.rb
  28. +16 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_multiple.rb
  29. +12 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_normal.rb
  30. +16 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_ontop.rb
  31. +43 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_optionparser.rb
  32. +25 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_proc.rb
  33. +101 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_proc.rb.output
  34. +22 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_proc_multiple.rb
  35. +2 −0 ...re/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_proc_multiple.rb.output
  36. +17 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/ctrl_proc_simple.rb
  37. +12 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/myserver.rb
  38. +14 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/myserver_crashing.rb
  39. +30 −0 ...ore/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/myserver_crashing.rb.output
  40. +8 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/examples/run/myserver_exiting.rb
  41. +283 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons.rb
  42. +372 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/application.rb
  43. +152 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/application_group.rb
  44. +117 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/cmdline.rb
  45. +134 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/controller.rb
  46. +263 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/daemonize.rb
  47. +28 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/exceptions.rb
  48. +127 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/monitor.rb
  49. +101 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/pid.rb
  50. +111 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/pidfile.rb
  51. +10 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/lib/daemons/pidmem.rb
  52. +1,360 −0 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/setup.rb
  53. +717 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/CHANGES.txt
  54. +20 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/MIT-LICENSE
  55. +102 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/README.txt
  56. +6 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/benchmark/Makefile
  57. +314 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/benchmark/bench.rb
  58. +141 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/benchmark/bench_context.yaml
  59. +4 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/benchmark/templates/_footer.html
  60. +52 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/benchmark/templates/_header.html
  61. +29 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/benchmark/templates/bench_erb.rhtml
  62. +29 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/benchmark/templates/bench_erubis.rhtml
  63. +29 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/benchmark/templates/bench_eruby.rhtml
  64. +11 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/bin/erubis
  65. +11 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/contrib/erubis
  66. +132 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/contrib/erubis-run.rb
  67. +153 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/contrib/inline-require
  68. +105 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/ActionView.html
  69. +181 −0 ...at/test_app/gems/gems/erubis-2.6.2/doc-api/classes/ActionView/TemplateHandlers/ErubisHandler.html
  70. +101 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/ERB.html
  71. +353 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis.html
  72. +175 −0 ...pec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/ArrayBufferEnhancer.html
  73. +120 −0 ...e/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/ArrayBufferEruby.html
  74. +174 −0 ...core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/ArrayEnhancer.html
  75. +120 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/ArrayEruby.html
  76. +112 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Basic.html
  77. +327 −0 ...re/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Basic/Converter.html
  78. +130 −0 ...-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Basic/Engine.html
  79. +215 −0 .../spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/BiPatternEnhancer.html
  80. +120 −0 ...ore/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/BiPatternEruby.html
  81. +386 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/CGenerator.html
  82. +113 −0 ...spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/CommandOptionError.html
  83. +344 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Context.html
  84. +283 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Converter.html
  85. +150 −0 ...ec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/DeleteIndentEnhancer.html
  86. +120 −0 .../spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/DeleteIndentEruby.html
  87. +126 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Ec.html
  88. +126 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Ejava.html
  89. +126 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Ejavascript.html
  90. +305 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Engine.html
  91. +126 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Eperl.html
  92. +126 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Ephp.html
  93. +175 −0 ...ore/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/ErboutEnhancer.html
  94. +120 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/ErboutEruby.html
  95. +117 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/ErubisError.html
  96. +132 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Eruby.html
  97. +165 −0 ...ore/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/EscapeEnhancer.html
  98. +120 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/EscapedEc.html
  99. +120 −0 ...-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/EscapedEjava.html
  100. +120 −0 ...spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/EscapedEjavascript.html
  101. +120 −0 ...-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/EscapedEperl.html
  102. +120 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/EscapedEphp.html
  103. +127 −0 ...-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/EscapedEruby.html
  104. +120 −0 ...ore/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/EscapedEscheme.html
  105. +126 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Escheme.html
  106. +212 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Evaluator.html
  107. +131 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/FastEruby.html
  108. +416 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Generator.html
  109. +267 −0 ...ec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/HeaderFooterEnhancer.html
  110. +120 −0 .../spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/HeaderFooterEruby.html
  111. +116 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Helpers.html
  112. +787 −0 ...public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Helpers/RailsFormHelper.html
  113. +349 −0 ...pec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Helpers/RailsHelper.html
  114. +164 −0 ...test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Helpers/RailsHelper/TemplateConverter.html
  115. +306 −0 ...c/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/InterpolationEnhancer.html
  116. +120 −0 ...spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/InterpolationEruby.html
  117. +359 −0 ...core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/JavaGenerator.html
  118. +386 −0 ...pec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/JavascriptGenerator.html
  119. +340 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/Main.html
  120. +249 −0 ...ore/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/NoCodeEnhancer.html
  121. +120 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/NoCodeEruby.html
  122. +159 −0 ...ore/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/NoTextEnhancer.html
  123. +120 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/NoTextEruby.html
  124. +119 −0 .../spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/NotSupportedError.html
  125. +163 −0 ...ore/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/OptimizedEruby.html
  126. +439 −0 ...spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/OptimizedGenerator.html
  127. +163 −0 .../spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/OptimizedXmlEruby.html
  128. +124 −0 merb-core/spec/public/webrat/test_app/gems/gems/erubis-2.6.2/doc-api/classes/Erubis/PI.html
Sorry, we could not display the entire diff because too many files (1,498) changed.
View
2 .gitignore
@@ -13,5 +13,5 @@ coverage
bundle
lib/merb-more.rb
*.DS_Store
-gems
+./gems
*.diff
View
3 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/ChangeLog
@@ -0,0 +1,3 @@
+: release 1.0.0 (2006-03-12)
+ - first release (1.0.0)
+
View
57 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/README.txt
@@ -0,0 +1,57 @@
+= README
+
+revision:: $Rev: 1 $
+release:: $Release: 1.0.0 $
+copyright:: copyright(c) 2006 kuwata-lab.com all rights reserved.
+
+
+== Introduction
+
+'abstract.rb' is a library which enable you to define abstract method in Ruby.
+
+The followings are examples:
+
+ ## example1. (shorter notation)
+ require 'rubygems' # if installed with 'gem install'
+ require 'abstract'
+ class Foo
+ abstract_method 'arg1, arg2=""', :method1, :method2, :method3
+ end
+
+ ## example2. (RDoc friendly notation)
+ require 'rubygems' # if installed with 'gem install'
+ require 'abstract'
+ class Bar
+ # ... method1 description ...
+ def method1(arg1, arg2="")
+ not_implemented
+ end
+ # ... method2 description ...
+ def method2(arg1, arg2="")
+ not_implemented
+ end
+ end
+
+
+Abstract method makes your code more descriptive.
+It is useful even for dynamic language such as Ruby.
+
+
+== Installation
+
+
+* Type 'gem install -r abstract' with root account if you have installed RubyGems.
+
+* Or type 'ruby setup.rb' with root account if you can be root account.
+
+* Or copy lib/abstract.rb into proper directory such as '/usr/local/lib/ruby/site_ruby'.
+
+
+== License
+
+Ruby's
+
+
+== Copyright
+
+copyright(c) 2006 kuwata-lab.com all rights reserved.
View
48 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/abstract.gemspec
@@ -0,0 +1,48 @@
+#!/usr/bin/env ruby
+
+###
+### RubyGems Specification file for abstract.rb
+###
+### $Rev: 1 $
+### $Release: 1.0.0 $
+### copyright(c) 2006 kuwata-lab.com all rights reserved.
+###
+
+require 'rubygems'
+
+spec = Gem::Specification.new do |s|
+ ## package information
+ s.name = 'abstract'
+ s.author = 'makoto kuwata'
+ s.version = ("$Release: 1.0.0 $" =~ /[\.\d]+/) && $&
+ s.platform = Gem::Platform::RUBY
+ s.homepage = 'http://rubyforge.org/projects/abstract'
+ s.summary = "a library which enable you to define abstract method in Ruby"
+ s.description = <<-'END'
+ 'abstract.rb' is a library which enable you to define abstract method in Ruby.
+ END
+
+ ## files
+ files = []
+ files += Dir.glob('lib/**/*')
+ files += Dir.glob('test/**/*')
+ files += %w[README.txt ChangeLog setup.rb abstract.gemspec]
+ #s.files = files.delete_if { |path| path =~ /\.svn/ }
+ s.files = files
+ s.test_file = 'test/test.rb'
+end
+
+# Quick fix for Ruby 1.8.3 / YAML bug (thanks to Ross Bamford)
+if (RUBY_VERSION == '1.8.3')
+ def spec.to_yaml
+ out = super
+ out = '--- ' + out unless out =~ /^---/
+ out
+ end
+end
+
+if $0 == __FILE__
+ Gem::manage_gems
+ Gem::Builder.new(spec).build
+end
+
View
75 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/lib/abstract.rb
@@ -0,0 +1,75 @@
+##
+## $Rev: 1 $
+## $Release: 1.0.0 $
+## copyright(c) 2006 kuwata-lab.com all rights reserved.
+##
+##
+## helper to define abstract method in Ruby.
+##
+##
+## example1. (shorter notation)
+##
+## require 'abstract'
+## class Foo
+## abstract_method 'arg1, arg2=""', :method1, :method2, :method3
+## end
+##
+##
+## example2. (RDoc friendly notation)
+##
+## require 'abstract'
+## class Bar
+## # ... method1 description ...
+## def method1(arg1, arg2="")
+## not_implemented
+## end
+##
+## # ... method2 description ...
+## def method2(arg1, arg2="")
+## not_implemented
+## end
+## end
+##
+
+
+##
+class Module
+
+ ##
+ ## define abstract methods
+ ##
+ def abstract_method args_str, *method_names
+ method_names.each do |name|
+ module_eval <<-END
+ def #{name}(#{args_str})
+ mesg = "class \#{self.class.name} must implement abstract method `#{self.name}##{name}()'."
+ #mesg = "\#{self.class.name}##{name}() is not implemented."
+ err = NotImplementedError.new mesg
+ err.set_backtrace caller()
+ raise err
+ end
+ END
+ end
+ end
+
+end
+
+
+##
+module Kernel
+
+ ##
+ ## raise NotImplementedError
+ ##
+ def not_implemented #:doc:
+ backtrace = caller()
+ method_name = (backtrace.shift =~ /`(\w+)'$/) && $1
+ mesg = "class #{self.class.name} must implement abstract method '#{method_name}()'."
+ #mesg = "#{self.class.name}##{method_name}() is not implemented."
+ err = NotImplementedError.new mesg
+ err.set_backtrace backtrace
+ raise err
+ end
+ private :not_implemented
+
+end
View
1,331 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/setup.rb
@@ -0,0 +1,1331 @@
+#
+# setup.rb
+#
+# Copyright (c) 2000-2004 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the terms of
+# the GNU Lesser General Public License version 2.1.
+#
+
+#
+# For backward compatibility
+#
+
+unless Enumerable.method_defined?(:map)
+ module Enumerable
+ alias map collect
+ end
+end
+
+unless Enumerable.method_defined?(:detect)
+ module Enumerable
+ alias detect find
+ end
+end
+
+unless Enumerable.method_defined?(:select)
+ module Enumerable
+ alias select find_all
+ end
+end
+
+unless Enumerable.method_defined?(:reject)
+ module Enumerable
+ def reject
+ result = []
+ each do |i|
+ result.push i unless yield(i)
+ end
+ result
+ end
+ end
+end
+
+unless Enumerable.method_defined?(:inject)
+ module Enumerable
+ def inject(result)
+ each do |i|
+ result = yield(result, i)
+ end
+ result
+ end
+ end
+end
+
+unless Enumerable.method_defined?(:any?)
+ module Enumerable
+ def any?
+ each do |i|
+ return true if yield(i)
+ end
+ false
+ end
+ end
+end
+
+unless File.respond_to?(:read)
+ def File.read(fname)
+ open(fname) {|f|
+ return f.read
+ }
+ end
+end
+
+#
+# Application independent utilities
+#
+
+def File.binread(fname)
+ open(fname, 'rb') {|f|
+ return f.read
+ }
+end
+
+# for corrupted windows stat(2)
+def File.dir?(path)
+ File.directory?((path[-1,1] == '/') ? path : path + '/')
+end
+
+#
+# Config
+#
+
+if arg = ARGV.detect{|arg| /\A--rbconfig=/ =~ arg }
+ ARGV.delete(arg)
+ require arg.split(/=/, 2)[1]
+ $".push 'rbconfig.rb'
+else
+ require 'rbconfig'
+end
+
+def multipackage_install?
+ FileTest.directory?(File.dirname($0) + '/packages')
+end
+
+
+class ConfigTable
+
+ c = ::Config::CONFIG
+
+ rubypath = c['bindir'] + '/' + c['ruby_install_name']
+
+ major = c['MAJOR'].to_i
+ minor = c['MINOR'].to_i
+ teeny = c['TEENY'].to_i
+ version = "#{major}.#{minor}"
+
+ # ruby ver. >= 1.4.4?
+ newpath_p = ((major >= 2) or
+ ((major == 1) and
+ ((minor >= 5) or
+ ((minor == 4) and (teeny >= 4)))))
+
+ subprefix = lambda {|path|
+ path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix')
+ }
+
+ if c['rubylibdir']
+ # V < 1.6.3
+ stdruby = subprefix.call(c['rubylibdir'])
+ siteruby = subprefix.call(c['sitedir'])
+ versite = subprefix.call(c['sitelibdir'])
+ sodir = subprefix.call(c['sitearchdir'])
+ elsif newpath_p
+ # 1.4.4 <= V <= 1.6.3
+ stdruby = "$prefix/lib/ruby/#{version}"
+ siteruby = subprefix.call(c['sitedir'])
+ versite = siteruby + '/' + version
+ sodir = "$site-ruby/#{c['arch']}"
+ else
+ # V < 1.4.4
+ stdruby = "$prefix/lib/ruby/#{version}"
+ siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
+ versite = siteruby
+ sodir = "$site-ruby/#{c['arch']}"
+ end
+
+ if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
+ makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
+ else
+ makeprog = 'make'
+ end
+
+ common_descripters = [
+ [ 'prefix', [ c['prefix'],
+ 'path',
+ 'path prefix of target environment' ] ],
+ [ 'std-ruby', [ stdruby,
+ 'path',
+ 'the directory for standard ruby libraries' ] ],
+ [ 'site-ruby-common', [ siteruby,
+ 'path',
+ 'the directory for version-independent non-standard ruby libraries' ] ],
+ [ 'site-ruby', [ versite,
+ 'path',
+ 'the directory for non-standard ruby libraries' ] ],
+ [ 'bin-dir', [ '$prefix/bin',
+ 'path',
+ 'the directory for commands' ] ],
+ [ 'rb-dir', [ '$site-ruby',
+ 'path',
+ 'the directory for ruby scripts' ] ],
+ [ 'so-dir', [ sodir,
+ 'path',
+ 'the directory for ruby extentions' ] ],
+ [ 'data-dir', [ '$prefix/share',
+ 'path',
+ 'the directory for shared data' ] ],
+ [ 'ruby-path', [ rubypath,
+ 'path',
+ 'path to set to #! line' ] ],
+ [ 'ruby-prog', [ rubypath,
+ 'name',
+ 'the ruby program using for installation' ] ],
+ [ 'make-prog', [ makeprog,
+ 'name',
+ 'the make program to compile ruby extentions' ] ],
+ [ 'without-ext', [ 'no',
+ 'yes/no',
+ 'does not compile/install ruby extentions' ] ]
+ ]
+ multipackage_descripters = [
+ [ 'with', [ '',
+ 'name,name...',
+ 'package names that you want to install',
+ 'ALL' ] ],
+ [ 'without', [ '',
+ 'name,name...',
+ 'package names that you do not want to install',
+ 'NONE' ] ]
+ ]
+ if multipackage_install?
+ DESCRIPTER = common_descripters + multipackage_descripters
+ else
+ DESCRIPTER = common_descripters
+ end
+
+ SAVE_FILE = 'config.save'
+
+ def ConfigTable.each_name(&block)
+ keys().each(&block)
+ end
+
+ def ConfigTable.keys
+ DESCRIPTER.map {|name, *dummy| name }
+ end
+
+ def ConfigTable.each_definition(&block)
+ DESCRIPTER.each(&block)
+ end
+
+ def ConfigTable.get_entry(name)
+ name, ent = DESCRIPTER.assoc(name)
+ ent
+ end
+
+ def ConfigTable.get_entry!(name)
+ get_entry(name) or raise ArgumentError, "no such config: #{name}"
+ end
+
+ def ConfigTable.add_entry(name, vals)
+ ConfigTable::DESCRIPTER.push [name,vals]
+ end
+
+ def ConfigTable.remove_entry(name)
+ get_entry(name) or raise ArgumentError, "no such config: #{name}"
+ DESCRIPTER.delete_if {|n, arr| n == name }
+ end
+
+ def ConfigTable.config_key?(name)
+ get_entry(name) ? true : false
+ end
+
+ def ConfigTable.bool_config?(name)
+ ent = get_entry(name) or return false
+ ent[1] == 'yes/no'
+ end
+
+ def ConfigTable.value_config?(name)
+ ent = get_entry(name) or return false
+ ent[1] != 'yes/no'
+ end
+
+ def ConfigTable.path_config?(name)
+ ent = get_entry(name) or return false
+ ent[1] == 'path'
+ end
+
+
+ class << self
+ alias newobj new
+ end
+
+ def ConfigTable.new
+ c = newobj()
+ c.initialize_from_table
+ c
+ end
+
+ def ConfigTable.load
+ c = newobj()
+ c.initialize_from_file
+ c
+ end
+
+ def initialize_from_table
+ @table = {}
+ DESCRIPTER.each do |k, (default, vname, desc, default2)|
+ @table[k] = default
+ end
+ end
+
+ def initialize_from_file
+ raise InstallError, "#{File.basename $0} config first"\
+ unless File.file?(SAVE_FILE)
+ @table = {}
+ File.foreach(SAVE_FILE) do |line|
+ k, v = line.split(/=/, 2)
+ @table[k] = v.strip
+ end
+ end
+
+ def save
+ File.open(SAVE_FILE, 'w') {|f|
+ @table.each do |k, v|
+ f.printf "%s=%s\n", k, v if v
+ end
+ }
+ end
+
+ def []=(k, v)
+ raise InstallError, "unknown config option #{k}"\
+ unless ConfigTable.config_key?(k)
+ @table[k] = v
+ end
+
+ def [](key)
+ return nil unless @table[key]
+ @table[key].gsub(%r<\$([^/]+)>) { self[$1] }
+ end
+
+ def set_raw(key, val)
+ @table[key] = val
+ end
+
+ def get_raw(key)
+ @table[key]
+ end
+
+end
+
+
+module MetaConfigAPI
+
+ def eval_file_ifexist(fname)
+ instance_eval File.read(fname), fname, 1 if File.file?(fname)
+ end
+
+ def config_names
+ ConfigTable.keys
+ end
+
+ def config?(name)
+ ConfigTable.config_key?(name)
+ end
+
+ def bool_config?(name)
+ ConfigTable.bool_config?(name)
+ end
+
+ def value_config?(name)
+ ConfigTable.value_config?(name)
+ end
+
+ def path_config?(name)
+ ConfigTable.path_config?(name)
+ end
+
+ def add_config(name, argname, default, desc)
+ ConfigTable.add_entry name,[default,argname,desc]
+ end
+
+ def add_path_config(name, default, desc)
+ add_config name, 'path', default, desc
+ end
+
+ def add_bool_config(name, default, desc)
+ add_config name, 'yes/no', default ? 'yes' : 'no', desc
+ end
+
+ def set_config_default(name, default)
+ if bool_config?(name)
+ ConfigTable.get_entry!(name)[0] = (default ? 'yes' : 'no')
+ else
+ ConfigTable.get_entry!(name)[0] = default
+ end
+ end
+
+ def remove_config(name)
+ ent = ConfigTable.get_entry(name)
+ ConfigTable.remove_entry name
+ ent
+ end
+
+end
+
+#
+# File Operations
+#
+
+module FileOperations
+
+ def mkdir_p(dirname, prefix = nil)
+ dirname = prefix + dirname if prefix
+ $stderr.puts "mkdir -p #{dirname}" if verbose?
+ return if no_harm?
+
+ # does not check '/'... it's too abnormal case
+ dirs = dirname.split(%r<(?=/)>)
+ if /\A[a-z]:\z/i =~ dirs[0]
+ disk = dirs.shift
+ dirs[0] = disk + dirs[0]
+ end
+ dirs.each_index do |idx|
+ path = dirs[0..idx].join('')
+ Dir.mkdir path unless File.dir?(path)
+ end
+ end
+
+ def rm_f(fname)
+ $stderr.puts "rm -f #{fname}" if verbose?
+ return if no_harm?
+
+ if File.exist?(fname) or File.symlink?(fname)
+ File.chmod 0777, fname
+ File.unlink fname
+ end
+ end
+
+ def rm_rf(dn)
+ $stderr.puts "rm -rf #{dn}" if verbose?
+ return if no_harm?
+
+ Dir.chdir dn
+ Dir.foreach('.') do |fn|
+ next if fn == '.'
+ next if fn == '..'
+ if File.dir?(fn)
+ verbose_off {
+ rm_rf fn
+ }
+ else
+ verbose_off {
+ rm_f fn
+ }
+ end
+ end
+ Dir.chdir '..'
+ Dir.rmdir dn
+ end
+
+ def move_file(src, dest)
+ File.unlink dest if File.exist?(dest)
+ begin
+ File.rename src, dest
+ rescue
+ File.open(dest, 'wb') {|f| f.write File.binread(src) }
+ File.chmod File.stat(src).mode, dest
+ File.unlink src
+ end
+ end
+
+ def install(from, dest, mode, prefix = nil)
+ $stderr.puts "install #{from} #{dest}" if verbose?
+ return if no_harm?
+
+ realdest = prefix + dest if prefix
+ realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
+ str = File.binread(from)
+ if diff?(str, realdest)
+ verbose_off {
+ rm_f realdest if File.exist?(realdest)
+ }
+ File.open(realdest, 'wb') {|f|
+ f.write str
+ }
+ File.chmod mode, realdest
+
+ File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
+ if prefix
+ f.puts realdest.sub(prefix, '')
+ else
+ f.puts realdest
+ end
+ }
+ end
+ end
+
+ def diff?(new_content, path)
+ return true unless File.exist?(path)
+ new_content != File.binread(path)
+ end
+
+ def command(str)
+ $stderr.puts str if verbose?
+ system str or raise RuntimeError, "'system #{str}' failed"
+ end
+
+ def ruby(str)
+ command config('ruby-prog') + ' ' + str
+ end
+
+ def make(task = '')
+ command config('make-prog') + ' ' + task
+ end
+
+ def extdir?(dir)
+ File.exist?(dir + '/MANIFEST')
+ end
+
+ def all_files_in(dirname)
+ Dir.open(dirname) {|d|
+ return d.select {|ent| File.file?("#{dirname}/#{ent}") }
+ }
+ end
+
+ REJECT_DIRS = %w(
+ CVS SCCS RCS CVS.adm
+ )
+
+ def all_dirs_in(dirname)
+ Dir.open(dirname) {|d|
+ return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS
+ }
+ end
+
+end
+
+#
+# Main Installer
+#
+
+class InstallError < StandardError; end
+
+
+module HookUtils
+
+ def run_hook(name)
+ try_run_hook "#{curr_srcdir()}/#{name}" or
+ try_run_hook "#{curr_srcdir()}/#{name}.rb"
+ end
+
+ def try_run_hook(fname)
+ return false unless File.file?(fname)
+ begin
+ instance_eval File.read(fname), fname, 1
+ rescue
+ raise InstallError, "hook #{fname} failed:\n" + $!.message
+ end
+ true
+ end
+
+end
+
+
+module HookScriptAPI
+
+ def get_config(key)
+ @config[key]
+ end
+
+ alias config get_config
+
+ def set_config(key, val)
+ @config[key] = val
+ end
+
+ #
+ # srcdir/objdir (works only in the package directory)
+ #
+
+ #abstract srcdir_root
+ #abstract objdir_root
+ #abstract relpath
+
+ def curr_srcdir
+ "#{srcdir_root()}/#{relpath()}"
+ end
+
+ def curr_objdir
+ "#{objdir_root()}/#{relpath()}"
+ end
+
+ def srcfile(path)
+ "#{curr_srcdir()}/#{path}"
+ end
+
+ def srcexist?(path)
+ File.exist?(srcfile(path))
+ end
+
+ def srcdirectory?(path)
+ File.dir?(srcfile(path))
+ end
+
+ def srcfile?(path)
+ File.file? srcfile(path)
+ end
+
+ def srcentries(path = '.')
+ Dir.open("#{curr_srcdir()}/#{path}") {|d|
+ return d.to_a - %w(. ..)
+ }
+ end
+
+ def srcfiles(path = '.')
+ srcentries(path).select {|fname|
+ File.file?(File.join(curr_srcdir(), path, fname))
+ }
+ end
+
+ def srcdirectories(path = '.')
+ srcentries(path).select {|fname|
+ File.dir?(File.join(curr_srcdir(), path, fname))
+ }
+ end
+
+end
+
+
+class ToplevelInstaller
+
+ Version = '3.2.4'
+ Copyright = 'Copyright (c) 2000-2004 Minero Aoki'
+
+ TASKS = [
+ [ 'config', 'saves your configurations' ],
+ [ 'show', 'shows current configuration' ],
+ [ 'setup', 'compiles ruby extentions and others' ],
+ [ 'install', 'installs files' ],
+ [ 'clean', "does `make clean' for each extention" ],
+ [ 'distclean',"does `make distclean' for each extention" ]
+ ]
+
+ def ToplevelInstaller.invoke
+ instance().invoke
+ end
+
+ @singleton = nil
+
+ def ToplevelInstaller.instance
+ @singleton ||= new(File.dirname($0))
+ @singleton
+ end
+
+ include MetaConfigAPI
+
+ def initialize(ardir_root)
+ @config = nil
+ @options = { 'verbose' => true }
+ @ardir = File.expand_path(ardir_root)
+ end
+
+ def inspect
+ "#<#{self.class} #{__id__()}>"
+ end
+
+ def invoke
+ run_metaconfigs
+ task = parsearg_global()
+ @config = load_config(task)
+ __send__ "parsearg_#{task}"
+ init_installers
+ __send__ "exec_#{task}"
+ end
+
+ def run_metaconfigs
+ eval_file_ifexist "#{@ardir}/metaconfig"
+ end
+
+ def load_config(task)
+ case task
+ when 'config'
+ ConfigTable.new
+ when 'clean', 'distclean'
+ if File.exist?('config.save')
+ then ConfigTable.load
+ else ConfigTable.new
+ end
+ else
+ ConfigTable.load
+ end
+ end
+
+ def init_installers
+ @installer = Installer.new(@config, @options, @ardir, File.expand_path('.'))
+ end
+
+ #
+ # Hook Script API bases
+ #
+
+ def srcdir_root
+ @ardir
+ end
+
+ def objdir_root
+ '.'
+ end
+
+ def relpath
+ '.'
+ end
+
+ #
+ # Option Parsing
+ #
+
+ def parsearg_global
+ valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
+
+ while arg = ARGV.shift
+ case arg
+ when /\A\w+\z/
+ raise InstallError, "invalid task: #{arg}" unless valid_task =~ arg
+ return arg
+
+ when '-q', '--quiet'
+ @options['verbose'] = false
+
+ when '--verbose'
+ @options['verbose'] = true
+
+ when '-h', '--help'
+ print_usage $stdout
+ exit 0
+
+ when '-v', '--version'
+ puts "#{File.basename($0)} version #{Version}"
+ exit 0
+
+ when '--copyright'
+ puts Copyright
+ exit 0
+
+ else
+ raise InstallError, "unknown global option '#{arg}'"
+ end
+ end
+
+ raise InstallError, <<EOS
+No task or global option given.
+Typical installation procedure is:
+ $ ruby #{File.basename($0)} config
+ $ ruby #{File.basename($0)} setup
+ # ruby #{File.basename($0)} install (may require root privilege)
+EOS
+ end
+
+
+ def parsearg_no_options
+ raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"\
+ unless ARGV.empty?
+ end
+
+ alias parsearg_show parsearg_no_options
+ alias parsearg_setup parsearg_no_options
+ alias parsearg_clean parsearg_no_options
+ alias parsearg_distclean parsearg_no_options
+
+ def parsearg_config
+ re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
+ @options['config-opt'] = []
+
+ while i = ARGV.shift
+ if /\A--?\z/ =~ i
+ @options['config-opt'] = ARGV.dup
+ break
+ end
+ m = re.match(i) or raise InstallError, "config: unknown option #{i}"
+ name, value = m.to_a[1,2]
+ if value
+ if ConfigTable.bool_config?(name)
+ raise InstallError, "config: --#{name} allows only yes/no for argument"\
+ unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ value
+ value = (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
+ end
+ else
+ raise InstallError, "config: --#{name} requires argument"\
+ unless ConfigTable.bool_config?(name)
+ value = 'yes'
+ end
+ @config[name] = value
+ end
+ end
+
+ def parsearg_install
+ @options['no-harm'] = false
+ @options['install-prefix'] = ''
+ while a = ARGV.shift
+ case a
+ when /\A--no-harm\z/
+ @options['no-harm'] = true
+ when /\A--prefix=(.*)\z/
+ path = $1
+ path = File.expand_path(path) unless path[0,1] == '/'
+ @options['install-prefix'] = path
+ else
+ raise InstallError, "install: unknown option #{a}"
+ end
+ end
+ end
+
+ def print_usage(out)
+ out.puts 'Typical Installation Procedure:'
+ out.puts " $ ruby #{File.basename $0} config"
+ out.puts " $ ruby #{File.basename $0} setup"
+ out.puts " # ruby #{File.basename $0} install (may require root privilege)"
+ out.puts
+ out.puts 'Detailed Usage:'
+ out.puts " ruby #{File.basename $0} <global option>"
+ out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
+
+ fmt = " %-20s %s\n"
+ out.puts
+ out.puts 'Global options:'
+ out.printf fmt, '-q,--quiet', 'suppress message outputs'
+ out.printf fmt, ' --verbose', 'output messages verbosely'
+ out.printf fmt, '-h,--help', 'print this message'
+ out.printf fmt, '-v,--version', 'print version and quit'
+ out.printf fmt, ' --copyright', 'print copyright and quit'
+
+ out.puts
+ out.puts 'Tasks:'
+ TASKS.each do |name, desc|
+ out.printf " %-10s %s\n", name, desc
+ end
+
+ out.puts
+ out.puts 'Options for config:'
+ ConfigTable.each_definition do |name, (default, arg, desc, default2)|
+ out.printf " %-20s %s [%s]\n",
+ '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
+ desc,
+ default2 || default
+ end
+ out.printf " %-20s %s [%s]\n",
+ '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
+
+ out.puts
+ out.puts 'Options for install:'
+ out.printf " %-20s %s [%s]\n",
+ '--no-harm', 'only display what to do if given', 'off'
+ out.printf " %-20s %s [%s]\n",
+ '--prefix', 'install path prefix', '$prefix'
+
+ out.puts
+ end
+
+ #
+ # Task Handlers
+ #
+
+ def exec_config
+ @installer.exec_config
+ @config.save # must be final
+ end
+
+ def exec_setup
+ @installer.exec_setup
+ end
+
+ def exec_install
+ @installer.exec_install
+ end
+
+ def exec_show
+ ConfigTable.each_name do |k|
+ v = @config.get_raw(k)
+ if not v or v.empty?
+ v = '(not specified)'
+ end
+ printf "%-10s %s\n", k, v
+ end
+ end
+
+ def exec_clean
+ @installer.exec_clean
+ end
+
+ def exec_distclean
+ @installer.exec_distclean
+ end
+
+end
+
+
+class ToplevelInstallerMulti < ToplevelInstaller
+
+ include HookUtils
+ include HookScriptAPI
+ include FileOperations
+
+ def initialize(ardir)
+ super
+ @packages = all_dirs_in("#{@ardir}/packages")
+ raise 'no package exists' if @packages.empty?
+ end
+
+ def run_metaconfigs
+ eval_file_ifexist "#{@ardir}/metaconfig"
+ @packages.each do |name|
+ eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig"
+ end
+ end
+
+ def init_installers
+ @installers = {}
+ @packages.each do |pack|
+ @installers[pack] = Installer.new(@config, @options,
+ "#{@ardir}/packages/#{pack}",
+ "packages/#{pack}")
+ end
+
+ with = extract_selection(config('with'))
+ without = extract_selection(config('without'))
+ @selected = @installers.keys.select {|name|
+ (with.empty? or with.include?(name)) \
+ and not without.include?(name)
+ }
+ end
+
+ def extract_selection(list)
+ a = list.split(/,/)
+ a.each do |name|
+ raise InstallError, "no such package: #{name}" \
+ unless @installers.key?(name)
+ end
+ a
+ end
+
+ def print_usage(f)
+ super
+ f.puts 'Inluded packages:'
+ f.puts ' ' + @packages.sort.join(' ')
+ f.puts
+ end
+
+ #
+ # multi-package metaconfig API
+ #
+
+ attr_reader :packages
+
+ def declare_packages(list)
+ raise 'package list is empty' if list.empty?
+ list.each do |name|
+ raise "directory packages/#{name} does not exist"\
+ unless File.dir?("#{@ardir}/packages/#{name}")
+ end
+ @packages = list
+ end
+
+ #
+ # Task Handlers
+ #
+
+ def exec_config
+ run_hook 'pre-config'
+ each_selected_installers {|inst| inst.exec_config }
+ run_hook 'post-config'
+ @config.save # must be final
+ end
+
+ def exec_setup
+ run_hook 'pre-setup'
+ each_selected_installers {|inst| inst.exec_setup }
+ run_hook 'post-setup'
+ end
+
+ def exec_install
+ run_hook 'pre-install'
+ each_selected_installers {|inst| inst.exec_install }
+ run_hook 'post-install'
+ end
+
+ def exec_clean
+ rm_f 'config.save'
+ run_hook 'pre-clean'
+ each_selected_installers {|inst| inst.exec_clean }
+ run_hook 'post-clean'
+ end
+
+ def exec_distclean
+ rm_f 'config.save'
+ run_hook 'pre-distclean'
+ each_selected_installers {|inst| inst.exec_distclean }
+ run_hook 'post-distclean'
+ end
+
+ #
+ # lib
+ #
+
+ def each_selected_installers
+ Dir.mkdir 'packages' unless File.dir?('packages')
+ @selected.each do |pack|
+ $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose']
+ Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
+ Dir.chdir "packages/#{pack}"
+ yield @installers[pack]
+ Dir.chdir '../..'
+ end
+ end
+
+ def verbose?
+ @options['verbose']
+ end
+
+ def no_harm?
+ @options['no-harm']
+ end
+
+end
+
+
+class Installer
+
+ FILETYPES = %w( bin lib ext data )
+
+ include HookScriptAPI
+ include HookUtils
+ include FileOperations
+
+ def initialize(config, opt, srcroot, objroot)
+ @config = config
+ @options = opt
+ @srcdir = File.expand_path(srcroot)
+ @objdir = File.expand_path(objroot)
+ @currdir = '.'
+ end
+
+ def inspect
+ "#<#{self.class} #{File.basename(@srcdir)}>"
+ end
+
+ #
+ # Hook Script API bases
+ #
+
+ def srcdir_root
+ @srcdir
+ end
+
+ def objdir_root
+ @objdir
+ end
+
+ def relpath
+ @currdir
+ end
+
+ #
+ # configs/options
+ #
+
+ def no_harm?
+ @options['no-harm']
+ end
+
+ def verbose?
+ @options['verbose']
+ end
+
+ def verbose_off
+ begin
+ save, @options['verbose'] = @options['verbose'], false
+ yield
+ ensure
+ @options['verbose'] = save
+ end
+ end
+
+ #
+ # TASK config
+ #
+
+ def exec_config
+ exec_task_traverse 'config'
+ end
+
+ def config_dir_bin(rel)
+ end
+
+ def config_dir_lib(rel)
+ end
+
+ def config_dir_ext(rel)
+ extconf if extdir?(curr_srcdir())
+ end
+
+ def extconf
+ opt = @options['config-opt'].join(' ')
+ command "#{config('ruby-prog')} #{curr_srcdir()}/extconf.rb #{opt}"
+ end
+
+ def config_dir_data(rel)
+ end
+
+ #
+ # TASK setup
+ #
+
+ def exec_setup
+ exec_task_traverse 'setup'
+ end
+
+ def setup_dir_bin(rel)
+ all_files_in(curr_srcdir()).each do |fname|
+ adjust_shebang "#{curr_srcdir()}/#{fname}"
+ end
+ end
+
+ # modify: #!/usr/bin/ruby
+ # modify: #! /usr/bin/ruby
+ # modify: #!ruby
+ # not modify: #!/usr/bin/env ruby
+ SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
+
+ def adjust_shebang(path)
+ return if no_harm?
+
+ tmpfile = File.basename(path) + '.tmp'
+ begin
+ File.open(path, 'rb') {|r|
+ File.open(tmpfile, 'wb') {|w|
+ first = r.gets
+ return unless SHEBANG_RE =~ first
+
+ $stderr.puts "adjusting shebang: #{File.basename path}" if verbose?
+ w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
+ w.write r.read
+ }
+ }
+ move_file tmpfile, File.basename(path)
+ ensure
+ File.unlink tmpfile if File.exist?(tmpfile)
+ end
+ end
+
+ def setup_dir_lib(rel)
+ end
+
+ def setup_dir_ext(rel)
+ make if extdir?(curr_srcdir())
+ end
+
+ def setup_dir_data(rel)
+ end
+
+ #
+ # TASK install
+ #
+
+ def exec_install
+ exec_task_traverse 'install'
+ end
+
+ def install_dir_bin(rel)
+ install_files collect_filenames_auto(), "#{config('bin-dir')}/#{rel}", 0755
+ end
+
+ def install_dir_lib(rel)
+ install_files ruby_scripts(), "#{config('rb-dir')}/#{rel}", 0644
+ end
+
+ def install_dir_ext(rel)
+ return unless extdir?(curr_srcdir())
+ install_files ruby_extentions('.'),
+ "#{config('so-dir')}/#{File.dirname(rel)}",
+ 0555
+ end
+
+ def install_dir_data(rel)
+ install_files collect_filenames_auto(), "#{config('data-dir')}/#{rel}", 0644
+ end
+
+ def install_files(list, dest, mode)
+ mkdir_p dest, @options['install-prefix']
+ list.each do |fname|
+ install fname, dest, mode, @options['install-prefix']
+ end
+ end
+
+ def ruby_scripts
+ collect_filenames_auto().select {|n| /\.rb\z/ =~ n }
+ end
+
+ # picked up many entries from cvs-1.11.1/src/ignore.c
+ reject_patterns = %w(
+ core RCSLOG tags TAGS .make.state
+ .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
+ *~ *.old *.bak *.BAK *.orig *.rej _$* *$
+
+ *.org *.in .*
+ )
+ mapping = {
+ '.' => '\.',
+ '$' => '\$',
+ '#' => '\#',
+ '*' => '.*'
+ }
+ REJECT_PATTERNS = Regexp.new('\A(?:' +
+ reject_patterns.map {|pat|
+ pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
+ }.join('|') +
+ ')\z')
+
+ def collect_filenames_auto
+ mapdir((existfiles() - hookfiles()).reject {|fname|
+ REJECT_PATTERNS =~ fname
+ })
+ end
+
+ def existfiles
+ all_files_in(curr_srcdir()) | all_files_in('.')
+ end
+
+ def hookfiles
+ %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
+ %w( config setup install clean ).map {|t| sprintf(fmt, t) }
+ }.flatten
+ end
+
+ def mapdir(filelist)
+ filelist.map {|fname|
+ if File.exist?(fname) # objdir
+ fname
+ else # srcdir
+ File.join(curr_srcdir(), fname)
+ end
+ }
+ end
+
+ def ruby_extentions(dir)
+ _ruby_extentions(dir) or
+ raise InstallError, "no ruby extention exists: 'ruby #{$0} setup' first"
+ end
+
+ DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/
+
+ def _ruby_extentions(dir)
+ Dir.open(dir) {|d|
+ return d.select {|fname| DLEXT =~ fname }
+ }
+ end
+
+ #
+ # TASK clean
+ #
+
+ def exec_clean
+ exec_task_traverse 'clean'
+ rm_f 'config.save'
+ rm_f 'InstalledFiles'
+ end
+
+ def clean_dir_bin(rel)
+ end
+
+ def clean_dir_lib(rel)
+ end
+
+ def clean_dir_ext(rel)
+ return unless extdir?(curr_srcdir())
+ make 'clean' if File.file?('Makefile')
+ end
+
+ def clean_dir_data(rel)
+ end
+
+ #
+ # TASK distclean
+ #
+
+ def exec_distclean
+ exec_task_traverse 'distclean'
+ rm_f 'config.save'
+ rm_f 'InstalledFiles'
+ end
+
+ def distclean_dir_bin(rel)
+ end
+
+ def distclean_dir_lib(rel)
+ end
+
+ def distclean_dir_ext(rel)
+ return unless extdir?(curr_srcdir())
+ make 'distclean' if File.file?('Makefile')
+ end
+
+ #
+ # lib
+ #
+
+ def exec_task_traverse(task)
+ run_hook "pre-#{task}"
+ FILETYPES.each do |type|
+ if config('without-ext') == 'yes' and type == 'ext'
+ $stderr.puts 'skipping ext/* by user option' if verbose?
+ next
+ end
+ traverse task, type, "#{task}_dir_#{type}"
+ end
+ run_hook "post-#{task}"
+ end
+
+ def traverse(task, rel, mid)
+ dive_into(rel) {
+ run_hook "pre-#{task}"
+ __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
+ all_dirs_in(curr_srcdir()).each do |d|
+ traverse task, "#{rel}/#{d}", mid
+ end
+ run_hook "post-#{task}"
+ }
+ end
+
+ def dive_into(rel)
+ return unless File.dir?("#{@srcdir}/#{rel}")
+
+ dir = File.basename(rel)
+ Dir.mkdir dir unless File.dir?(dir)
+ prevdir = Dir.pwd
+ Dir.chdir dir
+ $stderr.puts '---> ' + rel if verbose?
+ @currdir = rel
+ yield
+ Dir.chdir prevdir
+ $stderr.puts '<--- ' + rel if verbose?
+ @currdir = File.dirname(rel)
+ end
+
+end
+
+
+if $0 == __FILE__
+ begin
+ if multipackage_install?
+ ToplevelInstallerMulti.invoke
+ else
+ ToplevelInstaller.invoke
+ end
+ rescue
+ raise if $DEBUG
+ $stderr.puts $!.message
+ $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
+ exit 1
+ end
+end
View
91 merb-core/spec/public/webrat/test_app/gems/gems/abstract-1.0.0/test/test.rb
@@ -0,0 +1,91 @@
+##
+## $Rev: 1 $
+## $Release: 1.0.0 $
+## copyright(c) 2006 kuwata-lab.com all rights reserved.
+##
+
+testdir = File.dirname(File.expand_path(__FILE__))
+libdir = File.dirname(testdir) + "/lib"
+$: << libdir
+
+
+require 'test/unit'
+require 'abstract'
+
+
+class Foo
+ abstract_method "arg1, arg2=''", :m1, :m2, :m3
+end
+
+
+class Bar
+ def m1(arg1, arg2='')
+ not_implemented
+ end
+end
+
+
+
+class AbstractTest < Test::Unit::TestCase
+
+
+ def _test(obj)
+ assert_raise(NotImplementedError) do
+ begin
+ obj = Foo.new
+ obj.m1 'a'
+ rescue => ex
+ linenum = (ex.backtrace[0] =~ /:(\d+)/) && $1
+ raise ex
+ end
+ end
+ end
+
+
+ def test_abstract_method1
+ obj = Foo.new
+ assert_raise(NotImplementedError) { obj.m1 'a' }
+ assert_raise(NotImplementedError) { obj.m2 'a', 'b' }
+ end
+
+
+ def test_abstract_method2
+ begin
+ obj = Foo.new
+ linenum = __LINE__; obj.m1 'a'
+ rescue NotImplementedError => ex
+ actual_linenum = (ex.backtrace[0] =~ /:(\d+)/) && $1.to_i
+ end
+ assert_equal linenum, actual_linenum
+ end
+
+
+ def test_not_implemented1
+ obj = Bar.new
+ assert_raise(NotImplementedError) { obj.m1 123 }
+ end
+
+
+ def test_not_implemented2
+ begin
+ obj = Bar.new
+ linenum = __LINE__; obj.m1 'a'
+ rescue NotImplementedError => ex
+ actual_linenum = (ex.backtrace[0] =~ /:(\d+)/) && $1.to_i
+ end
+ assert_equal linenum, actual_linenum
+ end
+
+
+ def test_not_implemented3
+ begin
+ obj = Bar.new
+ obj.not_implemented
+ rescue Exception => ex
+ assert_instance_of(NoMethodError, ex)
+ assert_match(/private method/, ex.message)
+ end
+ end
+
+
+end
View
14 merb-core/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/CHANGELOG
@@ -0,0 +1,14 @@
+
+v2.5.0. Not required for JRuby.
+
+v2.4.0. Signed gem.
+
+v2.3.0. Use STDERR, not $stderr, just like Mongrel; tests now use Test::Unit; moving to the mongrel project on RubyForge.
+
+v2.2.0. Don't load on Ruby > 1.8.5; copyright correction.
+
+v2.1.0. License change due to no provision for use in original Ruby license (prevents installation in Florida).
+
+v2.0.0. Updated for second cgi.rb vulnerability.
+
+v1.0.0. Original single-patch release by Zed Shaw, et. al.
View
55 merb-core/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/LICENSE
@@ -0,0 +1,55 @@
+Mongrel Web Server (Mongrel) is copyrighted free software by Zed A. Shaw
+<zedshaw at zedshaw dot com> You can redistribute it and/or modify it under
+either the terms of the GPL or the conditions below:
+
+1. You may make and give away verbatim copies of the source form of the
+ software without restriction, provided that you duplicate all of the
+ original copyright notices and associated disclaimers.
+
+2. You may modify your copy of the software in any way, provided that
+ you do at least ONE of the following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or an
+ equivalent medium, or by allowing the author to include your
+ modifications in the software.
+
+ b) use the modified software only within your corporation or
+ organization.
+
+ c) rename any non-standard executables so the names do not conflict with
+ standard executables, which must also be provided.
+
+ d) make other distribution arrangements with the author.
+
+3. You may distribute the software in object code or executable
+ form, provided that you do at least ONE of the following:
+
+ a) distribute the executables and library files of the software,
+ together with instructions (in the manual page or equivalent) on where
+ to get the original distribution.
+
+ b) accompany the distribution with the machine-readable source of the
+ software.
+
+ c) give non-standard executables non-standard names, with
+ instructions on where to get the original software distribution.
+
+ d) make other distribution arrangements with the author.
+
+4. You may modify and include the part of the software into any other
+ software (possibly commercial). But some files in the distribution
+ are not written by the author, so that they are not under this terms.
+
+5. The scripts and library files supplied as input to or produced as
+ output from the software do not automatically fall under the
+ copyright of the software, but belong to whomever generated them,
+ and may be sold commercially, and may be aggregated with this
+ software.
+
+6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+
View
6 merb-core/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/Manifest
@@ -0,0 +1,6 @@
+CHANGELOG
+lib/cgi_multipart_eof_fix.rb
+LICENSE
+Manifest
+README
+test/test_cgi_multipart_eof_fix.rb
View
40 merb-core/spec/public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/README
@@ -0,0 +1,40 @@
+
+cgi_multipart_eof_fix
+
+Fix an exploitable bug in CGI multipart parsing.
+
+== License
+
+Copyright 2006, 2007 Cloudburst, LLC. Portions copyright 2006 Jeremy Kemper, Jamis Buck, Zed A. Shaw, and Yukihiro Matsumoto, and used with permission. See the included LICENSE file.
+
+== Description
+
+Fixes an exploitable bug in CGI multipart parsing which affects Ruby <= 1.8.5. When multipart boundary attributes contain non-halting regular expression strings, the boundary searcher in the CGI module does not properly escape the parameter and will execute arbitrary regular expressions. This fix adds escaping for the user data.
+
+* Affected application servers: standalone CGI, Mongrel, WEBrick
+* Unaffected: FastCGI, Ruby 1.8.6 (all servers)
+* Unknown: mod_ruby
+
+This fix will not modify versions of Ruby greater than 1.8.5, and is cumulative with previous CGI multipart vulnerability fixes.
+
+== Usage
+
+Install the gem:
+ sudo gem install cgi_multipart_eof_fix
+
+Run the included test to verify that the patch works as intended. Then, <tt>require</tt> the gem in every affected application, as follows:
+
+ require 'rubygems'
+ require 'cgi_multipart_eof_fix'
+
+Currently <tt>mongrel_rails</tt> requires this gem automatically. However, Mongrel may change in the future.
+
+== Reporting problems
+
+* http://rubyforge.org/tracker/?group_id=1306
+
+== Further resources
+
+* http://rubyforge.org/mailman/listinfo/mongrel-users
+* http://blog.evanweaver.com/articles/2006/12/05/cgi-rb-vulnerability-hotfix
+* http://www.ruby-lang.org/en/news/2006/12/04/another-dos-vulnerability-in-cgi-library/
View
44 ...ublic/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/cgi_multipart_eof_fix.gemspec
@@ -0,0 +1,44 @@
+
+# Gem::Specification for Cgi_multipart_eof_fix-2.5.0
+# Originally generated by Echoe
+
+Gem::Specification.new do |s|
+ s.name = %q{cgi_multipart_eof_fix}
+ s.version = "2.5.0"
+
+ s.specification_version = 2 if s.respond_to? :specification_version=
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.authors = ["Evan Weaver"]
+ s.date = %q{2007-10-26}
+ s.description = %q{Fix an exploitable bug in CGI multipart parsing.}
+ s.email = %q{}
+ s.files = ["CHANGELOG", "lib/cgi_multipart_eof_fix.rb", "LICENSE", "Manifest", "README", "test/test_cgi_multipart_eof_fix.rb", "cgi_multipart_eof_fix.gemspec"]
+ s.has_rdoc = true
+ s.homepage = %q{http://blog.evanweaver.com/pages/code#cgi_multipart_eof_fix}
+ s.require_paths = ["lib"]
+ s.rubyforge_project = %q{mongrel}
+ s.rubygems_version = %q{0.9.4.6}
+ s.summary = %q{Fix an exploitable bug in CGI multipart parsing.}
+ s.test_files = ["test/test_cgi_multipart_eof_fix.rb"]
+end
+
+
+# # Original Rakefile source (requires the Echoe gem):
+#
+#
+# require 'echoe'
+#
+# Echoe.new("cgi_multipart_eof_fix") do |p|
+# p.author = "Evan Weaver"
+# p.rubyforge_name = "mongrel"
+# p.summary = p.description = "Fix an exploitable bug in CGI multipart parsing."
+# p.url = "http://blog.evanweaver.com/pages/code#cgi_multipart_eof_fix"
+# p.docs_host = "blog.evanweaver.com:~/www/bax/public/files/doc/"
+# p.rdoc_pattern = /CHANGELOG|LICENSE|README|lib\/cgi_multipart_eof_fix/
+#
+# p.need_tar_gz = false
+# p.need_tgz = true
+# p.require_signed = true
+# end
+#
View
127 ...public/webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/lib/cgi_multipart_eof_fix.rb
@@ -0,0 +1,127 @@
+
+# unfortunately:
+# >> "1.8.6" < "1.8.10"
+# => false
+
+version = RUBY_VERSION.split(".").map {|i| i.to_i }
+
+if version [0] < 2 and version [1] < 9 and version [2] < 6 and RUBY_PLATFORM !~ /java/
+
+ STDERR.puts "** Ruby version is not up-to-date; loading cgi_multipart_eof_fix"
+
+ require 'cgi'
+
+ class CGI
+ module QueryExtension
+ def read_multipart(boundary, content_length)
+ params = Hash.new([])
+ boundary = "--" + boundary
+ quoted_boundary = Regexp.quote(boundary, "n")
+ buf = ""
+ bufsize = 10 * 1024
+ boundary_end=""
+
+ # start multipart/form-data
+ stdinput.binmode if defined? stdinput.binmode
+ boundary_size = boundary.size + EOL.size
+ content_length -= boundary_size
+ status = stdinput.read(boundary_size)
+ if nil == status
+ raise EOFError, "no content body"
+ elsif boundary + EOL != status
+ raise EOFError, "bad content body #{status.inspect} expected, got #{(boundary + EOL).inspect}"
+ end
+
+ loop do
+ head = nil
+ if 10240 < content_length
+ require "tempfile"
+ body = Tempfile.new("CGI")
+ else
+ begin
+ require "stringio"
+ body = StringIO.new
+ rescue LoadError
+ require "tempfile"
+ body = Tempfile.new("CGI")
+ end
+ end
+ body.binmode if defined? body.binmode
+
+ until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf)
+
+ if (not head) and /#{EOL}#{EOL}/n.match(buf)
+ buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
+ head = $1.dup
+ ""
+ end
+ next
+ end
+
+ if head and ( (EOL + boundary + EOL).size < buf.size )
+ body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
+ buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
+ end
+
+ c = if bufsize < content_length
+ stdinput.read(bufsize)
+ else
+ stdinput.read(content_length)
+ end
+ if c.nil? || c.empty?
+ raise EOFError, "bad content body"
+ end
+ buf.concat(c)
+ content_length -= c.size
+ end
+
+ buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do
+ body.print $1
+ if "--" == $2
+ content_length = -1
+ end
+ boundary_end = $2.dup
+ ""
+ end
+
+ body.rewind
+
+ /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
+ filename = ($1 or "")
+ if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
+ /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
+ (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
+ filename = CGI::unescape(filename)
+ end
+
+ /Content-Type: (.*)/ni.match(head)
+ content_type = ($1 or "")
+
+ (class << body; self; end).class_eval do
+ alias local_path path
+ define_method(:original_filename) {filename.dup.taint}
+ define_method(:content_type) {content_type.dup.taint}
+ end
+
+ /Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
+ name = $1.dup
+
+ if params.has_key?(name)
+ params[name].push(body)
+ else
+ params[name] = [body]
+ end
+ break if buf.size == 0
+ break if content_length === -1
+ end
+ raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/
+
+ params
+ end # read_multipart
+ private :read_multipart
+ end
+ end
+
+else
+ # Ruby version is up-to-date; cgi_multipart_eof_fix was not loaded
+end
View
59 .../webrat/test_app/gems/gems/cgi_multipart_eof_fix-2.5.0/test/test_cgi_multipart_eof_fix.rb
@@ -0,0 +1,59 @@
+#!/usr/bin/env ruby
+
+require 'test/unit'
+require 'cgi'
+require 'stringio'
+require 'timeout'
+
+BOUNDARY = '%?%(\w*)\\((\w*)\\)'
+PAYLOAD = "--#{BOUNDARY}\r\nContent-Disposition: form-data; name=\"a_field\"\r\n\r\nBang!\r\n--#{BOUNDARY}--\r\n"
+ENV['REQUEST_METHOD'] = "POST"
+ENV['CONTENT_TYPE'] = "multipart/form-data; boundary=\"#{BOUNDARY}\""
+ENV['CONTENT_LENGTH'] = PAYLOAD.length.to_s
+
+Object.send(:remove_const, :STDERR)
+STDERR = StringIO.new # hide the multipart load warnings
+
+version = RUBY_VERSION.split(".").map {|i| i.to_i }
+IS_VULNERABLE = (version [0] < 2 and version [1] < 9 and version [2] < 6 and RUBY_PLATFORM !~ /java/)
+
+class CgiMultipartTestError < StandardError
+end
+
+class CgiMultipartEofFixTest < Test::Unit::TestCase
+
+ def read_multipart
+ # can't use STDIN because of the dynamic constant assignment rule
+ $stdin = StringIO.new(PAYLOAD)
+
+ begin
+ Timeout.timeout(3) do
+ CGI.new
+ end
+ "CGI is safe: read_multipart does not hang on malicious multipart requests."
+ rescue TimeoutError
+ raise CgiMultipartTestError, "CGI is exploitable: read_multipart hangs on malicious multipart requests."
+ end
+ end
+
+ def test_exploitable
+ if IS_VULNERABLE
+ assert_raises CgiMultipartTestError do
+ read_multipart
+ end
+ else
+ # we're on 1.8.6 or higher already
+ assert_nothing_raised do
+ read_multipart
+ end
+ end
+ end
+
+ def test_fixed
+ assert_nothing_raised do
+ load "#{File.dirname(__FILE__)}/../lib/cgi_multipart_eof_fix.rb"
+ read_multipart
+ end
+ end
+
+end
View
29 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/LICENSE
@@ -0,0 +1,29 @@
+Copyright (c) 2005-2007 Thomas Uehlinger
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+This license does not apply to daemonize.rb, which is was written by
+Travis Whitton und published under the following license:
+
+The Daemonize extension module is copywrited free software by Travis Whitton
+<whitton@atlantic.net>. You can redistribute it under the terms specified in
+the COPYING file of the Ruby distribution.
View
223 merb-core/spec/public/webrat/test_app/gems/gems/daemons-1.0.10/README
@@ -0,0 +1,223 @@
+= Daemons Version 1.0.10
+
+(See Releases for release-specific information)
+
+== What is Daemons?
+
+Daemons provides an easy way to wrap existing ruby scripts (for example a self-written server)
+to be <i>run as a daemon</i> and to be <i>controlled by simple start/stop/restart commands</i>.
+
+If you want, you can also use daemons to <i>run blocks of ruby code in a daemon process</i> and to control
+these processes from the main application.
+
+Besides this basic functionality, daemons offers many advanced features like <i>exception backtracing</i>
+and logging (in case your ruby script crashes) and <i>monitoring</i> and automatic restarting of your processes
+if they crash.
+
+Daemons includes the <tt>daemonize.rb</tt> script written by <i>Travis Whitton</i> to do the daemonization
+process.
+
+== Basic Usage
+
+You can use Daemons in four differet ways:
+
+=== 1. Create wrapper scripts for your server scripts or applications
+
+Layout: suppose you have your self-written server <tt>myserver.rb</tt>:
+
+ # this is myserver.rb
+ # it does nothing really useful at the moment
+
+ loop do
+ sleep(5)
+ end
+
+To use <tt>myserver.rb</tt> in a production environment, you need to be able to
+run <tt>myserver.rb</tt> in the _background_ (this means detach it from the console, fork it
+in the background, release all directories and file descriptors).
+
+Just create <tt>myserver_control.rb</tt> like this:
+
+ # this is myserver_control.rb
+
+ require 'rubygems' # if you use RubyGems
+ require 'daemons'
+
+ Daemons.run('myserver.rb')
+
+And use it like this from the console:
+
+ $ ruby myserver_control.rb start
+ (myserver.rb is now running in the background)
+ $ ruby myserver_control.rb restart
+ (...)
+ $ ruby myserver_control.rb stop
+
+For testing purposes you can even run <tt>myserver.rb</tt> <i>without forking</i> in the background:
+
+ $ ruby myserver_control.rb run
+
+An additional nice feature of Daemons is that you can pass <i>additional arguments</i> to the script that
+should be daemonized by seperating them by two _hyphens_:
+
+ $ ruby myserver_control.rb start -- --file=anyfile --a_switch another_argument
+
+
+=== 2. Create wrapper scripts that include your server procs
+
+Layout: suppose you have some code you want to run in the background and control that background process
+from a script:
+
+ # this is your code
+ # it does nothing really useful at the moment
+
+ loop do
+ sleep(5)
+ end
+
+To run this code as a daemon create <tt>myproc_control.rb</tt> like this and include your code:
+
+ # this is myproc_control.rb
+
+ require 'rubygems' # if you use RubyGems
+ require 'daemons'
+
+ Daemons.run_proc('myproc.rb') do
+ loop do
+ sleep(5)
+ end
+ end
+
+And use it like this from the console:
+
+ $ ruby myproc_control.rb start
+ (myproc.rb is now running in the background)
+ $ ruby myproc_control.rb restart
+ (...)
+ $ ruby myproc_control.rb stop
+
+For testing purposes you can even run <tt>myproc.rb</tt> <i>without forking</i> in the background:
+
+ $ ruby myproc_control.rb run
+
+=== 3. Control a bunch of daemons from another application
+
+Layout: you have an application <tt>my_app.rb</tt> that wants to run a bunch of
+server tasks as daemon processes.
+
+ # this is my_app.rb
+
+ require 'rubygems' # if you use RubyGems
+ require 'daemons'
+
+ task1 = Daemons.call(:multiple => true) do
+ # first server task
+
+ loop {
+ conn = accept_conn()
+ serve(conn)
+ }
+ end
+
+ task2 = Daemons.call do
+ # second server task
+
+ loop {
+ something_different()
+ }
+ end
+
+ # the parent process continues to run
+
+ # we can even control our tasks, for example stop them
+ task1.stop
+ task2.stop
+
+ exit