Thumbnail

rani/cscroll.git

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

commit 8ae5a3b1dd08da551e9e59cc9ff90f7ab9705968 Author: rani <clagv.randomgames@gmail.com> Date: Thu May 04 19:51:45 2023 +0000 Added recursive directory removal 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