ls的C语言实现

  1. /* 
  2.     Name: list.c 
  3.     Author: guozan _SCS_BUPT 
  4.     Mail: guozan523@foxmail.com 
  5.     Date: 2010/4/6 
  6.     实验目的:练习vi,使用UNIX的系统调用和库函数,体会UNIX文件通配符的处理方式以及命令对选项的处理方式。 
  7.     编程实现程序list.c,列表普通磁盘文件(不考虑目录和设备文件等),列出文件名和文件大小。 
  8.     与ls命令类似,命令行参数可以有0到多个 
  9.     0个参数:列出当前目录下所有文件 
  10.     参数为普通文件:列出文件 
  11.     参数为目录:列出目录下所有文件 
  12.     实现自定义选项r,a,l,h,m以及-- 
  13.     r 递归方式列出子目录 
  14.     a 列出文件名第一个字符为圆点的普通文件(默认情况下不列出文件名首字符为圆点的文件) 
  15.     l 后跟一整数,限定文件大小的最小值(字节) 
  16.     h 后跟一整数,限定文件大小的最大值(字节) 
  17.     m 后跟一整数n,限定文件的最近修改时间必须在n天内 
  18.     --  显式地终止命令选项分析 
  19. */  
  20. #include <sys/stat.h>   
  21. #include <sys/types.h>   
  22. #include <dirent.h>   
  23. #include <unistd.h>   
  24. #include <stdio.h>   
  25. #include <string.h>   
  26. /* 
  27.     slective options about ls 
  28.     rflag is about recursive 
  29.     aflag is about ones with . infront 
  30.     lflag is about the minimum size 
  31.     hflag is about the maximum size 
  32.     mflag is about the modified time 
  33. */  
  34. int rflag, aflag, lflag, hflag, mflag;  
  35. long modified_time;        //the last time file be modified, days ago   
  36. off_t lower_size;            //file's minimum size   
  37. off_t upper_size;            //file's maximum size   
  38. /* 
  39.     set the flags, thus the ls option 
  40. */  
  41. void getoptions(int argc, char *argv[])  
  42. {  
  43.     char ch;  
  44.     //clear, all unseted   
  45.     rflag = 0; aflag = 0; lflag = 0; hflag = 0; mflag = 0;  
  46.     //use getopt to get the options, want to know more, call man   
  47.     //the last one or after -- was set in argv[optind]   
  48.     while ((ch = getopt(argc, argv, "ral:h:m:")) != -1) {  
  49.         switch (ch) {  
  50.             case 'r': rflag = 1; break;  
  51.             case 'a': aflag = 1; break;  
  52.             case 'l': lflag = 1; lower_size = atol(optarg); break;  
  53.             case 'h': hflag = 1; upper_size = atol(optarg); break;  
  54.             case 'm': mflag = 1; modified_time = atol(optarg); break;    //get days   
  55.             case '?': printf("Unknown option: %c/n", (char)optopt); break;  
  56.             default : printf("Step into default/n"); break;  
  57.         }  
  58.     }  
  59. }  
  60. /* 
  61.     the function to list things in path 
  62. */  
  63. int ls(char *path)  
  64. {  
  65.     struct stat st;        //for check this is a directory or file   
  66.     char temp[100];        //if path is null, it is used to get current directory   
  67.     // get the path   
  68.     if (path == NULL || path[0] == '-') {  
  69.         path = temp;  
  70.         getcwd(path, 100);  
  71.     }  
  72.     /* open the inode of file */  
  73.     if (lstat(path, &st)) {  
  74.         fprintf(stderr, "Error: %s not exist./n", path);  
  75.         return (-1);  
  76.     }  
  77.     /* judge whether the file is a file or a directory */  
  78.     if (S_ISDIR(st.st_mode)) {  
  79.         ls_dir(path);  
  80.     }  
  81.     else if (S_ISREG(st.st_mode)) {  
  82.         print(path);  
  83.     }  
  84.     else {  
  85.         printf("Not ordinary file, wouldn't be listed./n");  
  86.     }  
  87.     return 0;  
  88. }  
  89. /* 
  90.     list dirs, may recursively or not, depending on rflag 
  91.     one thing is sure that it will list directories and files first, 
  92.     then consider the things in the directories 
  93. */  
  94. int ls_dir(char *path)  
  95. {  
  96.     DIR *dp = NULL;  
  97.     struct dirent *dirp = NULL;  
  98.     if (path[0] != '.' || (path[0] == '.' && aflag == 1)) {  
  99.         printf("/n%s:/n****************************************/n", path);  
  100.         /* open the directory */  
  101.         if ((dp = opendir(path)) == NULL) {  
  102.             fprintf(stderr, "Error: can't open directory %s!/n", path);  
  103.             return (-1);  
  104.         }  
  105.         chdir(path);  
  106.         /* list all the things in directory */  
  107.         while ((dirp = readdir(dp)) != NULL) {  
  108.             print(dirp->d_name);  
  109.         }  
  110.         /* recursively ls dirs, after ls things together, 
  111.             it's time to list things in children directory */  
  112.         if (rflag == 1) {  
  113.             rewinddir(dp);    //reset dp   
  114.             while ((dirp = readdir(dp)) != NULL) {  
  115.                 if (strcmp(dirp->d_name, ".") == 0  
  116.                     || strcmp(dirp->d_name, "..") == 0) {    //no current and parent directory   
  117.                     continue;  
  118.                 }  
  119.                 ls_dir_r(dirp->d_name);        //only list directories, judged inside the function   
  120.             }  
  121.         }  
  122.         /* close the directory */  
  123.         if (closedir(dp)) {  
  124.             fprintf(stderr, "Error: can't close the directory %s!/n", path);  
  125.             return -1;  
  126.         }  
  127.         chdir("..");  
  128.     }  
  129.     return 0;  
  130. }  
  131. /* 
  132.     list directories recursively, 
  133.     only directories, nomatter what path you put in 
  134. */  
  135. int ls_dir_r(char *path)  
  136. {  
  137.     struct stat st;  
  138.     /* open the inode of file */  
  139.     if (lstat(path, &st)) {  
  140.         fprintf(stderr, "Error: %s not exist./n", path);  
  141.         return (-1);  
  142.     }  
  143.     /* only ls directories */  
  144.     if (S_ISDIR(st.st_mode)) {  
  145.         ls_dir(path);  
  146.     }  
  147. }  
  148. /* 
  149.     print the filetype/size/name on the screen 
  150. */  
  151. int print(char *path)  
  152. {  
  153.     struct stat st;  
  154.     time_t tp;  
  155.     char *filename = NULL;  
  156.     //get current time   
  157.     time(&tp);  
  158.     if (lstat(path, &st)) {  
  159.         fprintf(stderr, "Error: %s can't be opened./n", path);  
  160.         return (-1);  
  161.     }  
  162.     /* get file name */  
  163.     if ((filename = strrchr(path, '/')) != NULL) {  
  164.         filename++;  
  165.     }  
  166.     else {  
  167.         filename = path;  
  168.     }  
  169.     /* judge whether to list the file */  
  170.     if ((S_ISDIR(st.st_mode)|| S_ISREG(st.st_mode))    //only directories and normal files   
  171.         && (lflag == 0 || (lflag == 1 && (st.st_size >= lower_size)))         //the min size   
  172.         && (hflag == 0 || (hflag == 1 && (st.st_size <= upper_size)))     //the max size   
  173.         && (mflag == 0 || (mflag == 1 && ((tp - st.st_mtime) <= modified_time * 24 * 60 * 60)))    //modified time   
  174.         && (aflag == 1 || (aflag == 0 && filename[0] != '.'))    //file with a '.' infront   
  175.         ) {  
  176.         printf("%s/t%10ld/t%s/n", (S_ISDIR(st.st_mode) ? "DIR""FILE"), st.st_size, filename);  
  177.     }  
  178.     return 0;  
  179. }  
  180. /* 
  181.     The main function 
  182. */  
  183. int main(int argc, char *argv[])  
  184. {  
  185.     getoptions(argc, argv);  
  186.     ls(argv[optind]);  
  187.     return 0;  
  188. }  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值