commit fa5840fd48883d0cca6a2e1f2b8800bf51424899
Author: rani <clagv.randomgames@gmail.com>
Date: Tue Dec 30 19:05:49 2025 +0000
diff --git a/include/dir.h b/include/dir.h
index d806578..38f14d1 100644
--- a/include/dir.h
+++ b/include/dir.h
@@ -48 +423 @@
#include <time.h>
#include <stddef.h>
#include <stdint.h>
+#include <stdbool.h>
+#include <sys/stat.h>
#include "cvector.h"
+#define M_SUID S_ISUID
+#define M_SGID S_ISGID
+#define M_STICKY S_ISVTX
+#define M_USRR S_IRUSR
+#define M_USRW S_IWUSR
+#define M_USRX S_IXUSR
+#define M_GRPR S_IRGRP
+#define M_GRPW S_IWGRP
+#define M_GRPX S_IXGRP
+#define M_OTHR S_IROTH
+#define M_OTHW S_IWOTH
+#define M_OTHX S_IXOTH
+
enum de_type {
DE_FILE,
DE_DIR,
@@ -385 +5310 @@ typedef struct {
int dir_list(const char * path, dir_t * dir);
void dir_free(dir_t * dir);
+char dirent_crepr(const dirent_t * de); // character representing dir entry
+char dirent_creprl(const dirent_t * de); // like above, but for the link
+char dirent_longcrepr(const dirent_t * de); // like above, but for long mode
+bool dirent_isexec(const dirent_t * de);
+const char * dirent_prettymode(const dirent_t * de);
#endif /* DIR_H */
diff --git a/src/dir.c b/src/dir.c
index 211d783..7e68625 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -14 +15 @@
#include <sys/stat.h>
+#include <stdbool.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
@@ -136 +147 @@
#define LINKNAMESZ PATH_MAX
static void dir_entry(int dirfd, const char * name, dirent_t * dirent);
+static char de_crepr(enum de_type de_type);
static void free_dirent(void * p) {
dirent_t * de = (dirent_t*)p;
free(de->name);
@@ -587 +608 @@ void dir_entry(int dirfd, const char * name, dirent_t * dirent) {
struct stat statbuf;
if (fstatat(dirfd, name, &statbuf, AT_SYMLINK_NOFOLLOW) < 0) {
// in the case where stat fails, the file is marked unknown
- // every field other than type and name are left uninitialized
+ // every non string field other than type is left uninitialized
+ // strings are initialized to NULL
return;
}
@@ -1173 +12075 @@ void dir_entry(int dirfd, const char * name, dirent_t * dirent) {
void dir_free(dir_t * dir) {
cvector_free(dir->entries);
}
+
+char de_crepr(enum de_type de_type) {
+ switch (de_type) {
+ case DE_SOCKET: return '=';
+ case DE_LINK: return '@';
+ case DE_FILE: return 0;
+ case DE_BLOCK: return '#';
+ case DE_DIR: return '/';
+ case DE_CHAR: return '#';
+ case DE_FIFO: return '|';
+ default: return '?';
+ }
+}
+
+char dirent_crepr(const dirent_t * de) {
+ char c = de_crepr(de->type);
+ if (!c && dirent_isexec(de)) return '*';
+ return c;
+}
+
+char dirent_creprl(const dirent_t * de) {
+ return de_crepr(de->linktype);
+}
+
+char dirent_longcrepr(const dirent_t * de) {
+ switch (de->type) {
+ case DE_SOCKET: return '=';
+ case DE_LINK: return 'l';
+ case DE_BLOCK: return 'b';
+ case DE_DIR: return 'd';
+ case DE_CHAR: return 'c';
+ case DE_FIFO: return '|';
+ default: return '.';
+ }
+}
+
+bool dirent_isexec(const dirent_t * de) {
+ // this is because the condition can be truthy but is not actually a bool
+ return (de->mode & (M_USRX | M_GRPX | M_OTHX)) ? true : false;
+}
+
+const char * dirent_prettymode(const dirent_t * de) {
+ // 1 repr char, 9 mode bits, 1 null byte
+ static char s[11];
+ char * p = s;
+
+ if (de->type == DE_UNKNOWN) {
+ strcpy(s, "??????????");
+ return s;
+ }
+
+ *p++ = dirent_longcrepr(de);
+ *p++ = (de->mode & M_USRR) ? 'r' : '-';
+ *p++ = (de->mode & M_USRW) ? 'w' : '-';
+ *p++ = (de->mode & M_USRX) ?
+ (de->mode & M_SUID) ? 's' : 'x'
+ : (de->mode & M_SUID) ? 'S' : '-';
+ *p++ = (de->mode & M_GRPR) ? 'r' : '-';
+ *p++ = (de->mode & M_GRPW) ? 'w' : '-';
+ *p++ = (de->mode & M_GRPX) ?
+ (de->mode & M_SGID) ? 's' : 'x'
+ : (de->mode & M_SGID) ? 'S' : '-';
+ *p++ = (de->mode & M_OTHR) ? 'r' : '-';
+ *p++ = (de->mode & M_OTHW) ? 'w' : '-';
+ *p++ = (de->mode & M_OTHX) ?
+ (de->mode & M_STICKY) ? 't' : 'x'
+ : (de->mode & M_STICKY) ? 'T' : '-';
+
+ *p = 0;
+
+ return s;
+}
diff --git a/src/main.c b/src/main.c
index 7f748ab..7b4a140 100644
--- a/src/main.c
+++ b/src/main.c
@@ -99 +914 @@ int main(int argc, char ** argv) {
for (size_t i = 0; i < dir.len; i++) {
dirent_t * de = &dir.entries[i];
- printf("%s %s %lu %ld %s", de->uname, de->gname, de->size, de->mtime, de->name);
+ char c = dirent_crepr(de);
+ if (!c) c = ' ';
+ const char * pmode = dirent_prettymode(de);
+ printf("%s %s %s %lu %ld %s%c", pmode, de->uname, de->gname, de->size, de->mtime, de->name, c);
if (de->linkname) {
- printf(" -> %s\n", de->linkname);
+ c = dirent_creprl(de);
+ if (!c) c = ' ';
+ printf(" -> %s%c\n", de->linkname, c);
} else putchar('\n');
}