• 递归查找无效的符号链接 分类: linux c/c++ 2014-06-02 00:14 345人阅读 评论(0) 收藏


    本程序实现在指定目录下递归查找无效的符号链接。
    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
    ",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
    ", 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
    ",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
    ",filepath);
            continue;
          }
          object[buf1.st_size]='';
          
          /*获取目标文件的路径*/
          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
    ",filepath);    //若返回-1,则认为链接文件无效.
           }
        }
      }
      closedir(dp);
    }
    
    
    
    
    
    
    


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    【WPF】 前言
    【设计模式】 建造者
    拖动调整显示框的显示区域大小
    HTTP权威指南
    input自动获取焦点
    元素JS拖动的实现
    手机端html5触屏事件(touch事件)
    使用".."指定git提交范围与"..."指定git提交范围的区别
    Long-term stable release maintenance
    MEMS--微机电系统
  • 原文地址:https://www.cnblogs.com/luo-peng/p/4646259.html
Copyright © 2020-2023  润新知