From e552a95645562b038fbb8706271e32efc04d9fdb Mon Sep 17 00:00:00 2001 From: Castulo Martinez Date: Mon, 11 May 2020 13:08:33 -0700 Subject: [PATCH] Add function to remove the content of a directory Instead of having a function to remove the contents of a specific directory in the statedir this commit creates a generic function to remove the contents of a directory without removing the directory itself. Signed-off-by: Castulo Martinez --- src/cmds/bundle_add.c | 6 +++-- src/cmds/update.c | 5 +++- src/cmds/verify.c | 4 ++- src/lib/sys.c | 28 ++++++++++++++------ src/lib/sys.h | 7 +++++ src/swupd.h | 1 - src/swupd_lib/helpers.c | 57 ----------------------------------------- 7 files changed, 38 insertions(+), 70 deletions(-) diff --git a/src/cmds/bundle_add.c b/src/cmds/bundle_add.c index b85209ed..0a883013 100644 --- a/src/cmds/bundle_add.c +++ b/src/cmds/bundle_add.c @@ -285,9 +285,11 @@ static enum swupd_code download_content(struct manifest *mom, struct list *to_in /* download necessary packs */ timelist_timer_start(globals.global_times, "Download packs"); - if (rm_staging_dir_contents("download") < 0) { - debug("rm_staging_dir_contents failed - resuming operation\n"); + char *download_dir = statedir_get_download_dir(); + if (sys_rm_dir_contents(download_dir) < 0) { + debug("removing the contents from download in statedir failed - resuming operation\n"); } + FREE(download_dir); if (list_longer_than(to_install_files, 10 * list_len(to_install_bundles))) { download_zero_packs(to_install_bundles, mom); diff --git a/src/cmds/update.c b/src/cmds/update.c index 71bd3c08..6e016062 100644 --- a/src/cmds/update.c +++ b/src/cmds/update.c @@ -306,11 +306,14 @@ enum swupd_code execute_update_extra(extra_proc_fn_t post_update_fn, extra_proc_ /* housekeeping */ timelist_timer_start(globals.global_times, "Clean up download directory"); - if (rm_staging_dir_contents("download")) { + char *download_dir = statedir_get_download_dir(); + if (sys_rm_dir_contents(download_dir)) { + FREE(download_dir); error("There was a problem cleaning download directory\n"); ret = SWUPD_COULDNT_REMOVE_FILE; goto clean_curl; } + FREE(download_dir); timelist_timer_stop(globals.global_times); // closing: Clean up download directory /* setup manifests */ diff --git a/src/cmds/verify.c b/src/cmds/verify.c index cb346c67..75653e43 100644 --- a/src/cmds/verify.c +++ b/src/cmds/verify.c @@ -978,7 +978,9 @@ enum swupd_code execute_verify_extra(extra_proc_fn_t post_verify_fn) * certificate is hosed and the admin knows it and wants to recover. */ timelist_timer_start(globals.global_times, "Clean up download directory"); - ret = rm_staging_dir_contents("download"); + char *download_dir = statedir_get_download_dir(); + ret = sys_rm_dir_contents(download_dir); + FREE(download_dir); if (ret != 0) { warn("Failed to remove prior downloads, carrying on anyway\n"); } diff --git a/src/lib/sys.c b/src/lib/sys.c index 5e189fce..074e6633 100644 --- a/src/lib/sys.c +++ b/src/lib/sys.c @@ -506,7 +506,7 @@ static int sys_rmdir(const char *path) return 0; } -static int sys_rm_dir_recursive(const char *path) +int sys_rm_dir_contents(const char *path) { DIR *dir; struct dirent *entry; @@ -515,8 +515,7 @@ static int sys_rm_dir_recursive(const char *path) dir = opendir(path); if (dir == NULL) { - ret = -errno; - goto exit; + return -errno; } while (true) { @@ -531,21 +530,34 @@ static int sys_rm_dir_recursive(const char *path) continue; } - FREE(filename); - filename = str_or_die("%s/%s", path, entry->d_name); - + filename = sys_path_join("%s/%s", path, entry->d_name); ret = sys_rm_recursive(filename); if (ret) { + FREE(filename); goto exit; } + FREE(filename); + } + +exit: + closedir(dir); + return ret; +} + +static int sys_rm_dir_recursive(const char *path) +{ + int ret = 0; + + /* Delete directories content first */ + ret = sys_rm_dir_contents(path); + if (ret) { + goto exit; } /* Delete directory once it's empty */ ret = sys_rmdir(path); exit: - closedir(dir); - FREE(filename); return ret; } diff --git a/src/lib/sys.h b/src/lib/sys.h index 1a5486ae..5176dba0 100644 --- a/src/lib/sys.h +++ b/src/lib/sys.h @@ -214,6 +214,13 @@ bool sys_is_dir(const char *path); */ bool sys_filelink_is_dir(const char *path); +/** + * @brief Remove the content of a directory without removing the directory itself. + * + * @return 0 on success, negative value on errors + */ +int sys_rm_dir_contents(const char *path); + /** * @brief Remove file or directory. * diff --git a/src/swupd.h b/src/swupd.h index 4956b9e7..67d018cc 100644 --- a/src/swupd.h +++ b/src/swupd.h @@ -261,7 +261,6 @@ extern void populate_file_struct(struct file *file, char *filename); extern bool verify_file(struct file *file, char *filename); extern bool verify_file_lazy(char *filename); extern int verify_bundle_hash(struct manifest *manifest, struct file *bundle); -extern int rm_staging_dir_contents(const char *rel_path); void free_file_data(void *data); void remove_files_in_manifest_from_fs(struct manifest *m); void deduplicate_files_from_manifest(struct manifest **m1, struct manifest *m2); diff --git a/src/swupd_lib/helpers.c b/src/swupd_lib/helpers.c index fc9c9f5c..e06af218 100644 --- a/src/swupd_lib/helpers.c +++ b/src/swupd_lib/helpers.c @@ -47,63 +47,6 @@ void check_root(void) } } -/* Remove the contents of a staging directory (eg: /mnt/swupd/update/780 or - * /mnt/swupd/update/delta) which are not supposed to contain - * subdirectories containing files, ie: no need for true recursive removal. - * Just the relative path (et: "780" or "delta" is passed as a parameter). - * - * return: 0 on success, non-zero on error - */ -int rm_staging_dir_contents(const char *rel_path) -{ - DIR *dir; - struct dirent *entry; - char *filename; - char *abs_path; - int ret = 0; - - string_or_die(&abs_path, "%s/%s", globals.state_dir, rel_path); - - dir = opendir(abs_path); - if (dir == NULL) { - FREE(abs_path); - return -1; - } - - while (true) { - errno = 0; - entry = readdir(dir); - if (!entry) { - /* readdir returns NULL on the end of a directory stream, we only - * want to set ret if errno is also set, indicating a failure */ - if (errno) { - ret = errno; - } - break; - } - - if (!str_cmp(entry->d_name, ".") || - !str_cmp(entry->d_name, "..")) { - continue; - } - - string_or_die(&filename, "%s/%s", abs_path, entry->d_name); - - ret = remove(filename); - if (ret != 0) { - debug("Failed to remove file %s\n", filename); - FREE(filename); - break; - } - FREE(filename); - } - - FREE(abs_path); - closedir(dir); - - return ret; -} - void unlink_all_staged_content(struct file *file) { char *filename;