• 实现Linux下的ls -l命令


    基本实现了Linux下的ls -l命令,对于不同的文件显示不同的颜色和显示符号链接暂时没有实现:

      1 /*************************************************************************
      2     > File Name: dirwalk.c
      3     > Author: 
      4     > Mail: 
      5     > Created Time: Tue 31 Mar 2015 11:56:38 AM CST
      6  ************************************************************************/
      7 
      8 #include<stdio.h>
      9 #include <sys/types.h>
     10 #include <sys/stat.h>
     11 #include <fcntl.h>
     12 #include <unistd.h>
     13 #include <stdlib.h>
     14 #include <string.h>
     15 #include <dirent.h>
     16 #include <time.h>
     17 
     18 #define MAX_PATH 1024
     19 #define MODE_LEN 10
     20 #define TIME_LEN 20
     21 #define NAME_LEN 30
     22 
     23 unsigned long  ugo_mode[9] = {S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH};
     24 char* rwx[3] = {"r", "w", "x"};
     25 char* userpath = "/etc/passwd";
     26 char* grouppath = "/etc/group";
     27 
     28 /*dirwalk: apply fcn to all files in dir */
     29 void dirwalk(char* dir, void(*fcn)(char*))
     30 {
     31     struct dirent *dp;
     32     DIR* dfd;
     33 
     34     char name[MAX_PATH];
     35     if((dfd = opendir(dir)) == NULL)
     36     {
     37         fprintf(stderr, "dirwalk: can't open %s
    ", dir);
     38         return;
     39     }
     40 
     41     while((dp = readdir(dfd)) != NULL)
     42     {
     43         if(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
     44         {
     45             continue;
     46         }
     47 
     48         if(strlen(dir) + strlen(dp->d_name) + 2 > sizeof(name))
     49         {
     50             fprintf(stderr, "%s/%s too long
    ", dir, dp->d_name);
     51         }else
     52         {
     53             sprintf(name, "%s/%s", dir, dp->d_name);
     54             (*fcn)(name);
     55         }
     56     }
     57     closedir(dfd);
     58 }
     59 
     60 /*getname: get the name of the user and the name of the group name */
     61 void getname(char* path, int id, char* name)
     62 {   
     63 
     64     int fd, save_fd;
     65     if((fd = open(path, O_RDONLY)) < 0)
     66     {
     67         perror("open 
    ");
     68         exit(1);
     69     }
     70     
     71     save_fd = dup(STDIN_FILENO);
     72     dup2(fd, STDIN_FILENO);
     73     close(fd);
     74     char p[MAX_PATH];
     75     char usrid[20];
     76     sprintf(usrid, "%d", id);
     77     char* puid;
     78     while((scanf("%s", p)) != EOF)
     79     {
     80         if((puid = strstr(p, usrid)) != NULL)
     81         {
     82             char* pFlag;
     83             char* pResult;
     84             if((pFlag = strstr(p, ":")) != NULL)
     85             {
     86                 pResult = pFlag;
     87                 pFlag = strstr(pFlag + 1, ":");
     88             }
     89             if(pFlag != NULL)
     90             {
     91                 if((memcmp(pFlag + 1, puid, strlen(usrid))) == 0)
     92                 {
     93                     *pResult = '';
     94                     strcpy(name, p);
     95                 }
     96             }
     97             //printf("%s
    ", puid);
     98         }
     99     }
    100 
    101     dup2(save_fd, STDIN_FILENO);
    102     close(save_fd);
    103 }
    104 
    105 /*getmode: get the mode of a file in string format  by st_mode */
    106 void getmode(unsigned long  st_mode, char* mode)
    107 {
    108     switch(st_mode & S_IFMT)
    109     {
    110         case S_IFDIR:
    111             mode[0] = 'd';
    112             break;
    113         case S_IFIFO:
    114             mode[0] = 'p';
    115             break;
    116         case S_IFBLK:
    117             mode[0] = 'b';
    118             break;
    119         case S_IFCHR:
    120             mode[0] = 'c';
    121             break;
    122         case S_IFREG:
    123             mode[0] = '-';
    124             break;
    125         case S_IFLNK:
    126             mode[0] = 'l';
    127             break;
    128         case S_IFSOCK:
    129             mode[0] = 's';
    130             break;
    131         default:
    132             mode[0] = 'u';
    133             break;
    134     }
    135 
    136     int i;
    137     for(i = 0; i < 9; ++i)
    138     {
    139         if(st_mode & ugo_mode[i])
    140         {
    141             strcat(mode, rwx[i % 3]);
    142         }else
    143         {
    144             strcat(mode, "-");
    145         }
    146     }
    147 }
    148  
    149 
    150 /*gettime: get the time in string format */
    151 void gettime(const time_t ct, char* time)
    152 {
    153     char* tmp = ctime(&ct);
    154     time[0] = tmp[4];
    155     time[1] = tmp[5];
    156     time[2] = tmp[6];
    157     time[3] = ' ';
    158 
    159     struct tm* tm_buf = gmtime(&ct);
    160     char last[20];
    161     sprintf(last, "%02d %02d:%02d", tm_buf->tm_mday, tm_buf->tm_hour, tm_buf->tm_min);
    162     strcat(time, last);
    163 }
    164 
    165 /* print the file name and the size of the "name" */
    166 void fsize(char* name)
    167 {
    168     struct stat st_buf;
    169     if(stat(name, &st_buf) < 0)
    170     {
    171         fprintf(stderr, "fsize: can't access %s
    ", name);
    172         return;
    173     }
    174 
    175 
    176 
    177     if((st_buf.st_mode & S_IFMT) == S_IFDIR)
    178     {
    179         dirwalk(name, fsize);
    180     }
    181     char* time = (char*)malloc(sizeof(char) * TIME_LEN);
    182     memset(time, 0, TIME_LEN);
    183     gettime(st_buf.st_atime, time);
    184 
    185     char* mode = (char*)malloc(sizeof(char) * MODE_LEN);
    186     memset(mode, 0, MODE_LEN);
    187     getmode(st_buf.st_mode, mode);
    188 
    189 
    190     char* username = (char*)malloc(sizeof(char) * NAME_LEN);
    191     memset(username, 0, NAME_LEN);
    192     getname(userpath, st_buf.st_uid, username);
    193 
    194     char* groupname = (char*)malloc(sizeof(char) *  NAME_LEN);
    195     memset(groupname, 0, NAME_LEN);
    196     getname(grouppath, st_buf.st_gid, groupname);
    197 
    198     printf("%s %d %s %s  %4ld %s %s
    ", mode, (int)st_buf.st_nlink, username, groupname,  st_buf.st_size, time,  name);
    199     free(groupname);
    200     free(username);
    201     free(mode);
    202     free(time);
    203 }
    204 
    205 int main(int argc, char* argv[])
    206 {
    207     if(argc == 1)
    208         fsize(".");
    209     while(--argc)
    210         fsize(*++argv);
    211     return 0;
  • 相关阅读:
    myeclipse自带客户端连接mysql数据库
    javaweb学习总结八(xml约束DTD)
    javaweb学习总结七(XML语言作用、语法)
    javaweb学习总结六(泛型)
    plsql常用快捷键
    javaweb学习总结五(内省、beanUtils工具包)
    javaweb学习总结四(反射技术)
    javaweb学习总结三(枚举)
    eclipse常用快捷键汇总
    plsql设置窗口默认格式
  • 原文地址:https://www.cnblogs.com/wwblog/p/4382263.html
Copyright © 2020-2023  润新知