Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <git2/types.h>
#include <stdio.h>

#define LASER_VERSION "1.7.3"
#define LASER_VERSION "1.7.4"

typedef struct laser_opts
{
Expand Down
5 changes: 4 additions & 1 deletion include/laser.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
struct laser_dirent
{
struct dirent *d;

// NOTE THIS WILL NOT ALWAYS BE SET!!
struct stat s;
uint8_t stat_loaded : 1;

char git_status;
};

void laser_start(laser_opts opts);
void laser_process_single_file(laser_opts opts);
void laser_process_single_file(laser_opts opts, struct stat st);

#endif
3 changes: 2 additions & 1 deletion include/lua_filters.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "init_lua.h"
#include "laser.h"

int lua_filters_apply(laser_opts opts, struct laser_dirent *entry);
int lua_filters_apply(laser_opts opts, struct laser_dirent *entry,
const char *full_path);

#endif
2 changes: 1 addition & 1 deletion src/git/lgit.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void lgit_getGitStatus(laser_opts opts, struct laser_dirent *entry,
full_path += 2;

// so... git dosent track dirs, only files
if (S_ISDIR(entry->s.st_mode))
if (entry->d->d_type == DT_DIR)
{
lgit_getDirsStatus(opts, entry, full_path);
return;
Expand Down
161 changes: 99 additions & 62 deletions src/laser.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ static void laser_print_entry(struct laser_dirent *entry, const char *color,
char *indent, int depth, laser_opts opts,
int is_last);
static laser_color_type laser_color_for_format(const char *filename);
static laser_color_type laser_color_for_entry(struct laser_dirent *entry,
const char *full_path);

// returns size of directory if able. else returns -1
static off_t laser_get_dir_size(struct laser_dirent *entry, char *fp);
Expand Down Expand Up @@ -72,25 +74,38 @@ void laser_start(laser_opts opts)
}
}

void laser_process_single_file(laser_opts opts)
void laser_process_single_file(laser_opts opts, struct stat st)
{
struct stat file_stat;
if (lstat(opts.dir, &file_stat) == -1)
{
laser_logger_error("Couldn't stat file %s, %s\n", opts.dir,
strerror(errno));
return;
}

struct laser_dirent entry;
entry.s = file_stat;
struct laser_dirent entry = {0};
// always need to stat single files
// plus it ain't to bad cuz it just be only one stat call
entry.s = st;
entry.stat_loaded = 1;
entry.d = malloc(sizeof(struct dirent) + strlen(opts.dir) + 1);
if (entry.d == NULL)
laser_logger_fatal(1, "Failed to allocate entry struct: %s",
strerror(errno));

strcpy(entry.d->d_name, opts.dir);

// setup d_type cuz we ain't getting it
if (S_ISREG(st.st_mode))
entry.d->d_type = DT_REG;
else if (S_ISDIR(st.st_mode))
entry.d->d_type = DT_DIR;
else if (S_ISLNK(st.st_mode))
entry.d->d_type = DT_LNK;
else if (S_ISCHR(st.st_mode))
entry.d->d_type = DT_CHR;
else if (S_ISBLK(st.st_mode))
entry.d->d_type = DT_BLK;
else if (S_ISFIFO(st.st_mode))
entry.d->d_type = DT_FIFO;
else if (S_ISSOCK(st.st_mode))
entry.d->d_type = DT_SOCK;
else
entry.d->d_type = DT_UNKNOWN;

// default status to ' '
entry.git_status = ' ';
if (opts.show_git->show_git_status)
Expand Down Expand Up @@ -168,12 +183,6 @@ static void laser_process_entries(laser_opts opts, int depth, char *indent)
snprintf(full_path, sizeof(full_path), "%s/%s", opts.dir,
entry->d->d_name);

if (lstat(full_path, &entry->s) == -1)
{
laser_logger_error("%s\n", strerror(errno));
continue;
}

if (opts.show_git->hide_git_ignored)
{
if (strcmp(entry->d->d_name, ".git") == 0)
Expand All @@ -196,25 +205,39 @@ static void laser_process_entries(laser_opts opts, int depth, char *indent)
if (opts.show_git->show_git_status)
lgit_getGitStatus(opts, entry, full_path);

if (!lua_filters_apply(opts, entry))
if (!lua_filters_apply(opts, entry, full_path))
continue;

if (!opts.show_all && entry->d->d_name[0] == '.')
continue;

if ((S_ISDIR(entry->s.st_mode) && opts.show_directories) ||
(S_ISLNK(entry->s.st_mode) && opts.show_symlinks) ||
(S_ISREG(entry->s.st_mode) && opts.show_files))
// stat will be needed
if (entry->d->d_type == DT_UNKNOWN || opts.show_long ||
opts.show_directory_size)
{
if (lstat(full_path, &entry->s) == -1)
continue;
entry->stat_loaded = 1;

char *ownername = laser_getpwuid(entry->s.st_uid)->name;
ssize_t ownername_len = strlen(ownername);
if (ownername_len > longest_ownername)
longest_ownername = ownername_len;
}

if ((entry->d->d_type == DT_DIR && opts.show_directories) ||
(entry->d->d_type == DT_LNK && opts.show_symlinks) ||
(entry->d->d_type == DT_REG && opts.show_files))
{
if ((S_ISDIR(entry->s.st_mode) &&
if ((entry->d->d_type == DT_DIR &&
(opts.show_recursive || opts.show_directory_size)) &&
(strcmp(entry->d->d_name, ".") == 0 ||
strcmp(entry->d->d_name, "..") == 0))
continue;

if (opts.show_directory_size)
{
if (S_ISDIR(entry->s.st_mode))
if (entry->d->d_type == DT_DIR)
{
off_t dirsize = laser_get_dir_size(entry, full_path);
if (dirsize == -1)
Expand All @@ -227,11 +250,6 @@ static void laser_process_entries(laser_opts opts, int depth, char *indent)
current_dir_total_size += entry->s.st_size;
}

char *ownername = laser_getpwuid(entry->s.st_uid)->name;
ssize_t ownername_len = strlen(ownername);
if (ownername_len > longest_ownername)
longest_ownername = ownername_len;

if (!opts.sort)
{
laser_handle_entry(entry, full_path, indent, depth, opts, 0);
Expand Down Expand Up @@ -306,7 +324,7 @@ static void laser_handle_entry(struct laser_dirent *entry,
const char *full_path, char *indent, int depth,
laser_opts opts, int is_last)
{
if (S_ISDIR(entry->s.st_mode))
if (entry->d->d_type == DT_DIR)
{
laser_print_entry(entry, LASER_COLORS[LASER_COLOR_DIR].value, indent,
depth, opts, is_last);
Expand All @@ -320,7 +338,7 @@ static void laser_handle_entry(struct laser_dirent *entry,
return;
}

if (S_ISLNK(entry->s.st_mode) && opts.show_symlinks)
if (entry->d->d_type == DT_LNK && opts.show_symlinks)
{
char symlink_target[LASER_PATH_MAX];
int len =
Expand All @@ -338,9 +356,10 @@ static void laser_handle_entry(struct laser_dirent *entry,
if (ent == NULL)
laser_logger_fatal(1, "Failed to allocate entry struct: %s",
strerror(errno));

ent->s = entry->s;
ent->d = malloc(sizeof(struct dirent));
// +1 for the null
ent->d = malloc(offsetof(struct dirent, d_name) +
strlen(res_string) + 1); // allocating enough size
// for the name too
if (ent->d == NULL)
laser_logger_fatal(1, "Failed to allocate entry struct: %s",
strerror(errno));
Expand All @@ -349,6 +368,9 @@ static void laser_handle_entry(struct laser_dirent *entry,

ent->git_status = entry->git_status;

ent->s = entry->s;
ent->stat_loaded = 1;

laser_print_entry(ent, LASER_COLORS[LASER_COLOR_SYMLINK].value,
indent, depth, opts, is_last);

Expand All @@ -358,23 +380,9 @@ static void laser_handle_entry(struct laser_dirent *entry,
return;
}

if (laser_is_filestat_exec(&entry->s))
laser_print_entry(entry, LASER_COLORS[LASER_COLOR_EXEC].value, indent,
depth, opts, is_last);
else if (entry->d->d_name[0] == '.')
laser_print_entry(entry, LASER_COLORS[LASER_COLOR_HIDDEN].value, indent,
depth, opts, is_last);
else
{
// coloring which depends on formats
laser_color_type color_type = laser_color_for_format(full_path);
if (color_type != LASER_COLOR_FILE)
laser_print_entry(entry, LASER_COLORS[color_type].value, indent,
depth, opts, is_last);
else if (S_ISREG(entry->s.st_mode))
laser_print_entry(entry, LASER_COLORS[LASER_COLOR_FILE].value,
indent, depth, opts, is_last);
}
laser_color_type ctype = laser_color_for_entry(entry, full_path);
laser_print_entry(entry, LASER_COLORS[ctype].value, indent, depth, opts,
is_last);
}

// last parameter is only to match the signature for laser_sort
Expand All @@ -387,8 +395,8 @@ static int laser_cmp_dirent(const void *a, const void *b, const void *_)

lua_pushstring(L, dirent_a->d->d_name);
lua_pushstring(L, dirent_b->d->d_name);
lua_pushboolean(L, S_ISDIR(dirent_a->s.st_mode));
lua_pushboolean(L, S_ISDIR(dirent_b->s.st_mode));
lua_pushboolean(L, dirent_a->d->d_type == DT_DIR);
lua_pushboolean(L, dirent_b->d->d_type == DT_DIR);

if (lua_pcall(L, 4, 1, 0) != LUA_OK)
{
Expand Down Expand Up @@ -419,7 +427,7 @@ static void laser_print_long_entry(struct laser_dirent *entry,
lua_setfield(L, -2, "mode");

off_t size = entry->s.st_size;
if (S_ISDIR(entry->s.st_mode) && !opts.show_directory_size)
if (entry->d->d_type == DT_DIR && !opts.show_directory_size)
size = -1;
lua_pushinteger(L, size);
lua_setfield(L, -2, "size");
Expand All @@ -429,13 +437,13 @@ static void laser_print_long_entry(struct laser_dirent *entry,

lua_pushstring(L, laser_getpwuid(entry->s.st_uid)->name);
lua_setfield(L, -2, "owner");
lua_pushstring(L, S_ISDIR(entry->s.st_mode) ? "d"
: S_ISLNK(entry->s.st_mode) ? "l"
: S_ISCHR(entry->s.st_mode) ? "c"
: S_ISBLK(entry->s.st_mode) ? "b"
: S_ISFIFO(entry->s.st_mode) ? "p"
: S_ISSOCK(entry->s.st_mode) ? "s"
: "-");
lua_pushstring(L, entry->d->d_type == DT_DIR ? "d"
: entry->d->d_type == DT_LNK ? "l"
: entry->d->d_type == DT_CHR ? "c"
: entry->d->d_type == DT_BLK ? "b"
: entry->d->d_type == DT_FIFO ? "p"
: entry->d->d_type == DT_SOCK ? "s"
: "-");
lua_setfield(L, -2, "type");

lua_pushstring(
Expand Down Expand Up @@ -496,9 +504,37 @@ static laser_color_type laser_color_for_format(const char *filename)
return LASER_COLOR_FILE;
}

static laser_color_type laser_color_for_entry(struct laser_dirent *entry,
const char *full_path)
{
if (entry->d->d_name[0] == '.')
return LASER_COLOR_HIDDEN;

laser_color_type fmt_color = laser_color_for_format(full_path);
if (fmt_color != LASER_COLOR_FILE)
return fmt_color;

if (entry->d->d_type == DT_REG)
{
if (!entry->stat_loaded)
{
if (lstat(full_path, &entry->s) == -1)
return LASER_COLOR_FILE;
entry->stat_loaded = 1;
}

if (laser_is_filestat_exec(&entry->s))
return LASER_COLOR_EXEC;

return LASER_COLOR_FILE;
}

return LASER_COLOR_FILE;
}

static off_t laser_get_dir_size(struct laser_dirent *ent, char *fp)
{
if (!S_ISDIR(ent->s.st_mode))
if (ent->d->d_type != DT_DIR)
return -1;

DIR *dir = opendir(fp);
Expand Down Expand Up @@ -535,8 +571,9 @@ static off_t laser_get_dir_size(struct laser_dirent *ent, char *fp)
strerror(errno));
continue;
}
e.stat_loaded = 1;

if (S_ISDIR(e.s.st_mode))
if (e.d->d_type == DT_DIR)
{
off_t sub_s = laser_get_dir_size(&e, full_path);
if (sub_s == -1) // unable to calculate the size
Expand Down
Loading