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