#ifndef EMBEDDED

#include <unistd.h>
#include <dirent.h>
#include <limits.h>
#include <sys/fcntl.h>
#include <ftw.h>

#endif

#ifndef PATH_MAX
#define PATH_MAX 4096
#endif

#ifndef FTW_SL
#define FTW_SL 23
#endif

int ftw(const char *dir,int (*fn)(const char *file, const struct stat *sb, int flag), int depth) {
  int res=0;
  char *cwd;
  int cwdlen;
  DIR *d;
  struct dirent *de;
  struct stat sb;
  int fd=open(".",O_RDONLY);
  if (chdir(dir)) return -1;
  cwd=(char*)alloca(PATH_MAX+1);
  if (!getcwd(cwd,PATH_MAX)) { res=-1; goto error_out; }
  cwd[PATH_MAX]=0;
  cwdlen=strlen(cwd);
  if (!(d=opendir("."))) { res=-1; goto error_out; }
  while ((de=readdir(d))) {
    int flag;
    int nlen;
    char *filename;
    if (de->d_name[0]=='.' &&
	(de->d_name[1]==0 ||
	(de->d_name[1]=='.' && de->d_name[2]==0))) continue;
    nlen=strlen(de->d_name);
    filename=(char*)alloca(nlen+cwdlen+3);
//    if (!filename) return -1;
    memcpy(filename,cwd,cwdlen);
    filename[cwdlen]='/';
    memcpy(filename+cwdlen+1,de->d_name,nlen+1);
#ifdef DONT_NEED_FLAG
    lstat(de->d_name,&sb);
#else
    if (!lstat(de->d_name,&sb)) {
      if (S_ISLNK(sb.st_mode)) flag=FTW_SL; else
      if (S_ISDIR(sb.st_mode)) flag=FTW_D; else
      flag=FTW_F;
    } else
      flag=FTW_NS;
#endif
    res=fn(filename,&sb,flag);
    if (res) goto done;
    if (flag==FTW_D && depth>0) {
      res=ftw(filename,fn,depth-1);
      fchdir(fd);
      if (res) goto done;
    }
/*    puts(de->d_name); */
  }
done:
  closedir(d);
error_out:
  fchdir(fd);
  close(fd);
  return res;
}

