diff --git a/include/swupd.h b/include/swupd.h index 89141780..c37c5598 100644 --- a/include/swupd.h +++ b/include/swupd.h @@ -168,7 +168,7 @@ extern void increment_retries(int *retries, int *timeout); extern int main_update(void); extern int add_included_manifests(struct manifest *mom, int current, struct list **subs); extern int main_verify(int current_version); -extern int walk_tree(struct manifest *, const char *); +extern int walk_tree(struct manifest *, const char *, bool); extern int get_latest_version(void); extern void read_versions(int *current_version, int *server_version, char *path_prefix); diff --git a/src/extra_files.c b/src/extra_files.c index 8cc774f8..4f3c4bab 100644 --- a/src/extra_files.c +++ b/src/extra_files.c @@ -95,10 +95,11 @@ static int bsearch_helper(const void *A, const void *B) } /* expect the start to end in /usr and be the absolute path to the root */ -int walk_tree(struct manifest *manifest, const char *start) +int walk_tree(struct manifest *manifest, const char *start, bool fix) { /* Walk the tree, */ int rc; + char *temp; path_prefix_len = strlen(path_prefix); /* Set up the directories to skip */ for (size_t i = 0; i < sizeof(skip_dirs) / sizeof(skip_dirs[0]); i++) { @@ -131,8 +132,9 @@ int walk_tree(struct manifest *manifest, const char *start) found->in_manifest = true; } } - /* list files/directories which are extra */ - for (int i = 0; i < nF; i++) { + /* list files/directories which are extra. + * This is reverse so that files are removed before their parent dirs */ + for (int i = nF - 1; i >= 0; i--) { int skip_len; /* Length of directory name we are skipping * could have used strlen(skip_dir), but speed! */ if (!F[i].in_manifest) { @@ -148,9 +150,23 @@ int walk_tree(struct manifest *manifest, const char *start) if (F[i].dir) { /* Start of new dir to skip */ skip_dir = F[i].filename; skip_len = strlen(skip_dir); - printf("%s/\n", F[i].filename); + if (fix) { + string_or_die(&temp, "%s%s", path_prefix, F[i].filename); + fprintf(stderr, "REMOVING DIR %s/\n", F[i].filename); + remove(temp); + free(temp); + } else { + printf("%s/\n", F[i].filename); + } } else { - printf("%s\n", F[i].filename); + if (fix) { + string_or_die(&temp, "%s%s", path_prefix, F[i].filename); + fprintf(stderr, "REMOVING %s\n", F[i].filename); + remove(temp); + free(temp); + } else { + printf("%s\n", F[i].filename); + } } } else { skip_dir = NULL; diff --git a/src/verify.c b/src/verify.c index 2e49ac80..06f141f5 100644 --- a/src/verify.c +++ b/src/verify.c @@ -774,11 +774,21 @@ load_submanifests: if ((file_not_fixed_count == 0) && (file_not_replaced_count == 0)) { remove_orphaned_files(official_manifest); } + if (cmdline_option_picky) { + char *start = mk_full_filename(path_prefix, "/usr"); + fprintf(stderr, "--picky removing extra files under %s\n", start); + ret = walk_tree(official_manifest, start, true); + if (ret >= 0) { + file_checked_count = ret; + ret = 0; + } + free(start); + } grabtime_stop(×); } else if (cmdline_option_picky) { char *start = mk_full_filename(path_prefix, "/usr"); fprintf(stderr, "Generating list of extra files under %s\n", start); - ret = walk_tree(official_manifest, start); + ret = walk_tree(official_manifest, start, false); if (ret >= 0) { file_checked_count = ret; ret = 0;