zoukankan      html  css  js  c++  java
  • Understanding Unix/Linux Programming-ls指令练习二

    • 完善ls练习一的功能:
      1. 排序,使用qsort
      2. 分栏,计算宽度和行数
      3. 文件“.”的显示需要由-a选项来选择
      4. 详细信息的显示,-l选项
    • 将stat结构体中的st_mode——16位二进制数转换成10位的字符串
      • 15-12:type
      • 11:suid
      • 10:sgid
      • 9:sticky
      • 8-6:user
      • 5-3:group
      • 2-0:other
    • /etc/passwd文件中包含了用户信息,每行对应一个用户,不同的属性按照分号‘:’隔开。
      • 该文件并未包含所有的用户,在某些网络计算系统中,用户需要登录到任何一台主机上,会有NIS统一地进行身份验证,本地保存的只是一个用户子集。
      • getpwuid系统调用具有较好的可移植性,会从NIS中查找如果在本地找不到的话
    • /etc/group包含了组信息,字段分别为1,组名;2,组密码;3,组ID;4,组成员列表
      • 一个用户可以属于多个组的
      • getgrgid可以用来访问组列表,移植性同上getpwuid

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <sys/stat.h>
      4 #include <dirent.h>
      5 #include <pwd.h>
      6 #include <grp.h>
      7 #include <string.h>
      8 #include <time.h>
      9 
     10 void do_ls(char[]);
     11 void show_file_info(char * filename , struct stat * statbufp );
     12 void mode2letter(int mode , char str[]);
     13 void print_uid2name(uid_t uid );
     14 void print_gid2name(gid_t gid );
     15 
     16 int main(int ac , char * av[])
     17 {
     18     if(ac == 1 )
     19     {
     20         do_ls(".");
     21     }
     22     else
     23     {
     24         while( -- ac )
     25         {
     26             printf("%s:
    ", * (++ av) );
     27             do_ls(*av);
     28         }
     29     }
     30     return 0 ;
     31 }
     32 
     33 void do_ls(char dirname[])
     34 {
     35     DIR * dir_ptr ;
     36     struct dirent * direntp ;
     37     struct stat statbuf ;
     38 
     39     if( ( dir_ptr = opendir(dirname) )== NULL )
     40     {
     41         fprintf(stderr, "ls1 can not open %s
    ", dirname );
     42     }
     43     else
     44     {
     45         while( ( direntp = readdir(dir_ptr ) ) != NULL )
     46         {
     47             if( stat(direntp -> d_name , &statbuf) == -1 )
     48             {
     49                 perror(direntp -> d_name );
     50             }
     51             else
     52             {
     53                 show_file_info( direntp -> d_name , &statbuf);
     54             }
     55         }
     56     }
     57 
     58     closedir(dir_ptr);
     59 }
     60 
     61 void show_file_info( char * filename, struct stat * statbufp )
     62 {
     63     char modestr[11]; // include '' so 10 + 1 = 11
     64 
     65     mode2letter(statbufp -> st_mode , modestr) ;
     66     printf("%s",  modestr );
     67 
     68     printf("%4d", (int)statbufp -> st_nlink ) ;
     69     print_uid2name( statbufp -> st_uid ) ;
     70     print_gid2name( statbufp -> st_gid ) ;
     71     printf("%8ld", (long) (statbufp -> st_size) );
     72     printf(" %12.12s", (char*)(4 + ctime(&(statbufp -> st_mtime)) ));
     73     printf(" %s
    ",filename );
     74 }
     75 
     76 void mode2letter(int mode , char str[])
     77 {
     78     strcpy(str , "----------");
     79 
     80     if( S_ISDIR( mode ))
     81         str[0] = 'd' ;
     82     else if( S_ISCHR( mode ))
     83         str[0] = 'c' ;    // else for efficience
     84     else if( S_ISBLK( mode ))
     85         str[0] = 'b' ;
     86 
     87     if( mode & S_IRUSR )
     88         str[1] = 'r' ;
     89     if( mode & S_IWUSR )
     90         str[2] = 'w' ;
     91     if(mode & S_IXUSR )
     92         str[3] = 'x' ;
     93 
     94     if( mode & S_IRGRP )
     95         str[4] = 'r' ;
     96     if( mode & S_IWGRP )
     97         str[5] = 'w' ;
     98     if( mode & S_IXGRP )
     99         str[6] = 'x' ;
    100 
    101     if( mode & S_IROTH )
    102         str[7] = 'r' ;
    103     if( mode & S_IWOTH )
    104         str[8] = 'w' ;
    105     if( mode & S_IXOTH )
    106         str[9] = 'x' ;
    107 }
    108 
    109 void print_uid2name( uid_t uid )
    110 {
    111     struct passwd * passwdbufp ;
    112 
    113     if(( passwdbufp = getpwuid(uid)) != (struct passwd *)NULL ) // Except for error
    114     {
    115         printf( "%-8s" , passwdbufp -> pw_name ) ;
    116     }
    117     else
    118     {
    119         printf( "%8d" , uid) ;
    120     }
    121 
    122 }
    123 
    124 void print_gid2name(gid_t gid)
    125 {
    126     struct group * grp_ptr ;
    127     if(( grp_ptr = getgrgid(gid)) != (struct group * )NULL )
    128     {
    129         printf("%-8s" , grp_ptr -> gr_name ) ;
    130     }
    131     else
    132     {
    133         printf("%8d" , gid ) ;
    134     }
    135 }

    ls2.c完成了 ls -l 的功能。但是有几点不足之处:

    1. 不显示总数,这个容易解决
    2. 未排序
    3. 不支持参数-a
    4. 假设参数只是目录名
    5. 不能显示指定目录的信息

    以上代码在OpenSuse Leap42.1上测试通过,参考原书《Unix/Linux编程实践教程》,但是含有个人修改部分,不影响功能。

  • 相关阅读:
    校验器
    Mybatis分页中遇到的坑3

    Lock1
    Validation(4)-临时
    在Java中如何判断对象已死?
    垃圾回收算法的种类
    Java内存区域
    Java 中的 volatile关键字含义
    分别写出堆内存溢出与栈内存溢出的程序?
  • 原文地址:https://www.cnblogs.com/NJdonghao/p/5257721.html
Copyright © 2011-2022 走看看