Linuxでのls-lコマンドの実装

29651 ワード

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 = '\0'; 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;