aboutsummaryrefslogtreecommitdiff
path: root/core/ls.c
blob: 6a25a3f7faec2c28ab50c2b7e71a6a4cad38276b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "../lib/sys/sizes.h"
#include "../lib/sys/getdents.h"
#include "../lib/io/io.h"
#include "../lib/list/list.h"
#include "../lib/arg/arg.h"

#define BUF_SIZE sizeof(struct dirent) * 32

enum {
	FILTER_NONE   = 0,
	FILTER_HIDDEN = 1,
} filter = FILTER_HIDDEN;

list_t *dirs;


void set_filter_none()
{
	filter = FILTER_NONE;
}


void add_dir(const char *path)
{
	list_append(dirs, (void*)path);
}


u8 filter_entry(struct dirent *d)
{
	switch (filter) {
		case FILTER_HIDDEN:
			return d->d_name[0] != '.';
		case FILTER_NONE:
			return 1;
	}
}


int main(int argc, const char *argv[])
{
	int                  fd;
	char                 d_type;
	char                 buf[BUF_SIZE];
	long                 nread;
	struct dirent *d;
	dirs = new_list();

	arg_register_flag("-a", &set_filter_none);
	arg_register_default(&add_dir);
	arg_parse_arg(argc, argv);

	if (dirs->size == 0) {
		list_append(dirs, ".");
	}

	for (list_node_t *node = dirs->first; node; node = node->next) {
		fd = open(node->value, OPEN_READ_ONLY | OPEN_DIRECTORY, 0);

		while (1) {
			nread = getdents(fd, buf, BUF_SIZE);

			if (nread == 0)
				break;

			for (u64 bpos = 0; bpos < nread;) {
				d = (struct dirent*) (buf + bpos);
				if (filter_entry(d))
					wstdf("%s\n", d->d_name);
				bpos += d->d_reclen;
			}
		}

		close(fd);
	}

	return 0;
}