commit 2eb5bb3bcdeffa2c89f869fa233ce00a1a09e3e4
Author: Raniconduh <clagv.randomgames@gmail.com>
Date: Thu Jan 06 18:37:18 2022 +0000
diff --git a/include/dir.h b/include/dir.h
index 8b2952f..64ba618 100644
--- a/include/dir.h
+++ b/include/dir.h
@@ -214 +217 @@
#define DIR_H
#include <stdbool.h>
+#include <time.h>
+#define MOWNER(M) (M >> 6)
+#define MGROUP(M) (M >> 3)
+#define POWNER(M) (M << 6)
+#define PGROUP(M) (M << 3)
-int list_dir(char *);
-void free_dir_entries(void);
-void cd_back(void);
-void enter_dir(char *);
-void remove_marked(void);
-
+#define M_EXEC (1 << 0)
+#define M_WRITE (1 << 1)
+#define M_READ (1 << 2)
+#define M_SUID (1 << 10)
enum file_type_t {
FILE_REG,
@@ -2716 +3039 @@ enum mime_type_t {
MIME_ARCHIVE
};
+enum f_size {
+ B = 0,
+ KB = 1,
+ MB = 2,
+ GB = 3,
+ TB = 4,
+ PB = 5,
+};
+
struct dir_entry_t {
char * name;
enum file_type_t file_type;
enum file_type_t under_link;
enum mime_type_t m_type;
- bool exec;
bool marked;
+
+ uint16_t mode;
+ time_t mtime;
+ long owner;
+ long group;
+ int size;
+ enum f_size u_size;
};
+int list_dir(char *);
+void free_dir_entries(void);
+void cd_back(void);
+void enter_dir(char *);
+void remove_marked(void);
+char * mode_to_s(struct dir_entry_t *);
+
+
// number of directory entries
extern size_t n_dir_entries;
// actual directory entries
diff --git a/include/opts.h b/include/opts.h
index 7626a7d..d95dbfc 100644
--- a/include/opts.h
+++ b/include/opts.h
@@ -75 +76 @@
extern bool show_icons;
extern bool show_dot_files;
extern bool color;
+extern bool p_long;
#endif
diff --git a/src/commands.c b/src/commands.c
index 2550db4..51804ea 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -1496 +1497 @@ void set(char * v) {
#if ICONS
else if (!strcmp(v, "icons")) show_icons = true;
#endif
+ else if (!strcmp(v, "long")) p_long = true;
else {
printw("Unknown variable (%s)", v);
refresh();
@@ -1656 +1667 @@ void unset(char * v) {
#if ICONS
else if (!strcmp(v, "icons")) show_icons = false;
#endif
+ else if (!strcmp(v, "long")) p_long = false;
else {
printw("Unknown variable (%s)", v);
refresh();
diff --git a/src/dir.c b/src/dir.c
index 9a9472b..040957d 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -10414 +10452 @@ int list_dir(char * dir_path) {
dir_entry->file_type = FILE_UNKNOWN;
break;
}
- // S_IXUSR
- if (dir_entry->file_type != FILE_DIR)
- dir_entry->exec = (bool)(buf->st_mode & S_IXUSR);
- else dir_entry->exec = false;
-
+
+ dir_entry->mode = 0;
+
+ // other mode
+ if (buf->st_mode & S_IROTH)
+ dir_entry->mode |= M_READ;
+ if (buf->st_mode & S_IWOTH)
+ dir_entry->mode |= M_WRITE;
+ if (buf->st_mode & S_IXOTH)
+ dir_entry->mode |= M_EXEC;
+
+ // group mode
+ if (buf->st_mode & S_IRGRP)
+ dir_entry->mode |= PGROUP(M_READ);
+ if (buf->st_mode & S_IWGRP)
+ dir_entry->mode |= PGROUP(M_WRITE);
+ if (buf->st_mode & S_IXGRP)
+ dir_entry->mode |= PGROUP(M_EXEC);
+
+ // owner mode
+ if (buf->st_mode & S_IRUSR)
+ dir_entry->mode |= POWNER(M_READ);
+ if (buf->st_mode & S_IWUSR)
+ dir_entry->mode |= POWNER(M_WRITE);
+ if (buf->st_mode & S_IXUSR)
+ dir_entry->mode |= POWNER(M_EXEC);
+
+ if (buf->st_mode & S_ISUID)
+ dir_entry->mode |= M_SUID;
+
+ dir_entry->mtime = buf->st_mtim.tv_sec;
+ dir_entry->owner = buf->st_uid;
+ dir_entry->group = buf->st_gid;
+
+ dir_entry->size = buf->st_size;
+
+ for (int i = 0; i <= PB; i++) {
+ if (dir_entry->size < 1000) break;
+ dir_entry->size /= 1000;
+ dir_entry->u_size++;
+ }
+
free(tmp_path);
free(buf);
+ // figure out file 'mime' type
char * t_ext = get_ext(dir_entry->name);
if (t_ext && *t_ext) {
char * ext = malloc(strlen(t_ext));
@@ -1823 +22045 @@ void remove_marked(void) {
}
}
}
+
+
+char * mode_to_s(struct dir_entry_t * f) {
+ char * s = malloc(11);
+ char * p = s;
+ uint16_t mode = f->mode;
+
+ char x = 'x';
+ if (f->mode & M_SUID) x = 's';
+
+ if (f->file_type == FILE_DIR) *p++ = 'd';
+ else *p++ = '.';
+
+ if (MOWNER(mode) & M_READ) *p++ = 'r';
+ else *p++ = '-';
+ if (MOWNER(mode) & M_WRITE) *p++ = 'w';
+ else *p++ = '-';
+ if (MOWNER(mode) & M_EXEC) *p++ = x;
+ else if (mode & M_SUID) *p++ = 'S';
+ else *p++ = '-';
+
+ if (MGROUP(mode) & M_READ) *p++ = 'r';
+ else *p++ = '-';
+ if (MGROUP(mode) & M_WRITE) *p++ = 'w';
+ else *p++ = '-';
+ if (MGROUP(mode) & M_EXEC) *p++ = x;
+ else if (mode & M_SUID) *p++ = 'S';
+ else *p++ = '-';
+
+ if (mode & M_READ) *p++ = 'r';
+ else *p++ = '-';
+ if (mode & M_WRITE) *p++ = 'w';
+ else *p++ = '-';
+ if (mode & M_EXEC) { if (mode & M_SUID) *p++ = 't'; else *p++ = 'x'; }
+ else if (mode & M_SUID) *p++ = 'T';
+ else *p++ = '-';
+
+ *p++ = 0;
+
+ return s;
+}
+
diff --git a/src/io.c b/src/io.c
index 2c13bbb..820d3b4 100644
--- a/src/io.c
+++ b/src/io.c
@@ -56 +59 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
+#include <time.h>
+#include <pwd.h>
+#include <grp.h>
#if ICONS
#include "icons.h"
@@ -766 +7927 @@ void curses_write_file(struct dir_entry_t * dir_entry, bool highlight) {
#if ICONS
char * icon = NULL;
#endif
+ char * smode = NULL;
+ char * owner = NULL;
+ char * group = NULL;
+ char * size = NULL;
+ char time[128];
+
+ if (p_long) {
+ smode = mode_to_s(dir_entry);
+ owner = getpwuid(dir_entry->owner)->pw_name;
+ group = getgrgid(dir_entry->group)->gr_name;
+ switch (dir_entry->u_size) {
+ case 0: size = "B"; break;
+ case 1: size = "KB"; break;
+ case 2: size = "MB"; break;
+ case 3: size = "GB"; break;
+ case 4: size = "TB"; break;
+ case 5: size = "PB"; break;
+ }
+ strftime(time, sizeof(time), "%b %d %H:%M %Y",
+ localtime(&dir_entry->mtime));
+ }
switch (dir_entry->file_type) {
case FILE_DIR:
@@ -1457 +1699 @@ void curses_write_file(struct dir_entry_t * dir_entry, bool highlight) {
if (!icon && dir_entry->file_type == FILE_DIR) icon = ICON_DIR;
#endif
- if (dir_entry->exec && dir_entry->file_type != FILE_LINK) {
+ if ((dir_entry->mode & POWNER(M_EXEC)) &&
+ dir_entry->file_type != FILE_LINK &&
+ dir_entry->file_type != FILE_DIR) {
cp = GREEN;
if (f_ident == NO_IDENT) f_ident = '*';
#if ICONS
@@ -1646 +19012 @@ void curses_write_file(struct dir_entry_t * dir_entry, bool highlight) {
if (highlight) cp |= A_REVERSE;
if (dir_entry->marked) printw("%c ", '-');
+ if (p_long) {
+ printw("%s %s %s %-4d%2s %s ",
+ smode, owner, group,
+ dir_entry->size, size, time);
+ free(smode);
+ }
#if ICONS
if (show_icons) printw("%s ", icon);
#endif
diff --git a/src/main.c b/src/main.c
index c77d5c2..067c9fe 100644
--- a/src/main.c
+++ b/src/main.c
@@ -246 +248 @@ int main(int argc, char ** argv) {
} else if (!strcmp(argv[i], "-ni")) {
show_icons = false;
#endif
+ } else if (!strcmp(argv[i], "-l")) {
+ p_long = true;
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
help();
} else {
@@ -3786 +3807 @@ void help(void) {
#if ICONS
" -ni Turn off icons\n"
#endif
+ " -l Print files in long mode\n"
" -p Print the path cscroll is in when it exits\n"
"\n"
"See https://github.com/Raniconduh/cscroll for documentation\n"
diff --git a/src/opts.c b/src/opts.c
index efa93ef..f73621a 100644
--- a/src/opts.c
+++ b/src/opts.c
@@ -63 +64 @@
bool show_icons = true;
bool show_dot_files = false;
bool color = true;
+bool p_long = false;