home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
asm
/
chasm
/
chmod.asm
< prev
next >
Wrap
Assembly Source File
|
1986-03-08
|
13KB
|
370 lines
;================================================
; CHMOD Version 2.0 3/8/86
;
; by David Whitman
;
; Utility to examine and modify the read/write
; mode of a file under DOS 2.0.
;
; Syntax:
;
; CHMOD [d:][path] [filespec] [/N] [/R] [/S] [/H]
;
; If no file is specified, a help message is printed,
; summarizing the CHMOD command syntax.
;
; The attribute byte of the specified file is set
; according to the selected options:
;
; /N - normal file
; /R - read only
; /S - system file
; /H - hidden file
;
; Multiple options may be selected. /N will cancel
; options preceding it in the command line.
;
; If no options are selected, a report on the current
; mode of the specified file is sent to the standard output.
;
; On exit, ERRORLEVEL is set to reflect the current file
; mode, and/or the success of the change, as follows:
;
; normal file --> 0
; read only file --> 1
; hidden file --> 2
; system file --> 4
; failed operation --> 8
;
; Requires DOS 2.0, will abort under earlier versions.
;
; This source file is in CHASM assembler syntax.
;======================================================
;==========
; EQUATES
;==========
@chmod equ 43H ;change file mode
@dosver equ 30H ;get DOS version number
@exit equ 4CH ;set ERRORLEVEL and exit
@prnstr equ 09H ;print string
normal equ 00H
readonly equ 01H
hidden equ 02H
system equ 04H
failure equ 08H
true equ 0FFH ;boolean values
false equ 00H
cr equ 0DH ;carriage return
lf equ 0AH ;line feed
beep equ 07H ;bell
param_area equ [81H] ;unformatted parameter area
param_count equ [80H] ;number of characters in above
;===========================================================
chmod proc near
call chkdos ;test for proper DOS
call parsefile ;parse path/filename
call options ;parse options, set flags
call doit ;perform specified action
call cleanup ;final processing, exit
call set_errlev ;set errorlevel value in AL
mov ah, @exit ;and exit
int 21H
endp
;=================================================
; SUBROUTINE CHKDOS
; Checks for proper DOS, exits if not 2.0 or above
;=================================================
chkdos proc near
mov ah, @dosver ;get dos version number
int 21H ;with dos call
cmp al, 2 ;2.0 or over?
jae a1 ;yes, skip
mov ah, @prnstr ;no, bitch
mov dx, offset(baddos) ;point to message
int 21H ;and print it
pop ax ;reset stack
int 20H ;and exit
a1
ret
baddos db beep, cr, lf, 'This program requires DOS 2.0!' cr, lf, '$'
endp
;===================================================
; SUBROUTINE PARSEFILE
; Scans the parameter area for a path/filename.
; Sets PATHPTR to point to the name, and terminates
; it with a 0, to make an ASCIIZ string.
;
; If no name is found, ERRORLEVEL is set to 8,
; and control is passed back to DOS.
;===================================================
parsefile proc near
xor ch,ch ;cx <== # of parameter characters
mov cl, param_count ; "
mov di, offset(param_area)
mov al, ' ' ;search for first non-blank
rep
scasb
jcxz berror ;nothing? bitch
dec di ;back up to character found
inc cx ; "
cmpb [di], '/' ;are we into the options?
jne b1 ;no, skip
berror mov ah, @prnstr ;yes, print help message
mov dx, offset(nofile)
int 21H
pop ax ;reset stack
mov ah, @exit ;set error level and exit
mov al, failure
int 21H
b1
mov pathptr, di ;otherwise point to pathname
repne ;now search for next blank
scasb
jcxz b2 ;reached end of data?
dec di ;nope, back up to last non-blank
inc cx ; "
b2 movb [di], 00H ;ASCIIZ string terminator
ret
pathptr dw 0000H ;pointer to path/filename
nofile db cr, lf
db 'CHMOD version 2.0' cr lf
db cr lf
db 'Syntax: CHMOD [d:][path] [filespec] [/N] [/R] [/S] [/H]'
db cr lf cr lf
db 'The attribute byte of the specified file is set' cr lf
db 'according to the selected options:' cr lf
db cr lf
db ' /N - normal file' cr lf
db ' /R - read only' cr lf
db ' /S - system file' cr lf
db ' /H - hidden file' cr lf
db cr lf
db 'Multiple options may be selected.' cr lf
db cr lf
db 'If no options are specified, a report of the current' cr lf
db 'attributes is printed, and ERRORLEVEL is set to the' cr lf
db 'value of the attribute byte.' cr lf
db '$'
endp
;=====================================================
; SUBROUTINE OPTIONS
; Scans the command line for options, and builds
; the new attribute byte in NEWATTRIB.
;
; If options are found, OPFOUND is set true, otherwise
; it remains false.
;======================================================
options proc near
;cx still has number of chars. left,
;di points to current position.
c1 mov al, '/' ;options marked with '/'
repnz ;scan for options
scasb
jcxz cexit ;reached end
mov al, [di] ;get option character
and al, 0DFH ;guarantees upper case
cmp al, 'N' ;normal file?
jne c2 ;no, skip
movb newattrib, normal ;yes, clear all bits
movb opfound, true ;set found flag
jmps c1 ;and loop
c2 cmp al, 'R' ;read only?
jne c3 ;no, skip
orb newattrib, readonly ;yes, set option flag
movb opfound, true ;set found flag
jmps c1 ;and loop
c3 cmp al, 'S' ;system?
jne c4 ;no, skip
orb newattrib, system ;yes, set option flag
movb opfound, true ;set found flag
jmps c1 ;and loop
c4 cmp al, 'H' ;hidden?
jne c1 ;no, just loop
orb newattrib, hidden ;yes, set option flag
movb opfound, true ;set found flag
jmps c1 ;and loop
cexit ret
newattrib db 00H ;options selected - new attribute byte
opfound db 00H ;if non-zero, an option was decoded
endp
;========================================================
; SUBROUTINE DOIT
; Does the actual work. Either sets new file attribute,
; or reads the existing attribute.
;========================================================
doit proc near
;read the old attributes
mov dx, pathptr ;point DX at ASCIIZ path/filename
mov al, 00H ;read file mode
mov ah, @chmod ;specify CHMOD call
int 21H ;call dos
jc derr ;carry flag means error
and cl, 07H ;OK? mask off high bits
mov oldattrib, cl ;save attribute byte
cmpb opfound, true ;were there any options?
jne dexit ;no? exit
;yes, reset attributes
mov dx, pathptr ;point DX at ASCIIZ path/filename
xor ch, ch ;CX <== new attribute byte
mov cl, newattrib ; "
mov al, 01H ;set file mode
mov ah, @chmod ;specify CHMOD call
int 21H ;call dos
jc derr ;carry flag means error
jmps dexit ;otherwise done
derr cmp al, 02H ;file not found error?
jne d3
mov dx, offset(fnferror)
jmps dabort
d3 cmp al, 03H ;path not found error?
jne d4
mov dx, offset(pnferror)
jmps dabort
d4 cmp al, 05H ;access denied error?
jne dabort
mov dx, offset(aderror)
jmps dabort
mov dx, offset(unkerror) ;not matched? panic
dabort mov ah, @prnstr ;print the error message
int 21H
pop ax ;reset stack
mov al, failure ;set errorlevel
mov ah, @exit ;and abort to dos
int 21H
dexit ret ;normal return
oldattrib db 00H
fnferror db cr, lf, 'File not found.' cr, lf, '$'
pnferror db cr, lf, 'Path not found.' cr, lf, '$'
aderror db cr, lf, 'Access denied.' cr, lf, '$'
unkerror db cr, lf, 'CHMOD internal error.' cr, lf, '$'
endp
;==================================================
; SUBROUTINE CLEANUP
; Reports old and new attributes.
;==================================================
cleanup proc near
mov ah, @prnstr ;print crlf
mov dx, offset(newline)
int 21H
cmpb opfound, true ;were options specified?
jne p_current ;no, so just report current settings
mov ah, @prnstr ;yes, report old attributes...
mov dx, offset(oldheader)
int 21H
mov bl, oldattrib
call print_att
mov ah, @prnstr ;...and the new ones
mov dx, offset(newheader)
int 21H
mov bl, newattrib
call print_att
jmps clean_exit
p_current mov ah, @prnstr ;no options, just report current
mov dx, offset(newheader)
int 21H
mov bl, oldattrib
call print_att
clean_exit ret
newline db cr lf '$'
oldheader db 'Previous Attributes: $'
newheader db 'Current Attributes: $'
endp
;===========================================
; PRINT_ATT
;
; Decodes an attribute byte in BL and prints
; a summary.
;===========================================
print_att proc near
mov ah, @prnstr
test bl, readonly ;read only?
jz e1
mov dx, offset(roattrib) ;print attribute message
int 21H
e1 test bl, system ;system?
jz e2
mov dx, offset(sattrib) ;print attribute message
int 21H
e2 test bl, hidden ;hidden?
jz e3
mov dx, offset(hattrib) ;print attribute message
int 21H
;note: a "normal" byte has none of the bits set,
;so we use CMP rather than TEST
e3 cmp bl, normal ;normal?
jne eexit
mov dx, offset(nattrib) ;print attribute message
int 21H
eexit mov dx, offset(eolstr) ;terminate line
int 21H
ret
roattrib db 'Read only $'
sattrib db 'System $'
hattrib db 'Hidden $'
nattrib db 'Normal $'
eolstr db cr lf cr lf '$'
endp
;===========================================
; SET_ERRLEV
;
; Moves an attribute value into AL
; for output in ERRORLEVEL. If options were
; specified, the new attribute byte is used,
; otherwise the existing value is used.
;============================================
set_errlev proc near
cmpb opfound, true ;options found?
jne se1 ;no, skip
mov al, newattrib ;yes, use new attributes
jmps se_exit
se1 mov al, oldattrib ;no, use old attributes
se_exit ret
endp