递归查找无效的符号链接 分类: linux c/c++ 2014-06-02 00:14 345人阅读 评论(0) 收藏
本程序实现在指定目录下递归查找无效的符号链接。
1.设计思路
逐个读取给定目录中的目录项,判断类型
(1)若为目录,则读取该目录中的目录项并判断类型;
(2)若为链接文件,则读取出其指向文件的名称(绝对/相对路径);
若内容为绝对路径(以/开头),直接作为目标文件的路径;
若内容为相对路径(不以/开头),将链接文件所在目录的路径作为前缀;
这样构造出目标文件的路径,尝试用stat函数直接读取目标文件,若返回-1
则认为该链接文件失效。选用stat的好处是可以跳过连续符号链接,查看链接
最终指向的非链接文件的状态。
1.设计思路
逐个读取给定目录中的目录项,判断类型
(1)若为目录,则读取该目录中的目录项并判断类型;
(2)若为链接文件,则读取出其指向文件的名称(绝对/相对路径);
若内容为绝对路径(以/开头),直接作为目标文件的路径;
若内容为相对路径(不以/开头),将链接文件所在目录的路径作为前缀;
这样构造出目标文件的路径,尝试用stat函数直接读取目标文件,若返回-1
则认为该链接文件失效。选用stat的好处是可以跳过连续符号链接,查看链接
最终指向的非链接文件的状态。
(3)若为其他类型,直接跳过。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<dirent.h> #include<errno.h> #define MAX 1024 void list_dead_link(char *path); void main(int argc, char *argv[]) { if(argc!=2) { fprintf(stderr, "Usage: %s dir_name\n",argv[0]); exit(1); } list_dead_link(argv[1]); exit(0); } /*对目录树递归查找失效的符号链接*/ void list_dead_link(char *path) { DIR *dp; struct dirent *dirp; struct stat buf1,buf2; char object[MAX]={0}; char objectpath[MAX]={0}; char filepath[MAX]={0}; ssize_t n; if((dp = opendir(path)) == NULL) { fprintf(stderr, "can't open %s\n", path); return; } while((dirp=readdir(dp))!=NULL) { if(strcmp(dirp->d_name,".")==0||strcmp(dirp->d_name,"..")==0)//防止死循环. continue; sprintf(filepath,"%s/%s",path,dirp->d_name);//构造文件(夹)路径. if(lstat(filepath,&buf1) ==-1) { fprintf(stderr, "lstat %s error\n",filepath); continue; } if(S_ISDIR(buf1.st_mode))//若为目录,递归查找. list_dead_link(filepath); if(S_ISLNK(buf1.st_mode))//若为链接文件,则判断其是否有效. { if((n=readlink(filepath,object, buf1.st_size+1))==-1) { fprintf(stderr, "readlink %s error\n",filepath); continue; } object[buf1.st_size]='\0'; /*获取目标文件的路径*/ if(object[0]=='/') //若为绝对路径,直接作为目标文件路径 sprintf(objectpath,"%s",object); else //若为相对路径,则用path做前缀来构造 sprintf(objectpath,"%s/%s",path,object); if(stat(objectpath,&buf2)==-1) //此处使用stat()直接尝试读取objectpath指向的 { //目标文件,可跳过连续的符号链接. //if(errno==ENOENT||errno==ELOOP) printf("dead:%s\n",filepath); //若返回-1,则认为链接文件无效. } } } closedir(dp); }
版权声明:本文为博主原创文章,未经博主允许不得转载。