title whereis ;+ ; ; Find file(s) matching a wildcard. ; ; Things to fix: ; ; It would be nice to be able to search only a subtree. ; ; Output should be sorted out so that the dir being searched goes to STDERR, ; but actual matches go to STDOUT, without all the blanks and stuff, so that ; it's worthwhile to redirect the output to a file. ; ; By John Wilson. ; ; 03/18/94 JMBW Created. ; ;- .radix 8 ; bs= 10 lf= 12 cr= 15 ; code segment assume cs:code org 100h start: jmp short start1 db bs,bs,'By John Wilson',32 start1: cld ;DF=0 mov al,byte ptr ds:5Ch ;get drive # or al,al ;is there one? jnz gotdsk ;yes mov ah,19h ;func=get logged in disk int 21h inc ax ;+1 to conform to format gotdsk: add al,'A'-1 ;convert to letter mov byte ptr ds:wbuf,al ;save mov di,offset wbuf+3 ;include slash when printing root dir name call sroot ;search root directory recursively mov di,offset wbuf ;write null name to blank last one call pname int 20h ;+ ; ; Search a directory recursively. ; ; DS:WBUF contains a path prefix, DS:WPTR points past the end of the prefix. ; ;- sdir: mov di,ds:wptr ;get end of prefix dec di ;-1 to remove slash (looks funny) sroot: ; enter here to include slash for root directory call pname ;print dir name mov di,ds:wptr ;get and save end of prefix push di mov byte ptr [di-1],'/' ;add slash (PNAME may have nuked it) ; first search for matches mov di,ds:wptr ;pt at tail mov si,5Ch+1 ;pt at FCB #1 mov cx,8d ;copy up to 8 chars call copy mov al,'.' ;. stosb mov cl,3 ;copy up to 3 more call copy xor al,al ;NUL stosb mov dx,offset wbuf ;point at buf xor cx,cx ;match all attrs mov ah,4Eh ;func=find first int 21h jc sdir4 ;nothing found, skip sdir1: ; display this match mov si,80h+1Eh ;point at filename in DTA mov di,ds:wptr ;point into free space sdir2: lodsb ;get a byte or al,al ;is this end? jz sdir3 stosb ;no, save it jmp short sdir2 sdir3: call pname ;print the name mov dl,lf ;print a lf mov ah,02h ;func=CONOUT int 21h mov byte ptr ds:wid,0 ;blank line mov dx,80h ;pt at DTA (??? shouldn't be needed) mov ah,4Fh ;func=find next int 21h jnc sdir1 ;found one, display it sdir4: ; now search for directories into which to recurse mov di,ds:wptr ;pt at tail mov ax,".*" ;*.* stosw mov ax,'*' stosw mov di,ds:hptr ;get and save heap ptr push di mov dx,offset wbuf ;pt at wildcard mov cx,10h ;attr=directory mov ah,4Eh ;func=find first int 21h jc sdir10 ;not found, skip sdir5: ; found a match, save on heap if dir unless . or .. test byte ptr ds:80h+15h,10h ;is it a dir entry? jz sdir7 mov si,80h+1Eh ;yes, point at filename in DTA cmp byte ptr [si],'.' ;starts with .? (. or ..) je sdir7 ;yes, ignore sdir6: lodsb ;get a byte stosb ;save it or al,al ;copy up to NUL jnz sdir6 sdir7: ; look for next match mov dx,80h ;pt at DTA (DOS Tech Help says req'd 3.0+ ????) mov ah,4Fh ;func=find next int 21h jnc sdir5 ;loop if another match found xor al,al ;mark end of list with null file stosb mov si,di ;copy final heap ptr xchg si,ds:hptr ;update HPTR, get ptr to begn sdir8: ; recurse for each entry we found lodsb ;get a byte or al,al ;end of list? jz sdir10 mov di,ds:wptr ;pt at buffer push di ;save ptr sdir9: stosb ;save lodsb ;get next byte or al,al ;end of dir name? jnz sdir9 ;loop if not mov al,'/' ;add a slash stosb mov ds:wptr,di ;set ptr push si ;save list ptr call sdir ;recurse pop si ;restore list ptr pop ds:wptr ;restore wildcard ptr jmp short sdir8 sdir10: pop ds:hptr ;flush stuff we put on heap pop ds:wptr ;restore ret ;+ ; ; Copy non-blank chars of a filename element. ; ;- copy: lodsb ;get a char cmp al,' ' ;blank? je $+3 ;yes, skip stosb ;otherwise save loop copy ;loop ret ;+ ; ; Print a dir or file name, blanking out the previous one if there was one. ; ; di pointer past end of name (WBUF is beginning) ; ;- pname: mov dx,offset wbuf ;pt at name mov cx,di ;copy sub cx,dx ;find length mov bx,cx ;copy xchg bl,ds:wid ;get width of previous name cmp cl,bl ;is current name longer or equal? jae pname1 ;yes, no need to clear sub cx,bx ;find # blanks to add neg cx mov al,' ' ;load blank rep stosb ;pad pname1: mov al,cr ;cr stosb mov cx,di ;copy sub cx,dx ;find length mov bx,0001h ;handle=STDOUT mov ah,40h ;func=write int 21h ret ; hptr dw heap ;curr free loc in heap wid db 0 ;width of dir name displayed wptr dw wbuf+3 ;ptr to where to add filename wbuf db '?:/',256d dup(?) ;wildcard buffer heap label byte ;heap starts here ; code ends end start