#include #include #include #include #include #include #include #include "perr.h" #include "pclt.h" #include "fstrav.h" static int fstrav_do(pclt, path, func, sp) PCLT *pclt; char *path; int (*func)(const char *, const struct stat *, int, void *); void *sp; { char fullpath[PATH_MAX+1], *endpath; int pathlen, ret, inh; DIR *dir; struct dirent *dirent, direntbuff; struct stat stat; PCL *pcl; const PCLENT *pclent; if ((dir=opendir(path))==NULL) { pwarn2("opendir()", path); return (-1); } (void)strncpy(fullpath, path, PATH_MAX); fullpath[PATH_MAX-1]=(char)0x0; endpath=fullpath+strlen(fullpath); if (strncmp(fullpath, "/", 2)!=0) { *endpath++='/'; *endpath=(char)0x0; } pathlen=strlen(fullpath); pcl=pclt_get(pclt, fullpath, &inh); while ((ret=readdir_r(dir, &direntbuff, &dirent))==0 && dirent) { (void)strncpy(endpath, dirent->d_name, PATH_MAX-1-pathlen); fullpath[PATH_MAX-1]=(char)0x0; if (strncmp(dirent->d_name, ".", 2)==0 || strncmp(dirent->d_name, "..", 3)==0) continue; if ((ret=lstat(fullpath, &stat))!=0) { pwarn2("lstat()", fullpath); return (ret); } pclent=pcl_match(pcl, dirent->d_name, &stat, inh); if (pclent && PCL_ISSET(pclent->pcl_marks, PCL_MMATCH)) { if ((ret=func(fullpath, &stat, pclent->pcl_opt, sp))!=0) return (ret); } if (pclent && PCL_ISSET(pclent->pcl_marks, PCL_MSTOP)) continue; if (!S_ISDIR(stat.st_mode)) continue; if ((ret=fstrav_do(pclt, fullpath, func, sp))!=0) return (ret); } (void)closedir(dir); if (ret) { (void)strncpy(endpath, dirent->d_name, PATH_MAX-1-pathlen); pwarn2("readdir_r()", fullpath); return (-1); } return (0); } int fstrav(pclt, func, sp) PCLT *pclt; int (*func)(const char *, const struct stat *, int, void *); void *sp; { return (fstrav_do(pclt, "/", func, sp)); }