dsktool 0.1.5 → 0.1.6
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.
- data/bin/dskexplorer.rb +15 -4
- data/bin/dskexplorer.rb~ +275 -0
- data/bin/dsktool.rb +1 -1
- data/bin/dsktool.rb~ +150 -0
- data/lib/DSK.rb~ +134 -0
- data/test/tc_dos_disks.rb~ +79 -0
- metadata +65 -252
- data/doc/classes/AppleSoftFile.src/M000011.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000012.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000013.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000014.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000020.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000021.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000022.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000026.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000027.html +0 -18
- data/doc/classes/AppleSoftFile.src/M000028.html +0 -18
- data/doc/classes/BinaryFile.src/M000023.html +0 -18
- data/doc/classes/BinaryFile.src/M000024.html +0 -18
- data/doc/classes/BinaryFile.src/M000025.html +0 -18
- data/doc/classes/BinaryFile.src/M000026.html +0 -19
- data/doc/classes/BinaryFile.src/M000029.html +0 -18
- data/doc/classes/BinaryFile.src/M000030.html +0 -18
- data/doc/classes/BinaryFile.src/M000031.html +0 -19
- data/doc/classes/BinaryFile.src/M000039.html +0 -18
- data/doc/classes/BinaryFile.src/M000040.html +0 -18
- data/doc/classes/BinaryFile.src/M000041.html +0 -19
- data/doc/classes/BinaryFile.src/M000045.html +0 -18
- data/doc/classes/BinaryFile.src/M000046.html +0 -18
- data/doc/classes/BinaryFile.src/M000047.html +0 -19
- data/doc/classes/CatalogServlet.html +0 -146
- data/doc/classes/CatalogServlet.src/M000015.html +0 -20
- data/doc/classes/CatalogServlet.src/M000021.html +0 -20
- data/doc/classes/D65.src/M000009.html +0 -18
- data/doc/classes/D65.src/M000010.html +0 -18
- data/doc/classes/D65.src/M000011.html +0 -64
- data/doc/classes/D65.src/M000018.html +0 -18
- data/doc/classes/D65.src/M000019.html +0 -64
- data/doc/classes/D65.src/M000024.html +0 -18
- data/doc/classes/D65.src/M000025.html +0 -64
- data/doc/classes/DOSDisk.src/M000014.html +0 -20
- data/doc/classes/DOSDisk.src/M000015.html +0 -20
- data/doc/classes/DOSDisk.src/M000016.html +0 -19
- data/doc/classes/DOSDisk.src/M000017.html +0 -76
- data/doc/classes/DOSDisk.src/M000023.html +0 -20
- data/doc/classes/DOSDisk.src/M000024.html +0 -19
- data/doc/classes/DOSDisk.src/M000025.html +0 -76
- data/doc/classes/DOSDisk.src/M000029.html +0 -20
- data/doc/classes/DOSDisk.src/M000030.html +0 -19
- data/doc/classes/DOSDisk.src/M000031.html +0 -76
- data/doc/classes/DOSFile.src/M000026.html +0 -22
- data/doc/classes/DOSFile.src/M000027.html +0 -22
- data/doc/classes/DOSFile.src/M000028.html +0 -17
- data/doc/classes/DOSFile.src/M000029.html +0 -18
- data/doc/classes/DOSFile.src/M000032.html +0 -22
- data/doc/classes/DOSFile.src/M000033.html +0 -17
- data/doc/classes/DOSFile.src/M000034.html +0 -18
- data/doc/classes/DOSFile.src/M000042.html +0 -22
- data/doc/classes/DOSFile.src/M000043.html +0 -18
- data/doc/classes/DOSFile.src/M000044.html +0 -18
- data/doc/classes/DOSFile.src/M000048.html +0 -22
- data/doc/classes/DOSFile.src/M000049.html +0 -18
- data/doc/classes/DOSFile.src/M000050.html +0 -18
- data/doc/classes/DOSFile.src/M000051.html +0 -31
- data/doc/classes/DSK.src/M000021.html +0 -19
- data/doc/classes/DSK.src/M000022.html +0 -18
- data/doc/classes/DSK.src/M000023.html +0 -40
- data/doc/classes/DSK.src/M000024.html +0 -23
- data/doc/classes/DSK.src/M000027.html +0 -18
- data/doc/classes/DSK.src/M000028.html +0 -22
- data/doc/classes/DSK.src/M000029.html +0 -22
- data/doc/classes/DSK.src/M000030.html +0 -34
- data/doc/classes/DSK.src/M000031.html +0 -19
- data/doc/classes/DSK.src/M000032.html +0 -18
- data/doc/classes/DSK.src/M000033.html +0 -18
- data/doc/classes/DSK.src/M000034.html +0 -22
- data/doc/classes/DSK.src/M000035.html +0 -22
- data/doc/classes/DSK.src/M000036.html +0 -34
- data/doc/classes/DSK.src/M000037.html +0 -19
- data/doc/classes/DSK.src/M000038.html +0 -18
- data/doc/classes/DSK.src/M000039.html +0 -40
- data/doc/classes/DSK.src/M000040.html +0 -23
- data/doc/classes/DirectoryServlet.html +0 -146
- data/doc/classes/DirectoryServlet.src/M000017.html +0 -20
- data/doc/classes/DirectoryServlet.src/M000023.html +0 -20
- data/doc/classes/IntegerBasicFile.src/M000006.html +0 -18
- data/doc/classes/IntegerBasicFile.src/M000007.html +0 -18
- data/doc/classes/IntegerBasicFile.src/M000008.html +0 -18
- data/doc/classes/IntegerBasicFile.src/M000012.html +0 -18
- data/doc/classes/IntegerBasicFile.src/M000013.html +0 -18
- data/doc/classes/IntegerBasicFile.src/M000014.html +0 -18
- data/doc/classes/IntegerBasicFile.src/M000018.html +0 -18
- data/doc/classes/IntegerBasicFile.src/M000019.html +0 -18
- data/doc/classes/IntegerBasicFile.src/M000020.html +0 -18
- data/doc/classes/RDoc.html +0 -141
- data/doc/classes/RDoc.src/M000032.html +0 -40
- data/doc/classes/RDoc.src/M000033.html +0 -40
- data/doc/classes/RDoc.src/M000038.html +0 -40
- data/doc/classes/RDoc.src/M000048.html +0 -40
- data/doc/classes/RDoc.src/M000055.html +0 -40
- data/doc/classes/SCAsmFile.html +0 -226
- data/doc/classes/SCAsmFile.src/M000025.html +0 -18
- data/doc/classes/SCAsmFile.src/M000026.html +0 -18
- data/doc/classes/SCAsmFile.src/M000027.html +0 -18
- data/doc/classes/SCAsmFile.src/M000028.html +0 -36
- data/doc/classes/SCAsmFile.src/M000035.html +0 -18
- data/doc/classes/SCAsmFile.src/M000036.html +0 -18
- data/doc/classes/SCAsmFile.src/M000037.html +0 -18
- data/doc/classes/SCAsmFile.src/M000038.html +0 -36
- data/doc/classes/SCAsmFile.src/M000041.html +0 -18
- data/doc/classes/SCAsmFile.src/M000042.html +0 -18
- data/doc/classes/SCAsmFile.src/M000043.html +0 -18
- data/doc/classes/SCAsmFile.src/M000044.html +0 -36
- data/doc/classes/ShowFileServlet.html +0 -146
- data/doc/classes/ShowFileServlet.src/M000026.html +0 -21
- data/doc/classes/ShowFileServlet.src/M000032.html +0 -22
- data/doc/classes/TestDOSDisks.src/M000004.html +0 -41
- data/doc/classes/TestDOSDisks.src/M000005.html +0 -27
- data/doc/classes/TestDOSDisks.src/M000006.html +0 -24
- data/doc/classes/TestDOSDisks.src/M000007.html +0 -19
- data/doc/classes/TestDOSDisks.src/M000008.html +0 -19
- data/doc/classes/TestDOSDisks.src/M000009.html +0 -25
- data/doc/classes/TestDOSDisks.src/M000010.html +0 -41
- data/doc/classes/TestDOSDisks.src/M000011.html +0 -27
- data/doc/classes/TestDOSDisks.src/M000012.html +0 -24
- data/doc/classes/TestDOSDisks.src/M000013.html +0 -19
- data/doc/classes/TestDOSDisks.src/M000014.html +0 -19
- data/doc/classes/TestDOSDisks.src/M000015.html +0 -25
- data/doc/classes/TestDOSDisks.src/M000016.html +0 -41
- data/doc/classes/TestDOSDisks.src/M000017.html +0 -27
- data/doc/classes/TestDisassembly.src/M000007.html +0 -19
- data/doc/classes/TestDisassembly.src/M000008.html +0 -19
- data/doc/classes/TestDisassembly.src/M000009.html +0 -19
- data/doc/classes/TestDisassembly.src/M000016.html +0 -19
- data/doc/classes/TestDisassembly.src/M000022.html +0 -19
- data/doc/classes/TextFile.src/M000029.html +0 -18
- data/doc/classes/TextFile.src/M000030.html +0 -18
- data/doc/classes/TextFile.src/M000031.html +0 -18
- data/doc/classes/TextFile.src/M000032.html +0 -20
- data/doc/classes/TextFile.src/M000035.html +0 -18
- data/doc/classes/TextFile.src/M000036.html +0 -18
- data/doc/classes/TextFile.src/M000037.html +0 -20
- data/doc/classes/TextFile.src/M000045.html +0 -18
- data/doc/classes/TextFile.src/M000046.html +0 -18
- data/doc/classes/TextFile.src/M000047.html +0 -20
- data/doc/classes/TextFile.src/M000052.html +0 -18
- data/doc/classes/TextFile.src/M000053.html +0 -18
- data/doc/classes/TextFile.src/M000054.html +0 -20
- data/doc/dot/f_0.dot +0 -58
- data/doc/dot/f_0.png +0 -0
- data/doc/dot/f_1.dot +0 -14
- data/doc/dot/f_1.png +0 -0
- data/doc/dot/f_2.dot +0 -23
- data/doc/dot/f_2.png +0 -0
- data/doc/dot/f_3.dot +0 -32
- data/doc/dot/f_3.png +0 -0
- data/doc/dot/f_4.dot +0 -88
- data/doc/dot/f_4.png +0 -0
- data/doc/dot/f_5.dot +0 -23
- data/doc/dot/f_5.png +0 -0
- data/doc/dot/f_6.dot +0 -30
- data/doc/dot/f_6.png +0 -0
- data/doc/dot/f_7.dot +0 -32
- data/doc/dot/f_7.png +0 -0
- data/doc/dot/f_8.dot +0 -32
- data/doc/dot/f_8.png +0 -0
- data/doc/dot/f_9.dot +0 -14
- data/doc/dot/f_9.png +0 -0
- data/doc/dot/m_0_0.dot +0 -30
- data/doc/dot/m_0_0.png +0 -0
- data/doc/dot/m_6_0.dot +0 -30
- data/doc/dot/m_6_0.png +0 -0
- data/doc/files/bin/dskexplorer_rb.html +0 -339
- data/doc/files/bin/dskexplorer_rb.src/M000001.html +0 -21
- data/doc/files/bin/dskexplorer_rb.src/M000002.html +0 -21
- data/doc/files/bin/dskexplorer_rb.src/M000003.html +0 -22
- data/doc/files/bin/dskexplorer_rb.src/M000004.html +0 -19
- data/doc/files/bin/dskexplorer_rb.src/M000005.html +0 -20
- data/doc/files/bin/dskexplorer_rb.src/M000006.html +0 -22
- data/doc/files/bin/dskexplorer_rb.src/M000007.html +0 -20
- data/doc/files/bin/dskexplorer_rb.src/M000008.html +0 -43
- data/doc/files/bin/dskexplorer_rb.src/M000009.html +0 -55
- data/doc/files/bin/dskexplorer_rb.src/M000010.html +0 -43
- data/doc/files/bin/dskexplorer_rb.src/M000011.html +0 -34
- data/doc/files/bin/dskserver_rb.html +0 -247
- data/doc/files/bin/dskserver_rb.src/M000001.html +0 -22
- data/doc/files/bin/dskserver_rb.src/M000002.html +0 -19
- data/doc/files/bin/dskserver_rb.src/M000003.html +0 -62
- data/doc/files/bin/dskserver_rb.src/M000004.html +0 -39
- data/doc/files/bin/dskserver_rb.src/M000005.html +0 -26
- data/doc/files/lib/rdoc_patch_rb.html +0 -114
- data/test/white_11a.dsk +0 -0
data/bin/dskexplorer.rb
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/ruby
|
|
2
|
-
#
|
|
2
|
+
# dskexplorer.rb
|
|
3
3
|
#
|
|
4
4
|
# == Synopsis
|
|
5
5
|
# A web-based DSK file explorer
|
|
6
6
|
#
|
|
7
7
|
# == Usage
|
|
8
|
-
#
|
|
8
|
+
# dskexplorer.rb [switches]
|
|
9
9
|
#
|
|
10
10
|
# -h | --help display this message
|
|
11
11
|
# -p | --port PORT_NUMBER port number to listen on (default is 6052)
|
|
12
12
|
# -r | --root ROOT_DIR root directory to explore from (default is current directory)
|
|
13
13
|
# -v | --version show version number
|
|
14
|
+
#
|
|
15
|
+
# Examples
|
|
16
|
+
# dskexplorer.rb -r http://www.apple2.org.za/mirrors/
|
|
17
|
+
# dskexplorer.rb -r c:\downloads\apple2\ -p 8080
|
|
18
|
+
|
|
14
19
|
|
|
15
20
|
#make sure the relevant folder with our libraries is in the require path
|
|
16
21
|
lib_path=File.expand_path(File.dirname(__FILE__)+"//..//lib")
|
|
@@ -18,14 +23,14 @@ $:.unshift(lib_path) unless $:.include?(lib_path)
|
|
|
18
23
|
|
|
19
24
|
require 'optparse'
|
|
20
25
|
require 'rdoc_patch' #RDoc::usage patched to work under gem executables
|
|
21
|
-
|
|
26
|
+
dskexplorer_VERSION="0.1.0"
|
|
22
27
|
|
|
23
28
|
@listening_port=6502
|
|
24
29
|
@@root_directory="."
|
|
25
30
|
opts=OptionParser.new
|
|
26
31
|
opts.on("-h","--help") {RDoc::usage_from_file(__FILE__)}
|
|
27
32
|
opts.on("-v","--version") do
|
|
28
|
-
puts File.basename($0)+" "+
|
|
33
|
+
puts File.basename($0)+" "+dskexplorer_VERSION
|
|
29
34
|
exit
|
|
30
35
|
end
|
|
31
36
|
opts.on("-p","--port PORT_NUMBER",Integer) {|val| @listening_port=val%0xFFFF}
|
|
@@ -62,6 +67,7 @@ def common_header
|
|
|
62
67
|
end
|
|
63
68
|
def common_footer
|
|
64
69
|
"
|
|
70
|
+
<p><i>this is alpha software - please send feedback using the <a href=http://rubyforge.org/tracker/?group_id=3844> dsktool.rb forum</a><p>
|
|
65
71
|
"
|
|
66
72
|
end
|
|
67
73
|
|
|
@@ -226,6 +232,8 @@ class ShowFileServlet < HTTPServlet::AbstractServlet
|
|
|
226
232
|
end
|
|
227
233
|
end
|
|
228
234
|
|
|
235
|
+
|
|
236
|
+
|
|
229
237
|
s=HTTPServer.new(
|
|
230
238
|
:Port=>@listening_port
|
|
231
239
|
)
|
|
@@ -235,6 +243,9 @@ s.mount("/dir",DirectoryServlet)
|
|
|
235
243
|
s.mount("/catalog",CatalogServlet)
|
|
236
244
|
s.mount("/showfile",ShowFileServlet)
|
|
237
245
|
|
|
246
|
+
#default page - for now, just redirect to the default dir page
|
|
247
|
+
s.mount("/",DirectoryServlet)
|
|
248
|
+
|
|
238
249
|
puts "point your browser at http://localhost:#{@listening_port}/"
|
|
239
250
|
s.start
|
|
240
251
|
|
data/bin/dskexplorer.rb~
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
# dskserver.rb
|
|
3
|
+
#
|
|
4
|
+
# == Synopsis
|
|
5
|
+
# A web-based DSK file explorer
|
|
6
|
+
#
|
|
7
|
+
# == Usage
|
|
8
|
+
# dskserver.rb [switches]
|
|
9
|
+
#
|
|
10
|
+
# -h | --help display this message
|
|
11
|
+
# -p | --port PORT_NUMBER port number to listen on (default is 6052)
|
|
12
|
+
# -r | --root ROOT_DIR root directory to explore from (default is current directory)
|
|
13
|
+
# -v | --version show version number
|
|
14
|
+
#
|
|
15
|
+
# Examples
|
|
16
|
+
# dskexplorer.rb -r http://www.apple2.org.za/mirrors/
|
|
17
|
+
# dskexplorer.rb -r c:\downloads\apple2\ -p 8080
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
#make sure the relevant folder with our libraries is in the require path
|
|
21
|
+
lib_path=File.expand_path(File.dirname(__FILE__)+"//..//lib")
|
|
22
|
+
$:.unshift(lib_path) unless $:.include?(lib_path)
|
|
23
|
+
|
|
24
|
+
require 'optparse'
|
|
25
|
+
require 'rdoc_patch' #RDoc::usage patched to work under gem executables
|
|
26
|
+
DSKSERVER_VERSION="0.1.0"
|
|
27
|
+
|
|
28
|
+
@listening_port=6502
|
|
29
|
+
@@root_directory="."
|
|
30
|
+
opts=OptionParser.new
|
|
31
|
+
opts.on("-h","--help") {RDoc::usage_from_file(__FILE__)}
|
|
32
|
+
opts.on("-v","--version") do
|
|
33
|
+
puts File.basename($0)+" "+DSKSERVER_VERSION
|
|
34
|
+
exit
|
|
35
|
+
end
|
|
36
|
+
opts.on("-p","--port PORT_NUMBER",Integer) {|val| @listening_port=val%0xFFFF}
|
|
37
|
+
opts.on("-r","--root ROOT_DIR",String) {|val| @@root_directory=val}
|
|
38
|
+
|
|
39
|
+
filename=opts.parse(ARGV)[0] rescue RDoc::usage_from_file(__FILE__,'Usage')
|
|
40
|
+
|
|
41
|
+
require 'webrick'
|
|
42
|
+
require 'DSK'
|
|
43
|
+
include WEBrick
|
|
44
|
+
|
|
45
|
+
@@uri_cache={}
|
|
46
|
+
@@dsk_cache={}
|
|
47
|
+
def get_uri_from_cache(uri)
|
|
48
|
+
if @@uri_cache[uri].nil? then
|
|
49
|
+
@@uri_cache[uri]=open(uri).read
|
|
50
|
+
end
|
|
51
|
+
@@uri_cache[uri]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def get_dsk_from_cache(uri)
|
|
55
|
+
if @@dsk_cache[uri].nil? then
|
|
56
|
+
@@dsk_cache[uri]=DSK.read(uri)
|
|
57
|
+
end
|
|
58
|
+
@@dsk_cache[uri]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def common_header
|
|
62
|
+
"
|
|
63
|
+
<html>
|
|
64
|
+
<body>
|
|
65
|
+
<B>DSK Explorer</b><br>
|
|
66
|
+
"
|
|
67
|
+
end
|
|
68
|
+
def common_footer
|
|
69
|
+
"
|
|
70
|
+
<p><i>this is alpha software - please send feedback using the <a href=http://rubyforge.org/tracker/?group_id=3844> dsktool.rb forum</a><p>
|
|
71
|
+
"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def root_dir_is_website?
|
|
75
|
+
require 'hpricot'
|
|
76
|
+
require 'open-uri'
|
|
77
|
+
@@root_directory=~/^http[s]?:/?true : false
|
|
78
|
+
end
|
|
79
|
+
def make_absolute_path(relative_path)
|
|
80
|
+
if root_dir_is_website? then
|
|
81
|
+
@@root_directory+uri_encode(relative_path)
|
|
82
|
+
else
|
|
83
|
+
@@root_directory+relative_path
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def uri_encode(s)
|
|
88
|
+
#standard URI.escape appears to miss some important characters
|
|
89
|
+
require 'uri'
|
|
90
|
+
URI.escape(s).sub("[","%5b").sub("]","%5d")
|
|
91
|
+
end
|
|
92
|
+
def get_directories_and_files(relative_path)
|
|
93
|
+
directories=[]
|
|
94
|
+
dsk_files=[]
|
|
95
|
+
absolute_path=make_absolute_path(relative_path)
|
|
96
|
+
if root_dir_is_website? then
|
|
97
|
+
html=get_uri_from_cache(absolute_path)
|
|
98
|
+
doc=Hpricot(html)
|
|
99
|
+
doc.search("a[@href]").each do |a|
|
|
100
|
+
href=URI.unescape(a.attributes["href"])
|
|
101
|
+
if (href=~/\w\/$/)
|
|
102
|
+
if !(href=~/^\//) then #directories end with a /, but skip absolute paths
|
|
103
|
+
directories<<(href)
|
|
104
|
+
end
|
|
105
|
+
elsif DSK.is_dsk_file?(href) then
|
|
106
|
+
dsk_files<<(href)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
else
|
|
110
|
+
if File.exist?(absolute_path) && (File.stat(absolute_path).directory?) then
|
|
111
|
+
dir=Dir.new(absolute_path)
|
|
112
|
+
dir.each do |f|
|
|
113
|
+
directories<<f if (f[0].chr!=".") && (File.stat(absolute_path+"/"+f).directory?)
|
|
114
|
+
dsk_files<<f if (DSK.is_dsk_file?(f))
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
[directories,dsk_files]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def make_navigation_path(relative_path,filename=nil)
|
|
122
|
+
path_parts=relative_path.split("/")
|
|
123
|
+
#make the cookie-crumb-trail
|
|
124
|
+
partial_path=""
|
|
125
|
+
s="<a href=/dir/>#{@@root_directory}</a>"
|
|
126
|
+
path_parts.each do |p|
|
|
127
|
+
if p.length>0 then
|
|
128
|
+
partial_path+="/#{p}"
|
|
129
|
+
if DSK.is_dsk_file?(partial_path) then
|
|
130
|
+
s+="/<a href=/catalog#{uri_encode(partial_path)}>#{p}</a>"
|
|
131
|
+
else
|
|
132
|
+
s+="/<a href=/dir#{uri_encode(partial_path)}>#{p}</a>"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
if !filename.nil? then
|
|
138
|
+
s+="/<a href=/showfile/#{uri_encode(relative_path)+'?filename='+uri_encode(filename)}>#{filename}</a>"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
#show the contents of the current directory
|
|
143
|
+
directories,dsk_files=get_directories_and_files(relative_path)
|
|
144
|
+
|
|
145
|
+
#list out the directories
|
|
146
|
+
|
|
147
|
+
s+="<ul>"
|
|
148
|
+
#s+="<li>[dir] <a href=/#{uri_encode('/dir/'+File.dirname(relative_path))}>..</a>\n"
|
|
149
|
+
directories.sort.each do |d|
|
|
150
|
+
s+="<li>[dir] <a href=/dir/#{uri_encode(relative_path)}/#{uri_encode(d)}>#{d}</a>\n"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
#list out the DSK files
|
|
154
|
+
dsk_files.sort.each do |f|
|
|
155
|
+
s+="<li>[dsk] <a href=/catalog/#{uri_encode(relative_path)}/#{uri_encode(f)}>#{f}</a> [ <a href=#{uri_encode(@@root_directory+relative_path+'/'+f)}>download</a> ]\n"
|
|
156
|
+
end
|
|
157
|
+
s+="</ul>"
|
|
158
|
+
|
|
159
|
+
s
|
|
160
|
+
end
|
|
161
|
+
def make_catalog(relative_path)
|
|
162
|
+
s="<p>"
|
|
163
|
+
begin
|
|
164
|
+
absolute_path=make_absolute_path(relative_path)
|
|
165
|
+
dsk=get_dsk_from_cache(absolute_path)
|
|
166
|
+
if (dsk.is_dos33?) then
|
|
167
|
+
s+="<table>\n<th>TYPE</th><th>SECTORS</th><th>NAME</th></tr>\n"
|
|
168
|
+
dsk.files.each_value do |f|
|
|
169
|
+
display_url="/showfile/#{uri_encode(relative_path)+'?filename='+uri_encode(f.filename)}"
|
|
170
|
+
s+="<td>#{f.file_type}</td><td>#{sprintf('%03d',f.sector_count)}</td><td>#{f.filename}</td>"
|
|
171
|
+
s+="<td><a href=#{display_url}&mode=hex>hex dump</a></td>"
|
|
172
|
+
if f.file_type=="T" then
|
|
173
|
+
s+="<td><a href=#{display_url}&mode=text>text</a></td>"
|
|
174
|
+
else
|
|
175
|
+
s+="<td><a href=#{display_url}&mode=list>listing</a></td>"
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
s+="</tr>\n"
|
|
179
|
+
end
|
|
180
|
+
s+="</table>"
|
|
181
|
+
else
|
|
182
|
+
s+="<i>not DOS 3.3 format</i>"
|
|
183
|
+
end
|
|
184
|
+
rescue Exception => exception
|
|
185
|
+
s+="<i>ERROR:#{exception}</i>"
|
|
186
|
+
end
|
|
187
|
+
s
|
|
188
|
+
end
|
|
189
|
+
def show_file(relative_path,filename,display_mode)
|
|
190
|
+
absolute_path=make_absolute_path(relative_path)
|
|
191
|
+
dsk=get_dsk_from_cache(absolute_path)
|
|
192
|
+
file=dsk.files[filename]
|
|
193
|
+
if file.nil? then
|
|
194
|
+
s="<i>#{filename} not found</i>"
|
|
195
|
+
else
|
|
196
|
+
s="<hl><pre>"
|
|
197
|
+
if display_mode=="hex" then
|
|
198
|
+
s+=file.hex_dump
|
|
199
|
+
elsif display_mode=="list" && file.file_type=='B'
|
|
200
|
+
then s+=file.disassembly
|
|
201
|
+
else
|
|
202
|
+
s+= file.to_s
|
|
203
|
+
end
|
|
204
|
+
s+="\n</pre><hl>"
|
|
205
|
+
end
|
|
206
|
+
s
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
class DirectoryServlet < HTTPServlet::AbstractServlet
|
|
210
|
+
def do_GET(req,res)
|
|
211
|
+
relative_path=URI.unescape(req.path).sub(/^\/dir/,"")
|
|
212
|
+
res['Content-Type']="text/html"
|
|
213
|
+
res.body=common_header+make_navigation_path(relative_path)+common_footer
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
class CatalogServlet < HTTPServlet::AbstractServlet
|
|
218
|
+
def do_GET(req,res)
|
|
219
|
+
relative_path=URI.unescape(req.path).sub(/^\/catalog/,"")
|
|
220
|
+
res['Content-Type']="text/html"
|
|
221
|
+
res.body=common_header+make_navigation_path(relative_path)+make_catalog(relative_path)+common_footer
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
class ShowFileServlet < HTTPServlet::AbstractServlet
|
|
226
|
+
def do_GET(req,res)
|
|
227
|
+
relative_path=URI.unescape(req.path).sub(/^\/showfile/,"")
|
|
228
|
+
filename=URI.unescape(req.query['filename'])
|
|
229
|
+
display_mode=req.query['mode']
|
|
230
|
+
res['Content-Type']="text/html"
|
|
231
|
+
res.body=common_header+make_navigation_path(relative_path,filename)+show_file(relative_path,filename,display_mode)+common_footer
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
s=HTTPServer.new(
|
|
238
|
+
:Port=>@listening_port
|
|
239
|
+
)
|
|
240
|
+
trap("INT") {s.shutdown}
|
|
241
|
+
|
|
242
|
+
s.mount("/dir",DirectoryServlet)
|
|
243
|
+
s.mount("/catalog",CatalogServlet)
|
|
244
|
+
s.mount("/showfile",ShowFileServlet)
|
|
245
|
+
|
|
246
|
+
#default page - for now, just redirect to the default dir page
|
|
247
|
+
s.mount("/",DirectoryServlet)
|
|
248
|
+
|
|
249
|
+
puts "point your browser at http://localhost:#{@listening_port}/"
|
|
250
|
+
s.start
|
|
251
|
+
|
|
252
|
+
# == Author
|
|
253
|
+
# Jonno Downes (jonno@jamtronix.com)
|
|
254
|
+
#
|
|
255
|
+
# == Copyright
|
|
256
|
+
# Copyright (c) 2007 Jonno Downes (jonno@jamtronix.com)
|
|
257
|
+
#
|
|
258
|
+
#Permission is hereby granted, free of charge, to any person obtaining
|
|
259
|
+
#a copy of this software and associated documentation files (the
|
|
260
|
+
#"Software"), to deal in the Software without restriction, including
|
|
261
|
+
#without limitation the rights to use, copy, modify, merge, publish,
|
|
262
|
+
#distribute, sublicense, and/or sell copies of the Software, and to
|
|
263
|
+
#permit persons to whom the Software is furnished to do so, subject to
|
|
264
|
+
#the following conditions:
|
|
265
|
+
#
|
|
266
|
+
# The above copyright notice and this permission notice shall be
|
|
267
|
+
# included in all copies or substantial portions of the Software.
|
|
268
|
+
#
|
|
269
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
270
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
271
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
272
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
273
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
274
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
275
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/dsktool.rb
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
# dsktool.rb -x DOS3MASTR.dsk.gz -o /tmp/DOS3MASTR/
|
|
34
34
|
# dsktool.rb -c http://jamtronix.com/dsks/apshai.dsk.gz
|
|
35
35
|
|
|
36
|
-
DSKTOOL_VERSION="0.1.
|
|
36
|
+
DSKTOOL_VERSION="0.1.6"
|
|
37
37
|
|
|
38
38
|
#make sure the relevant folder with our libraries is in the require path
|
|
39
39
|
lib_path=File.expand_path(File.dirname(__FILE__)+"//..//lib")
|
data/bin/dsktool.rb~
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
# dsktool.rb
|
|
3
|
+
#
|
|
4
|
+
# == Synopsis
|
|
5
|
+
#
|
|
6
|
+
# Manipulate DSK format files (as used by Apple 2 emulators)
|
|
7
|
+
#
|
|
8
|
+
# == Usage
|
|
9
|
+
#
|
|
10
|
+
# dsktool.rb [switches] <filename.dsk>
|
|
11
|
+
# -c | --catalog display catalog
|
|
12
|
+
# -e | --extract FILENAME extract file by name (either to stdout,
|
|
13
|
+
# or file specified by --output)
|
|
14
|
+
# -h | --help display this message
|
|
15
|
+
# -d | --dump FILENAME hex dump
|
|
16
|
+
# -l | --list FILENAME monitor style listing (disassembles 65C02 opcodes)
|
|
17
|
+
# -o | --output FILENAME specify name to save extracted file as
|
|
18
|
+
# -r | --raw don't convert basic files to ASCII
|
|
19
|
+
# -x | --explode extract all files
|
|
20
|
+
# -v | --version show version number
|
|
21
|
+
#
|
|
22
|
+
# Currently only works with DOS 3.3 format DSK images
|
|
23
|
+
# Will uncompress gzipped files (with extension .gz)
|
|
24
|
+
# input files can be URLs
|
|
25
|
+
#
|
|
26
|
+
# examples:
|
|
27
|
+
# dsktool.rb -c DOS3MASTR.dsk.gz
|
|
28
|
+
# dsktool.rb -l FID DOS3MASTR.dsk
|
|
29
|
+
# dsktool.rb --list fid -o fid.lst DOS3MASTR.dsk
|
|
30
|
+
# dsktool.rb --extract "COLOR DEMOSOFT" DOS3MASTR.dsk
|
|
31
|
+
# dsktool.rb -e HELLO -o HELLO.bas DOS3MASTR.dsk
|
|
32
|
+
# dsktool.rb -x DOS3MASTR.dsk.gz
|
|
33
|
+
# dsktool.rb -x DOS3MASTR.dsk.gz -o /tmp/DOS3MASTR/
|
|
34
|
+
# dsktool.rb -c http://jamtronix.com/dsks/apshai.dsk.gz
|
|
35
|
+
|
|
36
|
+
DSKTOOL_VERSION="0.1.5"
|
|
37
|
+
|
|
38
|
+
#make sure the relevant folder with our libraries is in the require path
|
|
39
|
+
lib_path=File.expand_path(File.dirname(__FILE__)+"//..//lib")
|
|
40
|
+
$:.unshift(lib_path) unless $:.include?(lib_path)
|
|
41
|
+
|
|
42
|
+
require 'optparse'
|
|
43
|
+
require 'rdoc_patch' #RDoc::usage patched to work under gem executables
|
|
44
|
+
|
|
45
|
+
catalog=false
|
|
46
|
+
explode=false
|
|
47
|
+
output_filename=nil
|
|
48
|
+
extract_filename=nil
|
|
49
|
+
extract_mode=:default
|
|
50
|
+
explode_directory=nil
|
|
51
|
+
opts=OptionParser.new
|
|
52
|
+
opts.on("-h","--help") {RDoc::usage_from_file(__FILE__)}
|
|
53
|
+
opts.on("-v","--version") do
|
|
54
|
+
puts File.basename($0)+" "+DSKTOOL_VERSION
|
|
55
|
+
exit
|
|
56
|
+
end
|
|
57
|
+
opts.on("-r","--raw") {extract_mode=:raw}
|
|
58
|
+
opts.on("-c","--catalog") {catalog=true}
|
|
59
|
+
opts.on("-x","--explode") {explode=true}
|
|
60
|
+
opts.on("-l","--list FILENAME",String) do |val|
|
|
61
|
+
extract_filename=val.upcase
|
|
62
|
+
extract_mode=:list
|
|
63
|
+
end
|
|
64
|
+
opts.on("-d","--dump FILENAME",String) do |val|
|
|
65
|
+
extract_filename=val.upcase
|
|
66
|
+
extract_mode=:hex
|
|
67
|
+
end
|
|
68
|
+
opts.on("-e","--extract FILENAME",String) {|val| extract_filename=val.upcase}
|
|
69
|
+
opts.on("-o","--output FILENAME",String) {|val| output_filename=val}
|
|
70
|
+
filename=opts.parse(ARGV)[0] rescue RDoc::usage_from_file(__FILE__,'Usage')
|
|
71
|
+
RDoc::usage_from_file(__FILE__,'Usage') if (filename.nil?)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
require 'DSK'
|
|
75
|
+
dsk=DSK.read(filename)
|
|
76
|
+
output_file= case
|
|
77
|
+
when (output_filename.nil?) || (explode) then STDOUT
|
|
78
|
+
else File.open(output_filename,"wb")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
if(catalog) then
|
|
82
|
+
if (dsk.is_dos33?) then
|
|
83
|
+
dsk.dump_catalog
|
|
84
|
+
else
|
|
85
|
+
puts "#{filename} is not in DOS 3.3 format"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
if(explode) then
|
|
90
|
+
output_dir=output_filename.nil??File.basename(filename,".*"):output_filename
|
|
91
|
+
if !(File.exists?(output_dir)) then
|
|
92
|
+
Dir.mkdir(output_dir)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
dsk.files.each_value do |f|
|
|
96
|
+
if (raw_mode) then
|
|
97
|
+
output_filename=output_dir+"/"+f.filename+".raw"
|
|
98
|
+
File.open(output_filename,"wb") <<f.contents
|
|
99
|
+
else
|
|
100
|
+
output_filename=output_dir+"/"+f.filename+f.file_extension
|
|
101
|
+
File.open(output_filename,"wb") <<f
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
if (!extract_filename.nil?) then
|
|
108
|
+
file=dsk.files[extract_filename]
|
|
109
|
+
if file.nil? then
|
|
110
|
+
puts "'#{extract_filename}' not found in #{filename}"
|
|
111
|
+
else
|
|
112
|
+
output_file<< case extract_mode
|
|
113
|
+
when :raw then file.contents
|
|
114
|
+
when :hex then file.hex_dump
|
|
115
|
+
when :list then
|
|
116
|
+
if file.instance_of?(BinaryFile)
|
|
117
|
+
file.disassembly
|
|
118
|
+
else
|
|
119
|
+
puts "'#{extract_filename}' is not a binary file"
|
|
120
|
+
exit
|
|
121
|
+
end
|
|
122
|
+
else file.to_s
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# == Author
|
|
128
|
+
# Jonno Downes (jonno@jamtronix.com)
|
|
129
|
+
#
|
|
130
|
+
# == Copyright
|
|
131
|
+
# Copyright (c) 2007 Jonno Downes (jonno@jamtronix.com)
|
|
132
|
+
#
|
|
133
|
+
#Permission is hereby granted, free of charge, to any person obtaining
|
|
134
|
+
#a copy of this software and associated documentation files (the
|
|
135
|
+
#"Software"), to deal in the Software without restriction, including
|
|
136
|
+
#without limitation the rights to use, copy, modify, merge, publish,
|
|
137
|
+
#distribute, sublicense, and/or sell copies of the Software, and to
|
|
138
|
+
#permit persons to whom the Software is furnished to do so, subject to
|
|
139
|
+
#the following conditions:
|
|
140
|
+
#
|
|
141
|
+
# The above copyright notice and this permission notice shall be
|
|
142
|
+
# included in all copies or substantial portions of the Software.
|
|
143
|
+
#
|
|
144
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
145
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
146
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
147
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
148
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
149
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
150
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|