zoukankan      html  css  js  c++  java
  • myownftw.c(4.21)

    //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);
      }
    }
  • 相关阅读:
    centos 用户管理
    rsync 实验
    文件共享和传输
    PAT 1109 Group Photo
    PAT 1108 Finding Average
    PAT 1107 Social Clusters
    PAT 1106 Lowest Price in Supply Chain
    PAT 1105 Spiral Matrix
    PAT 1104 Sum of Number Segments
    PAT 1103 Integer Factorization
  • 原文地址:https://www.cnblogs.com/beanmoon/p/2731690.html
Copyright © 2011-2022 走看看