Thumbnail

rani/cscroll.git

Clone URL: https://git.buni.party/rani/cscroll.git

commit fa5840fd48883d0cca6a2e1f2b8800bf51424899 Author: rani <clagv.randomgames@gmail.com> Date: Tue Dec 30 19:05:49 2025 +0000 Add: file mode and pretty mode strings 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');   }