}
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;
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;
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));
struct razor_set *set;
struct array path;
struct list *index;
+ int post_order;
};
struct razor_entry *
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);
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))
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;
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);
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);
#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)
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);
}
}
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)
{
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);
#include <unistd.h>
#include <fcntl.h>
#ifdef MSWIN_API
+#include <windows.h>
#include <direct.h>
#endif
#if HAVE_SYS_MMAN_H
}
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;
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);