#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" #include "../lib/sys/errno.h" #include "../lib/aec/aec.h" #include "../lib/sys/stat.h" #define BUF_SIZE sizeof(dirent_t) * 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(dirent_t *d) { switch (filter) { case FILTER_HIDDEN: return d->d_name[0] != '.'; case FILTER_NONE: return 1; } } void set_color(int fd, const char *name) { stat_t st; const char *color; fstatat(fd, name, &st, 0); switch (st.mode & S_IFMT) { case S_IFREG: color = COLOR_WHITE; break; case S_IFDIR: color = COLOR_BLUE; break; case S_IFLNK: color = COLOR_CYAN; break; case S_IFSOCK: color = COLOR_RED; break; case S_IFBLK: color = COLOR_YELLOW; break; case S_IFCHR: color = COLOR_PINK; break; case S_IFIFO: color = COLOR_GREEN; break; default: color = COLOR_RED; break; } foreground(color); } 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; dirent_t *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); if (fd < 0) { wff(STDERR_FD, "error: %s", errstr[-fd]); continue; } while (1) { nread = getdents(fd, buf, BUF_SIZE); if (nread == 0) break; for (u64 bpos = 0; bpos < nread;) { d = (dirent_t*) (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"); set_color(fd, d->d_name); wstd(d->d_name); wstdf("%S", SGR_RESET) wstd(" "); current_width = cstr_length(d->d_name) + 2; } else { set_color(fd, d->d_name); wstdf("%s ", d->d_name); wstdf("%S", SGR_RESET) } } } bpos += d->d_reclen; } } close(fd); } if (istty) wstd("\n"); return 0; }