home *** CD-ROM | disk | FTP | other *** search
- ;------------------------------------------------------------------------
- ; purge.asm from "PC MAGAZIN" #3 vom 8-Jan-86
- ; plus quite a few hours from a non-assembler-programmer
- ; Hans ZURFCC::ZANGGER, SWAS Kloten
- ;
- ; BUG: if purge with just a trailing space and CR is given
- ; beautiful things happen (why not reboot from time to time?)
- ;
- ; ..Was in PARSE which didn't check for End-of-String
- ;
- ; Code - by the way is VERY CLUMSY - this ain't one of the better
- ; examples of assembly language coding ...
- ;
- ; Since code 'rides' on assumption, that 'STACK' handling is supplied
- ; by 'lower-levels' - U need to follow :
- ; MASM PURGE; !Assemble
- ; LINK PURGE; !Link and ignore Warning about missing STACK
- ; EXE2BIN PURGE.EXE PURGE.COM ! Make it non-relocatable/-sharable
- ; DEL PURGE.EXE !Get rid of LINK results
- ; DEL PURGE.OBJ !.. and MASM results.
- ; {B.E. 26-Nov-86}
- ;------------------------------------------------------------------------
- ;
- cseg segment 'code'
- assume cs:cseg, ds:cseg, es:cseg, ss:cseg
-
- org 5ch
- drive equ this byte
-
- org 80h
- command_tail equ this byte
-
- org 100h
-
- last_byte equ offset buffer
- found_file equ offset fcb + 30
- normal equ 20h
- dir equ 10h
- ;
- display macro string
- mov dx, offset string
- mov ah, 09h
- int 21h
- endm
- ;
- read_kbd macro
- mov ah, 08h
- int 21h
- endm
- ;
- display_char macro character
- mov dl, character
- mov ah, 02h
- int 21h
- endm
- ;
- ;------------------------------------------------------------------------
- main: jmp entry
- ;------------------------------------------------------------------------
- help_msg db 13, 10, 'Purge files (Nov 86 hz).', 09h
- db 'Enter Y, N or F11 (ESC)', 13, 10, '$'
- spruch db 'Delete file: $'
- bad_vers db 'Wrong DOS Version (must be V2.xx or higher)$'
- bad_drive db 'Bad Drive$'
- r_only db 'Read Only$'
- i_path db 'Invalid path...$'
- syntax_error db 13, 10, 'Use PURGE [drv:]filnam.ext$'
- search_string db 0, ':', 77 dup (0), '$'
- file_name db 13 dup (0)
- kill_file db 80 dup (0)
- found_flag db 0
- dir_level dw 0
- len db 0
- stardotstar db '*.*', 0
- dta_pointer dw last_byte + 64
- fcb db 43 dup (0)
- crlf db 13, 10, '$'
- string db 2 dup (?) ;1 char + CR
- prompt db ' ?', 08h, '$'
- deleted db 'Yes$'
- notdeleted db 'No$'
- abort_it db 'aborted$'
- space_1 db '.'
- space_2 db ' '
- temp db ' $'
-
- ;------------------------------------------------------------------------
- entry:
- cmp byte ptr [command_tail], 0
- jne bytes_da
- display syntax_error
- jmp short out
-
- bytes_da:
- cmp al, 0ffh
- jnz drive_ok
- lea dx, bad_drive
-
- err_end:
- mov ah, 09h
- int 21h
- out: mov ah, 4ch
- int 21h
-
- drive_ok:
- mov ah, 30h
- int 21h
- cmp al, 02h
- jnb vers_ok
- lea dx, bad_vers
- jmp short err_end
-
- vers_ok:
- display help_msg
- mov al, [drive]
- or al, al
- jnz not_default
- mov ah, 19h
- int 21h
- inc al
-
- not_default:
- add al, 40h
- mov search_string[0], al
- mov cl, byte ptr [command_tail]
- xor ch, ch
- mov si, cx
- add si, offset command_tail
- mov di, offset file_name
- mov bl, '\'
- mov bh, ':'
- dec cx
- call parser
- mov byte ptr [di], 0
- inc si
- cmp byte ptr [si], '\'
- je get_path
- mov di, offset search_string + 2
- jmp short entry_done
- or cx, cx
- jnz get_path
- mov di, offset search_string + 2
- jmp short entry_done
-
- get_path:
- mov di, offset search_string + 2 ;parse path
- mov bl, 20h ;stop at space
- inc cx
- call parser ;read path
-
- entry_done:
- display crlf
- xor bx, bx
- mov word ptr [bx + last_byte], di ;write first parameter
- ; in pointer chain
- mov dx, offset search_string ;pointer to search string
- ; for find_files
- mov si, offset file_name
- call find_files ;search first level
-
- set_up_dir_find:
- mov bx, dir_level ;dir_level points to pointer
- ; table of offsets for current
- ; path
- shl bx, 1
- mov di, word ptr [bx + last_byte] ;point to end
- mov si, offset stardotstar ;current search pat in di
- mov cx, 4 ;add *.* to it
- rep movsb
-
- find_dirs:
- mov dx, dta_pointer
- mov ah, 1ah ;function set dta
- int 21h
- cmp found_flag, 1 ;found something before?
- jz find_next
- mov dx, offset search_string ;else set pointer and
- mov cx, dir ; attribute and search
- mov ah, 4eh
- int 21h
- jmp short check_carry
-
- find_next:
- mov ah, 4fh ;find next
- int 21h
-
- check_carry:
- jnc found_one ;no carry -> found entry
- jmp check_level ;searched all dirs yet?
-
- ;found entry processing and discarding of . and ..
- found_one:
- mov si, dta_pointer ;point to found entry
- add si, 1eh
- cmp byte ptr [si - 1eh + 15h], dir ;is it a directory?
- jne find_next
- cmp byte ptr [si], '.' ;not the ones we want
- je find_next
- mov found_flag, 1
- xor ah, ah
- mov di, word ptr [bx + last_byte] ;point to end of search_string
-
- ;process string
- look4z:
- lodsb ;read chars
- cmp ah, al ;null char found?
- je found_z ;yes
- stosb ;move byte
- jmp short look4z
-
- found_z:
- mov byte ptr [di], '\' ;append backslash
- inc di
- add bx, 2
- mov word ptr [bx + last_byte], di ;update pointer table
- mov dx, offset search_string ;set pointer for find_files
- mov si, offset file_name
- call find_files
-
- ;update pointers and variables, search next directory entry
- ;
- update:
- add dta_pointer, 43 ;update dta pointer
- inc dir_level ;down one level
- mov found_flag, 0 ;start on new level
- jmp set_up_dir_find
-
- check_level:
- dec dir_level
- cmp dir_level, -1
- jz end ;this stops the game
- sub dta_pointer, 43 ;else adjust dta pointer
- mov found_flag, 1
- jmp set_up_dir_find ; and continue searching
- end:
- mov ah, 4ch
- int 21h
-
- ;------------------------------------------------------------------------
- parser proc near
- ;------------------------------------------------------------------------
- xor ax, ax
- push ax ;null as mark onto stack
- std ;set reverse
-
- parse_loop:
- xor ax, ax
- lodsb ;load byte in al
- ;First check if we're at end-of-string {B.E}
- cmp al, 0 ;is it NULL ? {B.E.}
- je parse_done
- cmp al, bh ;Scan for 1st requ. Break-Char
- je parse_done
- cmp al, bl ;Scan for 2nd one
- je parse_done
- cmp al, 'z' ;Check for 'lower-case'
- ja push_byte
- cmp al, 'a' ;Not really neccessary .. but . ;since DOS uppercases already
- jb push_byte
- xor al, 20h ;UPPERcase
-
- push_byte:
- push ax
- loop parse_loop
-
- parse_done:
- cld ;set forward
- pop_ax: pop ax
- cmp ax, 0
- je end_parse
- stosb
- jmp short pop_ax
- end_parse:
- ret
- parser endp
-
- ;------------------------------------------------------------------------
- find_files proc near
- ;------------------------------------------------------------------------
- ; dx points to current pathname
- ; si " " file name (search pattern)
- ; di " " first byte after pathname
- ;------------------------------------------------------------------------
-
- mov bp, dx ;save dx
- mov bx, di ;save di
- mov dx, offset fcb
- mov ah, 1ah ;set dta
- int 21h
- mov cx, 13 ;add 13 chars after pathname
- rep movsb
- xor al, al
- stosb ;make asciiz
- mov dx, bp
- mov cx, normal
- mov ah, 4eh ;find first
- int 21h
- jc not_found
- ;
- show_it:
- mov byte ptr [bx], 0 ;mark end of pathname
- mov dx, bp
- ;+++
- cld
- mov si, bp
- mov di, offset kill_file
- mov cx, 64
- rep movsb
- mov di, offset kill_file
- mov cx, 64
- xor al, al
- repne scasb ;find end of pathname
- dec di
- push di
- ;---
- mov dx, found_file ;extract filename
- mov di, offset fcb ;dest for stosb
- add di, 30 ;skip over fcb dir entry
- ; see page 1-136
- xor al, al ;clear out al for scasb
- mov cx, 12 ;move 12 chars
- repne scasb ;search for null char
- rep stosb
- ;+++
- mov si, found_file
- pop di
- mov cx, 13
- rep movsb
- mov di, offset kill_file
- mov cx, 64
- xor al, al
- repne scasb
- dec di
- mov byte ptr [di], '$'
- push di
- display spruch
- call lower_case
- display kill_file ;show pathname
- call spaces
- pop di
- mov byte ptr [di], 0 ;make string asciiz
- call yesno
- display crlf
- ;---
- mov dx, bp
- mov ah, 4fh ;find next
- int 21h
- jnc show_it
-
- not_found:
- ret
- find_files endp
-
- ;------------------------------------------------------------------------
- delete_file proc near
- ;------------------------------------------------------------------------
- ;
- push ax
- mov ah, 041h
- mov dx, offset kill_file
- int 21h
- jnc success
- cmp ax, 5 ;is directory or r/o
- je read_only
- cmp ax, 2 ;invalid path
- je inv_path
- read_only:
- display r_only
- pop ax
- ret
- inv_path:
- display i_path
- pop ax
- ret
- success:
- pop ax
- display deleted
- ret
-
- delete_file endp
-
- ;------------------------------------------------------------------------
- lower_case proc near
- ;------------------------------------------------------------------------
- ;
- mov bx, offset kill_file ;get string to lowercase
- start_lower:
- mov dl, [bx]
- cmp dl, '$'
- je lwr_done ;end of string?
- cmp dl, 'A'
- jl skip_char
- cmp dl, 'Z'
- jg skip_char
- ; or dl, ' '
- ; mov byte ptr [bx], dl ;put char back into string
- skip_char:
- inc bx
- loop start_lower ;loop for all chars
- lwr_done:
- mov dx, bx
- xor dh, dh
- mov len, dl
- ret
-
- lower_case endp
-
- ;------------------------------------------------------------------------
- yesno proc near
- ;------------------------------------------------------------------------
- ;
- push ax
- display prompt
- mov cx, 1 ;maximum length of entry (y/n)
- read_kbd
- ;display_char al
- cmp al, 'y'
- je delete_it
- cmp al, 'Y'
- je delete_it
- cmp al, 27 ;escape or F11
- je abort_show
- display notdeleted
- pop ax
- ret
-
- delete_it:
- pop ax
- call delete_file
- ret
-
- abort_show:
- pop ax
- display abort_it
- display crlf
- jmp out
-
- yesno endp
-
- ;------------------------------------------------------------------------
- spaces proc near
- ;------------------------------------------------------------------------
- ;
- display_char space_2
- mov cl, 60
- sub cl, len
- mov len, cl
- xor cx, cx
- mov cl, len
- disp:
- display_char space_1
- loop disp
- ret
- spaces endp
-
- ;------------------------------------------------------------------------
- ;
- buffer equ this byte
-
- cseg ends
- end main