summaryrefslogtreecommitdiff
path: root/src/commands/ls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/ls.c')
-rw-r--r--src/commands/ls.c50
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) {