commit 032489e95ad621896e7503217ba5e8b07a1ad6f9
Author: rani <clagv.randomgames@gmail.com>
Date: Mon Aug 29 20:44:50 2022 +0000
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;
}