rwdaddresses 0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. data/Readme.txt +57 -0
  2. data/bin/rwdaddresses +19 -0
  3. data/code/ag1core/aa0begin.rb +18 -0
  4. data/code/ag1core/rwdtinkerversion.rb +15 -0
  5. data/code/al5languagefiles/alanguagehashbegin.rb +4 -0
  6. data/code/al5languagefiles/languagehash.rb +4 -0
  7. data/code/al5languagefiles/templangfile.rb +6 -0
  8. data/code/al5languagefiles/zlanguagehashend.rb +6 -0
  9. data/code/gl3addresses/gl3viewnamedata.rb +26 -0
  10. data/code/gl3addresses/gl4listnamerecord.rb +11 -0
  11. data/code/gl3addresses/gl4viewphoto.rb +4 -0
  12. data/code/gl3addresses/gl5createnewnamerecord.rb +17 -0
  13. data/code/lm1installapplets/ll5listzips.rb +14 -0
  14. data/code/lm1installapplets/lm1installapplet.rb +20 -0
  15. data/code/ssdiagnostictab/diagnostictab.rb +20 -0
  16. data/code/xa5rwdtinkercallable/callable.rb +13 -0
  17. data/code/xb1rwdtinkerbackwindow/05listinstalledfiles.rb +11 -0
  18. data/code/xb1rwdtinkerbackwindow/diagnostictab.rb +20 -0
  19. data/code/xb1rwdtinkerbackwindow/ll1openname.rb +18 -0
  20. data/code/xb1rwdtinkerbackwindow/ll5listzips.rb +14 -0
  21. data/code/xb1rwdtinkerbackwindow/lm1installapplet.rb +20 -0
  22. data/code/xb1rwdtinkerbackwindow/mm1removeapplet.rb +28 -0
  23. data/code/xb1rwdtinkerbackwindow/rwdtinkerwin2version.rb +14 -0
  24. data/code/zz0applicationend/zz0end.rb +4 -0
  25. data/configuration/aa0rwdframework.cnf +11 -0
  26. data/configuration/ab1tinkerwin2.cnf +3 -0
  27. data/configuration/gl3addresses.cnf +2 -0
  28. data/ev/browser.rb +109 -0
  29. data/ev/ftools.rb +170 -0
  30. data/ev/net.rb +750 -0
  31. data/ev/ruby.rb +819 -0
  32. data/ev/rwd.rb +1848 -0
  33. data/ev/sgml.rb +236 -0
  34. data/ev/thread.rb +63 -0
  35. data/ev/tree.rb +343 -0
  36. data/ev/xml.rb +4 -0
  37. data/gui/en/aa2core/aa0rwdtop.rwd +3 -0
  38. data/gui/en/gl3addresses/gl3viewnamedata.rwd +16 -0
  39. data/gui/en/gl3addresses/gl4listnamerecordfiles.rwd +17 -0
  40. data/gui/en/gl3addresses/gl5createnewnamerecord.rwd +26 -0
  41. data/gui/en/ll1selectiontabbegin/selectiontabbegin.rwd +15 -0
  42. data/gui/en/ll5rwdtinkerwin2selectiontab/rwdwin2selectiontab.rwd +11 -0
  43. data/gui/en/lz1selectiontabend/endselectiontab.rwd +1 -0
  44. data/gui/en/tt0documentsbegin/tt0documentbegin.rwd +5 -0
  45. data/gui/en/uu5rwddocuments/uu5documents.rwd +13 -0
  46. data/gui/en/uu6rwdtinkerwin2documents/uu5documents.rwd +4 -0
  47. data/gui/en/uu8addresses/uu8doc_rwdschedule.rwd +4 -0
  48. data/gui/en/ww0documentsend/ww0documentend.rwd +6 -0
  49. data/gui/en/wz6finaltabs/xx0rwdfirsttab.rwd +4 -0
  50. data/gui/en/xa1versionwindow/1appname.rwd +17 -0
  51. data/gui/en/xa5rwdtinkercallablewindow/1appname.rwd +15 -0
  52. data/gui/en/xa5rwdtinkercallablewindow/9end.rwd +4 -0
  53. data/gui/en/xb1rwdtinkerbackwindow/1appname.rwd +3 -0
  54. data/gui/en/xb1rwdtinkerbackwindow/2tab1.rwd +9 -0
  55. data/gui/en/xb1rwdtinkerbackwindow/3arwddiagnostics.rwd +31 -0
  56. data/gui/en/xb1rwdtinkerbackwindow/4arwdlistapplets.rwd +42 -0
  57. data/gui/en/xb1rwdtinkerbackwindow/4arwdlistzips.rwd +33 -0
  58. data/gui/en/xb1rwdtinkerbackwindow/9backend.rwd +5 -0
  59. data/gui/en/ya1helpaboutbegin/ya0helpscreenstart.rwd +1 -0
  60. data/gui/en/yg5rwdhelpabout/1appname.rwd +2 -0
  61. data/gui/en/yg5rwdhelpabout/3copyright.rwd +1 -0
  62. data/gui/en/yg5rwdhelpabout/5version.rwd +9 -0
  63. data/gui/en/yg6rwdwin2helpabout/1appname.rwd +2 -0
  64. data/gui/en/yg6rwdwin2helpabout/3copyright.rwd +1 -0
  65. data/gui/en/yg6rwdwin2helpabout/5version.rwd +9 -0
  66. data/gui/en/yl3addresseshelp/yl3helpscreen.rwd +4 -0
  67. data/gui/en/yy7addressesphotowindow/yy7addressesphoto.rwd +3 -0
  68. data/gui/en/za1applicationend/yy9rwdend.rwd +2 -0
  69. data/gui/es/aa2core/aa0rwdtop.rwd +3 -0
  70. data/gui/es/gl3addresses/gl3viewnamedata.rwd +16 -0
  71. data/gui/es/gl3addresses/gl4listnamerecordfiles.rwd +17 -0
  72. data/gui/es/gl3addresses/gl5createnewnamerecord.rwd +26 -0
  73. data/gui/es/ll1selectiontabbegin/selectiontabbegin.rwd +15 -0
  74. data/gui/es/ll5rwdtinkerwin2selectiontab/rwdwin2selectiontab.rwd +11 -0
  75. data/gui/es/lz1selectiontabend/endselectiontab.rwd +1 -0
  76. data/gui/es/tt0documentsbegin/tt0documentbegin.rwd +5 -0
  77. data/gui/es/uu5rwddocuments/uu5documents.rwd +13 -0
  78. data/gui/es/uu6rwdtinkerwin2documents/uu5documents.rwd +4 -0
  79. data/gui/es/uu8addresses/uu8doc_rwdschedule.rwd +4 -0
  80. data/gui/es/ww0documentsend/ww0documentend.rwd +6 -0
  81. data/gui/es/wz6finaltabs/xx0rwdfirsttab.rwd +4 -0
  82. data/gui/es/xa1versionwindow/1appname.rwd +17 -0
  83. data/gui/es/xa5rwdtinkercallablewindow/1appname.rwd +15 -0
  84. data/gui/es/xa5rwdtinkercallablewindow/9end.rwd +4 -0
  85. data/gui/es/xb1rwdtinkerbackwindow/1appname.rwd +3 -0
  86. data/gui/es/xb1rwdtinkerbackwindow/2tab1.rwd +9 -0
  87. data/gui/es/xb1rwdtinkerbackwindow/3arwddiagnostics.rwd +31 -0
  88. data/gui/es/xb1rwdtinkerbackwindow/4arwdlistapplets.rwd +42 -0
  89. data/gui/es/xb1rwdtinkerbackwindow/4arwdlistzips.rwd +33 -0
  90. data/gui/es/xb1rwdtinkerbackwindow/9backend.rwd +5 -0
  91. data/gui/es/ya1helpaboutbegin/ya0helpscreenstart.rwd +1 -0
  92. data/gui/es/yg5rwdhelpabout/1appname.rwd +2 -0
  93. data/gui/es/yg5rwdhelpabout/3copyright.rwd +1 -0
  94. data/gui/es/yg5rwdhelpabout/5version.rwd +9 -0
  95. data/gui/es/yg6rwdwin2helpabout/1appname.rwd +2 -0
  96. data/gui/es/yg6rwdwin2helpabout/3copyright.rwd +1 -0
  97. data/gui/es/yg6rwdwin2helpabout/5version.rwd +9 -0
  98. data/gui/es/yl3addresseshelp/yl3helpscreen.rwd +4 -0
  99. data/gui/es/yy7addressesphotowindow/yy7addressesphoto.rwd +3 -0
  100. data/gui/es/za1applicationend/yy9rwdend.rwd +2 -0
  101. data/gui/nl/aa2core/aa0rwdtop.rwd +3 -0
  102. data/gui/nl/gl3addresses/gl3viewnamedata.rwd +16 -0
  103. data/gui/nl/gl3addresses/gl4listnamerecordfiles.rwd +17 -0
  104. data/gui/nl/gl3addresses/gl5createnewnamerecord.rwd +26 -0
  105. data/gui/nl/ll1selectiontabbegin/selectiontabbegin.rwd +15 -0
  106. data/gui/nl/ll5rwdtinkerwin2selectiontab/rwdwin2selectiontab.rwd +11 -0
  107. data/gui/nl/lz1selectiontabend/endselectiontab.rwd +1 -0
  108. data/gui/nl/tt0documentsbegin/tt0documentbegin.rwd +5 -0
  109. data/gui/nl/uu5rwddocuments/uu5documents.rwd +13 -0
  110. data/gui/nl/uu6rwdtinkerwin2documents/uu5documents.rwd +4 -0
  111. data/gui/nl/uu8addresses/uu8doc_rwdschedule.rwd +4 -0
  112. data/gui/nl/ww0documentsend/ww0documentend.rwd +6 -0
  113. data/gui/nl/wz6finaltabs/xx0rwdfirsttab.rwd +4 -0
  114. data/gui/nl/xa1versionwindow/1appname.rwd +17 -0
  115. data/gui/nl/xa5rwdtinkercallablewindow/1appname.rwd +15 -0
  116. data/gui/nl/xa5rwdtinkercallablewindow/9end.rwd +4 -0
  117. data/gui/nl/xb1rwdtinkerbackwindow/1appname.rwd +3 -0
  118. data/gui/nl/xb1rwdtinkerbackwindow/2tab1.rwd +9 -0
  119. data/gui/nl/xb1rwdtinkerbackwindow/3arwddiagnostics.rwd +31 -0
  120. data/gui/nl/xb1rwdtinkerbackwindow/4arwdlistapplets.rwd +42 -0
  121. data/gui/nl/xb1rwdtinkerbackwindow/4arwdlistzips.rwd +33 -0
  122. data/gui/nl/xb1rwdtinkerbackwindow/9backend.rwd +5 -0
  123. data/gui/nl/ya1helpaboutbegin/ya0helpscreenstart.rwd +1 -0
  124. data/gui/nl/yg5rwdhelpabout/1appname.rwd +2 -0
  125. data/gui/nl/yg5rwdhelpabout/3copyright.rwd +1 -0
  126. data/gui/nl/yg5rwdhelpabout/5version.rwd +9 -0
  127. data/gui/nl/yg6rwdwin2helpabout/1appname.rwd +2 -0
  128. data/gui/nl/yg6rwdwin2helpabout/3copyright.rwd +1 -0
  129. data/gui/nl/yg6rwdwin2helpabout/5version.rwd +9 -0
  130. data/gui/nl/yl3addresseshelp/yl3helpscreen.rwd +4 -0
  131. data/gui/nl/yy7addressesphotowindow/yy7addressesphoto.rwd +3 -0
  132. data/gui/nl/za1applicationend/yy9rwdend.rwd +2 -0
  133. data/init.rb +164 -0
  134. data/installed/addressessample1.inf +5 -0
  135. data/installed/rwdaddresses-0.8.inf +11 -0
  136. data/installed/rwdtinkerwin2-0.5.inf +16 -0
  137. data/lang/en/rwdcore/languagefile.rb +6 -0
  138. data/lang/es/rwdcore/languagefile.rb +4 -0
  139. data/lang/nl/rwdcore/languagefile.rb +4 -0
  140. data/lib/temp.rb +1 -0
  141. data/names/AngelinaJolie.nam +8 -0
  142. data/names/AngelinaJolie.png +0 -0
  143. data/names/StevenGibson.nam +5 -0
  144. data/names/StevenGibson.png +0 -0
  145. data/names/nophoto.png +0 -0
  146. data/rwd_files/HowTo_Addresses.html +163 -0
  147. data/rwd_files/HowTo_Addresses.txt +145 -0
  148. data/rwd_files/HowTo_Tinker.html +370 -0
  149. data/rwd_files/HowTo_Tinker.txt +244 -0
  150. data/rwd_files/HowTo_TinkerWin2.txt +202 -0
  151. data/rwd_files/Readme.txt +57 -0
  152. data/rwd_files/contacttmp.png +0 -0
  153. data/rwd_files/favicon.ico +0 -0
  154. data/rwd_files/rdoc-style.css +175 -0
  155. data/rwd_files/rwdapplications.html +54 -0
  156. data/rwd_files/rwdindex.html +6 -0
  157. data/tests/rubyslippers-0.92.gemspec +17 -0
  158. data/tests/rwdtinker-1.2.gemspec +17 -0
  159. data/tests/rwdtinkertestEN.rb +87 -0
  160. data/tests/temptest.out +18 -0
  161. data/tests/totranslate.lang +93 -0
  162. data/zips/rwdaviewphoto-0.3.zip +0 -0
  163. data/zips/rwdhelloworld-0.2.zip +0 -0
  164. data/zips/rwdrefreshacpi-0.1.zip +0 -0
  165. data/zips/rwdwtinkerwin2-0.5.zip +0 -0
  166. metadata +206 -0
@@ -0,0 +1,3 @@
1
+ RwdTinkerWin2Version = "0.5"
2
+ ZipsLocation = "zips" # not yet functional
3
+
@@ -0,0 +1,2 @@
1
+
2
+ $addressfiles_directory="names"
data/ev/browser.rb ADDED
@@ -0,0 +1,109 @@
1
+ require "ev/ruby"
2
+ require "ev/net"
3
+
4
+ begin
5
+ require "win32ole"
6
+ require "win32/registry"
7
+ rescue LoadError
8
+ $".push "win32ole.so"
9
+ $".push "win32/registry.rb"
10
+ end
11
+
12
+ def windowsbrowser
13
+ $stderr.puts "Looking for default browser..."
14
+
15
+ filetype = "htmlfile"
16
+ application = nil
17
+
18
+ begin
19
+ Win32::Registry::HKEY_CLASSES_ROOT.open('.html') do |reg|
20
+ filetype = reg[""]
21
+ end
22
+
23
+ Win32::Registry::HKEY_CLASSES_ROOT.open(filetype + '\shell\open\command') do |reg|
24
+ application = reg[""]
25
+ end
26
+ rescue NameError
27
+ $stderr.puts "Only available for Windows."
28
+ end
29
+
30
+ application
31
+ end
32
+
33
+ def linuxbrowser
34
+ application = ""
35
+
36
+ application = `which galeon 2> /dev/null`.chomp if application.empty?
37
+ application = `which mozilla 2> /dev/null`.chomp if application.empty?
38
+ application = `which firefox 2> /dev/null`.chomp if application.empty?
39
+ application = `which opera 2> /dev/null`.chomp if application.empty?
40
+ application = `which konqueror 2> /dev/null`.chomp if application.empty?
41
+ application = `which htmlview 2> /dev/null`.chomp if application.empty?
42
+ application = nil if application.empty?
43
+
44
+ application
45
+ end
46
+
47
+ def defaultbrowser
48
+ res = nil
49
+ res = windowsbrowser if windows?
50
+ res = linuxbrowser if linux?
51
+ res
52
+ end
53
+
54
+ def showinbrowser(html, browser=defaultbrowser)
55
+ port, io = TCPServer.freeport(7701, 7709)
56
+
57
+ unless browser.nil?
58
+ Thread.new do
59
+ begin
60
+ #command = "1234 \"http://localhost:#{port}\"" if linux?
61
+ #command = "L:/prog/MozillaFirefox/firefox.exe \"http://localhost:#{port}\"" if cygwin?
62
+ #command = Win32::Registry::HKEY_CLASSES_ROOT.open('htmlfile\shell\open\command')[0] + " \"http://localhost:#{port}/\"" if windows?
63
+
64
+ command = "#{browser} \"http://localhost:#{port}\""
65
+
66
+ Thread.pass
67
+
68
+ system(command)
69
+ rescue
70
+ end
71
+ end
72
+ end
73
+
74
+ HTTPServer.serve([port, io]) do |req, resp|
75
+ resp << html
76
+
77
+ resp.stop
78
+ end
79
+ end
80
+
81
+ def tab2html(tab)
82
+ res = ""
83
+
84
+ tab = tab.to_html(false)
85
+
86
+ res << "<html>\n"
87
+ res << "<body>\n"
88
+ res << "<table align='center' border='1' cellspacing='0' cellpadding='3'>\n"
89
+ res << "<tbody>\n"
90
+
91
+ tab.split(/\r*\n/).each do |line|
92
+ res << "<tr>\n"
93
+
94
+ line.split(/\t/, -1).each do |veld|
95
+ veld = "&nbsp;" if veld.compress.empty?
96
+
97
+ res << "<td>%s</td>\n" % veld
98
+ end
99
+
100
+ res << "</tr>\n"
101
+ end
102
+
103
+ res << "</tbody>\n"
104
+ res << "</table>\n"
105
+ res << "</body>\n"
106
+ res << "</html>\n"
107
+
108
+ res
109
+ end
data/ev/ftools.rb ADDED
@@ -0,0 +1,170 @@
1
+ require "ftools"
2
+
3
+ class Dir
4
+ def self.mkdirrec(dir)
5
+ pdir = File.dirname(dir)
6
+
7
+ if not pdir.empty? and not File.directory?(pdir)
8
+ Dir.mkdirrec(pdir)
9
+ end
10
+
11
+ Dir.mkdir(dir) rescue nil
12
+ end
13
+
14
+ def self.copy(from, to)
15
+ if File.directory?(from)
16
+ pdir = Dir.pwd
17
+ todir = File.expand_path(to)
18
+
19
+ mkdirrec(todir)
20
+
21
+ Dir.chdir(from)
22
+ Dir.new(".").each do |e|
23
+ Dir.copy(e, todir+"/"+e) if not [".", ".."].include?(e)
24
+ end
25
+ Dir.chdir(pdir)
26
+ else
27
+ todir = File.dirname(File.expand_path(to))
28
+
29
+ mkdirrec(todir)
30
+
31
+ File.copy(from, to)
32
+ end
33
+ end
34
+
35
+ def self.move(from, to)
36
+ Dir.copy(from, to)
37
+ Dir.rm_rf(from)
38
+ end
39
+
40
+ def self.rm_rf(entry)
41
+ if File.ftype(entry) == "directory"
42
+ pdir = Dir.pwd
43
+
44
+ Dir.chdir(entry)
45
+ Dir.new(".").each do |e|
46
+ Dir.rm_rf(e) if not [".", ".."].include?(e)
47
+ end
48
+ Dir.chdir(pdir)
49
+
50
+ Dir.delete(entry)
51
+ else
52
+ File.delete(entry)
53
+ end
54
+ end
55
+
56
+ def self.find(entry=nil, mask=nil)
57
+ entry = "." if entry.nil?
58
+
59
+ entry = entry.gsub!(/[\/\\]*$/, "") unless entry.nil?
60
+
61
+ mask = /^#{mask}$/i if mask.kind_of?(String)
62
+
63
+ res = []
64
+
65
+ if File.directory?(entry)
66
+ pdir = Dir.pwd
67
+
68
+ res += ["%s/" % entry] if mask.nil? or entry =~ mask
69
+
70
+ begin
71
+ Dir.chdir(entry)
72
+
73
+ begin
74
+ Dir.new(".").each do |e|
75
+ res += Dir.find(e, mask).collect{|e| entry+"/"+e} unless [".", ".."].include?(e)
76
+ end
77
+ ensure
78
+ Dir.chdir(pdir)
79
+ end
80
+ rescue Errno::EACCES => error
81
+ puts error
82
+ end
83
+ else
84
+ res += [entry] if mask.nil? or entry =~ mask
85
+ end
86
+
87
+ res
88
+ end
89
+ end
90
+
91
+ class File
92
+ def self.rollbackup(file, mode=nil)
93
+ backupfile = file + ".RB.BACKUP"
94
+ controlfile = file + ".RB.CONTROL"
95
+ res = nil
96
+
97
+ File.touch(file) unless File.file?(file)
98
+
99
+ # Rollback
100
+
101
+ if File.file?(backupfile) and File.file?(controlfile)
102
+ $stdout.puts "Restoring #{file}..."
103
+
104
+ File.copy(backupfile, file) # Rollback from phase 3
105
+ end
106
+
107
+ # Reset
108
+
109
+ File.delete(backupfile) if File.file?(backupfile) # Reset from phase 2 or 3
110
+ File.delete(controlfile) if File.file?(controlfile) # Reset from phase 3 or 4
111
+
112
+ # Backup
113
+
114
+ File.copy(file, backupfile) # Enter phase 2
115
+ File.touch(controlfile) # Enter phase 3
116
+
117
+ # The real thing
118
+
119
+ if block_given?
120
+ if mode.nil?
121
+ res = yield
122
+ else
123
+ File.open(file, mode) do |f|
124
+ res = yield(f)
125
+ end
126
+ end
127
+ end
128
+
129
+ # Cleanup
130
+
131
+ File.delete(backupfile) # Enter phase 4
132
+ File.delete(controlfile) # Enter phase 5
133
+
134
+ # Return, like File.open
135
+
136
+ res = File.open(file, (mode or "r")) unless block_given?
137
+
138
+ res
139
+ end
140
+
141
+ def self.touch(file)
142
+ File.open(file, "a"){|f|}
143
+ end
144
+
145
+ def self.which(file)
146
+ res = nil
147
+
148
+ if windows?
149
+ file = file.gsub(/\.exe$/i, "") + ".exe"
150
+ sep = ";"
151
+ else
152
+ sep = ":"
153
+ end
154
+
155
+ catch :stop do
156
+ ENV["PATH"].split(/#{sep}/).reverse.each do |d|
157
+ if File.directory?(d)
158
+ Dir.new(d).each do |e|
159
+ if e.downcase == file.downcase
160
+ res = File.expand_path(e, d)
161
+ throw :stop
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ res
169
+ end
170
+ end
data/ev/net.rb ADDED
@@ -0,0 +1,750 @@
1
+ require "ev/ruby"
2
+ require "ev/ftools"
3
+ require "net/http"
4
+ require "socket"
5
+ require "uri"
6
+ require "cgi"
7
+ require "md5"
8
+ require "thread"
9
+
10
+ $proxy = ENV["PROXY"] if $proxy.nil?
11
+
12
+ file = "#{home}/.evnet"
13
+ if File.file?(file)
14
+ Hash.file(file).each do |k, v|
15
+ eval "$#{k} = '#{v}'" unless k=~ /^\#/
16
+ #$proxy_auth = [$proxy_auth].pack("m").chomp if k == "proxy_auth"
17
+ end
18
+ end
19
+
20
+ def uri2txt(s)
21
+ i = s.index(/%[[:digit:]]{2}/)
22
+ while not i.nil?
23
+ s = s[0..(i-1)] + s[(i+1)..(i+2)].unpack('H2').shift.to_i.chr + s[(i+3)..-1]
24
+ i = s.index(/%[[:digit:]]{2}/)
25
+ end
26
+ s
27
+ end
28
+
29
+ class TCPServer
30
+ def self.freeport(from, to, remote=false)
31
+ if windows? or cygwin?
32
+ TCPServer.freeport_windows(from, to, remote)
33
+ else
34
+ TCPServer.freeport_linux(from, to, remote)
35
+ end
36
+ end
37
+
38
+ def self.freeport_linux(from, to, remote)
39
+ ports = (from..to).to_a
40
+ port = nil
41
+ res = nil
42
+
43
+ while res.nil? and not ports.empty?
44
+ begin
45
+ port = ports[0]
46
+ ports.delete(port)
47
+
48
+ io = TCPServer.new(remote ? "0.0.0.0" : "localhost", port)
49
+
50
+ res = [port, io]
51
+ rescue
52
+ end
53
+ end
54
+
55
+ res = [nil, nil] if res.nil?
56
+
57
+ port, io = res
58
+
59
+ return port, io
60
+ end
61
+
62
+ def self.freeport_windows(from, to, remote)
63
+ ports = (from..to).to_a
64
+ port = nil
65
+ res = nil
66
+
67
+ while res.nil? and not ports.empty?
68
+ begin
69
+ port = ports.any
70
+ ports.delete(port)
71
+
72
+ io = TCPSocket.new("localhost", port)
73
+ io.close
74
+ rescue
75
+ res = port
76
+ end
77
+ end
78
+
79
+ port, io = res
80
+
81
+ return port, io
82
+ end
83
+
84
+ def self.freeport_windows2(from, to, remote)
85
+ res = nil
86
+ port = from
87
+
88
+ while res.nil? and port <= to
89
+ begin
90
+ io = TCPSocket.new("localhost", port)
91
+ io.close
92
+
93
+ port += 1
94
+ rescue
95
+ res = port
96
+ end
97
+ end
98
+
99
+ return res
100
+ end
101
+
102
+ def self.usedports(from, to)
103
+ threads = []
104
+ res = []
105
+
106
+ from.upto(to) do |port|
107
+ threads << Thread.new do
108
+ begin
109
+ io = TCPSocket.new("localhost", port)
110
+ io.close
111
+
112
+ port
113
+ rescue
114
+ nil
115
+ end
116
+ end
117
+ end
118
+
119
+ threads.each do |thread|
120
+ port = thread.value
121
+ res << port unless port.nil?
122
+ end
123
+
124
+ return res
125
+ end
126
+ end
127
+
128
+ class EVURI
129
+ attr_reader :protocol
130
+ attr_writer :protocol
131
+ attr_reader :userpass
132
+ attr_writer :userpass
133
+ attr_reader :host
134
+ attr_writer :host
135
+ attr_reader :port
136
+ attr_writer :port
137
+ attr_reader :path
138
+ attr_writer :path
139
+ attr_reader :vars
140
+ attr_writer :vars
141
+ attr_reader :anchor
142
+ attr_writer :anchor
143
+
144
+ def initialize(url)
145
+ begin
146
+ @protocol, @userpass, @host, @port, d1, @path, d2, @vars, @anchor = URI.split(url.to_s)
147
+ rescue
148
+ end
149
+
150
+ @protocol = "" if @protocol.nil?
151
+ @userpass = "" if @userpass.nil?
152
+ @host = "" if @host.nil?
153
+ @port = 0 if @port.nil?
154
+ @path = "" if @path.nil?
155
+ @vars = "" if @vars.nil?
156
+ @anchor = "" if @anchor.nil?
157
+
158
+ res = {}
159
+ @varsvolgorde = []
160
+ @vars.split(/&/).each{|var| k, v = var.split(/=/) ; res[k] = v ; @varsvolgorde << k}
161
+ @vars = res
162
+
163
+ @port = @port.to_i
164
+ end
165
+
166
+ def + (url2)
167
+ url1 = self.to_s
168
+ url2 = url2.to_s if url2.kind_of?(self.class)
169
+
170
+ return EVURI.new((URI::Generic.new(*URI.split(url1)) + URI::Generic.new(*URI.split(url2))).to_s) rescue nil
171
+ end
172
+
173
+ def to_s
174
+ protocol = @protocol
175
+ userpass = @userpass
176
+ host = @host
177
+ port = @port.to_s
178
+ path = @path
179
+ vars = varstring
180
+ anchor = @anchor
181
+
182
+ protocol = nil if @protocol.empty?
183
+ userpass = nil if @userpass.empty?
184
+ host = nil if @host.empty?
185
+ port = nil if @port.zero?
186
+ path = nil if @path.empty?
187
+ vars = nil if @vars.empty?
188
+ anchor = nil if @anchor.empty?
189
+
190
+ res = URI::HTTP.new(@protocol, @userpass, @host, port, nil, @path, nil, vars, @anchor).to_s.from_html
191
+
192
+ res.gsub!(/@/, "") if (@userpass.nil? or @userpass.empty?)
193
+
194
+ res.gsub!(/\#$/, "")
195
+
196
+ return res
197
+ end
198
+
199
+ def varstring
200
+ res = []
201
+ vars = @vars.dup
202
+
203
+ @varsvolgorde.each do |k|
204
+ if vars.include?(k)
205
+ v = vars[k]
206
+ vars.delete(k)
207
+
208
+ res << (v.nil? ? k : "#{k}=#{v}")
209
+ end
210
+ end
211
+
212
+ res.concat(vars.collect{|k, v| v.nil? ? k : "#{k}=#{v}"})
213
+
214
+ return res.join("&")
215
+ end
216
+ end
217
+
218
+ class HTTPClient
219
+ @@versie = 1
220
+ @@mutex = Mutex.new
221
+ @@hosts = {}
222
+
223
+ class Header
224
+ attr_reader :header
225
+ attr_reader :protocol
226
+ attr_reader :code
227
+ attr_reader :text
228
+
229
+ def initialize(header)
230
+ @header = {}
231
+
232
+ if not header.nil?
233
+ firstline, rest = header.split(/\r*\n/, 2)
234
+
235
+ @protocol, @code, @text = firstline.split(/ */, 3)
236
+
237
+ @code = @code.to_i
238
+
239
+ if not rest.nil?
240
+ rest.split(/\r*\n/).each do |line|
241
+ key, value = line.split(/ /, 2)
242
+ @header[key.sub(/:$/, "").downcase] = value
243
+ end
244
+ end
245
+ end
246
+ end
247
+
248
+ def to_s
249
+ res = ""
250
+
251
+ res << "%s %s %s\n" % [@protocol, @code, @text]
252
+
253
+ @header.each do |k, v|
254
+ res << "%s=%s\n" % [k, v]
255
+ end
256
+
257
+ return res
258
+ end
259
+ end
260
+
261
+ class Chunk
262
+ def initialize(data)
263
+ @data = ""
264
+ line, data = data.split(/\r*\n/, 2)
265
+ size, ext = line.split(/;/, 2)
266
+ size = size.hex
267
+ while not size.zero? and not data.nil?
268
+ @data += data[0..(size-1)]
269
+ data = data[size..-1]
270
+ if not data.nil?
271
+ data.gsub!(/^\r*\n/, "")
272
+ line, data = data.split(/\r*\n/, 2)
273
+ size, ext = line.split(/;/, 2)
274
+ size = size.hex
275
+ end
276
+ end
277
+ end
278
+
279
+ def to_s
280
+ @data
281
+ end
282
+ end
283
+
284
+ def self.head(uri, form={}, recursive=true)
285
+ header = Header.new(nil)
286
+
287
+ begin
288
+ while not uri.nil?
289
+ if $proxy.nil? or $proxy.empty?
290
+ uri = EVURI.new(uri) if uri.kind_of? String
291
+ host = uri.host
292
+ port = uri.port
293
+ io = nil
294
+
295
+ @@mutex.synchronize do
296
+ @@hosts[host] = IPSocket.getaddress(host) if not @@hosts.include?(host)
297
+ io = TCPSocket.new(@@hosts[host], port.zero? ? 80 : port)
298
+ end
299
+
300
+ io.write("HEAD #{uri.path or '/'}#{uri.varstring.empty? ? '' : '?' + uri.varstring} HTTP/1.0\r\nHost: #{host}\r\n\r\n")
301
+ else
302
+ proxy = EVURI.new($proxy)
303
+ host = proxy.host
304
+ port = proxy.port
305
+
306
+ io = TCPSocket.new(host, port.zero? ? 8080 : port)
307
+
308
+ io.write("HEAD #{uri} HTTP/1.0\r\n#{"Proxy-Authorization: Basic "+$proxy_auth+"\r\n" if not $proxy_auth.nil?}\r\n\r\n")
309
+ end
310
+
311
+ io.close_write
312
+
313
+ res = io.read
314
+ header, data = nil, nil
315
+ header, data = res.split(/\r*\n\r*\n/, 2) if not res.nil?
316
+ header = Header.new(header)
317
+
318
+ if recursive and header.header["location"] != uri.to_s
319
+ uri = EVURI.new(uri) + header.header["location"]
320
+ else
321
+ uri = nil
322
+ end
323
+ end
324
+ rescue
325
+ header = Header.new(nil)
326
+ end
327
+
328
+ return header
329
+ end
330
+
331
+ def self.get(uri, form={})
332
+ post = Array.new
333
+ form.each_pair do |var, value|
334
+ post << "#{var.to_html}=#{value.to_html}"
335
+ end
336
+ post = post.join("?")
337
+
338
+ data = nil
339
+
340
+ begin
341
+ while not uri.nil?
342
+ if $proxy.nil? or $proxy.empty?
343
+ uri = EVURI.new(uri) if uri.kind_of? String
344
+ host = uri.host
345
+ port = uri.port
346
+
347
+ io = nil
348
+ @@mutex.synchronize do
349
+ @@hosts[host] = IPSocket.getaddress(host) if not @@hosts.include?(host)
350
+ io = TCPSocket.new(@@hosts[host], port.zero? ? 80 : port)
351
+ end
352
+
353
+ if post.empty?
354
+ io.write "GET %s%s HTTP/1.0\r\n" % [(uri.path or '/'), (uri.varstring.empty? ? '' : '?' + uri.varstring)]
355
+ else
356
+ io.write "POST %s%s HTTP/1.0\r\n" % [(uri.path or '/'), (uri.varstring.empty? ? '' : '?' + uri.varstring)]
357
+ end
358
+ else
359
+ proxy = EVURI.new($proxy)
360
+ host = proxy.host
361
+ port = proxy.port
362
+
363
+ io = TCPSocket.new(host, port.zero? ? 8080 : port)
364
+
365
+ if post.empty?
366
+ io.write "GET %s HTTP/1.0\r\n" % uri
367
+ else
368
+ io.write "POST %s HTTP/1.0\r\n" % uri
369
+ end
370
+ end
371
+
372
+ io.write "Host: %s\r\n" % host
373
+ io.write "User-Agent: evwget\r\n"
374
+ io.write "Proxy-Authorization: Basic %s\r\n" % $proxy_auth unless $proxy_auth.nil?
375
+ #io.write "Accept-Encoding: deflate\r\n"
376
+ #io.write "Connection: close\r\n"
377
+ io.write "Content-Type: application/x-www-form-urlencoded\r\n" unless post.empty?
378
+ io.write "Content-Length: %s\r\n" % post.length unless post.empty?
379
+ io.write "\r\n"
380
+ io.write post unless post.empty?
381
+
382
+ io.close_write
383
+
384
+ res = io.read
385
+ header, data = nil, nil
386
+ header, data = res.split(/\r*\n\r*\n/, 2) if not res.nil?
387
+
388
+ header = Header.new(header)
389
+
390
+ if header.header["location"] != uri.to_s
391
+ uri = EVURI.new(uri) + header.header["location"]
392
+ else
393
+ uri = nil
394
+ end
395
+
396
+ if header.header["transfer-encoding"] == "chunked"
397
+ data = Chunk.new(data).to_s if not data.nil?
398
+ end
399
+
400
+ data = nil unless header.code == 200
401
+ end
402
+ rescue
403
+ data = nil
404
+ end
405
+
406
+ return data
407
+ end
408
+
409
+ def self.head_from_cache(uri, form={})
410
+ from_cache("head", uri, form)
411
+ end
412
+
413
+ def self.get_from_cache(uri, form={})
414
+ from_cache("get", uri, form)
415
+ end
416
+
417
+ def self.from_cache(action, uri, form)
418
+ loc = uri.to_s + form.sort.inspect
419
+ hash = MD5.new("#{@@versie} #{loc}")
420
+
421
+ dir = "#{temp}/evcache.#{user}/httpclient.#{action}"
422
+ file = "#{dir}/#{hash}"
423
+ data = nil
424
+
425
+ Dir.mkdirrec(dir)
426
+
427
+ expire = 356*24*60*60
428
+
429
+ if File.file?(file) and (Time.new.to_f - File.stat(file).mtime.to_f < expire)
430
+ @@mutex.synchronize do
431
+ File.open(file, "rb") {|f| data = f.read}
432
+ end
433
+ else
434
+ data = method(action).call(uri, form)
435
+
436
+ if not data.nil?
437
+ @@mutex.synchronize do
438
+ File.open(file, "wb") {|f| f.write data}
439
+ end
440
+ end
441
+ end
442
+
443
+ return data
444
+ end
445
+ end
446
+
447
+ class RequestGet < Hash
448
+ def initialize(data)
449
+ CGI.parse(data).each do |k, v|
450
+ self[k] = v.join(" ")
451
+ end
452
+ end
453
+ end
454
+
455
+ class RequestPost < Hash
456
+ def initialize(data)
457
+ CGI.parse(data).each do |k, v|
458
+ self[k] = v.join(" ")
459
+ end
460
+ end
461
+ end
462
+
463
+ class RequestRequest
464
+ attr_reader :method
465
+ attr_reader :uri
466
+ attr_reader :path
467
+ attr_reader :data
468
+ attr_reader :protocol
469
+
470
+ def initialize(firstline)
471
+ @method, @uri, @protocol = firstline.split(/ /)
472
+ @path, @data = @uri.split(/\?/)
473
+ @data = "" if @data.nil? # TODO
474
+
475
+ # i = @path.index(/%[[:digit:]]{2}/)
476
+ # while not i.nil?
477
+ # @path = @path[0..(i-1)] + @path[(i+1)..(i+2)].unpack('H2').shift.to_i.chr + @path[(i+3)..-1]
478
+ # i = @path.index(/%[[:digit:]]{2}/)
479
+ # end
480
+ end
481
+
482
+ def to_s
483
+ "#{@method} #{@uri} #{@protocol}\r\n"
484
+ end
485
+
486
+ def inspect
487
+ "(RequestRequest: %s)" % [@method, @path, @data, @protocol].join(", ")
488
+ end
489
+ end
490
+
491
+ class Request < Hash
492
+ attr_reader :peeraddr
493
+ attr_reader :request
494
+ attr_reader :cookies
495
+ attr_reader :vars
496
+
497
+ def initialize(io)
498
+ @io = io
499
+
500
+ firstline = @io.gets
501
+
502
+ return if firstline.nil?
503
+
504
+ @request = RequestRequest.new(firstline.strip)
505
+
506
+ line = @io.gets
507
+ line = line.strip unless line.nil?
508
+ while not line.nil? and not line.empty?
509
+ key, value = line.split(" ", 2)
510
+ self[key.sub(/:$/, "").downcase] = value
511
+
512
+ line = @io.gets
513
+ line = line.strip unless line.nil?
514
+ end
515
+
516
+ cookie = self["cookie"]
517
+ cookie = "" if cookie.nil?
518
+ @cookies = {}
519
+ cookie.split(/;/).each do |s|
520
+ k, v = s.strip.split(/=/, 2)
521
+ @cookies[k] = v
522
+ end
523
+
524
+ if not @request.method.nil?
525
+ case @request.method.upcase
526
+ when "HEAD"
527
+ when "GET"
528
+ @vars = RequestGet.new(@request.data.nil? ? "" : @request.data)
529
+ when "POST"
530
+ data = (@io.read(self["content-length"].to_i) or "")
531
+ @vars = RequestPost.new((self["content-type"] == "application/x-www-form-urlencoded") ? data : "")
532
+ else
533
+ $stderr.puts "Unknown request ('#{firstline}')."
534
+ end
535
+ end
536
+
537
+ @peeraddr = @io.peeraddr
538
+
539
+ @pda = false
540
+ @pda = true if (self.include?("user-agent") and self["user-agent"].downcase.include?("windows ce"))
541
+ @pda = true if (self.include?("user-agent") and self["user-agent"].downcase.include?("handhttp"))
542
+
543
+ @io.close_read
544
+ end
545
+
546
+ def pda?
547
+ @pda
548
+ end
549
+
550
+ def to_s
551
+ res = @request.to_s
552
+ self.each do |k, v|
553
+ res << "#{k}: #{v}\r\n"
554
+ end
555
+ res
556
+ end
557
+
558
+ def inspect
559
+ "(Request: %s)" % [@peeraddr, @request.inspect, @vars.inspect, @cookies.inspect, super].join(", ")
560
+ end
561
+ end
562
+
563
+ class Response < Hash
564
+ attr_writer :response
565
+ attr_reader :cookies
566
+ attr_reader :stop
567
+ attr_reader :at_stop
568
+
569
+ def initialize(io)
570
+ @io = io
571
+ @response = "HTTP/1.0 200 OK"
572
+ @cookies = {}
573
+ @data = ""
574
+ @syncd = false
575
+ @stop = false
576
+ @at_stop = lambda{}
577
+ end
578
+
579
+ def flush
580
+ sync
581
+ @io.close
582
+ end
583
+
584
+ def to_s
585
+ res = "#{@response}\r\n"
586
+ self.each do |k, v|
587
+ res << "#{k}: #{v}\r\n"
588
+ end
589
+
590
+ @cookies.each do |k, v|
591
+ res << "Set-Cookie: %s=%s;\r\n" % [k, v]
592
+ end
593
+
594
+ res
595
+ end
596
+
597
+ def sync
598
+ @io.write("#{to_s}\r\n") unless @syncd
599
+ @io.write(@data)
600
+ @data = ""
601
+ @syncd = true
602
+ end
603
+
604
+ def << (s)
605
+ @data << s
606
+ end
607
+
608
+ def inspect
609
+ "(Response: %s)" % [@response, @data].join(", ")
610
+ end
611
+
612
+ def stop(&block)
613
+ @stop = true
614
+ @at_stop = block unless block.nil?
615
+ end
616
+
617
+ def stop?
618
+ @stop
619
+ end
620
+ end
621
+
622
+ class HTTPServerException < Exception
623
+ end
624
+
625
+ class HTTPServer
626
+ def self.serve(portio=80, remote=false, auth=nil, realm="ev/net")
627
+ port, server = portio
628
+
629
+ begin
630
+ server = TCPServer.new(remote ? "0.0.0.0" : "localhost", port) if server.nil?
631
+
632
+ $stderr.puts "Just point your browser to http://localhost:#{port}/ ..."
633
+ rescue
634
+ server = nil
635
+
636
+ $stderr.puts "Port #{port} is in use."
637
+ end
638
+
639
+ if not server.nil?
640
+ count = 0
641
+
642
+ at_exit do
643
+ $stderr.puts "Received #{count} requests"
644
+ end
645
+
646
+ serverthread =
647
+ Thread.new do
648
+ mutex = Mutex.new
649
+
650
+ Thread.current["threads"] = []
651
+
652
+ every(1, Thread.current) do |thread|
653
+ mutex.synchronize do
654
+ thread["threads"].delete_if{|t| (not t.alive?)}
655
+ end
656
+ end
657
+
658
+ loop do
659
+ io = server.accept
660
+ count += 1
661
+
662
+ thread =
663
+ Thread.new(Thread.current, count) do |parentthread, count2|
664
+ stop = false
665
+
666
+ begin
667
+ begin
668
+ req = Request.new(io)
669
+ resp = Response.new(io)
670
+ rescue
671
+ raise HTTPServerException
672
+ end
673
+
674
+ begin
675
+ ip = req.peeraddr[3]
676
+ rescue NameError
677
+ raise HTTPServerException
678
+ end
679
+
680
+ if (not remote) or (remote and (auth.nil? or auth.empty? or authenticate(auth, realm, req, resp)))
681
+ $stderr.puts "#{count2}, #{Time.new.strftime("%Y-%m-%d.%H:%M:%S")}, #{ip}, #{req.request.to_s.strip}"
682
+
683
+ begin
684
+ yield(req, resp)
685
+ rescue Exception => e
686
+ mutex.synchronize do
687
+ $stderr.puts e.class.to_s + ": " + e.message
688
+ $stderr.puts e.backtrace.collect{|s| "\t"+s}.join("\n")
689
+ end
690
+ end
691
+
692
+ stop = true if resp.stop?
693
+ end
694
+
695
+ begin
696
+ resp.flush
697
+ rescue
698
+ raise HTTPServerException
699
+ end
700
+ rescue HTTPServerException
701
+ end
702
+
703
+ parentthread["stop"] = resp if stop
704
+ end
705
+
706
+ mutex.synchronize do
707
+ Thread.current["threads"] << thread
708
+ end
709
+ end
710
+ end
711
+
712
+ sleep 0.1 while not serverthread["stop"]
713
+
714
+ serverthread["threads"].each {|t| t.join}
715
+
716
+ serverthread["stop"].at_stop.call
717
+
718
+ serverthread.kill
719
+ end
720
+ end
721
+
722
+ def self.authenticate(auth, realm, req, resp)
723
+ if auth.kind_of? String
724
+ file = "#{home}/#{auth}"
725
+ auths = {}
726
+ auths = Hash.file(file) if File.file?(file)
727
+ else
728
+ auths = auth
729
+ end
730
+
731
+ authuserpassword = req["authorization"]
732
+ if not authuserpassword.nil?
733
+ authtype, userpassword = authuserpassword.split(/ /)
734
+ if authtype == "Basic" and not userpassword.nil?
735
+ u, p = userpassword.unpack("m").shift.split(/:/)
736
+ end
737
+ end
738
+
739
+ ok = (auths.include?(u) and auths[u] == p)
740
+
741
+ if ok
742
+
743
+ else
744
+ resp["WWW-Authenticate"] = "Basic realm=\"#{realm}\""
745
+ resp.response = "HTTP/1.0 401 Unauthorized"
746
+ end
747
+
748
+ return ok
749
+ end
750
+ end