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