Advanced Programming in UNIX Environment Episode 18

#include "apue.h"
#include <dirent.h>
#include <limits.h>

typedef int Myfunc(const char *,const struct stat *,int);

static Myfunc myfunc;
static int myftw(char *,Myfunc *);
static int 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);
    ntot=nreg+ndir+nblk+nchr+nfifo+nslink+nsock;
    if(ntot==0)
    {
        ntot=1;
    }
    printf("regular files = %7ld,%5.2f %%\n",nreg,nreg*100.0/ntot);
    printf("directories = %7ld,ndir*100.0/ntot);
    printf("block special = %7ld,nblk*100.0/ntot);
    printf("char special = %7ld,nchr*100.0/ntot);
    printf("FIFOs = %7ld,nfifo*100.0/ntot);
    printf("symbolic links = %7ld,nslink*100.0/ntot);
    printf("sockets = %7ld,nsock*100.0/ntot);
    return 0;
}

#define FTW_F 1
#define FTW_D 2
#define FTW_DNR 3
#define FTW_NS 4

static char *fullpath;
static size_t pathlen;

static int myftw(char *pathname,Myfunc *func)
{
    fullpath=path_alloc(&pathlen);

    if(pathlen<=strlen(pathname))
    {
        pathlen=strlen(pathlen)*2;
        if((fullpath=realloc(fullpath,pathlen))==NULL)
            err_sys("realloc failed");
    }
    strcpy(fullpath,pathname);
    return dopath(func);
}

static int dopath(Myfunc *func)
{
    struct stat statbuf;
    struct dirent *dirp;
    DIR *dp;
    int ret,n;
    if(lstat(fullpath,&statbuf)<0)
        return func(fullpath,&statbuf,FTW_NS);
    if(S_ISDIR(statbuf.st_mode)==0)
        return func(fullpath,FTW_F);

    if((ret=func(fullpath,FTW_D))!=0)
        return ret;
    n=strlen(fullpath);
    if(n+NAME_MAX+2>pathlen)
    {
        pathlen*=2;
        if((fullpath=realloc(fullpath,pathlen))==NULL)
            err_sys("realloc failed");
    }
    fullpath[n++]='/';
    fullpath[n]=0;
    if((dp=opendir(fullpath))==NULL)
        return func(fullpath,FTW_DNR);
    while((dirp=readdir(dp))!=NULL)
    {
        if(strcmp(dirp->d_name,".")==0||
            strcmp(dirp->d_name,"..")==0)
                continue;
        strcpy(&fullpath[n],dirp->d_name);
        if((ret=dopath(func))!=0)
            break;
    }
    fullpath[n-1]=0;
    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:
            switch(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++;
                case S_IFSOCK:
                    nsock++;
                    break;
                case S_IFDIR:
                    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("unknown type %d for pathname %s",type,pathname);
    }
    return 0;
}

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...