hsfs.fth revision 629270abbcc9bcad8f09aeb9500f67a1933334d1
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ ident "%Z%%M% %I% %E% SMI"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ Use is subject to license terms.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ CDDL HEADER START
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ The contents of this file are subject to the terms of the
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ Common Development and Distribution License (the "License").
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ You may not use this file except in compliance with the License.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ See the License for the specific language governing permissions
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ and limitations under the License.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ When distributing Covered Code, include this CDDL HEADER in each
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ If applicable, add the following below this CDDL HEADER, with the
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ fields enclosed by brackets "[]" replaced with your own identifying
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ information: Portions Copyright [yyyy] [name of copyright owner]
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ CDDL HEADER END
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockid: %Z%%M% %I% %E% SMI
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockpurpose: HSFS file system support package for NewBoot
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockcopyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock\ High Sierra, Rock Ridge (CD-ROM) file system reader and boot block
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock" /packages" get-package push-package
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock fs-pkg$ device-name diag-cr?
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ HSFS variables
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 instance value dev-ih
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 instance value vol-desc
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 instance value dir-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 instance value sua-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 instance value ce-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ HSFS volume descriptor routines
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ unaligned load of 2-byte item
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : xw@ ( adr -- n )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup c@ swap char+ ( c0 adr+1 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock c@ ( c0 c1 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ unaligned store of 2-byte item
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : xw! ( n adr -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock swap wbsplit swap 2 pick c! swap char+ c!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ unaligned load of 4-byte item
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : xl@ ( adr -- n )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup xw@ swap wa1+ ( w0 adr+2 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock xw@ ( w0 w1 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ unaligned store of 4-byte item
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : xl! ( n adr -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock swap lwsplit swap 2 pick xw! swap wa1+ xw!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock d# 2048 constant /sector
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock d# 16 constant vol-desc-sector# ( -- n )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : +vd ( index -- adr )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock vol-desc 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ." invalid access of +vd" cr abort
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : root-dir ( -- n ) d# 156 +vd ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : /block ( -- n ) d# 128 +vd xw@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : byte>blkoff ( byte-off -- block-off ) /block mod ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : get-vol-desc ( -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock vol-desc /sector vol-desc-sector# /sector * dev-ih read-disk
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : read-fs-blocks ( adr len fs-blk# -- ) /block * dev-ih read-disk ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ HSFS directory routines
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Current directory variables.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock instance variable cdir-blk \ Current directory device block ptr.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock instance variable cdir-blk0 \ Current directory block0.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock instance variable cdir-offset \ Current directory logical offset.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock instance variable cdir-size \ Current directory logical size.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock instance variable cdir-ptr \ Current directory entry pointer.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock false instance value cdir-rescan \ Rescan current directory for symlink.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Access of current directory entry.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : +dr ( n -- adr ) cdir-ptr @ + ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-entrylen ( -- n ) d# 0 +dr c@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-block0 ( -- n ) d# 2 +dr xl@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-filesize ( -- n ) d# 10 +dr xl@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-flags ( -- n ) d# 25 +dr c@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-filenamelen ( -- n ) d# 32 +dr c@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-filename ( -- adr ) d# 33 +dr ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-isdir? ( -- flag ) dir-flags h# 02 and 0<> ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-file$ ( -- adr len ) dir-filename dir-filenamelen ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-sualen ( -- len ) dir-entrylen d# 33 - dir-filenamelen - ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ ISO name, including dot & dot-dot check
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir-iso$ ( -- adr len )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-filenamelen 1 = if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-filename c@ ( name[0] )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop " ." exit ( dot )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock " .." exit ( dot-dot )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-file$ ( name$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock false instance value symlink?
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : get-dirblk ( -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-buf /block cdir-blk @ read-fs-blocks
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 1 cdir-blk +!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : froot ( -- ) root-dir cdir-ptr ! ;
9af3851a3a831b4de34b42482c22351e14f33f16eschrock \ SUAs - System Use Area in directory entry (Rock Ridge
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Extensions to High Sierra/ISO 9660 Format).
9af3851a3a831b4de34b42482c22351e14f33f16eschrock \ Immediately follows directory entry name rounded up to
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ a half-word boundary.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 instance value sua-ptr
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 instance value sua-len
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : +suf ( n -- adr ) sua-ptr + ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-sig ( -- adr len ) sua-ptr 2 ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-len ( -- len ) 2 +suf c@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-dat ( -- data ) 5 +suf ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-ce-lbn ( -- lbn ) 4 +suf xl@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-ce-offset ( -- offset ) d# 12 +suf xl@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-ce-len ( -- len ) d# 20 +suf xl@ ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : init-sua ( -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-file$ + /w roundup to sua-ptr
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-sualen to sua-len
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : next-suf ( -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock sua-len suf-len - to sua-len
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-len +suf to sua-ptr
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : end-sua ( -- end? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock sua-len 4 <
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-nm$ ( -- adr len ) suf-dat suf-len 5 - ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Continuation suffix handling. When a 'CE' suffix is seen,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ record the CE parameters (logical block#, offset and length
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ of continuation). We process the CE continuation only after
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ we've finished processing the current SUA area.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock instance variable ce-lbn
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock instance variable ce-offset
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock instance variable ce-len
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-ce-set ( -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-ce-lbn ce-lbn !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-ce-offset ce-offset !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-ce-len ce-len !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-ce-process ( -- error? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ce-lbn @ 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock sua-buf ce-len @ ce-lbn @ read-fs-blocks
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock sua-buf to sua-ptr
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ce-len @ to sua-len
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 ce-len ! 0 ce-lbn ! 0 ce-offset !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /buf-len instance buffer: suf-sl-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock false instance value symlink-need-sep
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Format of Rock Ridge symlinks needs to be munged to unix-style
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ name. Format is: <flag><nbytes>file-name<flag><nbytes>filename...
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ where \ <flag> is flag byte (0=filename, 2=current dir, 4=parent
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ dir, 8=root dir) and <nbytes> is one-byte byte count (zero for
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ !filename).
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : suf-copy-to-symlinkbuf ( name$ -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock false to symlink-need-sep
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-sl-buf -rot bounds do ( dst )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock symlink-need-sep if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ascii / over c! char+
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock true to symlink-need-sep
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock i c@ dup 2 = if ( dst 2 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ CURRENT (".")
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop ascii . over c! char+ 2 ( dst' inc )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock else dup 4 = if ( dst 4 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ PARENT ("..")
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop " .." 2 pick swap move ( dst )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock wa1+ 2 ( dst' inc )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock else dup 8 = if ( dst 8 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ ROOT ("/")
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop ascii / over c! char+ 2 ( dst' inc )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock false to symlink-need-sep
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock else dup 0<> if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ." unknown SL flag: " .x cr abort
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock else ( dst c )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop ( dst )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock i char+ dup c@ >r ( dst src+1 R:nbytes )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock char+ over r@ move ( dst R:nbytes )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock r@ + ( dst' R:nbytes )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock r> wa1+ ( dst' inc )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then then then then
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock +loop ( dst )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Saved 'NM' prefix buffer.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /buf-len instance buffer: suf-nm-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 instance value suf-nm-size
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Return the Rock Ridge file name associated with the current
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ dirent ('NM' suffix). Otherwise returns standard iso filename.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Marks whether returned filename is a symbolic link ('SL' suffix)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ and also processes continuations ('CE' suffix).
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : rr-file$ ( -- adr len )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock false to symlink?
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 to suf-nm-size
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ select start of sua, record sua offset
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-ce-process if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-nm-size if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-nm-buf suf-nm-size ( NM$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-iso$ ( iso$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( file$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-sig ( sig-adr sig-len )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2dup " NM" $= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-nm$ to suf-nm-size ( sig-adr sig-len suf-nm-adr )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-nm-buf suf-nm-size move
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( sig-adr sig-len )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2dup " SL" $= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock true to symlink?
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-nm$ suf-copy-to-symlinkbuf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2dup " CE" $= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( sig-adr sig-len )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2drop next-suf ( )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ HSFS high-level routines
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Used for rescanning current directory for symbolic links.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Initializes current directory settings from current directory
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ entry pointer or for rescan. If it's not a rescan, we have
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ access to the actual directory entry, so we can check whether
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ it's a directory or not here.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : init-dent ( -- error? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cdir-rescan if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock false to cdir-rescan
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cdir-blk0 @ cdir-blk !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-isdir? 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-block0 dup cdir-blk ! cdir-blk0 !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-filesize cdir-size !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( blk0 size )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 cdir-offset !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : get-dent ( -- error? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Check for end of directory, return true if we're past the EOF.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cdir-offset @ cdir-size @ >= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ If we're at a block boundary, get the next block. Otherwise
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ increment the directory pointer.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cdir-offset @ byte>blkoff 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-buf cdir-ptr !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-entrylen cdir-ptr +!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ If dir-entrylen is not zero, increment the current directory
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ file offset. Otherwise, a dir-entrylen of zero indicates
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ the end of a dir block, so round up cdir-offset to fetch the
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-entrylen ?dup if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cdir-offset +! true
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cdir-offset @ /block roundup cdir-offset !
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock until false
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Look through current directory for file name 'file$'.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Will leave current directory entry (cdir-ptr) pointing
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ to matched entry on success.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dirlook ( file$ -- error? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock init-dent if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock begin get-dent 0= while ( file$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2dup rr-file$ $= if ( file$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2drop false exit ( succeeded )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( file$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock repeat 2drop true ( failed )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /buf-len instance buffer: symlink-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : symlink-buf$ ( -- path$ ) symlink-buf cscount ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : follow-symlink ( tail$ -- tail$' )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ copy symlink value (plus null) to buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock suf-sl-buf cscount 1+ symlink-buf swap move
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock false to symlink?
9af3851a3a831b4de34b42482c22351e14f33f16eschrock \ append to current path
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ?dup if ( tail$ )
9af3851a3a831b4de34b42482c22351e14f33f16eschrock " /" symlink-buf$ $append ( tail$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock symlink-buf$ $append ( )
9af3851a3a831b4de34b42482c22351e14f33f16eschrock else drop then ( )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock symlink-buf$ ( path$ )
9af3851a3a831b4de34b42482c22351e14f33f16eschrock over c@ ascii / = if ( path$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock froot str++ ( path$' )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock true to cdir-rescan
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( path$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : lookup ( path$ -- error? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock over c@ ascii / = if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock froot str++ ( path$' )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( path$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock begin ( path$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ascii / left-parse-string ( path$ file$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup while ( path$ file$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2drop true exit ( failed )
9af3851a3a831b4de34b42482c22351e14f33f16eschrock then ( path$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock symlink? if
9af3851a3a831b4de34b42482c22351e14f33f16eschrock follow-symlink ( path$' )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( path$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock repeat ( path$ file$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2drop 2drop false ( succeeded )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ HSFS installation routines
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Allocate memory for necessary data structures. Need to
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ read volume desriptor sector in order to get /block value.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : initialize ( -- error? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /sector mem-alloc to vol-desc
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock get-vol-desc
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /block mem-alloc to dir-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /block mem-alloc to sua-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /block mem-alloc to ce-buf
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : release-buffers ( -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ce-buf /block mem-free
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock sua-buf /block mem-free
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-buf /block mem-free
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock vol-desc /sector mem-free
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 to vol-desc
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ HSFS file interface
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /x field >filesize
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /x field >offset
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /x field >block0
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock constant /file-record
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock d# 10 constant #opens
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock #opens /file-record * constant /file-records
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock /file-records instance buffer: file-records
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock -1 instance value current-fd
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : fd>record ( fd -- record ) /file-record * file-records + ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : set-fd ( fd -- error? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup 0 #opens 1 - between 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop true exit
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup fd>record >block0 x@ 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop true exit
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock to current-fd false
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : file-offset@ ( -- off )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock current-fd fd>record >offset x@
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : file-offset! ( off -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock current-fd fd>record >offset x!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : file-size@ ( -- size )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock current-fd fd>record >filesize x@
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : file-size! ( size -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock current-fd fd>record >filesize x!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : file-block0@ ( -- block0 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock current-fd fd>record >block0 x@
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : file-block0! ( block0 -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock current-fd fd>record >block0 x!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : get-slot ( -- fd false | true )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock #opens 0 do
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock i fd>record >block0 x@ 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock i false unloop exit
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : free-slot ( fd -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock set-fd 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 file-offset!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 file-size!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 file-block0!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ initializes the open structure with information from
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ the inode (on UFS) or directory entry (from HSFS).
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : init-fd ( fd -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock to current-fd
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-block0 file-block0!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-filesize file-size!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 0 file-offset!
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : open ( -- okay? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock my-args dev-open dup 0= if ( 0 )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock exit ( failed )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then to dev-ih
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock initialize froot
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock file-records /file-records erase
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock true ( succeeded )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : close ( -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dev-ih dev-close
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock release-buffers
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : open-file ( path$ -- fd true | false )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock get-slot if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2drop false exit ( failed )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then -rot ( fd path$ )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock lookup if ( fd )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop false exit ( failed )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup init-fd true ( fd success )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : close-file ( fd -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock free-slot ( )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : read-file ( adr len fd -- #read )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Check if fd is valid, if it is set current-fd.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2drop 0 exit
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( adr len )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Adjust len if less than len bytes remain.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock file-size@ file-offset@ - min ( adr len' )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Check for invalid length read.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup 0<= if 2drop 0 exit then
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ Compute physical device byte offset.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock tuck ( len adr len )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock file-block0@ /block * file-offset@ + ( len adr len off )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dev-ih read-disk ( #read )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : seek-file ( off fd -- error? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock set-fd if ( off )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop false exit ( failed )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( off )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup file-size@ > if ( off )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock drop false exit ( failed )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock then ( off )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dup file-offset! true ( off succeeded )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : size-file ( fd -- size )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ we don't support compression (yet)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : cinfo-file ( fd -- bsize fsize comp? )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock set-fd if 0 0 0 else /block file-size@ 0 then
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ read ramdisk fcode at rd-offset
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : get-rd ( adr len -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock rd-offset dev-ih read-disk
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ no additional props needed for hsfs
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : bootprop ( -- ) false ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock \ debug words
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : chdir ( path$ -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 2dup lookup if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock type ." Not found" cr
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dir-isdir? 0= if
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock type ." Not a directory" cr
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cdir-blk0 @ .x
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cdir-size @ .x
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock : dir ( -- )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock begin get-dent 0= while
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock rr-file$ type
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ." flags " dir-flags .x
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ." blk0 " dir-block0 .x
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ." size " dir-filesize .x
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock true to cdir-rescan
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockfinish-device