Fix bugs when removing files and directories
authorJ. Ali Harlow <ali@juiblex.co.uk>
Wed, 8 Jul 2009 21:14:16 +0000 (22:14 +0100)
committerJ. Ali Harlow <ali@juiblex.co.uk>
Wed, 8 Jul 2009 21:14:16 +0000 (22:14 +0100)
librazor/iterator.c
librazor/razor-internal.h
librazor/razor.c
librazor/razor.h
librazor/types/list.c
librazor/types/types.h
librazor/util.c
src/main.c

index 533f18a..c50ae4f 100644 (file)
@@ -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));
index b7273b3..d2f77c7 100644 (file)
@@ -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);
index 44c3526..bbd5f6c 100644 (file)
@@ -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);
index c45ea15..82682e0 100644 (file)
@@ -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);
index 52aacfd..2d42128 100644 (file)
 
 #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)
 {
index 8f8443a..9cf253c 100644 (file)
@@ -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);
index 6bc5f6e..888e22c 100644 (file)
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #ifdef MSWIN_API
+#include <windows.h>
 #include <direct.h>
 #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;
index 92f70c5..a4e00fb 100644 (file)
@@ -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);