#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" #include "../lib/tctl/tctl.h" #include "../lib/cstr/cstr.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; u8 istty = isatty(); i64 maxwidth = istty ? tctl_get_window_size().width : -1; i64 current_width = 0; 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)) { if (!istty) { wstdf("%s\n", d->d_name); } else { current_width += cstr_length(d->d_name) + 2; if (current_width > maxwidth) { wstd("\n"); wstd(d->d_name); wstd(" "); current_width = cstr_length(d->d_name) + 2; } else { wstdf("%s ", d->d_name); } } } bpos += d->d_reclen; } } close(fd); } if (istty) wstd("\n"); return 0; }