Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83; site whuxle.UUCP
Path: utzoo!watmath!clyde!floyd!whuxle!jph
From: jph@whuxle.UUCP
Newsgroups: net.micro.pc
Subject: Re: CALLING ALL DOS 2.0 EXPERTS - (nf)
Message-ID: <249@whuxle.UUCP>
Date: Sat, 18-Feb-84 21:36:11 EST
Article-I.D.: whuxle.249
Posted: Sat Feb 18 21:36:11 1984
Date-Received: Sun, 19-Feb-84 08:03:25 EST
Sender: jph@whuxle.UUCP
Organization: Bell Labs, Whippany
Lines: 350

#R:rlgvax:-171200:whuxle:22700016:000:6083
whuxle!jph    Feb 18 21:35:00 1984

Here is the source code for WHEREIS which takes a file name
of pattern (e.g., *.BAS) as an argument and finds where it
is in the file system by starting at the root and working it
way down through all the sub-directories. You might take
this algorithm and use it in your function for C. I obtained
this from a BBS.
============================================

title WHEREIS
page	62,132
cgroup	group	code_seg,data_seg
	assume	cs:cgroup,ds:cgroup

;this is the format for the dos data transfer area used when dos 2.0
;searches for file match in directories

dta	struc
	reserved	db	21 dup (?)
	attribute	db
	time		dw
	date		dw
	size		dd
	name_found	db	13 dup (?)
dta	ends

data_seg	segment public
star_name	db	'*.*',0
path_name	db	'\',0
		db	80 dup (0)	;space for 64 char pathname and
					;13 char filename
file_name	db	13 dup (0)	;save room for full dos filename
disk_transfer_areas label byte		;this starts at the end of whereis
data_seg	ends

;  this is the main program that sets up the initial conditions for
;  search_directory which in turn, does a recursive search.
;	reads:	path_name
;	writes: file_name
;	calls:	search_directory
;
code_seg	segment
		org	100h
whereis proc	near
	mov	si, 82h 		;start of command line
	mov	di, offset cgroup:file_name

wh10:	lodsb				;get first char
	cmp	al, 0dh
	je	wh20			;if carriage return
	stosb
	jmp	wh10			;Loop --

wh20:	xor	al,al			;store zero at end
	stosb
	mov	di, offset cgroup:path_name
	xor	al, al
	cld
	mov	cx, 64
  repnz scasb
	mov	bx,di
	dec	bx			;ds:bx points to end of path_name
	mov	dx, 0
	call search_directory
	int	20h
whereis endp

; this procedure searches all the files in the current directory
; looking for a match.	It also prints the full name for each match
;
;	ds:bx	pointer to end of current path name
;	ds:dx	old disk transfer area (dta)
;
; reads:	disk transfer area (dta)
; writes:	disk transfer area (dta)
; calls 	build_name, get_first_Match
;		write_matched_name, get_next_match
;		build_star_name, search_sub_directory
;
search_directory proc	near

	push	si
	push	dx
	call	build_name
	call	get_first_match
	jc	sd20				;If no match --
	call	write_matched_name
sd10:	call	get_next_match
	jc	sd20
	call	write_matched_name
	jmp	sd10				;Loop --

sd20:	pop	dx
	push	dx
	call	build_star_name
	call	get_first_match
	jc	sd50				;If no match --
	mov	si,dx
	test	[si].attribute,10h
	jnz	sd40				;If directory entry --
sd30:	call	get_next_match
	jc	sd50				;If no more entries --
	test	[si].attribute,10h
	jz	sd30				;If not a directory --
sd40:	cmp	[si].name_found,'.'
	je	sd30				;If it's . or ..
	call	search_sub_directory		;search sub directory
	push	ax
	mov	ah,1ah
	int	21h
	pop	ax
	jmp	sd30

sd50:	pop	dx
	pop	si
	ret

search_directory  endp
page
; This procedure searches the sub directory who's name is in dta
;
;	ds:bx	end of the current pathname
;	ds:[dx].name_found	name of subdirectory for search
;
; reads:	path_name
; writes:	path_name
; calls:	search_directory
;

search_sub_directory  proc  near

	push	di
	push	si
	push	ax
	push	bx
	cld
	mov	si, dx
	add	si, offset name_found
	mov	di,bx
ss10:	lodsb
	stosb
	or	al,al
	jnz	ss10
	mov	bx,di
	std
	stosb
	mov	al,'\'
	stosb
	call	search_directory
	pop	bx
	mov	byte ptr [bx], 0
	pop	ax
	pop	si
	pop	di
	ret

search_sub_directory  endp
page

; This procedure prints the matched name after the path name
;
;  ds:dx	pointer to current disk transfer area
;
; reads:	path_name, name_found (in dta)
; writes:	write_string, send_crlf
;

write_matched_name	proc	near

	push	ax
	push	dx
	mov	dx,offset cgroup:path_name
	mov	al,[bx]
	mov	byte ptr [bx],0
	call	write_string
	mov	[bx],al
	pop	dx
	push	dx
	add	dx, offset name_found
	call	write_string
	call	send_crlf
	pop	dx
	pop	ax
	ret
write_matched_name endp


;  This procedure builds an absolute search name from path_name
;  followed by file_name
;
;  reads:	file_name
;  calls:	build	(to build the name)
;

build_name	proc	near

	push	si
	mov	si, offset cgroup:file_name
	call	build
	pop	si
	ret
build_name	endp

build_star_name proc	near
	push	si
	mov	si, offset cgroup:star_name
	call	build
	pop	si
	ret
build_star_name endp

page
; This procedure appends the string at ds:si to path_name in
; path_name.  It knows where the path name ends from knowing
; how long path_name is.
;
;	ds:si	name of file
;	ds:bx	end of path_name
;
; reads:	ds:si
; writes:	path_name
;

build	proc	near
	push	ax
	push	di
	mov	di,bx
	cld
bd10:	lodsb
	stosb
	or	al,al
	jnz	bd10			;If not end of string yet --
	pop	di
	pop	ax
	ret
build	endp

; This procedure find the first match between the name given by
; ds:dx and the directory entries found in the directory path_name
;
;	ds:dx	pointer to current disk transfer area
;
;  returns:
;	cf	0	a match was found
;		1	no match found
;	ax		error code returned
;		2	file not found
;		18	no more files
;	ds:dx		pointer to new disk transfer area
;
; reads:	path_name
; writes:	disk_transfer_areas
;

get_first_match proc	near

	push	cx
	cmp	dx,0
	ja	gf10			;go allocate space --
	mov	dx, offset cgroup:disk_transfer_areas-type dta
gf10:	add	dx,type dta
	mov	cx,10h
	mov	ah,1ah
	int	21h
	push	dx
	mov	dx, offset cgroup:path_name
	mov	ah,4eh			;call for find first match
	int	21h
	pop	dx
	pop	cx
	ret
get_first_match endp


; This procedure is much line get_first_match
;
; returns:
;	cf	0	a match was found
;		1	no match found
;	ax		error code returned
;		2	file not found
;		18	no more files
;
; reads:	path_name
; writes:	disk_transfer_areas
;

get_next_match	proc	near

	push	cx
	push	dx
	mov	dx, offset cgroup:path_name
	mov	cx,10h
	mov	ah,4fh
	int	21h
	pop	dx
	pop	cx
	ret
get_next_match	endp

; This procedure sends a crlf pair of characters to the screen
;

send_crlf	proc	near

	push	ax
	push	dx
	mov	ah,02
	mov	dl,0ah
	int	21h
	mov	dl,0dh
	int	21h
	pop	dx
	pop	ax
	ret
send_crlf	endp

; This procedure writes the asciiz string at
;  ds:dx	address of asciiz string
;

write_string	proc	near

	push	ax
	push	dx
	push	si
	cld
	mov	si,dx
	mov	ah,2
	lodsb
ws10:	mov	dl,al
	int	21h
	lodsb
	or	al,al
	jnz	ws10
	pop	si
	pop	dx
	pop	ax
	ret
write_string	endp

code_seg	ends

	end	whereis