0
|
1 #include "types.h"
|
|
2 #include "stat.h"
|
|
3 #include "user.h"
|
|
4 #include "fs.h"
|
|
5
|
|
6 char*
|
|
7 fmtname(char *path)
|
|
8 {
|
|
9 static char buf[DIRSIZ+1];
|
|
10 char *p;
|
|
11
|
|
12 // Find first character after last slash.
|
|
13 for(p=path+strlen(path); p >= path && *p != '/'; p--)
|
|
14 ;
|
|
15 p++;
|
|
16
|
|
17 // Return blank-padded name.
|
|
18 if(strlen(p) >= DIRSIZ)
|
|
19 return p;
|
|
20 memmove(buf, p, strlen(p));
|
|
21 memset(buf+strlen(p), ' ', DIRSIZ-strlen(p));
|
|
22 return buf;
|
|
23 }
|
|
24
|
|
25 void
|
|
26 ls(char *path)
|
|
27 {
|
|
28 char buf[512], *p;
|
|
29 int fd;
|
|
30 struct dirent de;
|
|
31 struct stat st;
|
|
32
|
|
33 if((fd = open(path, 0)) < 0){
|
|
34 printf(2, "ls: cannot open %s\n", path);
|
|
35 return;
|
|
36 }
|
|
37
|
|
38 if(fstat(fd, &st) < 0){
|
|
39 printf(2, "ls: cannot stat %s\n", path);
|
|
40 close(fd);
|
|
41 return;
|
|
42 }
|
|
43
|
|
44 switch(st.type){
|
|
45 case T_FILE:
|
|
46 printf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size);
|
|
47 break;
|
|
48
|
|
49 case T_DIR:
|
|
50 if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
|
|
51 printf(1, "ls: path too long\n");
|
|
52 break;
|
|
53 }
|
|
54 strcpy(buf, path);
|
|
55 p = buf+strlen(buf);
|
|
56 *p++ = '/';
|
|
57 while(read(fd, &de, sizeof(de)) == sizeof(de)){
|
|
58 if(de.inum == 0)
|
|
59 continue;
|
|
60 memmove(p, de.name, DIRSIZ);
|
|
61 p[DIRSIZ] = 0;
|
|
62 if(stat(buf, &st) < 0){
|
|
63 printf(1, "ls: cannot stat %s\n", buf);
|
|
64 continue;
|
|
65 }
|
|
66 printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size);
|
|
67 }
|
|
68 break;
|
|
69 }
|
|
70 close(fd);
|
|
71 }
|
|
72
|
|
73 int
|
|
74 main(int argc, char *argv[])
|
|
75 {
|
|
76 int i;
|
|
77
|
|
78 if(argc < 2){
|
|
79 ls(".");
|
|
80 exit();
|
|
81 }
|
|
82 for(i=1; i<argc; i++)
|
|
83 ls(argv[i]);
|
|
84 exit();
|
|
85 }
|