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;