1 \ *****************************************************************************
2 \ * Copyright (c) 2004, 2008 IBM Corporation
3 \ * All rights reserved.
4 \ * This program and the accompanying materials
5 \ * are made available under the terms of the BSD License
6 \ * which accompanies this distribution, and is available at
7 \ * http://www.opensource.org/licenses/bsd-license.php
10 \ * IBM Corporation - initial implementation
11 \ ****************************************************************************/
14 s" iso-9660" device-name
17 0 VALUE iso-debug-flag
19 \ Method for code clean up - For release version of code iso-debug-flag is
20 \ cleared and for debugging it is set
22 : iso-debug-print ( str len -- ) iso-debug-flag IF type cr ELSE 2drop THEN ;
25 \ --------------------------------------------------------
27 \ --------------------------------------------------------
34 0 VALUE logical-blk-size
42 INSTANCE VARIABLE dir-addr
43 INSTANCE VARIABLE data-buff
44 INSTANCE VARIABLE #data
45 INSTANCE VARIABLE ptable
46 INSTANCE VARIABLE file-loc
47 INSTANCE VARIABLE file-size
48 INSTANCE VARIABLE cur-file-offset
49 INSTANCE VARIABLE self
50 INSTANCE VARIABLE index
53 \ --------------------------------------------------------
55 \ --------------------------------------------------------
58 \ This method is used to seek to the required position
59 \ Which calls seek of disk-label
61 : seek ( pos.lo pos.hi -- status ) s" seek" $call-parent ;
64 \ This method is used to read the contents of disk
65 \ it calls read of disk-label
68 : read ( addr len -- actual ) s" read" $call-parent ;
71 \ This method releases the memory used as scratch pad buffer.
74 data-buff @ ( data-buff )
75 ?DUP IF #data @ free-mem 0 data-buff ! 0 #data ! THEN
79 \ This method will release the previous allocated scratch pad buffer and
80 \ allocates a fresh buffer and copies the required number of bytes from the
83 : read-data ( offset size -- )
85 free-data dup dup ( offset size size size )
86 #data ! alloc-mem data-buff ! ( offset size )
88 swap xlsplit ( size pos.lo pos.hi )
89 seek -2 and ABORT" seek failed."
90 data-buff @ over read ( size actual )
91 <> ABORT" read failed."
95 \ This method extracts the information required from primary volume
96 \ descriptor and stores the required information in the global variables
98 : extract-vol-info ( -- )
99 10 800 * 800 read-data
100 data-buff @ 88 + l@-be to path-tbl-size \ read path table size
101 data-buff @ 94 + l@-be to path-tbl-addr \ read big-endian path table
102 data-buff @ a2 + l@-be dir-addr ! \ gather of root directory info
103 data-buff @ 0aa + l@-be to root-dir-size \ get volume info
104 data-buff @ 54 + l@-be to vol-size \ size in blocks
105 data-buff @ 82 + l@-be to logical-blk-size
106 path-tbl-size alloc-mem dup TO path-table path-tbl-size erase
107 path-tbl-addr 800 * xlsplit seek drop
108 path-table path-tbl-size read drop \ pathtable in-system-memory copy
112 \ This method coverts the iso file name to user readble form
114 : file-name ( str len -- str' len' )
115 2dup [char] ; findchar IF
117 nip \ Omit the trailing ";1" revision of ISO9660 file name
118 2dup + 1- ( str newlen endptr )
120 1- ( str len' ) \ Remove trailing dot
126 \ triplicates top stack element
128 : dup3 ( num -- num num num ) dup dup dup ;
131 \ This method is used for traversing records of path table. If the
132 \ file identifier length is odd 1 byte padding is done else not.
134 : get-next-record ( rec-addr -- next-rec-offset )
135 dup3 ( rec-addr rec-addr rec-addr rec-addr )
136 self @ 1 + self ! ( rec-addr rec-addr rec-addr rec-addr )
137 c@ 1 AND IF ( rec-addr rec-addr rec-addr )
138 c@ + 9 ( rec-addr rec-addr' rec-len )
140 c@ + 8 ( rec-addr rec-addr' rec-len )
142 + swap - ( next-rec-offset )
146 \ This method does search of given directory name in the path table
147 \ and returns true if finds a match else false.
149 : path-table-search ( str len -- TRUE | FALSE )
150 path-table path-tbl-size + path-table ptable @ + DO ( str len )
151 2dup I 6 + w@-be index @ = ( str len str len )
154 ." ISO: comparing path name '"
155 4dup type ." ' with '" type ." '" cr
157 string=ci and IF ( str len )
158 s" Directory Matched!! " iso-debug-print ( str len )
159 self @ index ! ( str len )
160 I 2 + l@-be dir-addr ! I dup ( str len rec-addr )
161 get-next-record + path-table - ptable ! ( str len )
162 2drop TRUE UNLOOP EXIT ( TRUE )
164 I get-next-record ( str len next-rec-offset )
168 s" Invalid path / directory " iso-debug-print
172 \ METHOD for searching for a file with in a direcotory
174 : search-file-dir ( str len -- TRUE | FALSE )
175 dir-addr @ 800 * dir-addr ! ( str len )
176 dir-addr @ 100 read-data ( str len )
177 data-buff @ 0e + l@-be dup >r ( str len rec-len )
179 s" size dir record" iso-debug-print ( str len )
180 dir-addr @ r@ read-data ( str len )
182 r> data-buff @ + data-buff @ DO ( str len )
183 I 19 + c@ 2 and 0= I c@ 0<> and IF ( str len )
184 2dup ( str len str len )
185 I 21 + I 20 + c@ ( str len str len str' len' )
187 ." ISO: comparing file name '"
188 4dup type ." ' with '" type ." '" cr
190 file-name string=ci IF ( str len )
191 s" File found!" iso-debug-print ( str len )
192 I 6 + l@-be 800 * ( str len file-loc )
193 file-loc ! ( str len )
194 I 0e + l@-be file-size ! ( str len )
205 ." skipping " dup . ." bytes at end of sector" cr
212 s" file not found" iso-debug-print
216 \ This method splits the given absolute path in to directories from root and
217 \ calls search-path-table. when string reaches to state when it can not be
218 \ split i.e., end of the path, calls search-file-dir is made to search for
221 : search-path ( str len -- FALSE|TRUE )
227 3drop FALSE ( FALSE )
228 s" Empty path name " iso-debug-print EXIT ( FALSE )
230 OVER c@ ( str len char )
231 [char] \ = IF ( str len )
232 swap 1 + swap 1 - BEGIN ( str len )
233 [char] \ split ( str len str' len ' )
234 dup 0 = IF ( str len str' len ' )
235 2drop search-file-dir EXIT ( TRUE | FALSE )
237 2swap path-table-search invert IF ( str' len ' )
238 2drop FALSE EXIT ( FALSE )
243 [char] \ split dup 0 = IF ( str len str' len' )
244 2drop search-file-dir EXIT ( TRUE | FALSE )
246 2swap path-table-search invert IF ( str' len ' )
247 2drop FALSE EXIT ( FALSE )
255 \ this method will seek and read the file in to the given memory location
258 : load ( addr -- len )
260 file-loc @ xlsplit seek drop
261 file-size @ read ( file-size )
262 iso-debug-flag IF s" Bytes returned from read:" type dup . cr THEN
263 dup file-size @ <> ABORT" read failed!"
268 \ memory used by the file system will be freed
271 free-data count 1 - dup to count 0 = IF
272 path-table path-tbl-size free-mem
278 \ open method of the file system
280 : open ( -- TRUE | FALSE )
290 s" extract-vol-info called " iso-debug-print
294 my-args search-path IF
295 file-loc @ xlsplit seek drop
302 s" opened ISO9660 package" iso-debug-print
308 : seek ( pos.lo pos.hi -- status )
309 lxjoin dup cur-file-offset ! ( offset )
310 file-loc @ + xlsplit ( pos.lo pos.hi )
311 s" seek" $call-parent ( status )
317 : read ( addr len -- actual )
318 file-size @ cur-file-offset @ - ( addr len remainder-of-file )
319 min ( addr len|remainder-of-file )
320 s" read" $call-parent ( actual )
321 dup cur-file-offset @ + cur-file-offset ! ( actual )
322 cur-file-offset @ ( offset actual )
323 xlsplit seek drop ( actual )