
(defun find-subdirs (dir &optional recurse no-symlinks)
  (let ((files (directory-files dir))
        (result nil))
    (while files
      (let* ((f (car files))
             (path (concat dir "/" f)))
        (setq files (cdr files))
        (if (and 
	     (file-directory-p path)
	     (not (equal "." f))
	     (not (equal ".." f))
             (if no-symlinks
                 (not (file-symlink-p path))
               t))
            (progn
              (setq 
               result
               (if recurse
                   (cons (find-subdirs path recurse) result)
                 (cons f result)))))))
    (nreverse result)))

(defun find-files (dir &optional recurse)
  (let ((dirs (cons "." (if recurse (find-subdirs dir))))
        (result nil))
    (while dirs
      (let* ((relative-dir (car dirs))
             (dir-name (concat dir "/" relative-dir))
             (files (directory-files dir-name)))
        (while files 
          (let* ((f (car files))
                 (path (concat dir-name "/" f)))
            (if (and
                 (not (file-directory-p path))
                 (file-readable-p path))
                (setq result (cons path result))))
          (setq files (cdr files))))
      (setq dirs (cdr dirs)))
    (nreverse result)))

(defun find-files-pred (dir pred &optional recurse)
  (let ((files (find-files dir recurse))
        (result nil))
    (while files
      (let ((f (car files)))
        (if (pred f)
            (setq result (cons f result))))
      (setq files (cdr files)))))

(provide 'find-in-files)

