home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol004
/
dupusr2.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
7KB
|
272 lines
; title 'dupusr - duplicate a directory entry under a new user'
; by Bruce R. Ratoff - first version 5/17/80
; modified 5/17/80 for wildcard processing
; modified 5/18/80 to zero drive number before making file.
; modified 5/18/80 to operate from originating user #
; modified 6/3/80 to fix problem w/ multi-extent files
;
; The purpose of this program is to create extra entries in a CP/M 2.x
; directory that "point to" files which were actually created in a
; different directory. This way, you have access to the file from
; both user numbers without having to keep multiple copies of the
; actual file itself. To create duplicate entries on drive "d" for
; user "x" from files which currently reside at user "y", type:
; A>USER y ;log in to originating user y
; A>DUPUSR d:filename.typ x ;create files at destination user x
; Note that this program will totally duplicate the directory entry in
; all respects (except the user number, of course). This means that
; both entries will show the file with the same attributes, such as
; "read-only" or "system". The filename.typ may contain "?" and "*".
;
; The only known hazard in the use of this program occurs when erasing
; one of the duplicate entries. You must type control-c immediately
; after erasing the entry, so that cp/m is forced to rebuild the allocation
; vector for that drive. This is because the erase command frees the
; blocks shown for the erased file without checking if they are in use
; elsewhere. If you didn't type control-c, the next disk write would
; clobber these blocks, voiding all other pointers to the file.
; Unfortunately this would only be apparent the next time you tried
; to read the file from another user number, at which time you would
; read garbage.
;
; Please forward all comments, suggestions and improvements to:
; Bruce R. Ratoff
; 80 Gill Lane, Apt 1B
; Iselin, New Jersey 08830
;
;
;
bdos equ 5 ;cp/m entry point
exit equ 0 ;cp/m exit point
dfcb equ 5ch ;cp/m default fcb
dbuff equ 80h ;default disk buffer
;
pmessg equ 9 ;print message function
seldsk equ 14 ;select drive function
open equ 15 ;open file function
close equ 16 ;close file function
srchfst equ 17 ;search for first file match
srchnxt equ 18 ;search for next file match
delete equ 19 ;delete file function
make equ 22 ;make file function
attrib equ 30 ;set file attributes function
gsuser equ 32 ;get/set user function
;
;
org 100h
begin:
lhld bdos+1 ;set up a stack
sphl ;at top of tpa
mvi c,gsuser ;get our user #
mvi e,0ffh
call bdos
sta ourusr ;save for later
lda dfcb ;check for specific drive
dcr a
mov e,a ;set up for select disk call
mvi c,seldsk
inr a ;if no specified drive, skip call
cnz bdos
sub a ;now zap out drive spec
sta dfcb
mvi a,'?' ;force extent number wild
sta dfcb+12
lxi h,dfcb+17 ;point to originating user # in cmd line
mvi e,0
numlup:
mov a,m ;get numeric (i hope) character
inx h ;bump char pointer
sui '0' ;remove ascii bias
jc numdone
cpi 10 ;check if past 9
jnc numdone ;any invalid char ends number
mov d,a
mov a,e ;get accumulated number
add a ;times two
add a ;times four
add e ;times five
add a ;times ten
add d ;plus new digit
mov e,a ;save accumulation
jmp numlup ;loop back for next char
numdone:
lda ourusr ;make sure not same as us
cmp e
jz badusr
mov a,e ;get destination user number
sta dstusr ;save it
cpi 16 ;legal?
jc userok
badusr:
lxi d,ilgusr
mvi c,pmessg ;bitch about illegal user #
call bdos
jmp exit
ilgusr:
db 'Invalid destination user #$'
userok:
sub a ;zero out file count
sta filcnt
lxi d,dfcb ;find the first file and get its block map
mvi c,srchfst
call bdos
inr a ;search successful?
jnz gotfile ;yes, go process rest
lxi d,nofile
mvi c,pmessg ;say "no file"
call bdos
jmp exit
nofile:
db 'Originating file not found$'
gotfile:
dcr a ;compensate for inr above
rrc ;file offset to bits 5 and 6
rrc
rrc
ani 60h
lxi h,dbuff ;point to base of buffer
mov c,a
mvi b,0
dad b ;index by file offset
push h ;save for the moment
lxi b,filetable
call filepoint ;get table pointer to hl
xchg ;de now points to place in table
lda filcnt
inr a
sta filcnt ;bump file count
pop h ;hl points to directory entry
mvi b,32
call blkmov ;copy entry into table
mvi c,srchnxt ;search for another entry
lxi d,dfcb
call bdos
inr a ;returns 0ffh at end of search
jnz gotfile ;got another one...go save it
;
; end of directory encountered, now process them
;
lda dstusr ;set to dest user
mov e,a
mvi c,gsuser
call bdos
;
; main loop to set up one duplicate entry
;
makefile:
lxi b,filetable-32 ;allow for filcnt one greater than desired
call filepoint
push h ;save pointer
lxi d,dfcb ;copy next name to default fcb
mvi b,32
call blkmov
sub a
sta dfcb ;clear drive number
lxi d,-20 ;point back to extent field
dad d
mvi m,'$' ;tag end of print here
pop d ;get back pointer to start of entry
inx d ;bump fwd to name
mvi c,pmessg
call bdos ;say what we're working on
lxi h,dfcb
lxi d,ourfcb ;copy name data to work fcb
mvi b,14
call blkmov
lxi h,0
shld ourfcb+14 ;zap frebyt, extlen
lda ourfcb+9
ani 7fh ;clear r/o flag for create
sta ourfcb+9
sub a
sta ourfcb ;clear drive number
lxi d,ourfcb
mvi c,open
call bdos ;check for existing file of same name
inr a
jnz makeok ;skip create if already there
lxi d,ourfcb
mvi c,make ;create the file
call bdos
inr a ;check for errors
jnz makeok
lxi d,makerr
mvi c,pmessg ;say can't make file
call bdos
jmp exit
makerr:
db ', Cannot create file$'
makeok:
lxi h,dfcb+12 ;copy bookkeeping stuff from orig file
lxi d,ourfcb+12
mvi b,20
call blkmov
lda ourfcb+14 ;set update flag so that altered fcb
ani 1fh ;gets written by close function
sta ourfcb+14 ;(retain module # in low 5 bits)
lxi d,ourfcb
mvi c,close ;do a close to set size and block map
call bdos
inr a
jnz closok ;check for errors
lxi d,closerr
mvi c,pmessg
call bdos ;say close error
jmp exit
closerr:
db ', Cannot close file$'
closok:
lda dfcb+9 ;was original file r/o?
ora a ;set sign bit if yes
jp nextfile ;done if no
sta ourfcb+9 ;make our new file r/o to match
lxi d,ourfcb
mvi c,attrib ;do set attributes call
call bdos
nextfile:
lxi h,filcnt ;point to file counter
dcr m ;count it down
jz exit ;exit if done
lxi d,crlf
mvi c,pmessg ;else do a crlf
call bdos
jmp makefile ;and go work on next one
crlf:
db 13,10,'$'
;
;
; subroutine to do block moves
blkmov:
mov a,m ;copy byte from m(hl) to m(de)
stax d
inx h ;bump pointers
inx d
dcr b ;loop for count in b
jnz blkmov
ret
;
;
; subroutine to index bc by file counter
filepoint:
lhld filcnt ;get file counter
mvi h,0 ;force hi ord to 0
dad h ;multiply by 32
dad h
dad h
dad h
dad h
dad b ;use as index to file table
ret
;
;
;
;
filcnt: ds 1 ;count of files in filetable
ourusr: ds 1 ;storage for our user number
dstusr: ds 1 ;storage for destination user number
ourfcb: ds 32 ;file control block for create function
;
filetable equ $ ;start table here, take all avail memory
;
end