aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tree.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/tree.c b/tree.c
new file mode 100644
index 0000000..ab87cac
--- /dev/null
+++ b/tree.c
@@ -0,0 +1,73 @@
1#include <u.h>
2#include <libc.h>
3#include <fcall.h>
4#include <thread.h>
5#include <9p.h>
6
7void print_tree(char *basepath, int depth, char *prefix, int max_depth)
8{
9 Dir *dirs;
10 int i, n, fd;
11 char *newprefix;
12
13 if (max_depth >= 0 && depth > max_depth)
14 return;
15
16 if ((fd = open(basepath, OREAD)) < 0)
17 return;
18
19 while ((n = dirread(fd, &dirs)) > 0)
20 {
21 for (i = 0; i < n; i++)
22 {
23 Dir *d = &dirs[i];
24
25 if (strcmp(d->name, ".") == 0 || strcmp(d->name, "..") == 0)
26 continue;
27
28 if (i == n - 1)
29 {
30 print("%s└── %s\n", prefix, d->name);
31 newprefix = smprint("%s ", prefix);
32 }
33 else
34 {
35 print("%s├── %s\n", prefix, d->name);
36 newprefix = smprint("%s│ ", prefix);
37 }
38
39 if (d->mode & DMDIR)
40 {
41 char *newpath = smprint("%s/%s", basepath, d->name);
42 print_tree(newpath, depth + 1, newprefix, max_depth);
43 free(newpath);
44 }
45 free(newprefix);
46 }
47 free(dirs);
48 }
49 close(fd);
50}
51
52void main(int argc, char *argv[])
53{
54 int max_depth = -1;
55 char *start_dir = ".";
56
57 ARGBEGIN
58 {
59 case 'L':
60 max_depth = atoi(ARGF());
61 break;
62 default:
63 fprint(2, "usage: %s [-L depth] [dir]\n", argv0);
64 exits("usage");
65 }
66 ARGEND
67
68 if (argc > 0)
69 start_dir = argv[0];
70
71 print_tree(start_dir, 0, "", max_depth);
72 exits(0);
73}