//Having read code for a long time, finally i get it written down, and it doesn't seem that hard, you can do it!!
#include "apue.h"
#include <dirent.h>
#include <limits.h>
#ifdef PATH_MAX
static int pathmax = PATH_MAX;
#else
static int pathmax = 0;
#endif
#define SUSV3 200112L
static long posix_version = 0;
/* If PATH_MAX is indeterminate, no guarantee this is adequate */
#define PATH_MAX_GUESS 1024
char *
path_alloc(int *sizep) /* also return allocated size, if nonnull */
{
char *ptr;
int size;
if (posix_version == 0)
posix_version = sysconf(_SC_VERSION);
if (pathmax == 0) { /* first time through */
errno = 0;
if ((pathmax = pathconf("/", _PC_PATH_MAX)) < 0) {
if (errno == 0)
pathmax = PATH_MAX_GUESS; /* it's indeterminate */
else
err_sys("pathconf error for _PC_PATH_MAX");
} else {
pathmax++; /* add one since it's relative to root */
}
}
if (posix_version < SUSV3)
size = pathmax + 1;
else
size = pathmax;
if ((ptr = malloc(size)) == NULL)
err_sys("malloc error for pathname");
if (sizep != NULL)
*sizep = size;
return(ptr);
}
typedef int Myfunc(const char *,const struct stat *, int);
static Myfunc myfunc;
static int dopath(Myfunc *);
static int myftw(const char *, Myfunc *);
static int nreg, ndir, nblk, nchr, nsock, nslink, nfifo, ntot;
int main(int argc, char *argv[]){
int ret;
if(argc != 2)
err_quit("<usage> %s pathname", argv[0]);
ret = myftw(argv[1], myfunc);
ntot = nreg + nblk + nchr + ndir + nsock + nslink + nfifo;
if(ntot == 0)
ntot = 1;
printf("regular files = %7ld, %5.2f%%\n", nreg, nreg*100.0/ntot);
printf("directories = %7ld, %5.2f%%\n", ndir, ndir*100.0/ntot);
printf("character special = %7ld, %5.2f%%\n", nchr, nchr*100.0/ntot);
printf("block sepcial = %7ld, %5.2f%%\n", nblk, nblk*100.0/ntot);
printf("sockets = %7ld, %5.2f%%\n", nsock, nsock*100.0/ntot);
printf("symbolic link = %7ld, %5.2f%%\n", nslink, nslink*100.0/ntot);
printf("FIFOs = %7ld, %5.2f%%\n", nfifo, nfifo*100.0/ntot);
exit(ret);
}
static char *fullpath;
static int myftw(const char *pathname, Myfunc func){
int len, ret;
fullpath = path_alloc(&len);
strncpy(fullpath, pathname, len);
fullpath[len-1] = 0;
return(dopath(func));
}
#define FTW_F 1
#define FTW_D 2
#define FTW_NS 3
#define FTW_DNR 4
static int dopath(Myfunc func){
struct stat statbuf;
DIR *dp;
struct dirent *dirp;
int ret;
char *ptr;
if(lstat(fullpath, &statbuf) < 0)
return(func(fullpath, &statbuf, FTW_NS));
if(S_ISDIR(statbuf.st_mode) == 0)
return(func(fullpath, &statbuf, FTW_F));
if((ret = func(fullpath, &statbuf, FTW_D)) < 0)
return(ret);
ptr = fullpath + strlen(fullpath);
*ptr++ = '/';
*ptr = 0;
if((dp = opendir(fullpath)) == NULL)
return(func(fullpath, &statbuf, FTW_DNR));
while((dirp = readdir(dp)) != NULL){
if(!strcmp(dirp->d_name, ".") ||
!strcmp(dirp->d_name, ".."))
continue;
// not "strcat(fullpath, dirp->d_name)"
strcpy(ptr, dirp->d_name);
if((ret = dopath(func)) < 0)
break;
}
ptr[-1] = 0;
if(closedir(dp) < 0)
err_ret("close dir %s error", fullpath);
return ret;
}
static int
myfunc(const char *pathname, const struct stat *statbuf, int type){
switch(type){
case FTW_F:
switch(statbuf->st_mode & S_IFMT){
case S_IFREG: nreg++; break;
case S_IFCHR: nchr++; break;
case S_IFBLK: nblk++; break;
case S_IFIFO: nfifo++; break;
case S_IFSOCK: nsock++; break;
case S_IFLNK: nslink++; break;
case S_IFDIR:
err_dump("for S_IFDIR for %s", pathname);
}
break;
case FTW_D:
ndir++;
break;
case FTW_NS:
err_ret("stat error for %s", pathname);
break;
case FTW_DNR:
err_ret("can't read directory %s", pathname);
break;
default:
err_dump("unknown type %d for pathname %s", type, pathname);
return(0);
}
}
相关文章:
-
2022-02-23
-
2021-10-24
-
2021-12-31
-
2021-11-29
-
2021-05-08
-
2021-12-18
-
2021-07-19
-
2021-07-06
猜你喜欢
-
2022-12-23
-
2021-07-15
-
2021-04-15
-
2021-06-11
-
2022-02-12
-
2021-09-30
-
2021-12-03