commit 8ae5a3b1dd08da551e9e59cc9ff90f7ab9705968
Author: rani <clagv.randomgames@gmail.com>
Date: Thu May 04 19:51:45 2023 +0000
diff --git a/include/dir.h b/include/dir.h
index 8618ace..5d7208a 100644
--- a/include/dir.h
+++ b/include/dir.h
@@ -646 +647 @@ int list_dir(char *);
void free_dir_entries(void);
void cd_back(void);
void enter_dir(char *);
+int remove_file(struct dir_entry_t *);
void remove_marked(void);
char * mode_to_s(struct dir_entry_t *);
bool check_dpath(char *);
diff --git a/src/dir.c b/src/dir.c
index c1c9b6f..3d90de8 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -96 +97 @@
#include <errno.h>
#include <pwd.h>
#include <grp.h>
+#include <ftw.h>
#include "info.h"
#include "type.h"
@@ -28312 +28482 @@ void enter_dir(char * name) {
}
+static size_t file_count;
+static int nftw_file_count(const char * fp, const struct stat * sb, int tf, struct FTW * fb) {
+ (void)fp;
+ (void)sb;
+ (void)tf;
+ (void)fb;
+
+ file_count++;
+ return 0;
+}
+
+static int remove_all_failed;
+static int nftw_file_remove(const char * fp, const struct stat * sb, int tf, struct FTW * fb) {
+ (void)sb;
+ (void)tf;
+ (void)fb;
+
+ if (remove(fp) < 0) {
+ display_info(INFO_ERR, "%s: Remove failed (%s)", fp, strerror(errno));
+ remove_all_failed = 1;
+ }
+
+ return 0;
+}
+
+static size_t count_files(struct dir_entry_t * de) {
+ file_count = 0;
+
+ nftw(de->name, nftw_file_count, 0, FTW_MOUNT | FTW_PHYS);
+
+ return file_count;
+}
+
+
+static int remove_tree(struct dir_entry_t * de) {
+ remove_all_failed = 0;
+
+ nftw(de->name, nftw_file_remove, 0, FTW_MOUNT | FTW_PHYS | FTW_DEPTH);
+
+ return remove_all_failed;
+}
+
+
+int remove_file(struct dir_entry_t * de) {
+ // returns 1 on error, 0 on success, -1 on no action
+ if (de->file_type == FILE_DIR) {
+ size_t f_count = count_files(de);
+
+ char * REMOVE_FILE_PROMPT = "This action will remove %zu files. Continue?";
+ int plen = snprintf(NULL, 0, REMOVE_FILE_PROMPT, f_count);
+ char * p = malloc(plen + 1);
+ snprintf(p, plen + 1, REMOVE_FILE_PROMPT, f_count);
+
+ char * r = prompt(p, (char*[]){"No", "Yes", NULL});
+ free(p);
+
+ if (r && !strcmp(r, "Yes")) return remove_tree(de);
+ return -1;
+ } else {
+ return remove(de->name) < 0 ? 1 : 0;
+ }
+}
+
+
void remove_marked(void) {
+ char * REMOVE_MARKED_PROMPT = "Remove all marked files? (%zu)";
+ int plen = snprintf(NULL, 0, REMOVE_MARKED_PROMPT, n_marked_files);
+ char * p = malloc(plen + 1);
+ snprintf(p, plen + 1, REMOVE_MARKED_PROMPT, n_marked_files);
+
+ char * r = prompt(p, (char*[]){"No", "Yes", NULL});
+ if (!r || strcmp(r, "Yes")) return;
+
for (size_t i = 0; i < n_dir_entries; i++) {
if (dir_entries[i]->marked) {
- char p[strlen(cwd) + strlen(dir_entries[i]->name) + 1];
- sprintf(p, "%s/%s", cwd, dir_entries[i]->name);
- if (remove(p) == 0) n_marked_files--;
+ if (remove_file(dir_entries[i]) == 0) n_marked_files--;
}
}
}
diff --git a/src/main.c b/src/main.c
index dfadc88..17c2650 100644
--- a/src/main.c
+++ b/src/main.c
@@ -30840 +30824 @@ int main(int argc, char ** argv) {
last_f = LAST_F;
break;
case 'd':
- if (dir_entries[cursor - 1]->file_type == FILE_DIR)
- break;
- char * args[] = {"No", "Yes", NULL};
- if (n_marked_files) {
- char * p = malloc(40);
- sprintf(p, "Remove all marked files? (%lu)", n_marked_files);
- char * resp = prompt(p, args);
+ if (n_marked_files) remove_marked();
+ else {
+ char * rp = "Remove the file '%s'?";
+ int plen = snprintf(NULL, 0, rp, dir_entries[cursor - 1]->name);
+ char * p = malloc(plen + 1);
+ snprintf(p, plen + 1, rp, dir_entries[cursor - 1]->name);
+
+ char * r = prompt(p, (char*[]){"No", "Yes", NULL});
free(p);
- if (!resp || strcmp(resp, "Yes")) break;
- remove_marked();
- free_dir_entries();
- list_dir(cwd);
- cursor = 1;
- first_f = 0;
- last_f = LAST_F;
- break;
- }
- char * name = dir_entries[cursor - 1]->name;
- char * p = malloc(20 + strlen(name));
- sprintf(p, "Delete the file '%s'?", name);
- char * resp = prompt(p, args);
- free(p);
- if (!resp) break;
- if (!strcmp(resp, "Yes")) {
- p = malloc(strlen(cwd) + strlen(name) + 3);
- sprintf(p, "%s/%s", cwd, name);
- remove(p);
- free(p);
- free_dir_entries();
- list_dir(cwd);
- if (cursor > n_dir_entries) cursor--;
- last_f = LAST_F;
+ if (r && !strcmp(r, "Yes")) remove_file(dir_entries[cursor - 1]);
}
+
+ free_dir_entries();
+ list_dir(cwd);
+
+ if (cursor > n_dir_entries) cursor = n_dir_entries;
+ resize_fbufcur(cursor);
break;
case 'm':
// cannot mark files outside of start dir