updates to help find a file by path...

This commit is contained in:
Kelvin Sherlock 2015-08-16 16:10:30 -04:00
parent 66a91ae8fc
commit e5d9047073
7 changed files with 385 additions and 55 deletions

View File

@ -2,7 +2,7 @@
SOURCES = main.aii volume.aii get_file_info.aii \ SOURCES = main.aii volume.aii get_file_info.aii \
open.aii get_dir_entry.aii close.aii \ open.aii get_dir_entry.aii close.aii \
id_disk.aii stubs.aii tables.aii device.aii params.aii id_disk.aii stubs.aii tables.aii device.aii params.aii data.aii
OBJECTS=$(SOURCES:.aii=.o) OBJECTS=$(SOURCES:.aii=.o)

13
data.aii Normal file
View File

@ -0,0 +1,13 @@
case on
include 'records.equ'
data record
export target
target ds GSString32
endr
end

View File

@ -1,3 +1,10 @@
;
; This file contains the implementation of get_dir_entry.
; It also contains other functions for finding an entry within
; a directory.
;
case on
include 'gsos.equ' include 'gsos.equ'
include 'minix.equ' include 'minix.equ'
@ -10,6 +17,10 @@
include 'records.equ' include 'records.equ'
include 'p.equ' include 'p.equ'
; ;
; dirent_entry 0 is a special case. ; dirent_entry 0 is a special case.
; (assuming base = 1, displacement = 1) ; (assuming base = 1, displacement = 1)
@ -26,7 +37,10 @@
; dirent_entry = 2, dirent_zone = ..., dirent_offset = ... ; dirent_entry = 2, dirent_zone = ..., dirent_offset = ...
; ;
gde_dp record dp.__end ; don't think this needs to be dp... move to a normal record.
data record
; size of the directory, divided by dirent_size. ; size of the directory, divided by dirent_size.
@ -39,15 +53,8 @@ dirent_zone ds.w 1
dirent_offset ds.w 1 dirent_offset ds.w 1
dirent_entry ds.w 1 dirent_entry ds.w 1
IF *>=$d4 THEN
AERROR 'dp -- too large.'
ENDIF
endr
data record
dirent ds v1L_dirent dirent ds v1L_dirent
endr endr
@ -82,11 +89,13 @@ dirent ds v1L_dirent
entry do_name_buffer_1 entry do_name_buffer_1
entry do_entry_num entry do_entry_num
entry sparse_dirent_block
get_dir_entry procname export get_dir_entry procname export
with fst_parms with fst_parms
with dp with dp
with gde_dp with data
;~DebugSetTrace #1 ;~DebugSetTrace #1
@ -217,7 +226,7 @@ get_dir_entry_dcb_1
init proc init proc
with fst_parms,dp,gde_dp with fst_parms,dp,data
lda device lda device
sta dev_parms.dev_num sta dev_parms.dev_num
@ -305,7 +314,7 @@ minix
base_displace proc base_displace proc
with fst_parms, dp with fst_parms, dp
with gde_dp with data
; offset is $04 for class 0, $06 for class 1 ; offset is $04 for class 0, $06 for class 1
lda #$04 lda #$04
@ -368,7 +377,7 @@ count_entries proc
; count the number of entries. ; count the number of entries.
with fst_parms with fst_parms
with dp, gde_dp with dp, data
; read each block and count the entries. ; read each block and count the entries.
; only handles direct blocks. so there. ; only handles direct blocks. so there.
@ -378,27 +387,26 @@ count_entries proc
stz dirent_entry stz dirent_entry
ldx #0 ldx #0
zone_loop zone_loop
stx dirent_zone
lda disk_inode.zone,x lda disk_inode.zone,x
beq next ; directory should not be sparse! bne @ok ; directory should not be sparse!
; sparse!
jsr sparse_dirent_block
bcs done
bra next
phx ; save @ok
jsr read_data_block jsr read_data_block
plx ; and restore
bcs exit bcs exit
; phx
; phy
; pha
; ~DebugHexDump <io_buffer, #1024 ; ~DebugHexDump <io_buffer, #1024
; pla
; ply
; plx
jsr count_dirent_block jsr count_dirent_block
lda size lda size
beq done beq done
next next
ldx dirent_zone
inx inx
inx inx
cpx #v1.NR_DZONES*2 cpx #v1.NR_DZONES*2
@ -428,7 +436,7 @@ exit
count_dirent_block proc count_dirent_block proc
; 16-byte dirent entries -- 64 per block. ; 16-byte dirent entries -- 64 per block.
with dp, gde_dp with dp, data
ldy #0 ldy #0
loop loop
@ -457,7 +465,6 @@ done
strlen proc strlen proc
; strlen the dirent. ; strlen the dirent.
; will be 0-terminated unless if < dirent size. ; will be 0-terminated unless if < dirent size.
with gde_dp
lda data.dirent.inode lda data.dirent.inode
beq exit beq exit
@ -468,7 +475,7 @@ loop
lda data.dirent,x lda data.dirent,x
beq zero beq zero
inx inx
cpx dirent_size cpx data.dirent_size
bcc loop bcc loop
zero zero
long m long m
@ -480,6 +487,7 @@ zero
exit exit
rts rts
endp endp
do_flags proc do_flags proc
with fst_parms with fst_parms
@ -491,7 +499,7 @@ do_flags proc
do_entry_num proc do_entry_num proc
with fst_parms with fst_parms
with gde_dp with data
lda dirent_entry lda dirent_entry
sta [param_blk_ptr],y sta [param_blk_ptr],y
@ -621,7 +629,7 @@ exit
; ;
; ;
find_absolute_dirent proc find_absolute_dirent proc
with gde_dp with data
; if displacement > dirent_entry, we can re-use that info. ; if displacement > dirent_entry, we can re-use that info.
lda displacement lda displacement
@ -642,7 +650,7 @@ no
endp endp
find_next_dirent proc find_next_dirent proc
with gde_dp, dp with data, dp
lda dirent_entry lda dirent_entry
beq @first beq @first
@ -653,6 +661,10 @@ find_next_dirent proc
bmi eod bmi eod
@ok @ok
; make sure dir not empty (should never happen...)
lda size
beq eod
ldx dirent_zone ldx dirent_zone
loop loop
@ -674,8 +686,10 @@ loop
jsr find_dirent_block jsr find_dirent_block
bcs exit bcc next
bvc found_it ; a = 0 if it was found!
cmp #1
rts
next next
inx inx
@ -684,27 +698,11 @@ next
cpx #v1.NR_DZONES*2 cpx #v1.NR_DZONES*2
bcs exit bcs exit
; also check size
lda size
beq eod
bmi eod
bra loop bra loop
sparse sparse
; should never happen... jsr sparse_dirent_block
; skip over 1 block. bcs eod
; size -= dirents per block -- 32 for linux, 64 for minix
lda dirent_size ; 16 or 32. 32 -> 32, 16 -> 64.
cmp #32
beq @ok
lda #64
@ok
eor #$ffff
sec ; + 1
adc size
sta size
bra next bra next
@ -723,12 +721,12 @@ eod
; ;
; returns: ; returns:
; carry set on error. ; carry set on error or if found.
; overflow clear if found ; a = 0 if found, or error.
; ;
; inputs y = dirent offset ; inputs y = dirent offset
find_dirent_block proc find_dirent_block proc
with dp, gde_dp with dp, data
ldy dirent_offset ldy dirent_offset
loop loop
@ -753,7 +751,6 @@ next
lda #0 lda #0
clc clc
sep #p.v
rts rts
eod eod
@ -797,12 +794,183 @@ found_it
sta [my_fcr],y sta [my_fcr],y
lda #0 lda #0
clc sec ; found!
clv
rts rts
endp endp
strcmp proc
; clobbers ptr
; check if the name is even possible...
with dp
import target:GSString32
ldx target.length
beq no
; dirent size is DIRSIZE + 2. -1
; to compare >= DIRSIZE+1
lda data.dirent_size
dec a
cmp target.length
bcs no
iny ; skip inode
iny
tya
clc
adc io_buffer
sta ptr
adc io_buffer+2
sta ptr+2
ldx target.length
beq no
ldy #0
short m
; y = offset
; x = length of target string.
loop
lda [ptr],y
beq eos
cmp target.text,y
bne no8
iny
dex
bne loop
long m
yes
clc
rts
eos
long m
; end of string. if x = 1, it's a match!
dex
beq yes
no8
long m
no
sec
rts
endp
sparse_dirent_block proc
; (not 32-bit safe)
; decrease size by the appropriate amount
; for a sparse block.
; (should probably never happen!)
; sets c if size <= 0
with data
lda dirent_size
cmp #32 ; linux? 32 dirents per block
beq @ok
lda #64 ; minix? 64 dirents per block
@ok
eor #$ffff
sec
adc size
sta size
bmi eod
beq eod
clc
rts
eod
sec
rts
endp
find_entry_by_name proc export
; scan the directory and search by name...
with dp
with data
jsr init
lda size
beq fnf
bmi fnf
ldx #0
block_loop
; x = dirent_zone
stx dirent_zone
lda disk_inode,x
beq sparse
jsr read_data_block
bcc @ok
rts
@ok
ldy #0
dirent_loop
; y = dirent offset
sty dirent_offset
lda [io_buffer],y
beq next_dirent
sta inode ; optomistic...
jsr strcmp
bcs next_dirent
; found it!
lda #0
clc
rts
next_dirent
dec size
beq fnf
lda dirent_offset
clc
adc dirent_size
tay
cmp #1024
bcs next_zone
bra dirent_loop
next_zone
ldx dirent_zone
inx
inx
cpx #v1.NR_DZONES*2
bcc block_loop
; all out of zones -> not found!
fnf
stz inode
lda #file_not_found
sec
rts
sparse
; sparse block. jump to the next zone, decrement size appropriately.
jsr sparse_dirent_block
bcs fnf
bra next_zone
endp
end end

View File

@ -1,4 +1,5 @@
case on
include 'gsos.equ' include 'gsos.equ'
include 'minix.equ' include 'minix.equ'
@ -199,12 +200,21 @@ ok
endp endp
;
; sets inode, parent_inode, disk_inode,
; if file not present but path is otherwise, ok (eg, create),
; parent inode and disk_inode will be valid for the parent directory.
;
; uses path1, dev1, span1.
;
path_to_inode proc export path_to_inode proc export
with dp,fst_parms with dp,fst_parms
path equ path1_ptr path equ path1_ptr
dev_num equ dev1_num dev_num equ dev1_num
span equ span1
stz inode stz inode
lda #1 lda #1
@ -232,6 +242,11 @@ bps
rts rts
check_path check_path
lda span
cmp #v1L.DIRSIZE+1
bcs bps
; but is it relative? ; but is it relative?
lda [path] lda [path]
@ -245,6 +260,10 @@ check_path
lda dev_num lda dev_num
bne bps bne bps
jsr id_disk jsr id_disk
;
; now find the actual file...
;
;
rts rts
absolute absolute
@ -261,4 +280,111 @@ absolute
endp endp
find_file proc
with dp
import find_entry_by_name
path equ fst_parms.path1_ptr
dev_num equ fst_parms.dev1_num
span equ fst_parms.span1
import target:GSString32
stz more
stz path_offset
; we always need to load inode 1
lda #1
sta inode
jsr load_inode
_rts.cs
dir_loop
lda inode
sta parent_inode
; get a path component.
ldx #0
ldy #path_offset
path_loop
lda [path],y
beq eop
cmp #':'
beq eop
sta target.text,x
inx
bra path_loop
eop
sta more
long m
stx target.length
sty path_offset
and #$00ff
; a = ':' or 0 ... worry about which later!
; target is valid, inode is valid, is target in inode?
jsr find_entry_by_name
bcc @ok
; may be file_not_found, may be path_not_found.
ldx more
beq @exit
lda #path_not_found
@exit
sec
rts
@ok
; inode, has been updated.
jsr load_inode
_rts.cs
lda more
beq done
; more to go...
; this is a directory, right?
lda disk_inode.mode
and #S_IFMT
cmp #S_IFDIR
beq dir
lda #path_not_found
sec
rts
dir
; skip the ':'
short m
ldy path_offset
loop
lda [path],y
beq @ok
cmp #':'
bne @ok
iny
bra loop
@ok
long m
sty path_offset
bra dir_loop
done
clc
rts
path_offset ds.w 1
more ds.w 1
endp
end end

View File

@ -1,4 +1,5 @@
case on
include 'gsos.equ' include 'gsos.equ'
include 'minix.equ' include 'minix.equ'

View File

@ -19,6 +19,25 @@ __sizeof equ __end - __begin
mend mend
GSString255 begin_struct
length DS.W 1 ; Word - Number of Chars in text field
text DS.B 255 ; char[255] -
end_struct
GSString32 begin_struct
length DS.W 1 ; Word - Number of characters in text field
text DS.B 32 ; char[32] -
end_struct
ResultBuf255 begin_struct
bufSize DS.W 1
bufString DS GSString255
end_struct
ResultBuf32 begin_struct
bufSize DS.W 1
bufString DS GSString32
end_struct
TimeRec begin_struct TimeRec begin_struct
second DS.B 1 second DS.B 1

View File

@ -1,3 +1,6 @@
case on
include 'gsos.equ' include 'gsos.equ'
stubs proc stubs proc