diff options
Diffstat (limited to 'src/commands/ls.c')
-rw-r--r-- | src/commands/ls.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/src/commands/ls.c b/src/commands/ls.c index d31c143..b0b00a5 100644 --- a/src/commands/ls.c +++ b/src/commands/ls.c @@ -25,6 +25,7 @@ struct Flags { bool more_info; bool one_column; bool recurse; + bool colored; }; struct FileInfo { @@ -34,10 +35,11 @@ struct FileInfo { struct group* grp; char size[5]; char date[13]; - struct dirent* file; + char name[PATH_MAX]; bool set_uid; bool set_gid; bool exec; + unsigned char type; }; struct FileListInfo { @@ -61,14 +63,17 @@ static DIR* get_directory(char* path) { return d; } -static void append_path(char buf[PATH_MAX], const char* dir_path, const struct dirent* file) { +static void append_path(char buf[PATH_MAX], const char* dir_path, const char* file_path) { size_t dir_len = strlen(dir_path); + size_t file_len = strlen(file_path); + memcpy(buf, dir_path, dir_len); if (buf[dir_len-1] != '/') { buf[dir_len] = '/'; dir_len++; } - memcpy(buf + dir_len, file->d_name, strlen(file->d_name) + 1); + memcpy(buf + dir_len, file_path, file_len); + buf[dir_len + file_len] = '\0'; } static bool get_file_info(struct dirent* file, const char* dir_path, struct FileInfo* info) { @@ -77,17 +82,20 @@ static bool get_file_info(struct dirent* file, const char* dir_path, struct File gid_t gid = getgid(); char buf[PATH_MAX]; - append_path(buf, dir_path, file); + append_path(buf, dir_path, file->d_name); struct stat s; + memset(&s, 0, sizeof(struct stat)); + if (stat(buf, &s) < 0) { - printf("\x1b[0merror: failed to read file '%s': %s\n", buf, strerror(errno)); + // printf("\x1b[0merror: failed to read file '%s': %s\n", buf, strerror(errno)); return false; } info->set_uid = false; info->set_gid = false; info->exec = false; + info->name[0] = '\0'; if (file->d_type == DT_DIR) info->mode[0] = 'd'; @@ -137,8 +145,10 @@ static bool get_file_info(struct dirent* file, const char* dir_path, struct File info->usr = getpwuid(s.st_uid); info->grp = getgrgid(s.st_gid); - info->file = file; info->links = s.st_nlink; + info->type = file->d_type; + + strcpy(info->name, file->d_name); print_file_size(s.st_size, info->size); print_date_time(s.st_mtim.tv_sec + s.st_mtim.tv_nsec / 1000000, info->date); @@ -147,9 +157,9 @@ static bool get_file_info(struct dirent* file, const char* dir_path, struct File static char* get_file_color(struct FileInfo* info) { char* color; - if (info->file->d_type == DT_DIR) { + if (info->type == DT_DIR) { color = DIR_COLOR; - } else if (info->file->d_type == DT_LNK) { + } else if (info->type == DT_LNK) { color = LINK_COLOR; } else { if (info->set_uid) { @@ -171,6 +181,7 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo if (!isatty(1)) { flags->one_column = true; + flags->colored = false; } char* color; @@ -179,7 +190,6 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo for (int i = 0; i < file_len; i++) { struct FileInfo finfo = files[i]; - if (strlen(finfo.file->d_name) < 1) continue; color = get_file_color(&finfo); if (flags->more_info) { printf("%s %*d %*s %*s %*s %s %s%s\x1b[0m", @@ -193,12 +203,12 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo info.max_size, finfo.size, finfo.date, - color, - finfo.file->d_name + flags->colored ? color : FILE_COLOR, + finfo.name ); - if (finfo.file->d_type == DT_LNK) { + if (finfo.type == DT_LNK) { char path[PATH_MAX]; - append_path(path, dir_path, finfo.file); + append_path(path, dir_path, finfo.name); char lnk[PATH_MAX]; if (readlink(path, lnk, PATH_MAX) < 0) { @@ -211,13 +221,13 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo putchar('\n'); } } else if (flags->one_column) { - printf("%s%s\x1b[0m\n", color, finfo.file->d_name); + printf("%s%s\x1b[0m\n", color, finfo.name); } else { if (info.total_len > w.ws_col) { if (i != 0 && i % row_count == 0) putchar('\n'); - printf("%s%*s\x1b[0m", color, column_width, finfo.file->d_name); + printf("%s%*s\x1b[0m", flags->colored ? color : FILE_COLOR, -column_width, finfo.name); } else { - printf("%s%s\x1b[0m ", color, finfo.file->d_name); + printf("%s%s\x1b[0m ", flags->colored ? color : FILE_COLOR, finfo.name); } } } @@ -318,7 +328,7 @@ static bool recurse_directory(char* path, struct Flags* flags) { if (!flags->hidden && prefix(".", file->d_name)) continue; if (is_dot_dir(file->d_name)) continue; char buf[PATH_MAX]; - append_path(buf, path, file); + append_path(buf, path, file->d_name); recurse_directory(buf, flags); } @@ -374,11 +384,17 @@ COMMAND(ls) { flags.hide_dot = false; flags.one_column = false; flags.recurse = false; + flags.colored = false; + int start = 0; for (int i = 0; i < argc; i++) { if (!prefix("-", argv[i])) break; if (streql("--help", argv[i])) help(); start++; + if (streql("--color=auto", argv[i]) || streql("--color=yes", argv[i])) { + flags.colored = true; + continue; + } for (size_t j = 1; j < strlen(argv[i]); j++) { char c = argv[i][j]; switch (c) { |