From: James Bowes Date: Fri, 20 Jun 2008 23:04:06 +0000 (-0400) Subject: Merge branch 'krh/master' X-Git-Tag: 0.1~113^2 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=c778afefaa189c6aa8437fc00512f140a6a68efe;p=razor.git Merge branch 'krh/master' Conflicts: librazor/razor.h librazor/rpm.c razor.c src/main.c --- c778afefaa189c6aa8437fc00512f140a6a68efe diff --cc librazor/importer.c index 0000000,10d87c2..eca9ede mode 000000,100644..100644 --- a/librazor/importer.c +++ b/librazor/importer.c @@@ -1,0 -1,488 +1,505 @@@ + /* + * Copyright (C) 2008 Kristian Høgsberg + * Copyright (C) 2008 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + #define _GNU_SOURCE + + #include + #include "razor-internal.h" + #include "razor.h" + + void + razor_importer_begin_package(struct razor_importer *importer, + const char *name, + const char *version, + const char *arch) + { + struct razor_package *p; + + p = array_add(&importer->set->packages, sizeof *p); + p->name = hashtable_tokenize(&importer->table, name); + p->flags = 0; + p->version = hashtable_tokenize(&importer->table, version); + p->arch = hashtable_tokenize(&importer->table, arch); + + importer->package = p; + array_init(&importer->properties); + } + + + void + razor_importer_finish_package(struct razor_importer *importer) + { + list_set_array(&importer->package->properties, + &importer->set->property_pool, + &importer->properties, + 1); + + array_release(&importer->properties); + } + + void ++razor_importer_add_details(struct razor_importer *importer, ++ const char *summary, ++ const char *description, ++ const char *url, ++ const char *license) ++{ ++ importer->package->summary = hashtable_tokenize(&importer->details_table, summary); ++ importer->package->description = hashtable_tokenize(&importer->details_table, description); ++ importer->package->url = hashtable_tokenize(&importer->details_table, url); ++ importer->package->license = hashtable_tokenize(&importer->details_table, license); ++} ++ ++void + razor_importer_add_property(struct razor_importer *importer, + const char *name, + uint32_t flags, + const char *version) + { + struct razor_property *p; + uint32_t *r; + + p = array_add(&importer->set->properties, sizeof *p); + p->name = hashtable_tokenize(&importer->table, name); + p->flags = flags; + p->version = hashtable_tokenize(&importer->table, version); + list_set_ptr(&p->packages, importer->package - + (struct razor_package *) importer->set->packages.data); + + r = array_add(&importer->properties, sizeof *r); + *r = p - (struct razor_property *) importer->set->properties.data; + + if (((flags & RAZOR_PROPERTY_TYPE_MASK) == RAZOR_PROPERTY_REQUIRES) && + *name == '/') { + r = array_add(&importer->file_requires, sizeof *r); + *r = p->name; + } + } + + void + razor_importer_add_file(struct razor_importer *importer, const char *name) + { + struct import_entry *e; + + e = array_add(&importer->files, sizeof *e); + + e->package = importer->package - + (struct razor_package *) importer->set->packages.data; + e->name = strdup(name); + } + + struct razor_importer * + razor_importer_new(void) + { + struct razor_importer *importer; + + importer = zalloc(sizeof *importer); + importer->set = razor_set_create(); + hashtable_init(&importer->table, &importer->set->string_pool); ++ hashtable_init(&importer->details_table, ++ &importer->set->details_string_pool); ++ hashtable_init(&importer->file_table, ++ &importer->set->file_string_pool); + + return importer; + } + + /* Destroy an importer without creating the set. */ + void + razor_importer_destroy(struct razor_importer *importer) + { + /* FIXME: write this */ + } + + static int + compare_packages(const void *p1, const void *p2, void *data) + { + const struct razor_package *pkg1 = p1, *pkg2 = p2; + struct razor_set *set = data; + char *pool = set->string_pool.data; + + /* FIXME: what if the flags are different? */ + if (pkg1->name == pkg2->name) + return razor_versioncmp(&pool[pkg1->version], &pool[pkg2->version]); + else + return strcmp(&pool[pkg1->name], &pool[pkg2->name]); + } + + static int + compare_properties(const void *p1, const void *p2, void *data) + { + const struct razor_property *prop1 = p1, *prop2 = p2; + struct razor_set *set = data; + char *pool = set->string_pool.data; + + if (prop1->name != prop2->name) + return strcmp(&pool[prop1->name], &pool[prop2->name]); + else if (prop1->flags != prop2->flags) + return prop1->flags - prop2->flags; + else + return razor_versioncmp(&pool[prop1->version], &pool[prop2->version]); + } + + static uint32_t * + uniqueify_properties(struct razor_set *set) + { + struct razor_property *rp, *up, *rp_end; + struct array *pkgs, *p; + struct list_head *r; + uint32_t *map, *rmap; + int i, count, unique; + + count = set->properties.size / sizeof(struct razor_property); + map = razor_qsort_with_data(set->properties.data, + count, + sizeof(struct razor_property), + compare_properties, + set); + + rp_end = set->properties.data + set->properties.size; + rmap = malloc(count * sizeof *map); + pkgs = zalloc(count * sizeof *pkgs); + for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) { + if (rp->name != up->name || + rp->flags != up->flags || + rp->version != up->version) { + up++; + up->name = rp->name; + up->flags = rp->flags; + up->version = rp->version; + } + + unique = up - (struct razor_property *) set->properties.data; + rmap[map[i]] = unique; + r = array_add(&pkgs[unique], sizeof *r); + *r = rp->packages; + } + free(map); + + if (up != rp) + up++; + set->properties.size = (void *) up - set->properties.data; + rp_end = up; + for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) { + list_set_array(&rp->packages, &set->package_pool, p, 0); + array_release(p); + } + + free(pkgs); + + return rmap; + } + + static int + compare_filenames(const void *p1, const void *p2, void *data) + { + const struct import_entry *e1 = p1; + const struct import_entry *e2 = p2; + const char *n1 = e1->name; + const char *n2 = e2->name; + + /* Need to make sure that the contents of a directory + * are sorted immediately after it. So "foo/bar" has to + * sort before "foo.conf" + * + * FIXME: this is about 60% slower than strcmp + */ + while (*n1 && *n2) { + if (*n1 < *n2) + return *n2 == '/' ? 1 : -1; + else if (*n1 > *n2) + return *n1 == '/' ? -1 : 1; + n1++; + n2++; + } + if (*n1) + return 1; + else if (*n2) + return -1; + else + return 0; + } + + static void + count_entries(struct import_directory *d) + { + struct import_directory *p, *end; + + p = d->files.data; + end = d->files.data + d->files.size; + d->count = 0; + while (p < end) { + count_entries(p); + d->count += p->count + 1; + p++; + } + } + + static void + serialize_files(struct razor_set *set, + struct import_directory *d, struct array *array) + { + struct import_directory *p, *end; + struct razor_entry *e = NULL; + uint32_t s; + + p = d->files.data; + end = d->files.data + d->files.size; + s = array->size / sizeof *e + d->files.size / sizeof *p; + while (p < end) { + e = array_add(array, sizeof *e); + e->name = p->name; + e->flags = 0; + e->start = p->count > 0 ? s : 0; + s += p->count; + + list_set_array(&e->packages, &set->package_pool, &p->packages, 0); + array_release(&p->packages); + p++; + } + if (e != NULL) + e->flags |= RAZOR_ENTRY_LAST; + + p = d->files.data; + end = d->files.data + d->files.size; + while (p < end) { + serialize_files(set, p, array); + p++; + } + } + + static void + remap_property_package_links(struct array *properties, uint32_t *rmap) + { + struct razor_property *p, *end; + + end = properties->data + properties->size; + for (p = properties->data; p < end; p++) + list_remap_head(&p->packages, rmap); + } + + static void + build_file_tree(struct razor_importer *importer) + { + int count, i, length; + struct import_entry *filenames; + char *f, *end; + uint32_t name, *r; + char dirname[256]; + struct import_directory *d, root; + struct razor_entry *e; + + count = importer->files.size / sizeof (struct import_entry); + razor_qsort_with_data(importer->files.data, + count, + sizeof (struct import_entry), + compare_filenames, + NULL); + + root.name = hashtable_tokenize(&importer->table, ""); + array_init(&root.files); + array_init(&root.packages); + root.last = NULL; + + filenames = importer->files.data; + for (i = 0; i < count; i++) { + f = filenames[i].name; + if (*f != '/') + continue; + f++; + + d = &root; + while (*f) { + end = strchr(f, '/'); + if (end == NULL) + end = f + strlen(f); + length = end - f; + memcpy(dirname, f, length); + dirname[length] ='\0'; + name = hashtable_tokenize(&importer->table, dirname); + if (d->last == NULL || d->last->name != name) { + d->last = array_add(&d->files, sizeof *d); + d->last->name = name; + d->last->last = NULL; + array_init(&d->last->files); + array_init(&d->last->packages); + } + d = d->last; + f = end + 1; + if (*end == '\0') + break; + } + + r = array_add(&d->packages, sizeof *r); + *r = filenames[i].package; + free(filenames[i].name); + } + + count_entries(&root); + e = importer->set->files.data; + e->name = root.name; + e->flags = RAZOR_ENTRY_LAST; + e->start = importer->files.size ? 1 : 0; + list_set_empty(&e->packages); + + serialize_files(importer->set, &root, &importer->set->files); + + array_release(&importer->files); + } + + static void + list_to_array(struct list *list, struct array *array) + { + uint32_t *item; + + while (list) { + item = array_add(array, sizeof *item); + *item = list->data; + list = list_next(list); + } + } + + static int + compare_file_requires(const void *p1, const void *p2, void *data) + { + uint32_t *f1 = (void *)p1, *f2 = (void *)p2; + const char *pool = data; + + return strcmp(&pool[*f1], &pool[*f2]); + } + + static void + find_file_provides(struct razor_importer *importer) + { + struct razor_property *prop; + struct razor_entry *top, *entry; + struct razor_package *packages; + struct array pkgprops; + struct list *pkg; + uint32_t *req, *req_start, *req_end; + uint32_t *map, *newprop; + char *pool; + + pool = importer->set->string_pool.data; + packages = importer->set->packages.data; + top = importer->set->files.data; + + req = req_start = importer->file_requires.data; + req_end = importer->file_requires.data + importer->file_requires.size; + map = razor_qsort_with_data(req, req_end - req, sizeof *req, + compare_file_requires, pool); + free(map); + + for (req = req_start; req < req_end; req++) { + if (req > req_start && req[0] == req[-1]) + continue; + entry = razor_set_find_entry(importer->set, top, &pool[*req]); + if (!entry) + continue; + + for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) { + prop = array_add(&importer->set->properties, sizeof *prop); + prop->name = *req; + prop->flags = + RAZOR_PROPERTY_PROVIDES | RAZOR_PROPERTY_EQUAL; + prop->version = hashtable_tokenize(&importer->table, ""); + list_set_ptr(&prop->packages, pkg->data); + + /* Update property list of pkg */ + array_init(&pkgprops); + list_to_array(list_first(&packages[pkg->data].properties, &importer->set->property_pool), &pkgprops); + newprop = array_add(&pkgprops, sizeof *newprop); + *newprop = prop - (struct razor_property *)importer->set->properties.data; + list_set_array(&packages[pkg->data].properties, &importer->set->property_pool, &pkgprops, 1); + array_release(&pkgprops); + } + } + + array_release(&importer->file_requires); + } + + static void + build_package_file_lists(struct razor_set *set, uint32_t *rmap) + { + struct razor_package *p, *packages; + struct array *pkgs; + struct razor_entry *e, *end; + struct list *r; + uint32_t *q; + int i, count; + + count = set->packages.size / sizeof *p; + pkgs = zalloc(count * sizeof *pkgs); + + end = set->files.data + set->files.size; + for (e = set->files.data; e < end; e++) { + list_remap_head(&e->packages, rmap); + r = list_first(&e->packages, &set->package_pool); + while (r) { + q = array_add(&pkgs[r->data], sizeof *q); + *q = e - (struct razor_entry *) set->files.data; + r = list_next(r); + } + } + + packages = set->packages.data; + for (i = 0; i < count; i++) { + list_set_array(&packages[i].files, &set->file_pool, &pkgs[i], 0); + array_release(&pkgs[i]); + } + free(pkgs); + } + + struct razor_set * + razor_importer_finish(struct razor_importer *importer) + { + struct razor_set *set; + uint32_t *map, *rmap; + int i, count; + + build_file_tree(importer); + find_file_provides(importer); + + map = uniqueify_properties(importer->set); + list_remap_pool(&importer->set->property_pool, map); + free(map); + + count = importer->set->packages.size / sizeof(struct razor_package); + map = razor_qsort_with_data(importer->set->packages.data, + count, + sizeof(struct razor_package), + compare_packages, + importer->set); + + rmap = malloc(count * sizeof *rmap); + for (i = 0; i < count; i++) + rmap[map[i]] = i; + free(map); + + list_remap_pool(&importer->set->package_pool, rmap); + build_package_file_lists(importer->set, rmap); + remap_property_package_links(&importer->set->properties, rmap); + free(rmap); + + set = importer->set; + hashtable_release(&importer->table); + free(importer); + + return set; + } diff --cc librazor/razor-internal.h index 0000000,bcc5e11..94eac41 mode 000000,100644..100644 --- a/librazor/razor-internal.h +++ b/librazor/razor-internal.h @@@ -1,0 -1,177 +1,194 @@@ + #ifndef _RAZOR_INTERNAL_H_ + #define _RAZOR_INTERNAL_H_ + + #include + #include + + void *zalloc(size_t size); + + struct array { + void *data; + int size, alloc; + }; + + void array_init(struct array *array); + void array_release(struct array *array); + void *array_add(struct array *array, int size); + + + struct list_head { + uint32_t list_ptr : 24; + uint32_t flags : 8; + }; + + struct list { + uint32_t data : 24; + uint32_t flags : 8; + }; + + void list_set_empty(struct list_head *head); + 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_next(struct list *list); + + void list_remap_pool(struct array *pool, uint32_t *map); + void list_remap_head(struct list_head *list, uint32_t *map); + + + struct hashtable { + struct array buckets; + struct array *pool; + }; + + void hashtable_init(struct hashtable *table, struct array *pool); + void hashtable_release(struct hashtable *table); + uint32_t hashtable_insert(struct hashtable *table, const char *key); + uint32_t hashtable_lookup(struct hashtable *table, const char *key); + uint32_t hashtable_tokenize(struct hashtable *table, const char *string); + + + struct razor_set_section { + uint32_t type; + uint32_t offset; + uint32_t size; + }; + + struct razor_set_header { + uint32_t magic; + uint32_t version; + struct razor_set_section sections[0]; + }; + -#define RAZOR_MAGIC 0x7a7a7a7a ++#define RAZOR_MAGIC 0x7a7a7a7a ++#define RAZOR_DETAILS_MAGIC 0x7a7a7a7b ++#define RAZOR_FILES_MAGIC 0x7a7a7a7c + #define RAZOR_VERSION 1 + -#define RAZOR_STRING_POOL 0 -#define RAZOR_PACKAGES 1 -#define RAZOR_PROPERTIES 2 -#define RAZOR_FILES 3 -#define RAZOR_PACKAGE_POOL 4 -#define RAZOR_PROPERTY_POOL 5 -#define RAZOR_FILE_POOL 6 ++#define RAZOR_STRING_POOL 0 ++#define RAZOR_PACKAGES 1 ++#define RAZOR_PROPERTIES 2 ++#define RAZOR_PACKAGE_POOL 3 ++#define RAZOR_PROPERTY_POOL 4 ++ ++#define RAZOR_DETAILS_STRING_POOL 0 ++ ++#define RAZOR_FILES 0 ++#define RAZOR_FILE_POOL 1 ++#define RAZOR_FILE_STRING_POOL 2 + + struct razor_package { - uint32_t name : 24; - uint32_t flags : 8; ++ uint name : 24; ++ uint flags : 8; + uint32_t version; + uint32_t arch; ++ uint32_t summary; ++ uint32_t description; ++ uint32_t url; ++ uint32_t license; + struct list_head properties; + struct list_head files; + }; + ++ + struct razor_property { + uint32_t name; + uint32_t flags; + uint32_t version; + struct list_head packages; + }; + + struct razor_entry { + uint32_t name : 24; + uint32_t flags : 8; + uint32_t start; + struct list_head packages; + }; + + #define RAZOR_ENTRY_LAST 0x80 + + struct razor_set { + struct array string_pool; + struct array packages; + struct array properties; + struct array files; + struct array package_pool; + struct array property_pool; + struct array file_pool; ++ struct array file_string_pool; ++ struct array details_string_pool; + struct razor_set_header *header; ++ struct razor_set_header *details_header; ++ struct razor_set_header *files_header; + }; + + struct import_entry { + uint32_t package; + char *name; + }; + + struct import_directory { + uint32_t name, count; + struct array files; + struct array packages; + struct import_directory *last; + }; + + struct razor_importer { + struct razor_set *set; + struct hashtable table; ++ struct hashtable file_table; ++ struct hashtable details_table; + struct razor_package *package; + struct array properties; + struct array files; + struct array file_requires; + }; + + struct razor_package_iterator { + struct razor_set *set; + struct razor_package *package, *end; + struct list *index; + int free_index; + }; + + void + razor_package_iterator_init_for_property(struct razor_package_iterator *pi, + struct razor_set *set, + struct razor_property *property); + + struct razor_property_iterator { + struct razor_set *set; + struct razor_property *property, *end; + struct list *index; + }; + + #define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1)) + + struct razor_entry * + razor_set_find_entry(struct razor_set *set, + struct razor_entry *dir, const char *pattern); + + struct razor_merger * + razor_merger_create(struct razor_set *set1, struct razor_set *set2); + void + razor_merger_add_package(struct razor_merger *merger, + struct razor_package *package); + struct razor_set * + razor_merger_finish(struct razor_merger *merger); + + /* Utility functions */ + + int razor_create_dir(const char *root, const char *path); + int razor_write(int fd, const void *data, size_t size); + + + typedef int (*razor_compare_with_data_func_t)(const void *p1, + const void *p, + void *data); + uint32_t * + razor_qsort_with_data(void *base, size_t nelem, size_t size, + razor_compare_with_data_func_t compare, void *data); + + #endif /* _RAZOR_INTERNAL_H_ */ diff --cc librazor/razor.c index 0000000,210da4c..cddcc1b mode 000000,100644..100644 --- a/librazor/razor.c +++ b/librazor/razor.c @@@ -1,0 -1,463 +1,588 @@@ + /* + * Copyright (C) 2008 Kristian Høgsberg + * Copyright (C) 2008 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + #define _GNU_SOURCE + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "razor.h" + #include "razor-internal.h" + + void * + zalloc(size_t size) + { + void *p; + + p = malloc(size); + memset(p, 0, size); + + return p; + } + + struct razor_set_section razor_sections[] = { + { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) }, + { RAZOR_PACKAGES, offsetof(struct razor_set, packages) }, + { RAZOR_PROPERTIES, offsetof(struct razor_set, properties) }, - { RAZOR_FILES, offsetof(struct razor_set, files) }, + { RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) }, + { RAZOR_PROPERTY_POOL, offsetof(struct razor_set, property_pool) }, - { RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) }, + }; + ++struct razor_set_section razor_files_sections[] = { ++ { RAZOR_FILES, offsetof(struct razor_set, files) }, ++ { RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) }, ++ { RAZOR_FILE_STRING_POOL, offsetof(struct razor_set, file_string_pool) }, ++}; ++ ++struct razor_set_section razor_details_sections[] = { ++ { RAZOR_DETAILS_STRING_POOL, offsetof(struct razor_set, details_string_pool) }, ++}; + struct razor_set * + razor_set_create(void) + { + struct razor_set *set; + struct razor_entry *e; + char *empty; + + set = zalloc(sizeof *set); + + e = array_add(&set->files, sizeof *e); + empty = array_add(&set->string_pool, 1); + *empty = '\0'; + e->name = 0; + e->flags = RAZOR_ENTRY_LAST; + e->start = 0; + list_set_empty(&e->packages); + + return set; + } + + struct razor_set * + razor_set_open(const char *filename) + { + struct razor_set *set; + struct razor_set_section *s; + struct stat stat; + struct array *array; + int fd; + + set = zalloc(sizeof *set); + fd = open(filename, O_RDONLY); + if (fstat(fd, &stat) < 0) + return NULL; + set->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (set->header == MAP_FAILED) { + free(set); + return NULL; + } + + for (s = set->header->sections; ~s->type; s++) { + if (s->type >= ARRAY_SIZE(razor_sections)) + continue; + if (s->type != razor_sections[s->type].type) + continue; + array = (void *) set + razor_sections[s->type].offset; + array->data = (void *) set->header + s->offset; + array->size = s->size; + array->alloc = s->size; + } + close(fd); + + return set; + } + + void ++razor_set_open_details(struct razor_set *set, const char *filename) ++{ ++ struct razor_set_section *s; ++ struct stat stat; ++ struct array *array; ++ int fd; ++ ++ fd = open(filename, O_RDONLY); ++ if (fstat(fd, &stat) < 0) ++ return; ++ set->details_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); ++ if (set->details_header == MAP_FAILED) ++ return; ++ ++ for (s = set->details_header->sections; ~s->type; s++) { ++ if (s->type >= ARRAY_SIZE(razor_details_sections)) ++ continue; ++ if (s->type != razor_details_sections[s->type].type) ++ continue; ++ array = (void *) set + razor_details_sections[s->type].offset; ++ array->data = (void *) set->details_header + s->offset; ++ array->size = s->size; ++ array->alloc = s->size; ++ } ++ close(fd); ++} ++ ++void ++razor_set_open_files(struct razor_set *set, const char *filename) ++{ ++ struct razor_set_section *s; ++ struct stat stat; ++ struct array *array; ++ int fd; ++ ++ fd = open(filename, O_RDONLY); ++ if (fstat(fd, &stat) < 0) ++ return; ++ set->files_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); ++ if (set->files_header == MAP_FAILED) ++ return; ++ ++ for (s = set->files_header->sections; ~s->type; s++) { ++ if (s->type >= ARRAY_SIZE(razor_files_sections)) ++ continue; ++ if (s->type != razor_files_sections[s->type].type) ++ continue; ++ array = (void *) set + razor_files_sections[s->type].offset; ++ array->data = (void *) set->files_header + s->offset; ++ array->size = s->size; ++ array->alloc = s->size; ++ } ++ close(fd); ++} ++ ++void + razor_set_destroy(struct razor_set *set) + { + unsigned int size; + struct array *a; + int i; + + if (set->header) { + for (i = 0; set->header->sections[i].type; i++) + ; + size = set->header->sections[i].type; + munmap(set->header, size); + } else { + for (i = 0; i < ARRAY_SIZE(razor_sections); i++) { + a = (void *) set + razor_sections[i].offset; + free(a->data); + } + } + ++ if (set->details_header) { ++ for (i = 0; set->details_header->sections[i].type; i++) ++ ; ++ size = set->details_header->sections[i].type; ++ munmap(set->details_header, size); ++ } else { ++ for (i = 0; i < ARRAY_SIZE(razor_details_sections); i++) { ++ a = (void *) set + razor_details_sections[i].offset; ++ free(a->data); ++ } ++ } ++ ++ if (set->files_header) { ++ for (i = 0; set->files_header->sections[i].type; i++) ++ ; ++ size = set->files_header->sections[i].type; ++ munmap(set->files_header, size); ++ } else { ++ for (i = 0; i < ARRAY_SIZE(razor_files_sections); i++) { ++ a = (void *) set + razor_files_sections[i].offset; ++ free(a->data); ++ } ++ } ++ + free(set); + } + -int -razor_set_write_to_fd(struct razor_set *set, int fd) ++static int ++razor_set_write_sections_to_fd(struct razor_set *set, int fd, int magic, ++ struct razor_set_section *sections, ++ size_t array_size) + { + char data[4096]; + struct razor_set_header *header = (struct razor_set_header *) data; + struct array *a; + uint32_t offset; + int i; + + memset(data, 0, sizeof data); - header->magic = RAZOR_MAGIC; ++ header->magic = magic; + header->version = RAZOR_VERSION; + offset = sizeof data; + - for (i = 0; i < ARRAY_SIZE(razor_sections); i++) { - if (razor_sections[i].type != i) ++ for (i = 0; i < array_size; i++) { ++ if (sections[i].type != i) + continue; - a = (void *) set + razor_sections[i].offset; ++ a = (void *) set + sections[i].offset; + header->sections[i].type = i; + header->sections[i].offset = offset; + header->sections[i].size = a->size; + offset += ALIGN(a->size, 4096); + } + + header->sections[i].type = ~0; + header->sections[i].offset = 0; + header->sections[i].size = 0; + + razor_write(fd, data, sizeof data); + memset(data, 0, sizeof data); - for (i = 0; i < ARRAY_SIZE(razor_sections); i++) { - if (razor_sections[i].type != i) ++ for (i = 0; i < array_size; i++) { ++ if (sections[i].type != i) + continue; - a = (void *) set + razor_sections[i].offset; ++ a = (void *) set + sections[i].offset; + razor_write(fd, a->data, a->size); + razor_write(fd, data, ALIGN(a->size, 4096) - a->size); + } + + return 0; + } + + int -razor_set_write(struct razor_set *set, const char *filename) ++razor_set_write_to_fd(struct razor_set *set, int fd, ++ enum razor_repo_file_type type) ++{ ++ switch (type) { ++ case RAZOR_REPO_FILE_MAIN: ++ return razor_set_write_sections_to_fd(set, fd, RAZOR_MAGIC, ++ razor_sections, ++ ARRAY_SIZE(razor_sections)); ++ ++ case RAZOR_REPO_FILE_DETAILS: ++ return razor_set_write_sections_to_fd(set, fd, RAZOR_DETAILS_MAGIC, ++ razor_details_sections, ++ ARRAY_SIZE(razor_details_sections)); ++ case RAZOR_REPO_FILE_FILES: ++ return razor_set_write_sections_to_fd(set, fd, RAZOR_FILES_MAGIC, ++ razor_files_sections, ++ ARRAY_SIZE(razor_files_sections)); ++ default: ++ return -1; ++ } ++} ++ ++int ++razor_set_write(struct razor_set *set, const char *filename, ++ enum razor_repo_file_type type) + { + int fd, status; + + fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); + if (fd < 0) + return -1; + - status = razor_set_write_to_fd(set, fd); ++ status = razor_set_write_to_fd(set, fd, type); + if (status) { + close(fd); + return status; + } + + return close(fd); + } - + void + razor_build_evr(char *evr_buf, int size, const char *epoch, + const char *version, const char *release) + { + int len; + + if (!version || !*version) { + *evr_buf = '\0'; + return; + } + + if (epoch && *epoch && strcmp(epoch, "0") != 0) { + len = snprintf(evr_buf, size, "%s:", epoch); + evr_buf += len; + size -= len; + } + len = snprintf(evr_buf, size, "%s", version); + evr_buf += len; + size -= len; + if (release && *release) + snprintf(evr_buf, size, "-%s", release); + } + + int + razor_versioncmp(const char *s1, const char *s2) + { + const char *p1, *p2; + long n1, n2; + int res; + + n1 = strtol(s1, (char **) &p1, 10); + n2 = strtol(s2, (char **) &p2, 10); + + /* Epoch; if one but not the other has an epoch set, default + * the epoch-less version to 0. */ + res = (*p1 == ':') - (*p2 == ':'); + if (res < 0) { + n1 = 0; + p1 = s1; + p2++; + } else if (res > 0) { + p1++; + n2 = 0; + p2 = s2; + } + + if (n1 != n2) + return n1 - n2; + while (*p1 && *p2) { + if (*p1 != *p2) + return *p1 - *p2; + p1++; + p2++; + if (isdigit(*p1) && isdigit(*p2)) + return razor_versioncmp(p1, p2); + } + + return *p1 - *p2; + } + + struct razor_package * + razor_set_get_package(struct razor_set *set, const char *package) + { + struct razor_package_iterator *pi; + struct razor_package *p; + const char *name, *version, *arch; + + pi = razor_package_iterator_create(set); + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) { + if (strcmp(package, name) == 0) + break; + } + razor_package_iterator_destroy(pi); + + return p; + } + ++void ++razor_package_get_details(struct razor_set *set, struct razor_package *package, ++ const char **summary, const char **description, ++ const char **url, const char **license) ++{ ++ const char *pool = set->details_string_pool.data; ++ ++ *summary = &pool[package->summary]; ++ *description = &pool[package->description]; ++ *url = &pool[package->url]; ++ *license = &pool[package->license]; ++} ++ + struct razor_entry * + razor_set_find_entry(struct razor_set *set, + struct razor_entry *dir, const char *pattern) + { + struct razor_entry *e; + const char *n, *pool = set->string_pool.data; + int len; + + e = (struct razor_entry *) set->files.data + dir->start; + do { + n = pool + e->name; + if (strcmp(pattern + 1, n) == 0) + return e; + len = strlen(n); + if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 && + pattern[len + 1] == '/') { + return razor_set_find_entry(set, e, pattern + len + 1); + } + } while (!((e++)->flags & RAZOR_ENTRY_LAST)); + + return NULL; + } + + static void + list_dir(struct razor_set *set, struct razor_entry *dir, + char *prefix, const char *pattern) + { + struct razor_entry *e; + const char *n, *pool = set->string_pool.data; + + e = (struct razor_entry *) set->files.data + dir->start; + do { + n = pool + e->name; + if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0) + continue; + printf("%s/%s\n", prefix, n); + if (e->start) { + char *sub = prefix + strlen (prefix); + *sub = '/'; + strcpy (sub + 1, n); + list_dir(set, e, prefix, pattern); + *sub = '\0'; + } + } while (!((e++)->flags & RAZOR_ENTRY_LAST)); + } + + void + razor_set_list_files(struct razor_set *set, const char *pattern) + { + struct razor_entry *e; + char buffer[512], *p, *base; + + if (pattern == NULL || !strcmp (pattern, "/")) { + buffer[0] = '\0'; + list_dir(set, set->files.data, buffer, NULL); + return; + } + + strcpy(buffer, pattern); + e = razor_set_find_entry(set, set->files.data, buffer); + if (e && e->start > 0) { + base = NULL; + } else { + p = strrchr(buffer, '/'); + if (p) { + *p = '\0'; + base = p + 1; + } else { + base = NULL; + } + } + e = razor_set_find_entry(set, set->files.data, buffer); + if (e->start != 0) + list_dir(set, e, buffer, base); + } + + static struct list * + list_package_files(struct razor_set *set, struct list *r, + struct razor_entry *dir, uint32_t end, + char *prefix) + { + struct razor_entry *e, *f, *entries; + uint32_t next, file; + char *pool; + int len; + + entries = (struct razor_entry *) set->files.data; + pool = set->string_pool.data; + + e = entries + dir->start; + do { + if (entries + r->data == e) { + printf("%s/%s\n", prefix, pool + e->name); + r = list_next(r); + if (!r) + return NULL; + if (r->data >= end) + return r; + } + } while (!((e++)->flags & RAZOR_ENTRY_LAST)); + + e = entries + dir->start; + do { + if (e->start == 0) + continue; + + if (e->flags & RAZOR_ENTRY_LAST) + next = end; + else { + f = e + 1; + while (f->start == 0 && !(f->flags & RAZOR_ENTRY_LAST)) + f++; + if (f->start == 0) + next = end; + else + next = f->start; + } + + file = r->data; + if (e->start <= file && file < next) { + len = strlen(prefix); + prefix[len] = '/'; + strcpy(prefix + len + 1, pool + e->name); + r = list_package_files(set, r, e, next, prefix); + prefix[len] = '\0'; + } + } while (!((e++)->flags & RAZOR_ENTRY_LAST) && r != NULL); + + return r; + } + + void + razor_set_list_package_files(struct razor_set *set, const char *name) + { + struct razor_package *package; + struct list *r; + uint32_t end; + char buffer[512]; + + package = razor_set_get_package(set, name); + + r = list_first(&package->files, &set->file_pool); + end = set->files.size / sizeof (struct razor_entry); + buffer[0] = '\0'; + list_package_files(set, r, set->files.data, end, buffer); + } + + /* The diff order matters. We should sort the packages so that a + * REMOVE of a package comes before the INSTALL, and so that all + * requires for a package have been installed before the package. + **/ + + void + razor_set_diff(struct razor_set *set, struct razor_set *upstream, + razor_package_callback_t callback, void *data) + { + struct razor_package_iterator *pi1, *pi2; + struct razor_package *p1, *p2; + const char *name1, *name2, *version1, *version2, *arch1, *arch2; + int res; + + pi1 = razor_package_iterator_create(set); + pi2 = razor_package_iterator_create(upstream); + + razor_package_iterator_next(pi1, &p1, &name1, &version1, &arch1); + razor_package_iterator_next(pi2, &p2, &name2, &version2, &arch2); + + while (p1 || p2) { + if (p1 && p2) { + res = strcmp(name1, name2); + if (res == 0) + res = razor_versioncmp(version1, version2); + } else { + res = 0; + } + + if (p2 == NULL || res < 0) + callback(name1, version1, NULL, arch1, data); + else if (p1 == NULL || res > 0) + callback(name2, NULL, version2, arch2, data); + + if (p1 != NULL && res <= 0) + razor_package_iterator_next(pi1, &p1, + &name1, &version1, &arch1); + if (p2 != NULL && res >= 0) + razor_package_iterator_next(pi2, &p2, + &name2, &version2, &arch2); + } + + razor_package_iterator_destroy(pi1); + razor_package_iterator_destroy(pi2); + } diff --cc librazor/razor.h index c1dbb54,d073ebb..8429912 --- a/librazor/razor.h +++ b/librazor/razor.h @@@ -26,27 -26,31 +26,37 @@@ struct razor_set struct razor_package; struct razor_property; +enum razor_repo_file_type { + RAZOR_REPO_FILE_MAIN, + RAZOR_REPO_FILE_DETAILS, + RAZOR_REPO_FILE_FILES +}; + - enum razor_property_type { - RAZOR_PROPERTY_REQUIRES, - RAZOR_PROPERTY_PROVIDES, - RAZOR_PROPERTY_CONFLICTS, - RAZOR_PROPERTY_OBSOLETES + enum razor_property_flags { + RAZOR_PROPERTY_LESS = 1 << 0, + RAZOR_PROPERTY_GREATER = 1 << 1, + RAZOR_PROPERTY_EQUAL = 1 << 2, + RAZOR_PROPERTY_RELATION_MASK = + RAZOR_PROPERTY_LESS | + RAZOR_PROPERTY_GREATER | + RAZOR_PROPERTY_EQUAL, + + RAZOR_PROPERTY_REQUIRES = 0 << 3, + RAZOR_PROPERTY_PROVIDES = 1 << 3, + RAZOR_PROPERTY_CONFLICTS = 2 << 3, + RAZOR_PROPERTY_OBSOLETES = 3 << 3, + RAZOR_PROPERTY_TYPE_MASK = 3 << 3, + + RAZOR_PROPERTY_PRE = 1 << 5, + RAZOR_PROPERTY_POST = 1 << 6, + RAZOR_PROPERTY_PREUN = 1 << 7, + RAZOR_PROPERTY_POSTUN = 1 << 8 }; - enum razor_version_relation { - RAZOR_VERSION_LESS, - RAZOR_VERSION_LESS_OR_EQUAL, - RAZOR_VERSION_EQUAL, - RAZOR_VERSION_GREATER_OR_EQUAL, - RAZOR_VERSION_GREATER - }; - extern const char * const razor_version_relations[]; + const char * + razor_property_relation_to_string(struct razor_property *p); + const char * + razor_property_type_to_string(struct razor_property *p); struct razor_set *razor_set_create(void); struct razor_set *razor_set_open(const char *filename); @@@ -186,16 -149,10 +165,15 @@@ void razor_importer_begin_package(struc const char *name, const char *version, const char *arch); +void razor_importer_add_details(struct razor_importer *importer, + const char *summary, + const char *description, + const char *url, + const char *license); void razor_importer_add_property(struct razor_importer *importer, const char *name, - enum razor_version_relation relation, - const char *version, - enum razor_property_type type); + uint32_t flags, + const char *version); void razor_importer_add_file(struct razor_importer *importer, const char *name); void razor_importer_finish_package(struct razor_importer *importer); diff --cc librazor/root.c index 0000000,8c032ef..dc3b230 mode 000000,100644..100644 --- a/librazor/root.c +++ b/librazor/root.c @@@ -1,0 -1,168 +1,168 @@@ + #include + #include + #include + #include + #include + #include + #include + #include "razor.h" + #include "razor-internal.h" + + static const char system_repo_filename[] = "system.repo"; + static const char next_repo_filename[] = "system-next.repo"; + static const char razor_root_path[] = "/var/lib/razor"; + + struct razor_root { + struct razor_set *system; + struct razor_set *next; + int fd; + char path[PATH_MAX]; + char new_path[PATH_MAX]; + }; + + int + razor_root_create(const char *root) + { + struct stat buf; + struct razor_set *set; + char path[PATH_MAX]; + + if (stat(root, &buf) < 0) { + if (mkdir(root, 0777) < 0) { + fprintf(stderr, + "could not create install root \"%s\"\n", + root); + return -1; + } + fprintf(stderr, "created install root \"%s\"\n", root); + } else if (!S_ISDIR(buf.st_mode)) { + fprintf(stderr, + "install root \"%s\" exists, but is not a directory\n", + root); + return -1; + } + + snprintf(path, sizeof path, "%s/%s", + razor_root_path, system_repo_filename); + if (razor_create_dir(root, path) < 0) { + fprintf(stderr, "could not create %s%s\n", + root, razor_root_path); + return -1; + } + + set = razor_set_create(); + snprintf(path, sizeof path, "%s%s/%s", + root, razor_root_path, system_repo_filename); + if (stat(path, &buf) == 0) { + fprintf(stderr, + "a razor install root is already initialized\n"); + return -1; + } - if (razor_set_write(set, path) < 0) { ++ if (razor_set_write(set, path, RAZOR_REPO_FILE_MAIN) < 0) { + fprintf(stderr, "could not write initial package set\n"); + return -1; + } + razor_set_destroy(set); + + return 0; + } + + struct razor_root * + razor_root_open(const char *root, int flags) + { + struct razor_root *image; + + image = malloc(sizeof *image); + if (image == NULL) + return NULL; + + /* Create the new next repo file up front to ensure exclusive + * access. */ + snprintf(image->new_path, sizeof image->new_path, + "%s%s/%s", root, razor_root_path, next_repo_filename); + image->fd = open(image->new_path, + O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666); + if (image->fd < 0) { + fprintf(stderr, "failed to get lock file, " + "maybe previous operation crashed?\n"); + + /* FIXME: Use fcntl advisory locking on the system + * package set file to figure out whether previous + * operation crashed or is still in progress. */ + + free(image); + return NULL; + } + + snprintf(image->path, sizeof image->path, + "%s%s/%s", root, razor_root_path, system_repo_filename); + image->system = razor_set_open(image->path); + if (image->system == NULL) { + unlink(image->new_path); + close(image->fd); + free(image); + return NULL; + } + + return image; + } + + struct razor_set * + razor_root_open_read_only(const char *root) + { + char path[PATH_MAX]; + + snprintf(path, sizeof path, "%s%s/%s", + root, razor_root_path, system_repo_filename); + + return razor_set_open(path); + } + + struct razor_transaction * + razor_root_create_transaction(struct razor_root *image, + struct razor_set *upstream) + { + /* FIXME: This should take a number of upstream repos. */ + return razor_transaction_create(image->system, upstream); + } + + int + razor_root_close(struct razor_root *image) + { + unlink(image->new_path); + close(image->fd); + free(image); + + return 0; + } + + void + razor_root_update(struct razor_root *root, struct razor_set *next) + { - razor_set_write_to_fd(next, root->fd); ++ razor_set_write_to_fd(next, root->fd, RAZOR_REPO_FILE_MAIN); + root->next = next; + + /* Sync the new repo file so the new package set is on disk + * before we start upgrading. */ + fsync(root->fd); + printf("wrote %s\n", root->new_path); + } + + int + razor_root_commit(struct razor_root *image) + { + /* Make it so. */ + rename(image->new_path, image->path); + printf("renamed %s to %s\n", image->new_path, image->path); + close(image->fd); + free(image); + + return 0; + } + + void + razor_root_diff(struct razor_root *root, + razor_package_callback_t callback, void *data) + { + return razor_set_diff(root->system, root->next, callback, data); + } diff --cc librazor/rpm.c index 2832da3,7a26ef7..3f572c4 --- a/librazor/rpm.c +++ b/librazor/rpm.c @@@ -592,8 -781,8 +781,8 @@@ razor_rpm_close(struct razor_rpm *rpm int razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm) { - const char *name, *version, *release, *arch; + const char *name, *version, *release, *arch, *summary; - const uint_32 *epoch; + const uint32_t *epoch; char evr[128], buf[16]; name = razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL); diff --cc src/import-rpmdb.c index 0000000,22d0855..a373786 mode 000000,100644..100644 --- a/src/import-rpmdb.c +++ b/src/import-rpmdb.c @@@ -1,0 -1,161 +1,170 @@@ + /* + * Copyright (C) 2008 Kristian Høgsberg + * Copyright (C) 2008 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + #include + #include + #include + #include + #include + #include + + #include "razor.h" + + union rpm_entry { + void *p; + char *string; + char **list; + uint_32 *flags; + uint_32 integer; + }; + + static uint32_t + rpm_to_razor_flags(uint32_t flags) + { + uint32_t razor_flags; + + razor_flags = 0; + if (flags & RPMSENSE_LESS) + razor_flags |= RAZOR_PROPERTY_LESS; + if (flags & RPMSENSE_EQUAL) + razor_flags |= RAZOR_PROPERTY_EQUAL; + if (flags & RPMSENSE_GREATER) + razor_flags |= RAZOR_PROPERTY_GREATER; + + if (flags & RPMSENSE_SCRIPT_PRE) + razor_flags |= RAZOR_PROPERTY_PRE; + if (flags & RPMSENSE_SCRIPT_POST) + razor_flags |= RAZOR_PROPERTY_POST; + if (flags & RPMSENSE_SCRIPT_PREUN) + razor_flags |= RAZOR_PROPERTY_PREUN; + if (flags & RPMSENSE_SCRIPT_POSTUN) + razor_flags |= RAZOR_PROPERTY_POSTUN; + + return razor_flags; + } + + static void + add_properties(struct razor_importer *importer, + uint32_t type_flags, + Header h, int_32 name_tag, int_32 version_tag, int_32 flags_tag) + { + union rpm_entry names, versions, flags; + int_32 i, type, count; + + headerGetEntry(h, name_tag, &type, &names.p, &count); + headerGetEntry(h, version_tag, &type, &versions.p, &count); + headerGetEntry(h, flags_tag, &type, &flags.p, &count); + + for (i = 0; i < count; i++) + razor_importer_add_property(importer, + names.list[i], + rpm_to_razor_flags (flags.flags[i]) | type_flags, + versions.list[i]); + } + + struct razor_set * + razor_set_create_from_rpmdb(void) + { + struct razor_importer *importer; + rpmdbMatchIterator iter; + Header h; + int_32 type, count, i; + union rpm_entry name, epoch, version, release, arch; ++ union rpm_entry summary, description, url, license; + union rpm_entry basenames, dirnames, dirindexes; + char filename[PATH_MAX], evr[128], buf[16]; + rpmdb db; + + rpmReadConfigFiles(NULL, NULL); + + if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) { + fprintf(stderr, "cannot open rpm database\n"); + exit(1); + } + + importer = razor_importer_new(); + + iter = rpmdbInitIterator(db, 0, NULL, 0); + while (h = rpmdbNextIterator(iter), h != NULL) { + headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count); + headerGetEntry(h, RPMTAG_EPOCH, &type, &epoch.p, &count); + headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count); + headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count); + headerGetEntry(h, RPMTAG_ARCH, &type, &arch.p, &count); ++ headerGetEntry(h, RPMTAG_SUMMARY, &type, &summary.p, &count); ++ headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &description.p, ++ &count); ++ headerGetEntry(h, RPMTAG_URL, &type, &url.p, &count); ++ headerGetEntry(h, RPMTAG_LICENSE, &type, &license.p, &count); + + if (epoch.flags != NULL) { + snprintf(buf, sizeof buf, "%u", *epoch.flags); + razor_build_evr(evr, sizeof evr, + buf, version.string, release.string); + } else { + razor_build_evr(evr, sizeof evr, + NULL, version.string, release.string); + } + + razor_importer_begin_package(importer, + name.string, evr, arch.string); ++ razor_importer_add_details(importer, summary.string, ++ description.string, url.string, ++ license.string); + + add_properties(importer, RAZOR_PROPERTY_REQUIRES, h, + RPMTAG_REQUIRENAME, + RPMTAG_REQUIREVERSION, + RPMTAG_REQUIREFLAGS); + + add_properties(importer, RAZOR_PROPERTY_PROVIDES, h, + RPMTAG_PROVIDENAME, + RPMTAG_PROVIDEVERSION, + RPMTAG_PROVIDEFLAGS); + + add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h, + RPMTAG_OBSOLETENAME, + RPMTAG_OBSOLETEVERSION, + RPMTAG_OBSOLETEFLAGS); + + add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h, + RPMTAG_CONFLICTNAME, + RPMTAG_CONFLICTVERSION, + RPMTAG_CONFLICTFLAGS); + + headerGetEntry(h, RPMTAG_BASENAMES, &type, + &basenames.p, &count); + headerGetEntry(h, RPMTAG_DIRNAMES, &type, + &dirnames.p, &count); + headerGetEntry(h, RPMTAG_DIRINDEXES, &type, + &dirindexes.p, &count); + for (i = 0; i < count; i++) { + snprintf(filename, sizeof filename, "%s%s", + dirnames.list[dirindexes.flags[i]], + basenames.list[i]); + razor_importer_add_file(importer, filename); + } + + razor_importer_finish_package(importer); + } + + rpmdbClose(db); + + return razor_importer_finish(importer); + } diff --cc src/import-yum.c index 9ed10cf,2efd201..8132eb8 --- a/src/import-yum.c +++ b/src/import-yum.c @@@ -56,9 -53,9 +57,10 @@@ struct yum_context struct razor_importer *importer; struct import_property_context *current_property_context; - char name[256], arch[64], buffer[512], *p; + char name[256], arch[64], summary[512], description[4096]; + char url[256], license[64], buffer[512], *p; char pkgid[128]; + uint32_t property_type; int state; }; @@@ -130,17 -115,18 +129,21 @@@ yum_primary_start_element(void *data, c } else if (strcmp(name, "checksum") == 0) { ctx->p = ctx->pkgid; ctx->state = YUM_STATE_CHECKSUM; + } else if (strcmp(name, "rpm:license") == 0) { + ctx->p = ctx->license; + ctx->state = YUM_STATE_LICENSE; } else if (strcmp(name, "rpm:requires") == 0) { ctx->state = YUM_STATE_REQUIRES; + ctx->property_type = RAZOR_PROPERTY_REQUIRES; } else if (strcmp(name, "rpm:provides") == 0) { ctx->state = YUM_STATE_PROVIDES; + ctx->property_type = RAZOR_PROPERTY_PROVIDES; } else if (strcmp(name, "rpm:obsoletes") == 0) { ctx->state = YUM_STATE_OBSOLETES; + ctx->property_type = RAZOR_PROPERTY_OBSOLETES; } else if (strcmp(name, "rpm:conflicts") == 0) { ctx->state = YUM_STATE_CONFLICTS; + ctx->property_type = RAZOR_PROPERTY_CONFLICTS; } else if (strcmp(name, "rpm:entry") == 0 && ctx->state != YUM_STATE_BEGIN) { n = NULL; diff --cc src/main.c index 5eed6d4,6a2acf7..15b3b6e --- a/src/main.c +++ b/src/main.c @@@ -484,8 -477,9 +484,9 @@@ command_remove(int argc, const char *ar return 1; set = razor_transaction_finish(trans); - razor_set_write(set, updated_repo_filename); + razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN); razor_set_destroy(set); + razor_set_destroy(upstream); printf("wrote system-updated.repo\n"); return 0; diff --cc src/test-driver.c index 54dbde7,876d248..91bc62c --- a/src/test-driver.c +++ b/src/test-driver.c @@@ -260,16 -262,12 +262,16 @@@ end_transaction(struct test_context *ct pkg = razor_set_get_package(ctx->repo_set, ctx->install_pkgs[i]); razor_transaction_install_package(ctx->trans, pkg); - } + } for (i = 0; i < ctx->n_remove_pkgs; i++) { - pkg = razor_set_get_package(ctx->repo_set, + pkg = razor_set_get_package(ctx->system_set, ctx->remove_pkgs[i]); + if (!pkg) + pkg = razor_set_get_package(ctx->repo_set, + ctx->remove_pkgs[i]); + razor_transaction_remove_package(ctx->trans, pkg); - } + } errors = razor_transaction_resolve(ctx->trans); printf("\n");