* same with xv6
[mascara-docs.git] / i386 / ucla / src / lab5 / user / ls.c
blob779e3baf82aa42d8aab5798628820da45133683b
1 #include <inc/lib.h>
3 int flag[256];
5 void lsdir(const char*, const char*);
6 void ls1(const char*, bool, off_t, const char*);
8 void
9 ls(const char *path, const char *prefix)
11 int r;
12 struct Stat st;
14 if ((r = stat(path, &st)) < 0)
15 panic("stat %s: %e", path, r);
16 if (st.st_ftype == FTYPE_DIR && !flag[(int) 'd'])
17 lsdir(path, prefix);
18 else
19 ls1(0, st.st_ftype == FTYPE_DIR, st.st_size, path);
22 void
23 lsdir(const char *path, const char *prefix)
25 int fd, n;
26 char name[MAXNAMELEN];
27 struct Direntry de;
28 struct Stat st;
30 if ((fd = open(path, O_RDONLY)) < 0)
31 panic("open %s: %e", path, fd);
32 while ((n = readn(fd, &de, sizeof de)) == sizeof de)
33 if (de.de_inum) {
34 memcpy(name, de.de_name, MAXNAMELEN);
35 name[de.de_namelen] = 0;
36 istat(de.de_inum, &st);
37 ls1(prefix, st.st_ftype==FTYPE_DIR, st.st_size, name);
39 if (n > 0)
40 panic("short read in directory %s", path);
41 if (n < 0)
42 panic("error reading directory %s: %e", path, n);
45 void
46 ls1(const char *prefix, bool isdir, off_t size, const char *name)
48 const char *sep;
50 if (flag[(int) 'l'])
51 fprintf(1, "%11d %c ", size, isdir ? 'd' : '-');
52 if (prefix) {
53 if (prefix[0] && prefix[strlen(prefix)-1] != '/')
54 sep = "/";
55 else
56 sep = "";
57 fprintf(1, "%s%s", prefix, sep);
59 fprintf(1, "%s", name);
60 if (flag[(int) 'F'] && isdir)
61 fprintf(1, "/");
62 fprintf(1, "\n");
65 void
66 usage(void)
68 fprintf(1, "usage: ls [-dFl] [file...]\n");
69 exit();
72 asmlinkage void
73 umain(int argc, char **argv)
75 int i;
76 struct Argstate args;
78 argstart(&argc, argv, &args);
79 while ((i = argnext(&args)) >= 0)
80 switch (i) {
81 case 'd':
82 case 'F':
83 case 'l':
84 flag[i]++;
85 break;
86 default:
87 usage();
90 if (argc == 1)
91 ls("/", "");
92 else {
93 for (i = 1; i < argc; i++)
94 ls(argv[i], argv[i]);