⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3.c

📁 UNIX下编程:目录树的遍历。包含文件:apue.h、error2e.c、pathalloc.c、3.c
💻 C
字号:
#include "apue.h"#include <dirent.h>#include<limits.h>#include<unistd.h>#include<fcntl.h>typedef int Myfunc(const char*,const struct stat*,int);static Myfunc myfunc1,myfunc2,myfunc3;static int myftw(char *,Myfunc *);static int dopath(Myfunc *);static long nreg,nreg_4096,ndir,nblk,nchr,nfifo,nslink,nsock,ntot;static int fd,augnum;char *aug[10];int main (int argc,char*argv[]){     int ret;     if(argc <2)       err_quit("usage : ftw <starting-pathname");     if(argc == 2)//   {     ret=myftw(argv[1],myfunc1);     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("regular files<=4096 = %7ld, %5.2f %%\n",nreg_4096,nreg_4096*100.0/nreg);     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("FIFOs               = %7ld, %5.2f %%\n",nfifo,nfifo*100.0/ntot);     printf("symbolic link       = %7ld, %5.2f %%\n",nslink,nslink*100.0/ntot);     printf("sockets             = %7ld, %5.2f %%\n",nsock,nsock*100.0/ntot);   }   else if(argc==4&&strcmp(argv[2],"-comp")==0)   {        if((fd=open(argv[3],O_RDWR))==-1)           err_ret("Open file %s error",argv[3]);        else        {         printf("the same content as file %s are:\n",argv[3]);         ret=myftw(argv[1],myfunc2);        }   }   else if(argc>=4&&strcmp(argv[2],"-name")==0)   {        augnum=0;        int i;        for(i=3;i != argc;i++)        {          aug[i-3]=argv[i];          augnum++;        }        printf("the sanme name of file are:\n");        ret=myftw(argv[1],myfunc3);   }   exit(ret);}#define FTW_F 1#define FTW_D 2#define FTW_DNR 3#define FTW_NS 4static char *fullpath;static int myftw(char *pathname,Myfunc *func){    //获得绝对路径名     int current;    char *currentpath;     int len;    fullpath = path_alloc(&len);    currentpath=path_alloc(&current);    if(getcwd(currentpath,current)==NULL)//获得当前路径,保存于current        err_ret("get currnt path faild");    if(chdir(pathname)!=0)//切换到要查找的路劲,保存于pathname        err_ret("chdir to %s faild",pathname);    if(getcwd(fullpath,len)==NULL)//获得要查找的路径的完整路径名,保存于fullpath        err_ret("get %s faild",pathname);    fullpath[len-1] = 0;//终止字符     if(chdir(currentpath)!=0)//切换到原来的工作目录        err_ret("chdir to %s faild",currentpath);         return (dopath(func));}static int dopath(Myfunc* func){     struct stat statbuf;     struct dirent *dirp;     DIR *dp;     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,".")== 0 ||             strcmp(dirp->d_name,"..")== 0)                    continue;          strcpy(ptr,dirp->d_name);          if((ret = dopath(func))!=0)            break;     }     ptr[-1]= 0;     if(closedir(dp) < 0)       err_ret("can't close dirctory %s",fullpath);     return (ret);}static int myfunc1(const char *pathname,const struct stat *statptr,int type){       switch(type)     {       case FTW_F:            switch(statptr->st_mode & S_IFMT)            {               case S_IFREG:  nreg++;   if(statptr->st_size<=4096)nreg_4096++; 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:                      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("unknowm type %d for pathname %s",type,pathname);     }     return(0);}static int myfunc2(const char *pathname,const struct stat *statptr,int type){     switch(type)    {            case FTW_F:                  switch(statptr->st_mode & S_IFMT)                 {                        case S_IFREG:                        {                             int fd1;                              int m,n,r1;                             char c1,c2;                             if((fd1=open(pathname,O_RDWR))==-1)                               // err_ret("open file %s error",pathname);                               break;//can't open the file                             m=lseek(fd,SEEK_END,0);                             n=lseek(fd1,SEEK_END,0);                             if(m!=n) return(0);//长度不同则两个文件不同                              else                              {                                while((r1=read(fd,&c1,1))!=0)                                {                                     read(fd1,&c2,1);                                     if(c1!=c2) return 0;//存在两个不相同的字符说明文件不同                                 }                             }                            printf("%s\n",pathname);                            break;                        }                        case S_IFBLK:  break;                        case S_IFCHR:  break;                        case S_IFIFO:  break;                        case S_IFLNK:  break;                        case S_IFSOCK: break;                        case S_IFDIR:                               err_dump("for S_IFDIR for %s",pathname);                 }                 break;            case FTW_D:   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("unknowm type %d for pathname %s",type,pathname);    }    return 0;} static int myfunc3(const char *pathname,const struct stat *statptr,int type){        switch(type)        {              case FTW_F:                   switch(statptr->st_mode & S_IFMT)                   {                         case S_IFREG:                         {                            int i;                            const  char *buf;                            for(i=strlen(pathname)-1;pathname[i]!='/';i--);                            buf=&(pathname[i+1]);                            for(i=0;i<augnum;i++)                            {                               if( strcmp(buf,aug[i])==0)                                 printf("%s\n",pathname);                            }                           }                         case S_IFBLK:  break;                         case S_IFCHR:  break;                         case S_IFIFO:  break;                         case S_IFLNK:  break;                         case S_IFSOCK: break;                         case S_IFDIR:                              err_dump("for S_IFDIR for %s",pathname);                       }                   break;              case FTW_D:   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("unknowm type %d for pathname %s",type,pathname);        }        return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -