;  FILE_FIND.PRO  10-29-98   DSFoster
;
;----------------------------------------------------------------------------
;   function File_Find
;
; Takes file specification, expands it and returns a list of matching
; filenames. Returns -1 if no files are found (and argument FNAMES will
; be undefined). Returns -2 if arg FILESPEC is undefined or null.
; Returns the number of files found if no errors. Mostly borrowed from
; the PICKFILE widget.
;
; Set the DIR keyword if you want only the names of directories returned.
; In this case, FILESPEC has to specify a directory itself.
;
; Set the RECURSIVE keyword to have all files or directories searched
; recursively down the directory tree (Unix only).
;
; Modifications:
;
;  1-12-95 DSF Creation.
;  2-04-97 DSF Sort the filenames before returning. Set the keyword
;          NO_SORT to disable this.
;  6-13-97 DSF Make /RECURSIVE and /DIR independent, so you can search
;          recursively for files as well as directories. For non-UNIX
;          platforms just call FINDFILE() (/DIR and /RECURSIVE not
;          allowed).
; 10-29-98 DSF Use "find" command for /RECURSIVE to get correct results!
;          Add /PATH for use with /RECURSIVE to specify directory to
;          begin search. If /DIR specified use "ls" and return only 
;          directory names. Add "-d" argument to "ls" command for
;          nonrecursive searches to avoid listing directory contents.
;----------------------------------------------------------------------------

FUNCTION file_find, filespec, fnames, DIR=dir, RECURSIVE=recursive, $
			NO_SORT=no_sort, PATH=path

status = 0
fnames = ''

if (n_elements(filespec) eq 0) then begin
	status = -2
endif else if (strlen(filespec) eq 0) then begin
	status = -2
endif else begin

	if ( !version.os_family eq 'unix' ) then begin

		ON_IOERROR, io_error

		; Use the FIND command for /RECURSIVE, and LS otherwise.

		if (keyword_set(DIR)) then begin
			if (keyword_set(RECURSIVE)) then begin
				command = 'ls -lR ' + filespec + ' 2> /dev/null'
				cmd = 'ls'
			endif else begin
				command = 'ls -l ' + filespec + ' 2> /dev/null'
				cmd = 'ls'
			endelse
		endif else if (keyword_set(RECURSIVE)) then begin
			command = 'find ' + filespec + ' -type d 2> /dev/null'
			cmd = 'find'
		endif else begin
			command = "ls -ld " + filespec + " 2> /dev/null"
			cmd = 'ls'
		endelse
	
		if (keyword_set(PATH)) then begin
			cd, current=curdir
			cd, path
		endif

		SPAWN, ["/bin/sh", "-c", command], results, /NOSHELL

		if (keyword_set(PATH)) then $
			cd, curdir

		if (keyword_set(RESULTS)) then begin
			if (keyword_set(DIR)) then begin
				firsts = strupcase(strmid(results, 0, 1))
				fileinds = where(firsts eq "D", found)
			endif else if (keyword_set(RECURSIVE)) then begin
				pos = strpos(results, './')
				ind = where(pos eq 0)
				results(ind) = strmid(results(ind), 2, 1000)
				fnames = results
				found = (status = n_elements(fnames))
			endif else begin
				firsts = strupcase(strmid(results, 0, 1))
				fileinds = where(firsts eq "F" or firsts eq "-" OR $
						firsts eq "l", found)
			endelse
			if (found GT 0) then begin
				if (cmd eq 'ls') then begin
					results = results(fileinds)
					FOR i = 0, n_elements(results) - 1 DO begin
						spaceinds = where(BYTE(results(i)) EQ 32)
						spaceindex = spaceinds(n_elements(spaceinds) - 1)
						results(i) = strmid(results(i), spaceindex + 1, 100)
					endFOR
					fnames = results
					if (not keyword_set(NO_SORT)) then $     ; Sort?
						fnames = fnames( sort(fnames) )	
					status = n_elements(fnames)              ; Return-value
				endif
			 endif else begin
				status = -1
			 endelse
		endif else begin
			status = -1
		endelse

	endif else begin            ; Non-UNIX platforms

		if (keyword_set(DIR) or keyword_set(RECURSIVE)) then begin
			message, 'Keywords DIR and RECURSIVE on UNIX platforms only'
		endif else begin
			fnames = findfile(filespec, count = status)
			if (fnames(0) eq '') then $
				status = -1
		endelse

	endelse
	
endelse

return, status

io_error: return, -1 

end

