1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>
#include <ftw.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#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);
}
|