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

📄 myfind.c

📁 (1)myfind <pathname> 的功能: 除了具有与程序4-7相同的功能外
💻 C
字号:
#include "apue.h"#include <dirent.h>#include <limits.h>#include <fcntl.h>#include "pathalloc.c"   //pathalloc.c必须与myfind.c同一个目录#define	 BUFSIZE	1024 //缓冲区的大小typedef int Myfunc(const char *,const struct stat *,int);static Myfunc myfunc,myfunc2,myfunc3;static int myftw(char *,Myfunc *);static int dopath(Myfunc *);static long nreg,ndir,nchr,nblk,nfifo,nslink,nsock,ntot,ngre;//ngre用来统计文件大小<=4096的文件static long filedes,length;static char *str;int main(int argc,char *argv[]){    int ret;    if(argc<2 || argc==3)        err_quit("usage: myfind <pathname> or myfind <pathname> -comp <filename> or myfind <pathname> -name <str>...\n");    if(argc==2){   	 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("size of reg_file<=4096B 	         =%7ld, %5.2f %%\n",ngre,ngre*100.0/ntot);  	 printf("dirctories   				 =%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 links				 =%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")){//实现第二个功能:查找与argv[3]内容一样的文件	 if((filedes=open(argv[3],O_RDONLY))==-1)		err_quit("cannot open\n");	 if((length=lseek(filedes,0,SEEK_END))==-1)//用length来保存命令中argv[3]文件的大小		err_quit("lseek error\n");	 ret=myftw(argv[1],myfunc2);	 close(filedes);    }    else if(argc>=4 && !strcmp(argv[2],"-name")){//实现第三个功能:查找与<str>...相同的文件	int i,j;	for(i=4;i<=argc;i++){//用循环处理<str>...中的每一个		ret=strlen(argv[i-1]);		if((str=(char *)malloc(ret*sizeof(char)))==NULL)			err_quit("malloc error\n");		for(j=ret;argv[i-1][j]!='/' && j>=0;j--) ;//有路径,则定位到去除路径后的位置		strcpy(str,&argv[i-1][++j]);//用全局变量str来保存文件名		ret=myftw(argv[1],myfunc3);		free(str);	}    }    else	err_quit("usage:myfind <pathname> -comp <filename> or myfind <pathname> -name <str>...\n");    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 len;    fullpath=(char *)path_alloc(&len);    strncpy(fullpath,pathname,len);    fullpath[len-1]=0;    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 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++;				       if(statptr->st_size<=4096)				 		ngre++;			       	       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: 	;           		  }          	     break;      	      case FTW_D: ndir++;	break;      	      case FTW_DNR:	;	break;              case FTW_NS:	;	break;              default:		;  	 }	return 0;}static int myfunc2(const char *pathname,const struct stat *statptr,int type){	int  filede2,len,i,flags=0;	long length2;	char *buf2,*buf,*path;	if(type==FTW_F){//pathname是文件		if((filede2=open(pathname,O_RDONLY))==-1)	return 0;		if(length==statptr->st_size){//大小相同才有可能内容相同			if(lseek(filedes,0,SEEK_SET)==-1){close(filede2);return 0;}			i=length/BUFSIZE;//循环的次数			buf2=(char *)malloc((BUFSIZE+1)*sizeof(char));//最后一个来放'\0'			buf=(char *)malloc((BUFSIZE+1)*sizeof(char));			for(len=0;len<i;len++){	//以BUFSIZE大小逐一对两文件进行比较								if(read(filedes,buf,BUFSIZE)!=BUFSIZE){	flags=1;break;}				if(read(filede2,buf2,BUFSIZE)!=BUFSIZE){flags=1;break;}				buf[BUFSIZE]='\0';buf2[BUFSIZE]='\0';				if(strcmp(buf,buf2)){flags=1;break;}			}			if(flags){free(buf);free(buf2);close(filede2);return 0;}			else if((i=length%BUFSIZE)!=0){//比较最后大小小于BUFSIZE部分				if(read(filedes,buf,i)!=i){free(buf);free(buf2);close(filede2);return 0;}				if(read(filede2,buf2,i)!=i){free(buf);free(buf2);close(filede2); return 0;}				buf[i]='\0';buf2[i]='\0';				if(strcmp(buf,buf2)){free(buf);free(buf2);close(filede2);return 0;}			}			free(buf2);free(buf);			if((path=(char *)malloc(strlen(pathname)*sizeof(char)))==NULL){close(filede2); return 0;}			for(len=strlen(pathname)-1;pathname[len]!='/'&&len>=0;len--) ;//查找pathname文件所在目录			for(i=0;i<=len;i++)//把文件pathname的目录名拷贝到path里				path[i]=pathname[i];			path[i]='\0';			buf2=path_alloc(&len);			if(getcwd(buf2,len)==NULL){close(filede2);return 0;}//用buf2保存当前程序所在的目录			if(chdir(path)==-1){close(filede2);return 0;}//切换到文件pathname所在的目录			buf=path_alloc(&len);			if(getcwd(buf,len)==NULL){close(filede2);return 0;}//用buf保存pathname所在的目录			if(chdir(buf2)==-1){close(filede2);return 0;}//切换回到程序运行所在的目录			for(i=strlen(pathname)-1;pathname[i]!='/';i--) ;//把pathname文件名提取出来			strcat(buf,&pathname[i]);			printf("%s\n",buf);			free(buf);free(buf2);free(path);		}		close(filede2);	}        return 0;}static int myfunc3(const char *pathname,const struct stat *statptr,int type){	int len,i;	char *buf,*path,*buf2;	if(type==FTW_F){		if((path=(char *)malloc(strlen(pathname)*sizeof(char)))==NULL)	return 0;		for(len=strlen(pathname)-1;pathname[len]!='/' && len>=0;len--) ;//查找pathname文件所在目录		if(!strcmp(str,&pathname[len+1])){//文件名相等			for(i=0;i<=len;i++)//把文件pathname的目录名拷贝到path里				path[i]=pathname[i];			path[i]='\0';			buf2=path_alloc(&len);			if(getcwd(buf2,len)==NULL)	return 0;//用buf2保存当前程序所在的目录			if(chdir(path)==-1)		return 0;//切换到文件pathname所在的目录			buf=path_alloc(&len);			if(getcwd(buf,len)==NULL)	return 0;//用buf保存pathname所在的目录			if(chdir(buf2)==-1)		return 0;//切换回到程序运行所在的目录			for(i=strlen(pathname)-1;pathname[i]!='/';i--) ;//把pathname文件名提取出来			strcat(buf,&pathname[i]);			printf("%s\n",buf);			free(buf2);free(buf);free(path);		}	}	return 0;} 

⌨️ 快捷键说明

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