From: J. Ali Harlow Date: Wed, 8 Jul 2009 21:14:16 +0000 (+0100) Subject: Fix bugs when removing files and directories X-Git-Tag: 0.1~1 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=28d340b2b75c77f6884f2531fe5f059f83540e04;p=razor.git Fix bugs when removing files and directories --- diff --git a/librazor/iterator.c b/librazor/iterator.c index 533f18a..c50ae4f 100644 --- a/librazor/iterator.c +++ b/librazor/iterator.c @@ -231,7 +231,8 @@ razor_property_iterator_destroy(struct razor_property_iterator *pi) } RAZOR_EXPORT struct razor_file_iterator * -razor_file_iterator_create(struct razor_set *set, struct razor_package *package) +razor_file_iterator_create(struct razor_set *set, struct razor_package *package, + int post_order) { struct razor_file_iterator *fi; @@ -240,7 +241,11 @@ razor_file_iterator_create(struct razor_set *set, struct razor_package *package) fi = zalloc(sizeof *fi); fi->set = set; - fi->index = list_first(&package->files, &set->file_pool); + fi->post_order = post_order; + if (post_order) + fi->index = list_last(&package->files, &set->file_pool); + else + fi->index = list_first(&package->files, &set->file_pool); array_init(&fi->path); return fi; @@ -277,7 +282,10 @@ razor_file_iterator_next(struct razor_file_iterator *fi, strcpy(fi->path.data, "/"); } *name = fi->path.data; - fi->index = list_next(fi->index); + if (fi->post_order) + fi->index = list_prev(fi->index); + else + fi->index = list_next(fi->index); return 1; } } while (!((e++)->flags & RAZOR_ENTRY_LAST)); diff --git a/librazor/razor-internal.h b/librazor/razor-internal.h index b7273b3..d2f77c7 100644 --- a/librazor/razor-internal.h +++ b/librazor/razor-internal.h @@ -167,6 +167,7 @@ struct razor_file_iterator { struct razor_set *set; struct array path; struct list *index; + int post_order; }; struct razor_entry * @@ -203,6 +204,7 @@ razor_package_get_details_varg(struct razor_set *set, void razor_rpm_get_details_varg(struct razor_rpm *rpm, va_list args); int razor_create_dir(const char *root, const char *path); +int razor_remove(const char *path); int razor_write(int fd, const void *data, size_t size); void *razor_file_get_contents(const char *filename, size_t *length); diff --git a/librazor/razor.c b/librazor/razor.c index 44c3526..bbd5f6c 100644 --- a/librazor/razor.c +++ b/librazor/razor.c @@ -498,25 +498,19 @@ razor_package_remove(struct razor_set *set, struct razor_package *package, environment_add_variable(&env, buffer, prefix); link = list_next(link); } + environment_set(&env); razor_package_get_details(set, package, RAZOR_DETAIL_PREUNPROG, &program, RAZOR_DETAIL_PREUN, &script, RAZOR_DETAIL_LAST); - environment_set(&env); retval = razor_run_script(root, RAZOR_PROPERTY_PREUN, program, script, install_count); - environment_unset(&env); - if (retval) { - environment_release(&env); - return -1; - } - - fi = razor_file_iterator_create(set, package); + fi = razor_file_iterator_create(set, package, 1); - while (!retval && razor_file_iterator_next(fi, &name)) { + while (razor_file_iterator_next(fi, &name)) { pi = razor_package_iterator_create_for_file(set, name); count = 0; while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST)) @@ -524,27 +518,25 @@ razor_package_remove(struct razor_set *set, struct razor_package *package, razor_package_iterator_destroy(pi); if (count <= 1) { snprintf(buffer, sizeof buffer, "%s%s", root, name); - retval = remove(buffer); + if (razor_remove(buffer) && errno != ENOENT) { + perror(name); + retval = -1; + } } } razor_file_iterator_destroy(fi); - if (retval) { - environment_release(&env); - return retval; - } - razor_package_get_details(set, package, RAZOR_DETAIL_POSTUNPROG, &program, RAZOR_DETAIL_POSTUN, &script, RAZOR_DETAIL_LAST); - environment_set(&env); - retval = razor_run_script(root, RAZOR_PROPERTY_POSTUN, program, script, - install_count); - environment_unset(&env); + if (razor_run_script(root, RAZOR_PROPERTY_POSTUN, program, script, + install_count)) + retval = -1; + environment_unset(&env); environment_release(&env); return retval; @@ -700,7 +692,7 @@ razor_set_list_package_files(struct razor_set *set, assert (set != NULL); assert (package != NULL); - fi = razor_file_iterator_create(set, package); + fi = razor_file_iterator_create(set, package, 0); while (razor_file_iterator_next(fi, &name)) printf("%s\n", name); diff --git a/librazor/razor.h b/librazor/razor.h index c45ea15..82682e0 100644 --- a/librazor/razor.h +++ b/librazor/razor.h @@ -189,7 +189,7 @@ razor_property_iterator_destroy(struct razor_property_iterator *pi); struct razor_file_iterator; struct razor_file_iterator * razor_file_iterator_create(struct razor_set *set, - struct razor_package *package); + struct razor_package *package, int post_order); int razor_file_iterator_next(struct razor_file_iterator *fi, const char **name); void razor_file_iterator_destroy(struct razor_file_iterator *fi); diff --git a/librazor/types/list.c b/librazor/types/list.c index 52aacfd..2d42128 100644 --- a/librazor/types/list.c +++ b/librazor/types/list.c @@ -23,10 +23,10 @@ #include "types.h" -/* RAZOR_IMMEDIATE and RAZOR_ENTRY_LAST must have the same value */ -#define RAZOR_ENTRY_LAST 0x80 -#define RAZOR_IMMEDIATE 0x80 -#define RAZOR_EMPTY_LIST 0xff +#define RAZOR_ENTRY_LAST 0x80 +#define RAZOR_ENTRY_FIRST 0x40 +#define RAZOR_IMMEDIATE (RAZOR_ENTRY_LAST | RAZOR_ENTRY_FIRST) +#define RAZOR_EMPTY_LIST 0xff void list_set_empty(struct list_head *head) @@ -61,7 +61,8 @@ list_set_array(struct list_head *head, struct array *pool, p = array_add(pool, items->size); memcpy(p, items->data, items->size); - p[items->size / sizeof *p - 1].flags = RAZOR_ENTRY_LAST; + p->flags = RAZOR_ENTRY_FIRST; + p[items->size / sizeof *p - 1].flags |= RAZOR_ENTRY_LAST; list_set_ptr(head, p - (struct list *) pool->data); } @@ -77,13 +78,38 @@ list_first(struct list_head *head, struct array *pool) } struct list * +list_last(struct list_head *head, struct array *pool) +{ + struct list *list; + + if (head->flags == RAZOR_EMPTY_LIST) + return NULL; + else if (head->flags == RAZOR_IMMEDIATE) + return (struct list *) head; + else { + list = (struct list *) pool->data + head->list_ptr; + while((list->flags & RAZOR_ENTRY_LAST) == 0) + list++; + return list; + } +} + +struct list * list_next(struct list *list) { - if (list->flags) + if (list->flags & RAZOR_ENTRY_LAST) return NULL; return ++list; } +struct list * +list_prev(struct list *list) +{ + if (list->flags & RAZOR_ENTRY_FIRST) + return NULL; + return --list; +} + void list_remap_pool(struct array *pool, uint32_t *map) { diff --git a/librazor/types/types.h b/librazor/types/types.h index 8f8443a..9cf253c 100644 --- a/librazor/types/types.h +++ b/librazor/types/types.h @@ -53,7 +53,9 @@ void list_set_ptr(struct list_head *head, uint32_t ptr); void list_set_array(struct list_head *head, struct array *pool, struct array *items, int force_indirect); struct list *list_first(struct list_head *head, struct array *pool); +struct list *list_last(struct list_head *head, struct array *pool); struct list *list_next(struct list *list); +struct list *list_prev(struct list *list); void list_remap_pool(struct array *pool, uint32_t *map); void list_remap_head(struct list_head *list, uint32_t *map); diff --git a/librazor/util.c b/librazor/util.c index 6bc5f6e..888e22c 100644 --- a/librazor/util.c +++ b/librazor/util.c @@ -31,6 +31,7 @@ #include #include #ifdef MSWIN_API +#include #include #endif #if HAVE_SYS_MMAN_H @@ -122,6 +123,39 @@ razor_create_dir(const char *root, const char *path) } int +razor_remove(const char *path) +{ +#ifdef MSWIN_API + DWORD err; + + if (DeleteFile(path)) + return 0; + + err = GetLastError(); + if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) + return 0; + + if (SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL) && DeleteFile(path)) + return 0; + + if (RemoveDirectory(path) || GetLastError() == ERROR_DIR_NOT_EMPTY) + return 0; + + /* + * It would be tempting to use: + * MoveFileEx(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) + * but unless we can guarantee that the system will be rebooted + * before we (or some other application) write another file with the + * same path, this is likely to cause more problems than it solves. + */ + + /* Use remove() as a fallback so that errno is set appropriately */ +#endif + + return remove(path); +} + +int razor_write(int fd, const void *data, size_t size) { size_t rest; diff --git a/src/main.c b/src/main.c index 92f70c5..a4e00fb 100644 --- a/src/main.c +++ b/src/main.c @@ -860,7 +860,7 @@ relocate_packages(struct razor_set *set, struct razor_relocations *relocations) name, flags, version); razor_property_iterator_destroy(prop_iter); - file_iter = razor_file_iterator_create(set, package); + file_iter = razor_file_iterator_create(set, package, 0); while (razor_file_iterator_next(file_iter, &name)) { name = razor_relocations_apply(relocations, name); razor_importer_add_file(importer, name);