/* ftw.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */

#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <ftw.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

static int ftw_recurse (int (*fn)(const char *name,
                                  const struct stat *stat_ptr,
                                  int flag),
                        char *name_buf, int index)
{
  int rc, flag, len;
  struct stat st;
  DIR *dir;
  struct dirent *ent;

  dir = opendir (name_buf);
  if (dir == NULL)
    return (-1);
  if (index < 1 || (name_buf[index-1] != '/' && name_buf[index-1] != '\\'))
    name_buf[index++] = '/';
  rc = 0;
  for (;;)
    {
      ent = readdir (dir);      /* emx version never fails */
      if (ent == NULL)
        break;
      len = strlen (ent->d_name);
      if (index + len >= MAXPATHLEN)
        {
          errno = ENAMETOOLONG;
          rc = -1;
          break;
        }
      strcpy (name_buf + index, ent->d_name);
      if (stat (name_buf, &st) != 0)
        flag = FTW_NS;
      else if ((st.st_mode & S_IFMT) == S_IFDIR)
        flag = FTW_D;
      else
        flag = FTW_F;
      if (flag != FTW_D || (strcmp (ent->d_name, ".") != 0 &&
                            strcmp (ent->d_name, "..") != 0))
        {
          rc = fn (name_buf, &st, flag);
          if (rc != 0)
            break;
          if (flag == FTW_D)
            {
              rc = ftw_recurse (fn, name_buf, index + len);
              if (rc != 0)
                break;
            }
        }
    }
  closedir (dir);
  return (rc);
}


int ftw (const char *path,
         int (*fn)(const char *name, const struct stat *stat_ptr, int flag),
         int depth)
{
  struct stat st;
  char name_buf[MAXPATHLEN+1];
  int rc, len;

  len = strlen (path);
  if (len >= MAXPATHLEN)
    {
      errno = ENAMETOOLONG;
      return (-1);
    }
  if (stat (path, &st) != 0)
    return (-1);
  if ((st.st_mode & S_IFMT) != S_IFDIR)
    {
      errno = ENOTDIR;
      return (-1);
    }
  strcpy (name_buf, path);
  rc = fn (name_buf, &st, FTW_D);
  if (rc != 0)
    return (rc);
  return (ftw_recurse (fn, name_buf, len));
}
