xref: /titanic_52/usr/src/psm/stand/bootblks/hsfs/common/hsfs.fth (revision 2a55f96f316db08eb5801e122b96b149215c5095)
1986fd29aSsetje\
2986fd29aSsetje\ CDDL HEADER START
3986fd29aSsetje\
4986fd29aSsetje\ The contents of this file are subject to the terms of the
5986fd29aSsetje\ Common Development and Distribution License (the "License").
6986fd29aSsetje\ You may not use this file except in compliance with the License.
7986fd29aSsetje\
8986fd29aSsetje\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9986fd29aSsetje\ or http://www.opensolaris.org/os/licensing.
10986fd29aSsetje\ See the License for the specific language governing permissions
11986fd29aSsetje\ and limitations under the License.
12986fd29aSsetje\
13986fd29aSsetje\ When distributing Covered Code, include this CDDL HEADER in each
14986fd29aSsetje\ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15986fd29aSsetje\ If applicable, add the following below this CDDL HEADER, with the
16986fd29aSsetje\ fields enclosed by brackets "[]" replaced with your own identifying
17986fd29aSsetje\ information: Portions Copyright [yyyy] [name of copyright owner]
18986fd29aSsetje\
19986fd29aSsetje\ CDDL HEADER END
20986fd29aSsetje\
21986fd29aSsetje\
22c713350eSJohn Johnson\
23c713350eSJohn Johnson\ Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24c713350eSJohn Johnson\ Use is subject to license terms.
25c713350eSJohn Johnson\
26986fd29aSsetje
27986fd29aSsetjepurpose: HSFS file system support package for NewBoot
28c713350eSJohn Johnsoncopyright: Copyright 2009 Sun Microsystems, Inc. All Rights Reserved
29986fd29aSsetje
30986fd29aSsetje\ High Sierra, Rock Ridge (CD-ROM) file system reader and boot block
31986fd29aSsetje
32986fd29aSsetjeheaders
33986fd29aSsetje" /packages" get-package  push-package
34986fd29aSsetje
35986fd29aSsetjenew-device
36986fd29aSsetje   fs-pkg$  device-name  diag-cr?
37986fd29aSsetje
38986fd29aSsetje   \
39986fd29aSsetje   \	HSFS variables
40986fd29aSsetje   \
41986fd29aSsetje   0 instance value dev-ih
42986fd29aSsetje   0 instance value vol-desc
43986fd29aSsetje   0 instance value dir-buf
44986fd29aSsetje   0 instance value sua-buf
45986fd29aSsetje   0 instance value ce-buf
46986fd29aSsetje
47986fd29aSsetje   \
48986fd29aSsetje   \	HSFS volume descriptor routines
49986fd29aSsetje   \
50986fd29aSsetje
51986fd29aSsetje   \ unaligned load of 2-byte item
52986fd29aSsetje   : xw@  ( adr -- n )
53986fd29aSsetje      dup c@ swap char+   ( c0 adr+1 )
54986fd29aSsetje      c@                  ( c0 c1 )
55986fd29aSsetje      bwjoin
56986fd29aSsetje   ;
57986fd29aSsetje
58986fd29aSsetje   \ unaligned store of 2-byte item
59986fd29aSsetje   : xw!  ( n adr -- )
60986fd29aSsetje      swap wbsplit swap 2 pick c! swap char+ c!
61986fd29aSsetje   ;
62986fd29aSsetje
63986fd29aSsetje   \ unaligned load of 4-byte item
64986fd29aSsetje   : xl@  ( adr -- n )
65986fd29aSsetje      dup xw@ swap wa1+   ( w0 adr+2 )
66986fd29aSsetje      xw@                 ( w0 w1 )
67986fd29aSsetje      wljoin
68986fd29aSsetje   ;
69986fd29aSsetje   \ unaligned store of 4-byte item
70986fd29aSsetje   : xl!  ( n adr -- )
71986fd29aSsetje      swap lwsplit swap 2 pick xw! swap wa1+ xw!
72986fd29aSsetje   ;
73986fd29aSsetje
74986fd29aSsetje   d# 2048 constant /sector
75986fd29aSsetje   d# 16 constant vol-desc-sector#  ( -- n )
76986fd29aSsetje
77986fd29aSsetje   : +vd  ( index -- adr )
78986fd29aSsetje      vol-desc 0= if
79986fd29aSsetje         ." invalid access of +vd" cr abort
80986fd29aSsetje      then
81986fd29aSsetje      vol-desc +
82986fd29aSsetje   ;
83986fd29aSsetje
84986fd29aSsetje   : root-dir  ( -- n )  d# 156 +vd  ;
85986fd29aSsetje   : /block    ( -- n )  d# 128 +vd xw@  ;
86986fd29aSsetje   : byte>blkoff  ( byte-off -- block-off )  /block mod  ;
87986fd29aSsetje
88986fd29aSsetje   : get-vol-desc  ( -- )
89986fd29aSsetje      vol-desc  /sector  vol-desc-sector# /sector *  dev-ih  read-disk
90986fd29aSsetje   ;
91986fd29aSsetje
92986fd29aSsetje   : read-fs-blocks  ( adr len fs-blk# -- )  /block *  dev-ih  read-disk  ;
93986fd29aSsetje
94986fd29aSsetje   \
95986fd29aSsetje   \	HSFS directory routines
96986fd29aSsetje   \
97986fd29aSsetje
98986fd29aSsetje   \ Current directory variables.
99986fd29aSsetje   instance variable cdir-blk		\ Current directory device block ptr.
100986fd29aSsetje   instance variable cdir-blk0          \ Current directory block0.
101986fd29aSsetje   instance variable cdir-offset	\ Current directory logical offset.
102986fd29aSsetje   instance variable cdir-size		\ Current directory logical size.
103986fd29aSsetje   instance variable cdir-ptr		\ Current directory entry pointer.
104986fd29aSsetje   false instance value cdir-rescan     \ Rescan current directory for symlink.
105986fd29aSsetje
106986fd29aSsetje   \ Access of current directory entry.
107986fd29aSsetje   : +dr  ( n -- adr )  cdir-ptr @ +  ;
108986fd29aSsetje
109986fd29aSsetje   : dir-entrylen    ( -- n )    d# 0  +dr c@  ;
110986fd29aSsetje   : dir-block0      ( -- n )    d# 2  +dr xl@  ;
111986fd29aSsetje   : dir-filesize    ( -- n )    d# 10 +dr xl@  ;
112986fd29aSsetje   : dir-flags       ( -- n )    d# 25 +dr c@  ;
113986fd29aSsetje   : dir-filenamelen ( -- n )    d# 32 +dr c@  ;
114986fd29aSsetje   : dir-filename    ( -- adr )  d# 33 +dr  ;
115986fd29aSsetje
116986fd29aSsetje   : dir-isdir?      ( -- flag )  dir-flags  h# 02  and  0<>  ;
117986fd29aSsetje   : dir-file$       ( -- adr len )  dir-filename  dir-filenamelen  ;
118986fd29aSsetje   : dir-sualen      ( -- len )  dir-entrylen  d# 33 -  dir-filenamelen -  ;
119986fd29aSsetje
120629270abSjgj   \ ISO name, including dot & dot-dot check
121629270abSjgj   : dir-iso$        ( -- adr len )
122629270abSjgj      dir-filenamelen 1  =  if
123629270abSjgj         dir-filename c@             ( name[0] )
124629270abSjgj         dup 0=  if
125629270abSjgj            drop " ."  exit          ( dot )
126629270abSjgj         then
127629270abSjgj         1 =  if                     (  )
128629270abSjgj            " .."  exit              ( dot-dot )
129629270abSjgj         then
130629270abSjgj      then
131629270abSjgj      dir-file$                      ( name$ )
132629270abSjgj   ;
133629270abSjgj
134986fd29aSsetje   false instance value symlink?
135986fd29aSsetje
136986fd29aSsetje   : get-dirblk  ( -- )
137986fd29aSsetje      dir-buf /block  cdir-blk @  read-fs-blocks
138986fd29aSsetje      1 cdir-blk +!
139986fd29aSsetje   ;
140986fd29aSsetje
141986fd29aSsetje   : froot  ( -- )  root-dir cdir-ptr !  ;
142986fd29aSsetje
143986fd29aSsetje   \
144986fd29aSsetje   \ SUAs - System Use Area in directory entry (Rock Ridge
145986fd29aSsetje   \  Extensions to High Sierra/ISO 9660 Format).
146986fd29aSsetje   \  Immediately follows directory entry name rounded up to
147986fd29aSsetje   \  a half-word boundary.
148986fd29aSsetje   \
149986fd29aSsetje   0 instance value sua-ptr
150986fd29aSsetje   0 instance value sua-len
151986fd29aSsetje
152986fd29aSsetje   : +suf           ( n -- adr )    sua-ptr +  ;
153986fd29aSsetje   : suf-sig        ( -- adr len )  sua-ptr 2  ;
154986fd29aSsetje   : suf-len        ( -- len )      2 +suf c@  ;
155986fd29aSsetje   : suf-dat        ( -- data )     5 +suf  ;
156986fd29aSsetje   : suf-ce-lbn     ( -- lbn )      4 +suf xl@ ;
157986fd29aSsetje   : suf-ce-offset  ( -- offset )   d# 12 +suf xl@ ;
158986fd29aSsetje   : suf-ce-len     ( -- len )      d# 20 +suf xl@ ;
159986fd29aSsetje
160986fd29aSsetje   : init-sua     ( -- )
161986fd29aSsetje      dir-file$ +  /w roundup  to sua-ptr
162986fd29aSsetje      dir-sualen               to sua-len
163986fd29aSsetje   ;
164986fd29aSsetje
165986fd29aSsetje   : next-suf  ( -- )
166986fd29aSsetje      sua-len suf-len -  to sua-len
167986fd29aSsetje      suf-len +suf       to sua-ptr
168986fd29aSsetje   ;
169986fd29aSsetje
170986fd29aSsetje   : end-sua  ( -- end? )
171986fd29aSsetje      sua-len 4 <
172986fd29aSsetje   ;
173986fd29aSsetje
174986fd29aSsetje   : suf-nm$  ( -- adr len )  suf-dat  suf-len 5 -  ;
175986fd29aSsetje
176986fd29aSsetje   \ Continuation suffix handling.  When a 'CE' suffix is seen,
177986fd29aSsetje   \ record the CE parameters (logical block#, offset and length
178986fd29aSsetje   \ of continuation).  We process the CE continuation only after
179986fd29aSsetje   \ we've finished processing the current SUA area.
180986fd29aSsetje   instance variable ce-lbn
181986fd29aSsetje   instance variable ce-offset
182986fd29aSsetje   instance variable ce-len
183986fd29aSsetje   : suf-ce-set  ( -- )
184986fd29aSsetje      suf-ce-lbn ce-lbn !
185986fd29aSsetje      suf-ce-offset ce-offset !
186986fd29aSsetje      suf-ce-len ce-len !
187986fd29aSsetje   ;
188986fd29aSsetje
189986fd29aSsetje   : suf-ce-process  ( -- error? )
190986fd29aSsetje      ce-lbn @ 0= if
191986fd29aSsetje         true
192986fd29aSsetje      else
193986fd29aSsetje         sua-buf ce-len @ ce-lbn @  read-fs-blocks
194986fd29aSsetje         sua-buf   to sua-ptr
195986fd29aSsetje         ce-len @  to sua-len
196986fd29aSsetje         0 ce-len ! 0 ce-lbn ! 0 ce-offset !
197986fd29aSsetje         false
198986fd29aSsetje      then
199986fd29aSsetje   ;
200986fd29aSsetje
201986fd29aSsetje   /buf-len  instance buffer: suf-sl-buf
202986fd29aSsetje   false     instance value   symlink-need-sep
203986fd29aSsetje
204986fd29aSsetje   \ Format of Rock Ridge symlinks needs to be munged to unix-style
205986fd29aSsetje   \ name.  Format is:  <flag><nbytes>file-name<flag><nbytes>filename...
206986fd29aSsetje   \ where \ <flag> is flag byte (0=filename, 2=current dir, 4=parent
207986fd29aSsetje   \ dir, 8=root dir) and <nbytes> is one-byte byte count (zero for
208986fd29aSsetje   \ !filename).
209986fd29aSsetje   : suf-copy-to-symlinkbuf  ( name$  -- )
210986fd29aSsetje       false to symlink-need-sep
211986fd29aSsetje       suf-sl-buf -rot bounds do           ( dst )
212986fd29aSsetje          symlink-need-sep if
213986fd29aSsetje             ascii / over c! char+
214986fd29aSsetje          then
215986fd29aSsetje          true to symlink-need-sep
216986fd29aSsetje          i c@ dup 2 = if                   ( dst 2 )
217986fd29aSsetje             \ CURRENT (".")
218986fd29aSsetje             drop ascii . over c! char+ 2   ( dst' inc )
219986fd29aSsetje          else  dup 4 =  if                 ( dst 4 )
220986fd29aSsetje             \ PARENT ("..")
221986fd29aSsetje             drop " .." 2 pick swap move    ( dst )
222986fd29aSsetje             wa1+ 2                         ( dst' inc )
223986fd29aSsetje          else  dup 8 =  if                 ( dst 8 )
224986fd29aSsetje             \ ROOT ("/")
225986fd29aSsetje             drop ascii / over c! char+ 2   ( dst' inc )
226986fd29aSsetje             false to symlink-need-sep
227986fd29aSsetje          else  dup 0<> if
228986fd29aSsetje             ." unknown SL flag: " .x cr abort
229986fd29aSsetje          else                              ( dst c )
230986fd29aSsetje             drop                           ( dst )
231986fd29aSsetje             i char+ dup c@ >r              ( dst src+1  R:nbytes )
232986fd29aSsetje             char+ over r@ move             ( dst R:nbytes )
233986fd29aSsetje             r@ +                           ( dst' R:nbytes )
234986fd29aSsetje             r> wa1+                        ( dst' inc )
235986fd29aSsetje          then then then then
236986fd29aSsetje       +loop                                ( dst )
237986fd29aSsetje       0 swap c!
238986fd29aSsetje    ;
239986fd29aSsetje
240986fd29aSsetje   \ Saved 'NM' prefix buffer.
241986fd29aSsetje   /buf-len  instance buffer: suf-nm-buf
242986fd29aSsetje   0 instance value suf-nm-size
243986fd29aSsetje
244986fd29aSsetje   \ Return the Rock Ridge file name associated with the current
245986fd29aSsetje   \ dirent ('NM' suffix).  Otherwise returns standard iso filename.
246986fd29aSsetje   \ Marks whether returned filename is a symbolic link ('SL' suffix)
247986fd29aSsetje   \ and also processes continuations ('CE' suffix).
248986fd29aSsetje   : rr-file$ ( -- adr len )
249986fd29aSsetje      false to symlink?
250986fd29aSsetje      0 to suf-nm-size
251986fd29aSsetje
252986fd29aSsetje      \ select start of sua, record sua offset
253986fd29aSsetje      init-sua
254986fd29aSsetje      begin
255986fd29aSsetje         end-sua  if
256986fd29aSsetje            suf-ce-process if
257986fd29aSsetje               suf-nm-size if
258629270abSjgj                  suf-nm-buf suf-nm-size       ( NM$ )
259986fd29aSsetje               else
260629270abSjgj                  dir-iso$                     ( iso$ )
261629270abSjgj               then                            ( file$ )
262986fd29aSsetje               exit
263986fd29aSsetje            then
264986fd29aSsetje         then
265986fd29aSsetje         suf-sig                               ( sig-adr sig-len )
266986fd29aSsetje         2dup " NM"  $=  if
267986fd29aSsetje            suf-nm$ to suf-nm-size             ( sig-adr sig-len suf-nm-adr )
268986fd29aSsetje            suf-nm-buf suf-nm-size move
269986fd29aSsetje         then                                  ( sig-adr sig-len )
270986fd29aSsetje         2dup " SL"  $=  if
271986fd29aSsetje            true to symlink?
272986fd29aSsetje            suf-nm$ suf-copy-to-symlinkbuf
273986fd29aSsetje         then
274986fd29aSsetje         2dup " CE"  $=  if
275986fd29aSsetje            suf-ce-set
276986fd29aSsetje         then                                  ( sig-adr sig-len )
277986fd29aSsetje         2drop  next-suf                       (  )
278986fd29aSsetje      again
279986fd29aSsetje   ;
280986fd29aSsetje
281986fd29aSsetje   \
282986fd29aSsetje   \	HSFS high-level routines
283986fd29aSsetje   \
284986fd29aSsetje
285986fd29aSsetje   \ Used for rescanning current directory for symbolic links.
286986fd29aSsetje
287986fd29aSsetje   \ Initializes current directory settings from current directory
288986fd29aSsetje   \ entry pointer or for rescan.  If it's not a rescan, we have
289986fd29aSsetje   \ access to the actual directory entry, so we can check whether
290986fd29aSsetje   \ it's a directory or not here.
291986fd29aSsetje   : init-dent  ( -- error? )
292986fd29aSsetje      cdir-rescan if
293986fd29aSsetje         false to cdir-rescan
294986fd29aSsetje         cdir-blk0 @ cdir-blk !
295986fd29aSsetje      else
296986fd29aSsetje         dir-isdir? 0= if
297986fd29aSsetje            true exit
298986fd29aSsetje         then
299986fd29aSsetje         dir-block0 dup cdir-blk ! cdir-blk0 !
300986fd29aSsetje         dir-filesize cdir-size !
301986fd29aSsetje      then                                    ( blk0 size )
302986fd29aSsetje      0 cdir-offset !
303986fd29aSsetje      false
304986fd29aSsetje   ;
305986fd29aSsetje
306986fd29aSsetje   : get-dent ( -- error? )
307986fd29aSsetje      begin
308986fd29aSsetje         \ Check for end of directory, return true if we're past the EOF.
309986fd29aSsetje         cdir-offset @  cdir-size @  >=  if
310986fd29aSsetje            true  exit
311986fd29aSsetje         then
312986fd29aSsetje
313986fd29aSsetje         \ If we're at a block boundary, get the next block.  Otherwise
314986fd29aSsetje         \ increment the directory pointer.
315986fd29aSsetje         cdir-offset @ byte>blkoff  0=  if
316986fd29aSsetje            get-dirblk
317986fd29aSsetje            dir-buf cdir-ptr !
318986fd29aSsetje         else
319986fd29aSsetje            dir-entrylen cdir-ptr +!
320986fd29aSsetje         then
321986fd29aSsetje
322986fd29aSsetje         \ If dir-entrylen is not zero, increment the current directory
323986fd29aSsetje         \ file offset.  Otherwise, a dir-entrylen of zero indicates
324986fd29aSsetje         \ the end of a dir block, so round up cdir-offset to fetch the
325986fd29aSsetje         \ next one
326986fd29aSsetje         dir-entrylen ?dup if
327986fd29aSsetje            cdir-offset +!  true
328986fd29aSsetje         else
329986fd29aSsetje            cdir-offset @  /block  roundup  cdir-offset !
330986fd29aSsetje            false
331986fd29aSsetje         then
332986fd29aSsetje      until  false
333986fd29aSsetje   ;
334986fd29aSsetje
335986fd29aSsetje   \ Look through current directory for file name 'file$'.
336986fd29aSsetje   \ Will leave current directory entry (cdir-ptr) pointing
337986fd29aSsetje   \ to matched entry on success.
338986fd29aSsetje   : dirlook  ( file$ -- error? )
339986fd29aSsetje      init-dent if
340986fd29aSsetje         true exit
341986fd29aSsetje      then
342986fd29aSsetje      begin  get-dent 0=  while      ( file$ )
343986fd29aSsetje         2dup rr-file$ $=  if        ( file$ )
344629270abSjgj            2drop false  exit        ( succeeded )
345986fd29aSsetje         then                        ( file$ )
346986fd29aSsetje      repeat 2drop true              ( failed )
347986fd29aSsetje   ;
348986fd29aSsetje
349986fd29aSsetje   /buf-len  instance buffer: symlink-buf
350986fd29aSsetje   : symlink-buf$  ( -- path$ )  symlink-buf cscount  ;
351986fd29aSsetje
352986fd29aSsetje   : follow-symlink  ( tail$ -- tail$' )
353986fd29aSsetje
354986fd29aSsetje      \ copy symlink value (plus null) to buf
355986fd29aSsetje      suf-sl-buf cscount 1+  symlink-buf swap  move
356986fd29aSsetje      false to symlink?
357986fd29aSsetje
358986fd29aSsetje      \ append to current path
359986fd29aSsetje      ?dup  if                                              ( tail$ )
360986fd29aSsetje	 " /" symlink-buf$  $append                         ( tail$ )
361986fd29aSsetje	 symlink-buf$  $append                              (  )
362986fd29aSsetje      else  drop  then                                      (  )
363986fd29aSsetje      symlink-buf$                                          ( path$ )
364986fd29aSsetje      over c@  ascii /  =  if                               ( path$ )
365986fd29aSsetje	 froot  str++                                       ( path$' )
366986fd29aSsetje      else
367986fd29aSsetje         true to cdir-rescan
368986fd29aSsetje      then                                                  ( path$ )
369986fd29aSsetje   ;
370986fd29aSsetje
371986fd29aSsetje   : lookup  ( path$ -- error? )
372986fd29aSsetje      over c@  ascii /  =  if
373986fd29aSsetje	 froot  str++                            ( path$' )
374986fd29aSsetje      then                                       ( path$ )
375986fd29aSsetje      begin                                      ( path$ )
376986fd29aSsetje         ascii / left-parse-string               ( path$ file$ )
377986fd29aSsetje      dup  while                                 ( path$ file$ )
378986fd29aSsetje         dirlook  if
379986fd29aSsetje            2drop true  exit                     ( failed )
380986fd29aSsetje         then                                    ( path$ )
381986fd29aSsetje         symlink?  if
382986fd29aSsetje            follow-symlink                       ( path$' )
383986fd29aSsetje         then                                    ( path$ )
384986fd29aSsetje      repeat                                     ( path$ file$ )
385986fd29aSsetje      2drop 2drop  false                         ( succeeded )
386986fd29aSsetje   ;
387986fd29aSsetje
388986fd29aSsetje
389986fd29aSsetje   \
390986fd29aSsetje   \	HSFS installation routines
391986fd29aSsetje   \
392986fd29aSsetje
393986fd29aSsetje   \ Allocate memory for necessary data structures.  Need to
394986fd29aSsetje   \ read volume desriptor sector in order to get /block value.
395986fd29aSsetje   : initialize  ( -- error? )
396986fd29aSsetje      /sector  mem-alloc to vol-desc
397986fd29aSsetje      get-vol-desc
398986fd29aSsetje      /block   mem-alloc to dir-buf
399986fd29aSsetje      /block   mem-alloc to sua-buf
400986fd29aSsetje      /block   mem-alloc to ce-buf
401986fd29aSsetje   ;
402986fd29aSsetje
403986fd29aSsetje   : release-buffers  ( -- )
404986fd29aSsetje      ce-buf      /block  mem-free
405986fd29aSsetje      sua-buf	  /block  mem-free
406986fd29aSsetje      dir-buf     /block  mem-free
407986fd29aSsetje      vol-desc    /sector mem-free
408986fd29aSsetje      0 to vol-desc
409986fd29aSsetje   ;
410986fd29aSsetje
411986fd29aSsetje
412986fd29aSsetje   \ HSFS file interface
413986fd29aSsetje   struct
414986fd29aSsetje      /x     field >filesize
415986fd29aSsetje      /x     field >offset
416986fd29aSsetje      /x     field >block0
417986fd29aSsetje   constant /file-record
418986fd29aSsetje
419986fd29aSsetje   d# 10                  constant #opens
420986fd29aSsetje   #opens /file-record *  constant /file-records
421986fd29aSsetje
422986fd29aSsetje   /file-records  instance buffer: file-records
423986fd29aSsetje
424986fd29aSsetje   -1 instance value current-fd
425986fd29aSsetje
426986fd29aSsetje   : fd>record  ( fd -- record )  /file-record *  file-records +  ;
427986fd29aSsetje
428986fd29aSsetje   : set-fd  ( fd -- error? )
429986fd29aSsetje      dup 0 #opens 1 - between 0= if
430986fd29aSsetje         drop true exit
431986fd29aSsetje      then
432986fd29aSsetje      dup fd>record  >block0 x@ 0= if
433986fd29aSsetje         drop true exit
434986fd29aSsetje      then
435986fd29aSsetje      to current-fd false
436986fd29aSsetje   ;
437986fd29aSsetje
438986fd29aSsetje   : file-offset@  ( -- off )
439986fd29aSsetje      current-fd fd>record >offset x@
440986fd29aSsetje   ;
441986fd29aSsetje
442986fd29aSsetje   : file-offset!  ( off -- )
443986fd29aSsetje      current-fd fd>record >offset x!
444986fd29aSsetje   ;
445986fd29aSsetje
446986fd29aSsetje   : file-size@  ( -- size )
447986fd29aSsetje      current-fd fd>record >filesize x@
448986fd29aSsetje   ;
449986fd29aSsetje
450986fd29aSsetje   : file-size!  ( size -- )
451986fd29aSsetje      current-fd fd>record >filesize x!
452986fd29aSsetje   ;
453986fd29aSsetje
454986fd29aSsetje   : file-block0@  ( -- block0 )
455986fd29aSsetje      current-fd fd>record >block0 x@
456986fd29aSsetje   ;
457986fd29aSsetje
458986fd29aSsetje   : file-block0!  ( block0 -- )
459986fd29aSsetje      current-fd fd>record >block0 x!
460986fd29aSsetje   ;
461986fd29aSsetje
462986fd29aSsetje   : get-slot  ( -- fd false | true )
463986fd29aSsetje      #opens 0  do
464986fd29aSsetje         i fd>record >block0 x@  0=  if
465986fd29aSsetje            i false  unloop exit
466986fd29aSsetje         then
467986fd29aSsetje      loop  true
468986fd29aSsetje   ;
469986fd29aSsetje
470986fd29aSsetje   : free-slot  ( fd -- )
471986fd29aSsetje      set-fd 0= if
472986fd29aSsetje         0 file-offset!
473986fd29aSsetje         0 file-size!
474986fd29aSsetje         0 file-block0!
475986fd29aSsetje      then
476986fd29aSsetje   ;
477986fd29aSsetje
478986fd29aSsetje   \ initializes the open structure with information from
479986fd29aSsetje   \ the inode (on UFS) or directory entry (from HSFS).
480986fd29aSsetje   : init-fd  ( fd -- )
481986fd29aSsetje      to current-fd
482986fd29aSsetje      dir-block0 file-block0!
483986fd29aSsetje      dir-filesize file-size!
484986fd29aSsetje      0 file-offset!
485986fd29aSsetje   ;
486986fd29aSsetje
487986fd29aSsetje   external
488986fd29aSsetje
489986fd29aSsetje   : open ( -- okay? )
490986fd29aSsetje      my-args dev-open  dup 0=  if       ( 0 )
491986fd29aSsetje         exit                            ( failed )
492986fd29aSsetje      then  to dev-ih
493986fd29aSsetje
494986fd29aSsetje      initialize  froot
495986fd29aSsetje      file-records /file-records  erase
496986fd29aSsetje      true                               ( succeeded )
497986fd29aSsetje   ;
498986fd29aSsetje
499986fd29aSsetje   : close  ( -- )
500986fd29aSsetje      dev-ih dev-close
501986fd29aSsetje      release-buffers
502986fd29aSsetje   ;
503986fd29aSsetje
504986fd29aSsetje   : open-file  ( path$ -- fd true | false )
505986fd29aSsetje      get-slot  if
506986fd29aSsetje	 2drop false  exit            ( failed )
507986fd29aSsetje      then  -rot                      ( fd path$ )
508986fd29aSsetje
509986fd29aSsetje      lookup  if                      ( fd )
510986fd29aSsetje	 drop false  exit             ( failed )
511986fd29aSsetje      then
512986fd29aSsetje
513986fd29aSsetje      dup init-fd true                ( fd success )
514986fd29aSsetje   ;
515986fd29aSsetje
516986fd29aSsetje   : close-file  ( fd -- )
517986fd29aSsetje      free-slot   (  )
518986fd29aSsetje   ;
519986fd29aSsetje
520986fd29aSsetje   : read-file   ( adr len fd -- #read )
521986fd29aSsetje
522986fd29aSsetje      \ Check if fd is valid, if it is set current-fd.
523986fd29aSsetje      set-fd if
524986fd29aSsetje         2drop 0 exit
525986fd29aSsetje      then                                   ( adr len )
526986fd29aSsetje
527986fd29aSsetje      \ Adjust len if less than len bytes remain.
528986fd29aSsetje      file-size@ file-offset@ - min          ( adr len' )
529986fd29aSsetje
530986fd29aSsetje      \ Check for invalid length read.
531986fd29aSsetje      dup 0<=  if  2drop 0 exit  then
532986fd29aSsetje
533986fd29aSsetje      \ Compute physical device byte offset.
534986fd29aSsetje      tuck                                   ( len adr len )
535986fd29aSsetje      file-block0@ /block * file-offset@ +   ( len adr len off )
536986fd29aSsetje      dev-ih read-disk                       ( #read )
537*2a55f96fSJohn Johnson      dup file-offset@ +  file-offset!
538986fd29aSsetje   ;
539986fd29aSsetje
540986fd29aSsetje   : seek-file  ( off fd -- error? )
541986fd29aSsetje      set-fd  if                ( off )
542986fd29aSsetje         drop false  exit       ( failed )
543986fd29aSsetje      then                      ( off )
544986fd29aSsetje
545986fd29aSsetje      dup file-size@ >  if      ( off )
546986fd29aSsetje         drop false  exit       ( failed )
547986fd29aSsetje      then                      ( off )
548986fd29aSsetje      dup  file-offset!  true   ( off succeeded )
549986fd29aSsetje   ;
550986fd29aSsetje
551986fd29aSsetje   : size-file  ( fd -- size )
552986fd29aSsetje      set-fd if
553986fd29aSsetje         0
554986fd29aSsetje      else
555986fd29aSsetje         file-size@
556986fd29aSsetje      then
557986fd29aSsetje   ;
558986fd29aSsetje
559986fd29aSsetje   \ we don't support compression (yet)
560986fd29aSsetje   : cinfo-file  ( fd -- bsize fsize comp? )
561986fd29aSsetje      set-fd  if  0 0 0  else  /block file-size@ 0  then
562986fd29aSsetje   ;
563986fd29aSsetje
564986fd29aSsetje   \ read ramdisk fcode at rd-offset
565986fd29aSsetje   : get-rd   ( adr len -- )
566986fd29aSsetje      rd-offset dev-ih  read-disk
567986fd29aSsetje   ;
568986fd29aSsetje
569986fd29aSsetje   \ no additional props needed for hsfs
570986fd29aSsetje   : bootprop  ( -- )  false  ;
571986fd29aSsetje
572986fd29aSsetje   \ debug words
573986fd29aSsetje   : chdir  ( path$ -- )
574986fd29aSsetje      2dup lookup if
575986fd29aSsetje         type ."  Not found" cr
576986fd29aSsetje      else
577986fd29aSsetje         dir-isdir? 0= if
578986fd29aSsetje            type ."  Not a directory" cr
579986fd29aSsetje         else
580986fd29aSsetje            type
581986fd29aSsetje	    ."  blk0 "
582986fd29aSsetje            cdir-blk0 @ .x
583986fd29aSsetje            ."  size "
584986fd29aSsetje            cdir-size @ .x
585986fd29aSsetje            cr
586986fd29aSsetje         then
587986fd29aSsetje      then
588986fd29aSsetje   ;
589986fd29aSsetje
590986fd29aSsetje   : dir  ( -- )
591986fd29aSsetje      init-dent
592986fd29aSsetje      begin  get-dent 0=  while
593986fd29aSsetje         rr-file$ type
594986fd29aSsetje         ."  flags " dir-flags .x
595986fd29aSsetje         ." blk0 " dir-block0 .x
596986fd29aSsetje         ." size " dir-filesize .x
597986fd29aSsetje         cr
598986fd29aSsetje      repeat
599986fd29aSsetje      true to cdir-rescan
600986fd29aSsetje   ;
601986fd29aSsetje
602986fd29aSsetje
603986fd29aSsetjefinish-device
604986fd29aSsetjepop-package
605986fd29aSsetje
606