#include #include #include #include #include #include #include #include "dietdirent.h" int ftw(const char*dir,int(*f)(const char*file,const struct stat*sb,int flag),int dpth){ char* cd; size_t cdl; DIR* d; struct dirent* de; struct stat sb; int r; unsigned int oldlen=0; char* filename; /* the warning gcc issues here is bogus */ if(chdir(dir))return-1; cd=alloca(PATH_MAX+1); if(!getcwd(cd,PATH_MAX))return-1; cd[PATH_MAX]='\0'; cdl=strlen(cd); if(!(d=opendir(".")))return-1; while((de=readdir(d))){ int flg; size_t nl; if(de->d_name[0]=='.'){if(!de->d_name[1])continue;if(de->d_name[1]=='.'&&!de->d_name[2])continue;} nl=strlen(de->d_name); if (nl+cdl+2>oldlen) filename=alloca(oldlen=nl+cdl+2); memmove(filename,cd,cdl); filename[cdl]='/'; memmove(filename+cdl+1,de->d_name,nl+1); if(!lstat(de->d_name,&sb)){ if(S_ISLNK(sb.st_mode))flg=FTW_SL;else if(S_ISDIR(sb.st_mode))flg=FTW_D;else flg=FTW_F; }else flg=FTW_NS; r=f(filename,&sb,flg); if(r){closedir(d);return r;} if(flg==FTW_D&&dpth){ r=ftw(filename,f,dpth-1); fchdir(d->fd); if (r){closedir(d);return r;} } } return closedir(d); }