Recursive their oaths traversal of directory hierarchies and counting by file type

Source: Internet
Author: User
Tags lstat

This program uses a number of functions to manipulate the directory to write a program to traverse the file hierarchy, and finally the various types of file count. This program has only one parameter, which shows the starting path name, from which the recursive their oaths sequence traverses the file hierarchy. It also uses a function path_alloc that dynamically allocates the store for the path name.

ftw.c//2015-08-18 Lucifer zhang//recursively descend a directory hierarchy, counting file Types#include "Apue.h" #i Nclude "pathalloc.h" #include <dirent.h> #include <limits.h>//function type that's called for each filenamety pedef int Myfunc (const char *, const struct STAT *, int); static Myfunc myfunc;static int myftw (char *, Myfunc *); static in  T Dopath (Myfunc *); static long Nreg, Ndir, Nblk, NCHR, Nfifo, Nslink, Nsock, ntot;int main (int argc, char *argv[]) {int    Ret    if (argc! = 2) {err_quit ("usage:ftw <starting-pathname>"); } ret = MYFTW (argv[1], myfunc);    Does it all Ntot = Nreg + ndir + nblk + nchr + nfifo + nslink + nsock; if (Ntot = = 0) {Ntot = 1;//avoid divide by 0; Print 0 for all counts} printf ("Regular files =%7ld,%5.2    F%%\n ", Nreg, Nreg * 100.0/ntot);    printf ("directories =%7ld,%5.2f%%\n", Ndir, Ndir * 100.0/ntot);    printf ("Block special =%7ld,%5.2f%%\n", nblk, nblk * 100.0/ntot);printf ("Char special =%7ld,%5.2f%%\n", NCHR, NCHR * 100.0/ntot);    printf ("Fifls =%7ld,%5.2f%%\n", Nfifo, Nfifo * 100.0/ntot);    printf ("Symbolic links =%7ld,%5.2f%%\n", Nslink, Nslink * 100.0/ntot);    printf ("sockets =%7ld,%5.2f%%\n", Nsock, Nsock * 100.0/ntot); Exit (ret);} /* * Descend through the hierarchy starting at "pathname". * The caller ' s func () is called for every file. * */#define FTW_F 1//file other than Directory#define Ftw_d 2//Directory#define FTW_DNR 3//directory Thar can ' t is read#define ftw_ns 4//file that we can ' t statstatic char *fullpath; Contains full pathname for every filestatic size_t pathlen;static int myftw (char *pathname, Myfunc *func)//We return Whatever func () returns{FullPath = Path_alloc (&pathlen);//malloc path_max+1 bytes if (pathlen <= strlen (PA        Thname)) {Pathlen = strlen (pathname) * 2; if ((FullPath = ReAlloc (FullPath, pathlen)) = = = NULL) {Err_sys("ReAlloc failed");    }} strcpy (FullPath, pathname); Return (Dopath (func));} /* * Descend through the hierarchy, starting at "FullPath". * If "FullPath" is anything other than a directory, we Lstat () it * call Func (), and return. For a directory, we are ourself * recursively for each name in the directory.    * */static int Dopath (Myfunc *func)//We return whatever func () returns{struct stat statbuf;    struct Dirent *dirp;    DIR * DP;    int ret, n;    if (Lstat (FullPath, &statbuf) < 0) {//STAT error return (func (FullPath, &statbuf, Ftw_ns));    } if (S_isdir (statbuf.st_mode) = = 0) {//Not a directory return (func (FullPath, &statbuf, Ftw_f)); }/* * It ' s a directory.     First call Func () for the directory, * then process each of the filename in the directory.    * */if (ret = func (FullPath, &statbuf, ftw_d))! = 0) {return ret;    } n = strlen (FullPath); if (n + name_max +2 > Pathlen) {//expand path BUffer Pathlen *= 2;        if (FullPath = ReAlloc (FullPath, pathlen)) = = NULL) {Err_sys ("ReAlloc failed");    }} fullpath[n++] = '/';    Fullpath[n] = 0;    if (DP = Opendir (fullpath)) = = NULL) {//can ' t read directory return func (FullPath, &statbuf, FTW_DNR);            } while ((DIRP = Readdir (DP)) = NULL) {if (strcmp (Dirp->d_name, ".") = = 0 | | strcmp (Dirp->d_name, "..") = = 0) {continue;//Ignore dot and Dot-dot} strcpy (&fullpath[ N], dirp->d_name);    Append name Agter "/" if (ret = Dopath (func))! = 0) {//recursive break;//Time to leave} } fullpath[n-1] = 0;    Erase everything from slash onward if (Closedir (DP) < 0) {Err_ret ("can ' t close directory%s", FullPath); } return ret;} static int myfunc (const char *pathname, const struct STAT *statptr, int type) {switch (type) {case FTW_F:SW Itch (Statptr->st_mode &            S_IFMT) {case S_ifreg: ++nreg;        Break            Case S_IFBLK: ++nblk;        Break            Case S_IFCHR: ++NCHR;        Break            Case S_IFIFO: ++nfifo;        Break            Case S_iflnk: ++nslink;        Break            Case S_ifsock: ++nsock;        Break        Case S_IFDIR://directories should has type = Ftw_d err_dump ("For S_ifdir for%s", pathname);    } break;        Case Ftw_d: ++ndir;    Break        Case Ftw_dnr:err_ret ("can ' t read directory%s", pathname);    Break        Case Ftw_ns:err_ret ("Stat error for%s", pathname);    Break    Default:err_dump ("Unknow type%d for pathname%s", type, pathname); } return 0;}

pathalloc.h//2015-08-18 Lucifer zhang//Dynamically allocate space for a pathname#include "apue.h" #include <errn o.h> #include <limits.h> #ifdef path_maxstatic long pathmax = Path_max; #elsestatic long pathmax = 0; #endifstatic l Ong posix_version = 0;static Long xsi_version = 0;//If Path_max is indeterminate, no guarantee the is Adequate#define PA    Th_max_guess 1024char* Path_alloc (size_t *sizep) {//also return allocated size, if nonnull char *ptr;    size_t size;    if (posix_version = = 0) {posix_version = sysconf (_sc_version);    } if (xsi_version = = 0) {xsi_version = sysconf (_sc_xopen_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;//And One since it s relative to root}}/* * Before posix.1-2001, we aren ' t guaranteed that Phat_max include S * the terminating null byte.     Same goes for XPG3.    */if ((Posix_version < 200112L) && (Xsi_version < 4)) {size = Pathmax + 1;    } else {size = Pathmax;    } if (ptr = malloc (size) = = NULL) {err_sys ("malloc error for pathname");    } if (Sizep! = NULL) {*sizep = size; } return ptr;}

Test results on the Centos6.7:


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Recursive their oaths traversal of directory hierarchies and counting by file type

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.