Thumbnail

rani/cscroll.git

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

commit 032489e95ad621896e7503217ba5e8b07a1ad6f9 Author: rani <clagv.randomgames@gmail.com> Date: Mon Aug 29 20:44:50 2022 +0000 allow listing single files in oneshot mode diff --git a/include/dir.h b/include/dir.h index 4927f3c..a15fa71 100644 --- a/include/dir.h +++ b/include/dir.h @@ -636 +637 @@ void enter_dir(char *);  void remove_marked(void);  char * mode_to_s(struct dir_entry_t *);  bool check_dpath(char *); +struct dir_entry_t * gen_dir_entry(char *, char *);      // number of directory entries @@ -785 +796 @@ extern struct dir_entry_t ** dir_entries;  extern char * cwd;    extern bool permission_denied; +extern bool cwd_is_file;    #endif /* _DIR_H */ diff --git a/src/dir.c b/src/dir.c index fd6fdea..2efe580 100644 --- a/src/dir.c +++ b/src/dir.c @@ -236 +237 @@ size_t dir_longest_group = 0;  struct dir_entry_t ** dir_entries = NULL;    bool permission_denied = false; +bool cwd_is_file = false;      static int cmp(const void * a, const void * b) { @@ -446 +45126 @@ static int acmp(const void * a, const void * b) {  }     +struct dir_entry_t * gen_dir_entry(char * dir_path, char * d_name) { + struct dir_entry_t * dir_entry = malloc(sizeof(struct dir_entry_t) + 12); + + size_t d_name_len = strlen(d_name); + + + struct stat * buf = malloc(sizeof(struct stat)); + char * tmp_path = malloc(d_name_len + strlen(dir_path) + 2); + sprintf(tmp_path, "%s/%s", dir_path, d_name); + if (lstat(tmp_path, buf) == -1) { + free(dir_entry); + free(buf); + free(tmp_path); + + return NULL; + } + + dir_entry->name = malloc(d_name_len + 1); + + strcpy(dir_entry->name, d_name); + + dir_entry->file_type = FILE_UNKNOWN; + switch(buf->st_mode & S_IFMT) { + case S_IFBLK: + case S_IFCHR: + dir_entry->file_type = FILE_BLK; + break; + case S_IFSOCK: + dir_entry->file_type = FILE_SOCK; + break; + case S_IFDIR: + dir_entry->file_type = FILE_DIR; + break; + case S_IFLNK: + dir_entry->file_type = FILE_LINK; + struct stat * buf2 = malloc(sizeof(struct stat)); + stat(tmp_path, buf2); + if ((buf2->st_mode & S_IFMT) == S_IFDIR) + dir_entry->under_link = FILE_DIR; + else dir_entry->under_link = FILE_UNKNOWN; + free(buf2); + break; + case S_IFIFO: + dir_entry->file_type = FILE_FIFO; + break; + case S_IFREG: + dir_entry->file_type = FILE_REG; + break; + default: + dir_entry->file_type = FILE_UNKNOWN; + break; + } + + 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; + if (buf->st_mode & S_ISVTX) // sticky + dir_entry->mode |= M_SUID; + + // 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); + if (buf->st_mode & S_ISGID) // suid; group + dir_entry->mode |= PGROUP(M_SUID); + + // 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) // suid + dir_entry->mode |= POWNER(M_SUID); + + +#if defined(__APPLE__) || defined(__MACH__) + dir_entry->mtime = buf->st_mtime; +#else + dir_entry->mtime = buf->st_mtim.tv_sec; +#endif + size_t n; + dir_entry->owner = buf->st_uid; + if ((n = strlen(getpwuid(buf->st_uid)->pw_name)) > dir_longest_owner) + dir_longest_owner = n; + dir_entry->group = buf->st_gid; + if ((n = strlen(getgrgid(buf->st_gid)->gr_name)) > dir_longest_group) + dir_longest_group = n; + + dir_entry->size = buf->st_size; + dir_entry->u_size = 0; + + 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 + dir_entry->m_type = get_mime(dir_entry->name); + + dir_entry->marked = false; + + return dir_entry; +} + +  int list_dir(char * dir_path) {   struct dirent * d_entry;   DIR * dir = opendir(dir_path); @@ -59126 +18022 @@ int list_dir(char * dir_path) {   permission_denied = false;     while ((d_entry = readdir(dir))) { - struct dir_entry_t * dir_entry = malloc(sizeof(struct dir_entry_t) + 12); -   char * d_name = d_entry->d_name; - size_t d_name_len = strlen(d_name);     if ((!strcmp(d_name, ".") || !strcmp(d_name, "..")) - && !show_dot_dirs) { - free(dir_entry); + && !show_dot_dirs) {   continue; - } - else if (!show_dot_files && d_name[0] == '.') { - free(dir_entry); + } else if (!show_dot_files && d_name[0] == '.') {   continue;   }   - struct stat * buf = malloc(sizeof(struct stat)); - char * tmp_path = malloc(d_name_len + strlen(dir_path) + 2); - sprintf(tmp_path, "%s/%s", dir_path, d_name); - lstat(tmp_path, buf); + struct dir_entry_t * dir_entry = gen_dir_entry(dir_path, d_name);   - dir_entries = realloc(dir_entries, sizeof(struct dir_entry_t) * (n_dir_entries + 1)); - dir_entry->name = malloc(d_name_len + 1); - - strcpy(dir_entry->name, d_name); - - dir_entry->file_type = FILE_UNKNOWN; - switch(buf->st_mode & S_IFMT) { - case S_IFBLK: - case S_IFCHR: - dir_entry->file_type = FILE_BLK; - break; - case S_IFSOCK: - dir_entry->file_type = FILE_SOCK; - break; - case S_IFDIR: - dir_entry->file_type = FILE_DIR; - break; - case S_IFLNK: - dir_entry->file_type = FILE_LINK; - struct stat * buf2 = malloc(sizeof(struct stat)); - stat(tmp_path, buf2); - if ((buf2->st_mode & S_IFMT) == S_IFDIR) - dir_entry->under_link = FILE_DIR; - else dir_entry->under_link = FILE_UNKNOWN; - free(buf2); - break; - case S_IFIFO: - dir_entry->file_type = FILE_FIFO; - break; - case S_IFREG: - dir_entry->file_type = FILE_REG; - break; - default: - dir_entry->file_type = FILE_UNKNOWN; - break; + if (!dir_entry) { + continue; // possibly display message   }   - 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; - if (buf->st_mode & S_ISVTX) // sticky - dir_entry->mode |= M_SUID; - - // 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); - if (buf->st_mode & S_ISGID) // suid; group - dir_entry->mode |= PGROUP(M_SUID); - - // 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) // suid - dir_entry->mode |= POWNER(M_SUID); - - -#if defined(__APPLE__) || defined(__MACH__) - dir_entry->mtime = buf->st_mtime; -#else - dir_entry->mtime = buf->st_mtim.tv_sec; -#endif - size_t n; - dir_entry->owner = buf->st_uid; - if ((n = strlen(getpwuid(buf->st_uid)->pw_name)) > dir_longest_owner) - dir_longest_owner = n; - dir_entry->group = buf->st_gid; - if ((n = strlen(getgrgid(buf->st_gid)->gr_name)) > dir_longest_group) - dir_longest_group = n; - - dir_entry->size = buf->st_size; - dir_entry->u_size = 0; - - 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 - dir_entry->m_type = get_mime(dir_entry->name); - - dir_entry->marked = false; - + dir_entries = realloc(dir_entries, sizeof(struct dir_entry_t) * (n_dir_entries + 1));   dir_entries[n_dir_entries] = dir_entry;   n_dir_entries++;   } diff --git a/src/io.c b/src/io.c index 9c0ed82..7a20ba5 100644 --- a/src/io.c +++ b/src/io.c @@ -3896 +38936 @@ void resize_fbuf(void) {      void print_oneshot(void) { + if (cwd_is_file) { + char * end_sep = strrchr(cwd, '/'); + char * f_name; + char * wd; + bool malloc_wd = false; + + if (end_sep) { + *end_sep = '\0'; + f_name = end_sep + 1; + wd = cwd; + } else { + f_name = cwd; + malloc_wd = true; + wd = malloc(128); + getcwd(wd, 128); + } + + struct dir_entry_t * de = gen_dir_entry(wd, f_name); + if (malloc_wd) free(wd); + if (!de) { + fputs("No such file or directory\n", stderr); + free(cwd); + exit(1); + } + + n_dir_entries = 1; + dir_entries = malloc(sizeof(struct dir_entry_t)); + dir_entries[0] = de; + } +   if (p_long) {   char * icon = "";   char *owner, *group, *size; diff --git a/src/main.c b/src/main.c index 5ffba8c..5aa3931 100644 --- a/src/main.c +++ b/src/main.c @@ -4920 +4911 @@ int main(int argc, char ** argv) {   oneshot = true;   } else {   cwd = realpath(argv[i], NULL); - if (!check_dpath(cwd)) { - fputs("Invalid directory specified\n", stderr); - exit(1); - } - chdir(cwd); + if (!cwd) cwd = strdup(argv[i]);   }   }   }   - if (show_dot_dirs && !oneshot) { - fputs("-a is only available in oneshot mode\n", stderr); - exit(1); - } -   if (!cwd) {   char p[2048];   getcwd(p, sizeof(p)); @@ -7015 +6133 @@ int main(int argc, char ** argv) {   strcpy(cwd, p);   }   + if (oneshot) { + if (!check_dpath(cwd)) cwd_is_file = true; + } else if (!check_dpath(cwd)) { + if (oneshot) { + cwd_is_file = true; + } else { + fputs("Invalid directory specified\n", stderr); + exit(1); + } + } else { + chdir(cwd); + } + + if (show_dot_dirs && !oneshot) { + fputs("-a is only available in oneshot mode\n", stderr); + exit(1); + }     if (oneshot) { - list_dir(cwd); + if (!cwd_is_file) list_dir(cwd);     print_oneshot();     free_dir_entries();   free(dir_entries);   terminate_var(); + free(cwd);   exit(0);   }   @@ -4446 +4538 @@ done:     if (print_path) puts(cwd);   + free(cwd); +   return 0;  }