rwdtorrent 0.01

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. data/Readme.txt +146 -0
  2. data/bin/rwdtorrent +19 -0
  3. data/code/01rwdcore/01rwdcore.rb +22 -0
  4. data/code/01rwdcore/02helptexthashbegin.rb +4 -0
  5. data/code/01rwdcore/03helptexthash.rb +31 -0
  6. data/code/01rwdcore/04helptextend.rb +6 -0
  7. data/code/01rwdcore/openhelpwindow.rb +31 -0
  8. data/code/01rwdcore/returntomain.rb +10 -0
  9. data/code/01rwdcore/rwdtinkerversion.rb +15 -0
  10. data/code/01rwdcore/rwdwindowreturn.rb +11 -0
  11. data/code/01rwdcore/test_cases.rb +126 -0
  12. data/code/01rwdcore/test_harness.rb +15 -0
  13. data/code/01rwdcore/uploadreturns.rb +62 -0
  14. data/code/superant.com.rwdtinkerbackwindow/controlclient.rb +99 -0
  15. data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +25 -0
  16. data/code/superant.com.rwdtinkerbackwindow/helptexthashtinkerwin2.rb +61 -0
  17. data/code/superant.com.rwdtinkerbackwindow/installapplet.rb +24 -0
  18. data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +20 -0
  19. data/code/superant.com.rwdtinkerbackwindow/installremotegem.rb +19 -0
  20. data/code/superant.com.rwdtinkerbackwindow/listgemdirs.rb +12 -0
  21. data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +54 -0
  22. data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +11 -0
  23. data/code/superant.com.rwdtinkerbackwindow/listzips.rb +31 -0
  24. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +32 -0
  25. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +13 -0
  26. data/code/superant.com.rwdtinkerbackwindow/network.rb +87 -0
  27. data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +18 -0
  28. data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +42 -0
  29. data/code/superant.com.rwdtinkerbackwindow/remotegemlist.rb +24 -0
  30. data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +32 -0
  31. data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +12 -0
  32. data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +14 -0
  33. data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +18 -0
  34. data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +21 -0
  35. data/code/superant.com.rwdtinkerbackwindow/viewgemappletcontents.rb +21 -0
  36. data/code/superant.com.rwdtorrent/helptesthashrwdtorrent.rb +55 -0
  37. data/code/superant.com.rwdtorrent/listnamerecord.rb +15 -0
  38. data/code/superant.com.rwdtorrent/loadconfigurationrecord.rb +36 -0
  39. data/code/superant.com.rwdtorrent/loadconfigurationvariables.rb +13 -0
  40. data/code/superant.com.rwdtorrent/openhelpwindowtorrent.rb +32 -0
  41. data/code/superant.com.rwdtorrent/returntomain.rb +10 -0
  42. data/code/superant.com.rwdtorrent/runtorrentwindow.rb +57 -0
  43. data/code/superant.com.rwdtorrent/rwdtorrenthelpabout.rb +14 -0
  44. data/code/superant.com.rwdtorrent/saveconfigurationrecord.rb +18 -0
  45. data/code/superant.com.rwdtorrent/stoptorrentdownload.rb +12 -0
  46. data/code/superant.com.rwdtorrent/viewtorrentlist.rb +20 -0
  47. data/code/superant.com.rwdtorrent/viewtorrentmetafile.rb +36 -0
  48. data/code/zz0applicationend/zz0end.rb +4 -0
  49. data/configuration/language.dist +7 -0
  50. data/configuration/rwdapplicationidentity.dist +3 -0
  51. data/configuration/rwdtinker.dist +15 -0
  52. data/configuration/rwdtorrent.dist +11 -0
  53. data/configuration/tinkerwin2variables.dist +17 -0
  54. data/downloads/nodownloads.txt +1 -0
  55. data/ev/browser.rb +109 -0
  56. data/ev/ftools.rb +170 -0
  57. data/ev/net.rb +750 -0
  58. data/ev/ruby.rb +819 -0
  59. data/ev/rwd.rb +1849 -0
  60. data/ev/sgml.rb +236 -0
  61. data/ev/thread.rb +63 -0
  62. data/ev/tree.rb +343 -0
  63. data/ev/xml.rb +4 -0
  64. data/extras/aversa.rb +261 -0
  65. data/extras/rconftool.rb +380 -0
  66. data/extras/rubytorrent.rb +94 -0
  67. data/extras/rubytorrent/bencoding.rb +174 -0
  68. data/extras/rubytorrent/controller.rb +610 -0
  69. data/extras/rubytorrent/message.rb +128 -0
  70. data/extras/rubytorrent/metainfo.rb +214 -0
  71. data/extras/rubytorrent/package.rb +600 -0
  72. data/extras/rubytorrent/peer.rb +536 -0
  73. data/extras/rubytorrent/server.rb +166 -0
  74. data/extras/rubytorrent/tracker.rb +225 -0
  75. data/extras/rubytorrent/typedstruct.rb +132 -0
  76. data/extras/rubytorrent/util.rb +186 -0
  77. data/extras/zip/ioextras.rb +114 -0
  78. data/extras/zip/stdrubyext.rb +111 -0
  79. data/extras/zip/tempfile_bugfixed.rb +195 -0
  80. data/extras/zip/zip.rb +1377 -0
  81. data/extras/zip/zipfilesystem.rb +558 -0
  82. data/extras/zip/ziprequire.rb +61 -0
  83. data/gui/00coreguibegin/applicationguitop.rwd +4 -0
  84. data/gui/frontwindow0/10viewnote.rwd +32 -0
  85. data/gui/frontwindow0/30viewtorrent.rwd +13 -0
  86. data/gui/frontwindow0/40rwdtorrentrefresh.rwd +28 -0
  87. data/gui/frontwindow0/67viewconfiguration.rwd +38 -0
  88. data/gui/frontwindowselectionbegin/selectiontabbegin/selectiontabbegin.rwd +16 -0
  89. data/gui/frontwindowselections/superant.com.rwdtinkerwin2selectiontab/rwdwin2selectiontab.rwd +12 -0
  90. data/gui/frontwindowselectionzend/viewselectionzend/viewselectionend.rwd +3 -0
  91. data/gui/frontwindowtdocumentbegin/superant.com.documentsbegin/tt0documentbegin.rwd +6 -0
  92. data/gui/frontwindowtdocuments/superant.com.documents/uu5documents.rwd +15 -0
  93. data/gui/frontwindowtdocuments/superant.com.tinkerwin2documents/uu5documents.rwd +6 -0
  94. data/gui/frontwindowtdocuments/superant.com.torrentdocument/doctorrent.rwd +6 -0
  95. data/gui/frontwindowtdocumentzend/superant.com.documentsend/ww0documentend.rwd +12 -0
  96. data/gui/frontwindowz1end/frontwindowend/xx0rwdfirsttab.rwd +6 -0
  97. data/gui/helpaboutbegin/superant.com.helpaboutbegin/ya0helpscreenstart.rwd +3 -0
  98. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/1appname.rwd +4 -0
  99. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/3copyright.rwd +3 -0
  100. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/5version.rwd +10 -0
  101. data/gui/helpaboutinstalled/superant.com.torrenthelpabout/1appname.rwd +4 -0
  102. data/gui/helpaboutinstalled/superant.com.torrenthelpabout/3copyright.rwd +3 -0
  103. data/gui/helpaboutinstalled/superant.com.torrenthelpabout/5version.rwd +9 -0
  104. data/gui/helpaboutzend/superant.com.helpaboutend/helpscreenend.rwd +3 -0
  105. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/1appname.rwd +5 -0
  106. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/40rwdlistzips.rwd +42 -0
  107. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/45installremotezip.rwd +44 -0
  108. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd +44 -0
  109. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/60editconfiguration.rwd +38 -0
  110. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +29 -0
  111. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/75rwdcontrol.rwd +33 -0
  112. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/80tab1.rwd +11 -0
  113. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/9backend.rwd +6 -0
  114. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/1appname.rwd +31 -0
  115. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/9end.rwd +4 -0
  116. data/gui/tinkerbackwindows/superant.com.torrentdisplay/torrentdisplaywindow.rwd +31 -0
  117. data/gui/tinkerbackwindows/superant.com.versionwindow/1appname.rwd +19 -0
  118. data/gui/zzcoreguiend/tinkerapplicationguiend/yy9rwdend.rwd +4 -0
  119. data/init.rb +277 -0
  120. data/installed/rwdviewlogo-0.4.inf +4 -0
  121. data/lang/en/rwdcore/languagefile.rb +16 -0
  122. data/lang/es/rwdcore/languagefile-es.rb +14 -0
  123. data/lang/jp/rwdcore/languagefile.rb +9 -0
  124. data/lang/nl/rwdcore/languagefile.rb +19 -0
  125. data/lib/temp.rb +1 -0
  126. data/rwd_files/HowTo_Tinker.txt +405 -0
  127. data/rwd_files/HowTo_TinkerWin2.txt +202 -0
  128. data/rwd_files/HowTo_Torrent.txt +146 -0
  129. data/rwd_files/Readme.txt +57 -0
  130. data/rwd_files/favicon.ico +0 -0
  131. data/rwd_files/rdoc-style.css +175 -0
  132. data/rwd_files/rwdapplications.html +54 -0
  133. data/rwd_files/rwdindex.html +6 -0
  134. data/rwd_files/tinker.png +0 -0
  135. data/rwdconfig.dist +10 -0
  136. data/tests/checkdepends.sh +4 -0
  137. data/tests/cleancnf.sh +5 -0
  138. data/tests/makedist.rb +44 -0
  139. data/tests/rdep.rb +354 -0
  140. data/tests/rwdtinkertestEN.rb +163 -0
  141. data/tests/test.result +32 -0
  142. data/tests/totranslate.lang +93 -0
  143. data/torrentfiles/freeculture-audiobook.zip.torrent +0 -0
  144. data/torrentfiles/freeculture.zip.torrent +0 -0
  145. data/zips/rwdahelloworld-0.5.zip +0 -0
  146. metadata +199 -0
@@ -0,0 +1,186 @@
1
+ ## util.rb -- miscellaneous RubyTorrent utility modules.
2
+ ## Copyright 2005 William Morgan.
3
+ ##
4
+ ## This file is part of RubyTorrent. RubyTorrent is free software;
5
+ ## you can redistribute it and/or modify it under the terms of version
6
+ ## 2 of the GNU General Public License as published by the Free
7
+ ## Software Foundation.
8
+ ##
9
+ ## RubyTorrent is distributed in the hope that it will be useful, but
10
+ ## WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ ## General Public License (in the file COPYING) for more details.
13
+
14
+ def rt_debug(*args)
15
+ if $DEBUG || RubyTorrent.log
16
+ stream = RubyTorrent.log || $stdout
17
+ stream << args.join << "\n"
18
+ stream.flush
19
+ end
20
+ end
21
+
22
+ def rt_warning(*args)
23
+ if $DEBUG || RubyTorrent.log
24
+ stream = RubyTorrent.log || $stderr
25
+ stream << "warning: " << args.join << "\n"
26
+ stream.flush
27
+ end
28
+ end
29
+
30
+ module RubyTorrent
31
+
32
+ @log = nil
33
+ def log_output_to(fn)
34
+ @log = File.open(fn, "w")
35
+ end
36
+ attr_reader :log
37
+ module_function :log_output_to, :log
38
+
39
+
40
+ ## parse final hash of pseudo-keyword arguments
41
+ def get_args(rest, *names)
42
+ hash = rest.find { |x| x.is_a? Hash }
43
+ if hash
44
+ rest.delete hash
45
+ hash.each { |k, v| raise ArgumentError, %{unknown argument "#{k}"} unless names.include?(k) }
46
+ end
47
+
48
+ [hash || {}, rest]
49
+ end
50
+ module_function :get_args
51
+
52
+ ## "events": very similar to Observable, but cleaner, IMO. events are
53
+ ## listened to and sent in instance space, but registered in class
54
+ ## space. example:
55
+ ##
56
+ ## class C
57
+ ## include EventSource
58
+ ## event :goat, :boat
59
+ ##
60
+ ## def send_events
61
+ ## send_event :goat
62
+ ## send_event(:boat, 3)
63
+ ## end
64
+ ## end
65
+ ##
66
+ ## c = C.new
67
+ ## c.on_event(:goat) { puts "got goat!" }
68
+ ## c.on_event(:boat) { |x| puts "got boat: #{x}" }
69
+ ##
70
+ ## Defining them in class space is not really necessary, except as an
71
+ ## error-checking mechanism.
72
+ module EventSource
73
+ def on_event(who, *events, &b)
74
+ @event_handlers ||= Hash.new { [] }
75
+ events.each do |e|
76
+ raise ArgumentError, "unknown event #{e} for #{self.class}" unless (self.class.class_eval "@@event_has")[e]
77
+ @event_handlers[e] <<= [who, b]
78
+ end
79
+ nil
80
+ end
81
+
82
+ def send_event(e, *args)
83
+ raise ArgumentError, "unknown event #{e} for #{self.class}" unless (self.class.class_eval "@@event_has")[e]
84
+ @event_handlers ||= Hash.new { [] }
85
+ @event_handlers[e].each { |who, proc| proc[self, *args] }
86
+ nil
87
+ end
88
+
89
+ def unregister_events(who, *events)
90
+ @event_handlers.each do |event, handlers|
91
+ handlers.each do |ewho, proc|
92
+ if (ewho == who) && (events.empty? || events.member?(event))
93
+ @event_handlers[event].delete [who, proc]
94
+ end
95
+ end
96
+ end
97
+ nil
98
+ end
99
+
100
+ def relay_event(who, *events)
101
+ @event_handlers ||= Hash.new { [] }
102
+ events.each do |e|
103
+ raise "unknown event #{e} for #{self.class}" unless (self.class.class_eval "@@event_has")[e]
104
+ raise "unknown event #{e} for #{who.class}" unless (who.class.class_eval "@@event_has")[e]
105
+ @event_handlers[e] <<= [who, lambda { |s, *a| who.send_event e, *a }]
106
+ end
107
+ nil
108
+ end
109
+
110
+ def self.append_features(mod)
111
+ super(mod)
112
+ mod.class_eval %q{
113
+ @@event_has ||= Hash.new(false)
114
+ def self.event(*args)
115
+ args.each { |a| @@event_has[a] = true }
116
+ end
117
+ }
118
+ end
119
+ end
120
+
121
+ ## ensure that a method doesn't execute more frequently than some
122
+ ## number of seconds. e.g.:
123
+ ##
124
+ ## def meth
125
+ ## ...
126
+ ## end
127
+ ## min_iterval :meth, 10
128
+ ##
129
+ ## ensures that "meth" won't be executed more than once every 10
130
+ ## seconds.
131
+ module MinIntervalMethods
132
+ def min_interval(meth, int)
133
+ class_eval %{
134
+ @@min_interval ||= {}
135
+ @@min_interval[:#{meth}] = [nil, #{int.to_i}]
136
+ alias :min_interval_#{meth} :#{meth}
137
+ def #{meth}(*a, &b)
138
+ last, int = @@min_interval[:#{meth}]
139
+ unless last && ((Time.now - last) < int)
140
+ min_interval_#{meth}(*a, &b)
141
+ @@min_interval[:#{meth}][0] = Time.now
142
+ end
143
+ end
144
+ }
145
+ end
146
+ end
147
+
148
+ ## boolean attributes now get question marks in their accessors
149
+ ## don't forget to 'extend' rather than 'include' this one
150
+ module AttrReaderQ
151
+ def attr_reader_q(*args)
152
+ args.each { |v| class_eval "def #{v}?; @#{v}; end" }
153
+ end
154
+
155
+ def attr_writer_q(*args)
156
+ args.each { |v| attr_writer v }
157
+ end
158
+
159
+ def attr_accessor_q(*args)
160
+ attr_reader_q args
161
+ attr_writer_q args
162
+ end
163
+ end
164
+
165
+ module ArrayShuffle
166
+ def shuffle!
167
+ each_index do |i|
168
+ j = i + rand(self.size - i);
169
+ self[i], self[j] = self[j], self[i]
170
+ end
171
+ end
172
+
173
+ def shuffle
174
+ self.clone.shuffle! # dup doesn't preserve shuffle! method
175
+ end
176
+ end
177
+
178
+ module StringMapBytes
179
+ def map_bytes
180
+ ret = []
181
+ each_byte { |x| ret.push(yield(x)) }
182
+ ret
183
+ end
184
+ end
185
+
186
+ end
@@ -0,0 +1,114 @@
1
+ module IOExtras
2
+ module FakeIO
3
+ def kind_of?(object)
4
+ object == IO || super
5
+ end
6
+ end
7
+
8
+ # Implements many of the convenience methods of IO
9
+ # such as gets, getc, readline and readlines
10
+ # depends on: input_finished?, produce_input and read
11
+ module AbstractInputStream
12
+ include Enumerable
13
+ include FakeIO
14
+
15
+ def initialize
16
+ super
17
+ @lineno = 0
18
+ @outputBuffer = ""
19
+ end
20
+
21
+ attr_accessor :lineno
22
+
23
+ def readlines(aSepString = $/)
24
+ retVal = []
25
+ each_line(aSepString) { |line| retVal << line }
26
+ return retVal
27
+ end
28
+
29
+ def gets(aSepString=$/)
30
+ @lineno = @lineno.next
31
+ return read if aSepString == nil
32
+ aSepString="#{$/}#{$/}" if aSepString == ""
33
+
34
+ bufferIndex=0
35
+ while ((matchIndex = @outputBuffer.index(aSepString, bufferIndex)) == nil)
36
+ bufferIndex=@outputBuffer.length
37
+ if input_finished?
38
+ return @outputBuffer.empty? ? nil : flush
39
+ end
40
+ @outputBuffer << produce_input
41
+ end
42
+ sepIndex=matchIndex + aSepString.length
43
+ return @outputBuffer.slice!(0...sepIndex)
44
+ end
45
+
46
+ def flush
47
+ retVal=@outputBuffer
48
+ @outputBuffer=""
49
+ return retVal
50
+ end
51
+
52
+ def readline(aSepString = $/)
53
+ retVal = gets(aSepString)
54
+ raise EOFError if retVal == nil
55
+ return retVal
56
+ end
57
+
58
+ def each_line(aSepString = $/)
59
+ while true
60
+ yield readline(aSepString)
61
+ end
62
+ rescue EOFError
63
+ end
64
+
65
+ alias_method :each, :each_line
66
+ end
67
+
68
+
69
+ #relies on <<
70
+ module AbstractOutputStream
71
+ include FakeIO
72
+
73
+ def write(data)
74
+ self << data
75
+ data.to_s.length
76
+ end
77
+
78
+
79
+ def print(*params)
80
+ self << params.to_s << $\.to_s
81
+ end
82
+
83
+ def printf(aFormatString, *params)
84
+ self << sprintf(aFormatString, *params)
85
+ end
86
+
87
+ def putc(anObject)
88
+ self << case anObject
89
+ when Fixnum then anObject.chr
90
+ when String then anObject
91
+ else raise TypeError, "putc: Only Fixnum and String supported"
92
+ end
93
+ anObject
94
+ end
95
+
96
+ def puts(*params)
97
+ params << "\n" if params.empty?
98
+ params.flatten.each {
99
+ |element|
100
+ val = element.to_s
101
+ self << val
102
+ self << "\n" unless val[-1,1] == "\n"
103
+ }
104
+ end
105
+
106
+ end
107
+
108
+ end # IOExtras namespace module
109
+
110
+
111
+
112
+ # Copyright (C) 2002-2004 Thomas Sondergaard
113
+ # rubyzip is free software; you can redistribute it and/or
114
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,111 @@
1
+ unless Enumerable.method_defined?(:inject)
2
+ module Enumerable #:nodoc:all
3
+ def inject(n = 0)
4
+ each { |value| n = yield(n, value) }
5
+ n
6
+ end
7
+ end
8
+ end
9
+
10
+ module Enumerable #:nodoc:all
11
+ # returns a new array of all the return values not equal to nil
12
+ # This implementation could be faster
13
+ def select_map(&aProc)
14
+ map(&aProc).reject { |e| e.nil? }
15
+ end
16
+ end
17
+
18
+ unless Object.method_defined?(:object_id)
19
+ class Object
20
+ # Using object_id which is the new thing, so we need
21
+ # to make that work in versions prior to 1.8.0
22
+ alias object_id id
23
+ end
24
+ end
25
+
26
+ unless File.respond_to?(:read)
27
+ class File
28
+ # singleton method read does not exist in 1.6.x
29
+ def self.read(fileName)
30
+ open(fileName) { |f| f.read }
31
+ end
32
+ end
33
+ end
34
+
35
+ class String
36
+ def starts_with(aString)
37
+ rindex(aString, 0) == 0
38
+ end
39
+
40
+ def ends_with(aString)
41
+ index(aString, -aString.size)
42
+ end
43
+
44
+ def ensure_end(aString)
45
+ ends_with(aString) ? self : self + aString
46
+ end
47
+
48
+ def lchop
49
+ slice(1, length)
50
+ end
51
+ end
52
+
53
+ class Time
54
+
55
+ #MS-DOS File Date and Time format as used in Interrupt 21H Function 57H:
56
+ #
57
+ # Register CX, the Time:
58
+ # Bits 0-4 2 second increments (0-29)
59
+ # Bits 5-10 minutes (0-59)
60
+ # bits 11-15 hours (0-24)
61
+ #
62
+ # Register DX, the Date:
63
+ # Bits 0-4 day (1-31)
64
+ # bits 5-8 month (1-12)
65
+ # bits 9-15 year (four digit year minus 1980)
66
+
67
+
68
+ def to_binary_dos_time
69
+ (sec/2) +
70
+ (min << 5) +
71
+ (hour << 11)
72
+ end
73
+
74
+ def to_binary_dos_date
75
+ (day) +
76
+ (month << 5) +
77
+ ((year - 1980) << 9)
78
+ end
79
+
80
+ # Dos time is only stored with two seconds accuracy
81
+ def dos_equals(other)
82
+ to_i/2 == other.to_i/2
83
+ end
84
+
85
+ def self.parse_binary_dos_format(binaryDosDate, binaryDosTime)
86
+ second = 2 * ( 0b11111 & binaryDosTime)
87
+ minute = ( 0b11111100000 & binaryDosTime) >> 5
88
+ hour = (0b1111100000000000 & binaryDosTime) >> 11
89
+ day = ( 0b11111 & binaryDosDate)
90
+ month = ( 0b111100000 & binaryDosDate) >> 5
91
+ year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980
92
+ begin
93
+ return Time.local(year, month, day, hour, minute, second)
94
+ end
95
+ end
96
+ end
97
+
98
+ class Module
99
+ def forward_message(forwarder, *messagesToForward)
100
+ methodDefs = messagesToForward.map {
101
+ |msg|
102
+ "def #{msg}; #{forwarder}(:#{msg}); end"
103
+ }
104
+ module_eval(methodDefs.join("\n"))
105
+ end
106
+ end
107
+
108
+
109
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
110
+ # rubyzip is free software; you can redistribute it and/or
111
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,195 @@
1
+ #
2
+ # tempfile - manipulates temporary files
3
+ #
4
+ # $Id: tempfile_bugfixed.rb,v 1.2 2004/03/28 12:46:36 thomas Exp $
5
+ #
6
+
7
+ require 'delegate'
8
+ require 'tmpdir'
9
+
10
+ module BugFix
11
+
12
+ # A class for managing temporary files. This library is written to be
13
+ # thread safe.
14
+ class Tempfile < DelegateClass(File)
15
+ MAX_TRY = 10
16
+ @@cleanlist = []
17
+
18
+ # Creates a temporary file of mode 0600 in the temporary directory
19
+ # whose name is basename.pid.n and opens with mode "w+". A Tempfile
20
+ # object works just like a File object.
21
+ #
22
+ # If tmpdir is omitted, the temporary directory is determined by
23
+ # Dir::tmpdir provided by 'tmpdir.rb'.
24
+ # When $SAFE > 0 and the given tmpdir is tainted, it uses
25
+ # /tmp. (Note that ENV values are tainted by default)
26
+ def initialize(basename, tmpdir=Dir::tmpdir)
27
+ if $SAFE > 0 and tmpdir.tainted?
28
+ tmpdir = '/tmp'
29
+ end
30
+
31
+ lock = nil
32
+ n = failure = 0
33
+
34
+ begin
35
+ Thread.critical = true
36
+
37
+ begin
38
+ tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n)
39
+ lock = tmpname + '.lock'
40
+ n += 1
41
+ end while @@cleanlist.include?(tmpname) or
42
+ File.exist?(lock) or File.exist?(tmpname)
43
+
44
+ Dir.mkdir(lock)
45
+ rescue
46
+ failure += 1
47
+ retry if failure < MAX_TRY
48
+ raise "cannot generate tempfile `%s'" % tmpname
49
+ ensure
50
+ Thread.critical = false
51
+ end
52
+
53
+ @data = [tmpname]
54
+ @clean_proc = Tempfile.callback(@data)
55
+ ObjectSpace.define_finalizer(self, @clean_proc)
56
+
57
+ @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
58
+ @tmpname = tmpname
59
+ @@cleanlist << @tmpname
60
+ @data[1] = @tmpfile
61
+ @data[2] = @@cleanlist
62
+
63
+ super(@tmpfile)
64
+
65
+ # Now we have all the File/IO methods defined, you must not
66
+ # carelessly put bare puts(), etc. after this.
67
+
68
+ Dir.rmdir(lock)
69
+ end
70
+
71
+ # Opens or reopens the file with mode "r+".
72
+ def open
73
+ @tmpfile.close if @tmpfile
74
+ @tmpfile = File.open(@tmpname, 'r+')
75
+ @data[1] = @tmpfile
76
+ __setobj__(@tmpfile)
77
+ end
78
+
79
+ def _close # :nodoc:
80
+ @tmpfile.close if @tmpfile
81
+ @data[1] = @tmpfile = nil
82
+ end
83
+ protected :_close
84
+
85
+ # Closes the file. If the optional flag is true, unlinks the file
86
+ # after closing.
87
+ #
88
+ # If you don't explicitly unlink the temporary file, the removal
89
+ # will be delayed until the object is finalized.
90
+ def close(unlink_now=false)
91
+ if unlink_now
92
+ close!
93
+ else
94
+ _close
95
+ end
96
+ end
97
+
98
+ # Closes and unlinks the file.
99
+ def close!
100
+ _close
101
+ @clean_proc.call
102
+ ObjectSpace.undefine_finalizer(self)
103
+ end
104
+
105
+ # Unlinks the file. On UNIX-like systems, it is often a good idea
106
+ # to unlink a temporary file immediately after creating and opening
107
+ # it, because it leaves other programs zero chance to access the
108
+ # file.
109
+ def unlink
110
+ # keep this order for thread safeness
111
+ File.unlink(@tmpname) if File.exist?(@tmpname)
112
+ @@cleanlist.delete(@tmpname) if @@cleanlist
113
+ end
114
+ alias delete unlink
115
+
116
+ if RUBY_VERSION > '1.8.0'
117
+ def __setobj__(obj)
118
+ @_dc_obj = obj
119
+ end
120
+ else
121
+ def __setobj__(obj)
122
+ @obj = obj
123
+ end
124
+ end
125
+
126
+ # Returns the full path name of the temporary file.
127
+ def path
128
+ @tmpname
129
+ end
130
+
131
+ # Returns the size of the temporary file. As a side effect, the IO
132
+ # buffer is flushed before determining the size.
133
+ def size
134
+ if @tmpfile
135
+ @tmpfile.flush
136
+ @tmpfile.stat.size
137
+ else
138
+ 0
139
+ end
140
+ end
141
+ alias length size
142
+
143
+ class << self
144
+ def callback(data) # :nodoc:
145
+ pid = $$
146
+ lambda{
147
+ if pid == $$
148
+ path, tmpfile, cleanlist = *data
149
+
150
+ print "removing ", path, "..." if $DEBUG
151
+
152
+ tmpfile.close if tmpfile
153
+
154
+ # keep this order for thread safeness
155
+ File.unlink(path) if File.exist?(path)
156
+ cleanlist.delete(path) if cleanlist
157
+
158
+ print "done\n" if $DEBUG
159
+ end
160
+ }
161
+ end
162
+
163
+ # If no block is given, this is a synonym for new().
164
+ #
165
+ # If a block is given, it will be passed tempfile as an argument,
166
+ # and the tempfile will automatically be closed when the block
167
+ # terminates. In this case, open() returns nil.
168
+ def open(*args)
169
+ tempfile = new(*args)
170
+
171
+ if block_given?
172
+ begin
173
+ yield(tempfile)
174
+ ensure
175
+ tempfile.close
176
+ end
177
+
178
+ nil
179
+ else
180
+ tempfile
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ end # module BugFix
187
+ if __FILE__ == $0
188
+ # $DEBUG = true
189
+ f = Tempfile.new("foo")
190
+ f.print("foo\n")
191
+ f.close
192
+ f.open
193
+ p f.gets # => "foo\n"
194
+ f.close!
195
+ end