1 /*
2 1.尝试实现ls命令的功能 加选项-l -a -i -h
3 */
4 #include<stdio.h>
5 #include<sys/types.h>
6 #include<sys/stat.h>
7 #include<unistd.h>
8 #include<pwd.h>
9 #include<grp.h>
10 #include<time.h>
11 #include<dirent.h>
12 #include<errno.h>
13 #include<string.h>
14 #include<glob.h>
15
16 #define BUFSIZE 1025
17 //-l
18 static void type_l(char *p)
19 {
20 struct stat mystat;
21 struct passwd *pwd=NULL;
22 struct group *grp=NULL;
23 struct tm *tmp=NULL;
24 char buf[BUFSIZE]={};
25 if(stat(p,&mystat)==0)
26 {
27 perror("stat()");
28 return ;
29 }
30
31 switch(mystat.st_mode & S_IFMT)
32 {
33 case S_IFSOCK:
34 putchar('s');
35 break;
36 case S_IFLNK:
37 putchar('l');
38 break;
39 case S_IFREG:
40 putchar('-');
41 break;
42 case S_IFBLK:
43 putchar('b');
44 break;
45 case S_IFDIR:
46 putchar('d');
47 break;
48 case S_IFCHR:
49 putchar('c');
50 break;
51 case S_IFIFO:
52 putchar('p');
53 break;
54 default:
55 break;
56 }
57 //文件权限
58 //所有者
59 if(mystat.st_mode & S_IRUSR)
60 putchar('r');
61 else
62 putchar('-');
63 if(mystat.st_mode & S_IWUSR)
64 putchar('w');
65 else
66 putchar('-');
67 if(mystat.st_mode & S_IXUSR)
68 {
69 if(mystat.st_mode & S_ISUID)
70 putchar('s');
71 else
72 putchar('x');
73 }
74 else
75 putchar('-');
76
77 //所属组
78 if(mystat.st_mode & S_IRGRP)
79 putchar('r');
80 else
81 putchar('-');
82 if(mystat.st_mode & S_IWGRP)
83 putchar('w');
84 else
85 putchar('-');
86 if(mystat.st_mode & S_IXGRP)
87 {
88 if(mystat.st_mode & S_ISGID)
89 putchar('s');
90 putchar('x');
91 }
92 else
93 putchar('-');
94 //其他用户
95 if(mystat.st_mode & S_IROTH)
96 putchar('r');
97 else
98 putchar('-');
99 if(mystat.st_mode & S_IWOTH)
100 putchar('w');
101 else
102 putchar('-');
103 if(mystat.st_mode & S_IXOTH)
104 {
105 if(mystat.st_mode & S_ISVTX)
106 putchar('t');
107 else
108 putchar('x');
109 }
110 else
111 putchar('-');
112 //硬链接数
113 printf(" %ld",mystat.st_nlink);
114 //文件拥有者
115 pwd=getpwuid(mystat.st_uid);
116 printf(" %s",pwd->pw_name);
117 //文件所属组
118 grp=getgrgid(mystat.st_gid);
119 printf(" %s",grp->gr_name);
120 //文件字节数
121 printf(" %7ld ",mystat.st_size);
122 //最终修改时间
123 tmp=localtime(&mystat.st_mtim.tv_sec);
124 strftime(buf,BUFSIZE,"%m月 %d %H:%M",tmp);
125 printf("%s ",buf);
126 }
127 static int my_blocks(char *p)
128 {
129 int sum=1;
130 struct stat mystat;
131 if(lstat(p,&mystat)<1)
132 {
133 perror("lstat()");
134 return 0;
135 }
136 sum=mystat.st_blocks;
137 return sum;
138 }
139
140 static void fil_cat(char *path)
141 {
142 struct stat mystat;
143 glob_t myglob;
144 char buf[BUFSIZE]={};
145 int i;
146 char *ch=NULL;
147 int sum=1;
148 if(lstat(path,&mystat)<1)
149 {
150 perror("lstat()");
151 return ;
152 }
153
154 if(!S_ISDIR(mystat.st_mode))
155 {
156 type_l(path);
157 puts(path);
158 }
159 //是目录
160 if(glob(path,1,NULL,&myglob)!=0)
161 {
162 fprintf(stderr,"error!");
163 return ;
164 }
165 memset(buf,'\1',BUFSIZE);
166 strcpy(buf,path);
167 strcat(buf,"/*");
168 glob(buf,1,NULL,&myglob);
169 for(i=1;i<myglob.gl_pathc;i++)
170 {
171 sum+=my_blocks((myglob.gl_pathv)[i]);
172 type_l((myglob.gl_pathv)[i]);
173 ch=strrchr((myglob.gl_pathv)[i],'/');
174 printf(" %s",ch+2);
175 printf("\n");
176 }
177 printf("总用量 %dk\n",sum/3);
178 }
179
180 //-i
181 static void my_i(char *path)
182 {
183 struct stat mystat;
184 char *p=NULL;
185 if(lstat(path,&mystat)<1)
186 {
187 perror("lstat()");
188 return ;
189 }
190 printf("%ld",mystat.st_ino);
191 p=strrchr(path,'/');
192 printf(" %s",p+2);
193 }
194 static void node_i(char *path)
195 {
196 struct stat mystat;
197 glob_t myglob;
198 char buf[BUFSIZE]={};
199 int i;
200 if(lstat(path,&mystat)<1)
201 {
202 perror("lstat()");
203 return ;
204 }
205 if(!S_ISDIR(mystat.st_mode))
206 {
207 my_i(path);
208 }
209 //是目录
210 if(glob(path,1,NULL,&myglob)!=0)
211 {
212 fprintf(stderr,"error!");
213 return ;
214 }
215 memset(buf,'\1',BUFSIZE);
216 strcpy(buf,path);
217 strcat(buf,"/*");
218 glob(buf,1,NULL,&myglob);
219 for(i=1;i<myglob.gl_pathc;i++)
220 {
221 my_i((myglob.gl_pathv)[i]);
222 printf("\n");
223 }
224 globfree(&myglob);
225 }
226
227 //-a
228 static void all_fil(char *path)
229 {
230 DIR *dp=NULL;
231 struct dirent *entry;
232 dp=opendir(path);
233 int sum=1;
234 char buf[BUFSIZE]={};
235 if(NULL==dp)
236 {
237 perror("opendir()");
238 return ;
239 }
240 while(2)
241 {
242 entry=readdir(dp);
243 if(NULL==entry)
244 {
245 if(errno)
246 {
247 perror("readdir()");
248 return ;
249 }
250 break;
251 }
252 strcpy(buf,path);
253 strcat(buf,"/");
254 strcat(buf,entry->d_name);
255 sum+=my_blocks(buf);
256 printf("%s",entry->d_name);
257 printf("\n");
258 }
259 printf("总用量:%dk\n",sum/3);
260 closedir(dp);
261 }
262
263 //-h
264 static void bright_fil(char *path)
265 {
266 struct stat mystat;
267 glob_t myglob;
268 char buf[BUFSIZE]={};
269 int i;
270 char *ch;
271 if(lstat(path,&mystat)<1)
272 {
273 perror("lstat()");
274 return ;
275 }
276 if(glob(path,1,NULL,&myglob)!=0)
277 {
278 fprintf(stderr,"error!");
279 return ;
280 }
281 memset(buf,'\1',BUFSIZE);
282 strcpy(buf,path);
283 strcat(buf,"/*");
284 glob(buf,1,NULL,&myglob);
285 for(i=1;i<myglob.gl_pathc;i++)
286 {
287 ch=strrchr((myglob.gl_pathv)[i],'/');
288 printf("%s",ch+2);
289 printf("\n");
290 }
291 }
292
293 int main(int argc,char *argv[])
294 {
295 int ch;
296 char *optstring="-laih";
297 struct stat my_stat;
298 if(argc<4)
299 return 2;
300 while(2)
301 {
302 ch=getopt(argc,argv,optstring);
303 if(ch==0)
304 break;
305 switch(ch)
306 {
307 case 'l':
308 fil_cat(argv[1]);
309 printf("\n");
310 break;
311 case 'a':
312 all_fil(argv[1]);
313 printf("\n");
314 break;
315 case 'i':
316 node_i(argv[1]);
317 printf("\n");
318 break;
319 case 'h':
320 bright_fil(argv[1]);
321 printf("\n");
322 break;
323 default:
324 break;
325 }
326 }
327 return 0;
328 }