📄 ftw.c
字号:
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <young/youngc.h>
/*******************************************************************************/
#define FTW_F 1 /* file other than directory */
#define FTW_D 2 /* directory */
#define FTW_DNR 3 /* directory than can't be read */
#define FTW_NS 4 /* file that we can't stat */
typedef int (*ftwFunc)( const char*, const struct stat*, int );
static ncstring fullpath;
static int dopath( ftwFunc func )
{
struct stat statbuf;
struct dirent* dirp;
DIR* dp;
const char* path;
size_t endindex;
int ret;
path = ncstr_to_string( &fullpath );
if( lstat(path, &statbuf) < 0 )
return func( path, &statbuf, FTW_NS );
if( S_ISDIR(statbuf.st_mode) == 0 )
return func( path, &statbuf, FTW_F );
if( (ret = func(path, &statbuf, FTW_D)) != 0 )
return ret;
if( ncstr_back(&fullpath) != '/' )
ncstr_push_back( &fullpath, '/' );
path = ncstr_to_string( &fullpath );
endindex = ncstr_size( &fullpath );
if( NULL == (dp = opendir(path)) )
return func( path, &statbuf, FTW_DNR );
while( (dirp = readdir(dp)) != NULL )
{
if( strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0 )
continue;
ncstr_replace_array( &fullpath, endindex, SIZE_MAX,
dirp->d_name, strlen(dirp->d_name) );
printf( "\n%s", ncstr_to_string(&fullpath) );
if( (ret = dopath(func)) != 0 )
break;
}
if( closedir(dp) < 0 )
printf( "can't close directory %s\n", ncstr_to_string(&fullpath) );
return ret;
}
int ftw( const char* pathname, ftwFunc func )
{
int ret;
ncstr_init( &fullpath );
ncstr_replace_array( &fullpath, 0, SIZE_MAX, pathname, strlen(pathname) );
ret = dopath( func );
ncstr_destroy( &fullpath );
return ret;
}
/*******************************************************************************/
static size_t nreg = 0, ndir = 0, nblk = 0, nchr = 0, nfifo = 0,
nslink = 0, nsock = 0, ntot = 0;
int total_file( const char* path, const struct stat* statbuf, int type )
{
switch( type )
{
case FTW_F:
{
if( S_ISREG(statbuf->st_mode) )
++nreg;
else if( S_ISBLK(statbuf->st_mode) )
++nblk;
else if( S_ISCHR(statbuf->st_mode) )
++nchr;
else if( S_ISFIFO(statbuf->st_mode) )
++nfifo;
else if( S_ISLNK(statbuf->st_mode) )
++nslink;
else if( S_ISSOCK(statbuf->st_mode) )
++nsock;
else if( S_ISDIR(statbuf->st_mode) )
printf( "for S_IFDIR for %s\n", path );
break;
}
case FTW_D:
++ndir;
break;
case FTW_DNR:
printf( "can't read directory %s\n", path );
break;
case FTW_NS:
printf( "stat error for %s\n", path );
break;
default:
printf( "unknown type %d for pathname %s\n", type, path );
}
return 0;
}
int main( int argc, char** argv )
{
int ret;
if( argc != 2 )
{
printf( "usage: ftw <starting-pathname>" );
return 0;
}
ret = ftw( argv[1], total_file );
ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
if( ntot == 0 )
ntot = 1;
printf( "\n\nregular files = %7u, %5.2f %%\n", nreg, nreg * 100.0 / ntot );
printf( "directories = %7u, %5.2f %%\n", ndir, ndir * 100.0 / ntot );
printf( "block special = %7u, %5.2f %%\n", nblk, nblk * 100.0 / ntot );
printf( "char special = %7u, %5.2f %%\n", nchr, nchr * 100.0 / ntot );
printf( "FIFOs = %7u, %5.2f %%\n", nfifo, nfifo * 100.0 / ntot );
printf( "symbolic links = %7u, %5.2f %%\n", nslink, nslink * 100.0 / ntot );
printf( "sockets = %7u, %5.2f %%\n", nsock, nsock * 100.0 / ntot );
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -