📄 ftw.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include "..\h\dirent.h"
#include "..\h\ftw.h"
struct odl
{
DIR *pd;
struct odl *podlNext;
char szFileCur[_MAX_FNAME + _MAX_EXT];
};
static int ftwRecurse(char [], int (*)(char *, struct stat *, int), int, struct stat *, struct odl *);
static DIR *SearchDir(char [], char *);
static int CloseTop(struct odl *);
static int DoDir(char [], int (*)(char *, struct stat *, int), int, struct stat *, struct odl *);
int ftw(
char *path,
int (*fn)(char *, struct stat *, int),
int depth)
{
char szPath[_MAX_PATH];
struct stat st;
if ((NULL == path) || (NULL == fn) || (strlen(path) <= 0))
{
errno = EINVAL;
return -1;
}
else
{
strcpy(szPath, path);
return ftwRecurse(szPath, fn, max(depth, 1), &st, NULL);
}
}
static int ftwRecurse(
char szPath[_MAX_PATH],
int (*fn)(char *, struct stat *, int),
int depth,
struct stat *pst,
struct odl *podl)
{
struct odl odl;
int rc = 0;
assert((NULL != szPath) && (strlen(szPath) < _MAX_PATH));
assert(depth >= 0);
assert(NULL != pst);
errno = 0;
if (stat(szPath, pst))
return (*fn)(szPath, pst, FTW_NS);
else if ((pst->st_mode & S_IFDIR) != S_IFDIR)
return (*fn)(szPath, pst, FTW_F);
else if ((1 > depth) && (++depth, (rc = CloseTop(podl))))
return rc;
else if (NULL == (odl.pd = opendir(szPath)))
return (*fn)(szPath, pst, FTW_DNR);
else if (rc = (*fn)(szPath, pst, FTW_D))
{
closedir(odl.pd);
return rc;
}
else
{
if ((NULL == podl) || (NULL == podl->pd))
odl.podlNext = NULL;
else
odl.podlNext = podl;
return DoDir(szPath, fn, depth, pst, &odl);
}
}
static int DoDir(
char szPath[_MAX_PATH],
int (*fn)(char *, struct stat *, int),
int depth,
struct stat *pst,
struct odl *podl)
{
int rc;
struct dirent *pde;
char *szFile = szPath + strlen(szPath);
assert((NULL != szPath) && (strlen(szPath) < _MAX_PATH));
assert(depth >= 0);
assert(NULL != pst);
assert(NULL != podl);
if (('/' != *(szFile - 1)) && ('\\' != *(szFile - 1)))
{
*szFile = '\\';
*++szFile = '\0';
}
for (rc = 0; (NULL != (pde = readdir(podl->pd))) && (0 == rc);)
{
if (!strcmp(pde->d_name, ".") ||
!strcmp(pde->d_name, ".."))
continue;
else
strcpy(podl->szFileCur, strcpy(szFile, pde->d_name));
if (rc = ftwRecurse(szPath, fn, depth - 1, pst, podl))
;
else if ((NULL == podl->pd) && ((*szFile = '\0'),
(NULL == (podl->pd =
SearchDir(szPath, podl->szFileCur)))))
rc = -1;
else
errno = 0;
}
if ((NULL != podl->pd) && closedir(podl->pd) && (0 == rc))
rc = -1;
return rc;
}
static DIR *SearchDir(
char szPath[_MAX_PATH],
char *szFile)
{
register struct dirent *pde;
register DIR *pd;
assert((NULL != szPath) && (strlen(szPath) < _MAX_PATH));
assert((NULL != szFile) && (strlen(szFile) > 0));
errno = 0;
if (NULL == (pd = opendir(szPath)))
{
return NULL;
}
while (NULL != (pde = readdir(pd)))
if (!strcmp(pde->d_name, szFile))
return pd;
if (0 == errno)
errno = ENOENT; // Can't find file
closedir(pd); // Don't care if we fail, might change errno
return NULL;
}
static int CloseTop(register struct odl *podl)
{
register struct odl *podlPrev = podl;
while (NULL != podl)
{
if (NULL == podl->podlNext)
{
int rc = closedir(podl->pd);
podl->pd = NULL;
podlPrev->podlNext = NULL;
return rc;
}
else
{
podlPrev = podl;
podl = podl->podlNext;
}
}
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -