xref: /xv6-public/ls.c (revision 7894fcd2)
1 #include "types.h"
2 #include "stat.h"
3 #include "user.h"
4 #include "fs.h"
5 
6 char*
fmtname(char * path)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
ls(char * path)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
main(int argc,char * argv[])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 }
86