# HG changeset patch # User J. Ali Harlow # Date 1240409357 -3600 # Node ID c9c90315ea24aa190ce1c25be3075f49db20ada1 # Parent 13beaca8b75f88c78ab753001679bdb527843145 Add support for named roots so that we can understand MS-Windows paths such as c:/windows. Without this, the user always has to ensure they are on the correct drive before running razor. diff -r 13beaca8b75f -r c9c90315ea24 librazor/importer.c --- a/librazor/importer.c Fri Apr 17 23:08:11 2009 +0100 +++ b/librazor/importer.c Wed Apr 22 15:09:17 2009 +0100 @@ -367,48 +367,56 @@ int count, i, length; struct import_entry *filenames; char *f, *end; - uint32_t name, *r; - char dirname[256]; - struct import_directory *d, root; + uint32_t name, *r, s; + char rootname[256], dirname[256]; + struct import_directory *d, *last_root; + struct array roots; struct razor_entry *e; count = importer->files.size / sizeof (struct import_entry); - razor_qsort_with_data(importer->files.data, + filenames = importer->files.data; + razor_qsort_with_data(filenames, count, sizeof (struct import_entry), compare_filenames, NULL); - root.name = hashtable_tokenize(&importer->file_table, ""); - array_init(&root.files); - array_init(&root.packages); - root.last = NULL; + array_init(&roots); + last_root = NULL; - filenames = importer->files.data; for (i = 0; i < count; i++) { f = filenames[i].name; - if (*f != '/') - continue; - f++; - - d = &root; + d = NULL; while (*f) { end = strchr(f, '/'); if (end == NULL) end = f + strlen(f); length = end - f; memcpy(dirname, f, length); - dirname[length] ='\0'; + dirname[length] = '\0'; name = hashtable_tokenize(&importer->file_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); + if (!d) { + if (!last_root || last_root->name != name) { + d = array_add(&roots, sizeof *d); + d->name = name; + d->last = NULL; + array_init(&d->files); + array_init(&d->packages); + last_root = d; + } + d = last_root; + } else { + if (!d->last || 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; } - d = d->last; f = end + 1; if (*end == '\0') break; @@ -419,16 +427,33 @@ 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); + count = roots.size / sizeof (struct import_directory); + d = roots.data; + s = count; + for (i = 0; i < count; i++) { + count_entries(d); + if (i) + e = array_add(&importer->set->files, sizeof *e); + else + e = importer->set->files.data; + e->name = d->name; + e->flags = 0; + e->start = d->count > 0 ? s : 0; + s += d->count; + list_set_empty(&e->packages); + d++; + } + if (count) + e->flags |= RAZOR_ENTRY_LAST; - serialize_files(importer->set, &root, &importer->set->files); + d = roots.data; + for (i = 0; i < count; i++) { + serialize_files(importer->set, d, &importer->set->files); + d++; + } array_release(&importer->files); + array_release(&roots); } static void diff -r 13beaca8b75f -r c9c90315ea24 librazor/merger.c --- a/librazor/merger.c Fri Apr 17 23:08:11 2009 +0100 +++ b/librazor/merger.c Wed Apr 22 15:09:17 2009 +0100 @@ -231,16 +231,15 @@ uint32_t e; int found_file = 0; - e = top->start; + e = top - files; do { - if (files[e].start) - fix_file_map(map, files, &files[e]); + if (files[e].start && + fix_file_map(map, files, &files[files[e].start])) + map[e] = 1; if (map[e]) found_file = 1; } while (!(files[e++].flags & RAZOR_ENTRY_LAST)); - if (found_file) - map[top - files] = 1; return found_file; } @@ -271,9 +270,9 @@ array_init(&merge_stack); start = merger->set->files.size / sizeof (struct razor_entry); - last = 0; - e1 = md->dir1 ? root1 + md->dir1 : NULL; - e2 = md->dir2 ? root2 + md->dir2 : NULL; + last = 0xFFFFFFFF; + e1 = md->dir1 != 0xFFFFFFFF ? root1 + md->dir1 : NULL; + e2 = md->dir2 != 0xFFFFFFFF ? root2 + md->dir2 : NULL; while (e1 || e2) { if (!e2 && !map1[e1 - root1]) { if ((e1++)->flags & RAZOR_ENTRY_LAST) @@ -311,7 +310,7 @@ child_md = array_add(&merge_stack, sizeof (struct merge_directory)); child_md->merged = last; child_md->dir1 = e1->start; - child_md->dir2 = 0; + child_md->dir2 = 0xFFFFFFFF; } } if ((e1++)->flags & RAZOR_ENTRY_LAST) @@ -323,7 +322,7 @@ if (e2->start) { child_md = array_add(&merge_stack, sizeof (struct merge_directory)); child_md->merged = last; - child_md->dir1 = 0; + child_md->dir1 = 0xFFFFFFFF; child_md->dir2 = e2->start; } } @@ -335,8 +334,8 @@ if (e1->start || e2->start) { child_md = array_add(&merge_stack, sizeof (struct merge_directory)); child_md->merged = last; - child_md->dir1 = e1->start; - child_md->dir2 = e2->start; + child_md->dir1 = e1->start ? e1->start : 0xFFFFFFFF; + child_md->dir2 = e2->start ? e2->start : 0xFFFFFFFF; } if ((e1++)->flags & RAZOR_ENTRY_LAST) e1 = NULL; @@ -346,11 +345,10 @@ } mroot = (struct razor_entry *)merger->set->files.data; - if (last) { + if (last != 0xFFFFFFFF) { mroot[last].flags = RAZOR_ENTRY_LAST; mroot[md->merged].start = start; - } else - mroot[md->merged].start = 0; + } end_md = merge_stack.data + merge_stack.size; for (child_md = merge_stack.data; child_md < end_md; child_md++) @@ -374,17 +372,23 @@ root = (struct razor_entry *) merger->source1.set->files.data; if (root->start) fix_file_map(map1, root, root); - md.dir1 = root->start; - } else md.dir1 = 0; + } else { + md.dir1 = 0xFFFFFFFF; + } if (merger->source2.set->files.size) { root = (struct razor_entry *) merger->source2.set->files.data; if (root->start) fix_file_map(map2, root, root); - md.dir2 = root->start; - } else md.dir2 = 0; + } else { + md.dir2 = 0xFFFFFFFF; + } + + /* Remove the unnamed root which razor_set_create() added */ + array_release(&merger->set->files); + array_init(&merger->set->files); merge_one_directory(merger, &md); } diff -r 13beaca8b75f -r c9c90315ea24 librazor/razor.c --- a/librazor/razor.c Fri Apr 17 23:08:11 2009 +0100 +++ b/librazor/razor.c Wed Apr 22 15:09:17 2009 +0100 @@ -504,7 +504,7 @@ razor_set_find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern) { - struct razor_entry *e; + struct razor_entry *e, *subdir; const char *n, *pool = set->file_string_pool.data; int len; @@ -512,15 +512,18 @@ assert (dir != NULL); assert (pattern != NULL); - e = (struct razor_entry *) set->files.data + dir->start; + e = dir; do { n = pool + e->name; - if (strcmp(pattern + 1, n) == 0) + if (strcmp(pattern, 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); + if (e->start != 0 && strncmp(pattern, n, len) == 0 && + pattern[len] == '/') { + subdir = (struct razor_entry *) set->files.data + + e->start; + return razor_set_find_entry(set, subdir, + pattern + len + 1); } } while (!((e++)->flags & RAZOR_ENTRY_LAST)); @@ -531,10 +534,10 @@ list_dir(struct razor_set *set, struct razor_entry *dir, char *prefix, const char *pattern) { - struct razor_entry *e; + struct razor_entry *e, *subdir; const char *n, *pool = set->file_string_pool.data; - e = (struct razor_entry *) set->files.data + dir->start; + e = dir; do { n = pool + e->name; if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0) @@ -544,7 +547,9 @@ char *sub = prefix + strlen (prefix); *sub = '/'; strcpy (sub + 1, n); - list_dir(set, e, prefix, pattern); + subdir = (struct razor_entry *) set->files.data + + e->start; + list_dir(set, subdir, prefix, pattern); *sub = '\0'; } } while (!((e++)->flags & RAZOR_ENTRY_LAST)); @@ -553,20 +558,28 @@ RAZOR_EXPORT void razor_set_list_files(struct razor_set *set, const char *pattern) { - struct razor_entry *e; + struct razor_entry *root, *e; char buffer[512], *p, *base; assert (set != NULL); - if (pattern == NULL || !strcmp (pattern, "/")) { - buffer[0] = '\0'; - list_dir(set, set->files.data, buffer, NULL); + root = (struct razor_entry *) set->files.data; + + if (pattern == NULL) { + p = set->file_string_pool.data; + e = root; + do { + if (e->start) { + strcpy(buffer, p + e->name); + list_dir(set, root + e->start, buffer, NULL); + } + } while (!((e++)->flags & RAZOR_ENTRY_LAST)); return; } strcpy(buffer, pattern); - e = razor_set_find_entry(set, set->files.data, buffer); - if (e && e->start > 0) { + e = razor_set_find_entry(set, root, buffer); + if (e && e->start) { base = NULL; } else { p = strrchr(buffer, '/'); @@ -577,9 +590,9 @@ base = NULL; } } - e = razor_set_find_entry(set, set->files.data, buffer); - if (e && e->start != 0) - list_dir(set, e, buffer, base); + e = razor_set_find_entry(set, root, buffer); + if (e && e->start) + list_dir(set, root + e->start, buffer, base); } RAZOR_EXPORT void diff -r 13beaca8b75f -r c9c90315ea24 librazor/razor.h --- a/librazor/razor.h Fri Apr 17 23:08:11 2009 +0100 +++ b/librazor/razor.h Wed Apr 22 15:09:17 2009 +0100 @@ -378,5 +378,7 @@ const char *version, const char *release); int razor_versioncmp(const char *s1, const char *s2); +void razor_disable_root_name_checks(int disable); + #endif /* _RAZOR_H_ */ diff -r 13beaca8b75f -r c9c90315ea24 librazor/rpm.c --- a/librazor/rpm.c Fri Apr 17 23:08:11 2009 +0100 +++ b/librazor/rpm.c Wed Apr 22 15:09:17 2009 +0100 @@ -380,8 +380,6 @@ RAZOR_EXPORT void razor_relocations_destroy(struct razor_relocations *rr) { - printf("razor_relocations_destroy(rr=%p): path=%p, rel=%p\n", - rr,rr->path,rr->relocations); free(rr->path); free(rr->relocations); free(rr); diff -r 13beaca8b75f -r c9c90315ea24 librazor/util.c --- a/librazor/util.c Fri Apr 17 23:08:11 2009 +0100 +++ b/librazor/util.c Wed Apr 22 15:09:17 2009 +0100 @@ -30,19 +30,49 @@ #include #include #include +#ifdef MSWIN_API +#include +#endif #if HAVE_SYS_MMAN_H #include #endif +#include "razor.h" #include "razor-internal.h" #ifndef O_BINARY #define O_BINARY 0 #endif +#define RAZOR_ASCII_ISALPHA(c) \ + ((c) >= 'A' && (c) <= 'Z' || (c) >= 'a' && (c) <= 'z') + /* Required by gnulib on non-libc platforms */ char *program_name = "librazor"; +static int allow_all_root_names = 0; + +/* + * Primarily intended for testing named roots under UNIX platforms. + */ +RAZOR_EXPORT void razor_disable_root_name_checks(int disable) +{ + allow_all_root_names = disable; +} + +static int razor_valid_root_name(const char *name) +{ + if (allow_all_root_names) + return !strchr(name,'/'); + +#ifdef MSWIN_API + return RAZOR_ASCII_ISALPHA(name[0]) && name[1] == ':' && + name[2] == '\0'; +#else + return name[0] == '\0'; +#endif +} + int razor_create_dir(const char *root, const char *path) { @@ -51,8 +81,9 @@ struct stat buf; /* Create all sub-directories in dir. We know root exists and - * is a dir, root does not end in a '/', and path has a - * leading '/'. */ + * is a dir, root does not end in a '/', and path either has a + * leading '/' or (on MS-Windows only) root is the empty string + * and path starts with drive (eg., "c:/windows"). */ strcpy(buffer, root); p = buffer + strlen(buffer); @@ -66,6 +97,9 @@ p += next - slash; *p = '\0'; + if (razor_valid_root_name(buffer)) + continue; + if (stat(buffer, &buf) == 0) { if (!S_ISDIR(buf.st_mode)) { fprintf(stderr, diff -r 13beaca8b75f -r c9c90315ea24 src/main.c --- a/src/main.c Fri Apr 17 23:08:11 2009 +0100 +++ b/src/main.c Wed Apr 22 15:09:17 2009 +0100 @@ -1165,6 +1165,9 @@ if (yum_url == NULL) yum_url = YUM_URL; + if (getenv("RAZOR_NO_ROOT_NAME_CHECKS")) + razor_disable_root_name_checks(1); + if (argc < 2) return usage(); diff -r 13beaca8b75f -r c9c90315ea24 test/Makefile.am --- a/test/Makefile.am Fri Apr 17 23:08:11 2009 +0100 +++ b/test/Makefile.am Wed Apr 22 15:09:17 2009 +0100 @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -check_SCRIPTS = relocate +check_SCRIPTS = relocate named-root if HAVE_LUA check_SCRIPTS += lua endif @@ -8,6 +8,9 @@ relocate: relocate.sh primary.xml.gz cp $(srcdir)/relocate.sh relocate +named-root: named-root.sh primary.xml.gz + cp $(srcdir)/named-root.sh named-root + lua: lua.sh primary.xml.gz cp $(srcdir)/lua.sh lua @@ -32,6 +35,7 @@ zsh.spec \ filesystem.spec \ lua.sh \ + named-root.sh \ relocate.sh clean-local : diff -r 13beaca8b75f -r c9c90315ea24 test/named-root.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/named-root.sh Wed Apr 22 15:09:17 2009 +0100 @@ -0,0 +1,53 @@ +#!/bin/sh +check_file() +{ + ../src/razor list-files | grep -x "$1" > /dev/null + if [ $? -ne 0 ]; then + echo $1: Not in database >&2 + ../src/razor list-files >&2 + exit 1 + fi + ../src/razor list-files c: | grep -x "$1" > /dev/null + if [ $? -ne 0 ]; then + echo $1: Not seen by named root list >&2 + ../src/razor list-files c: >&2 + exit 1 + fi + ../src/razor list-files "$1" | grep -x "$1" > /dev/null + if [ $? -ne 0 ]; then + echo $1: Not seen by patterned list >&2 + ../src/razor list-files "$1" >&2 + exit 1 + fi + pkgs=`../src/razor list-file-packages "$1"` + if [ -z "$pkgs" ]; then + echo $1: Not owned by any package >&2 + ../src/razor list-file-packages "$1" + exit 1 + fi + for nevra in "$pkgs"; do + name=`echo $nevra | sed 's/\-.*$//'` + ../src/razor list-package-files "$name" | grep -x "$1" > /dev/null + if [ $? -ne 0 ]; then + echo $1: Not in database for package $name >&2 + ../src/razor list-package-files "$name" + exit 1 + fi + done + if [ ! -e "$RAZOR_ROOT$1" ]; then + echo $1: Not in filesystem >&2 + exit 1 + fi +} +tmpdir=`mktemp -dt` || exit 1 +export RAZOR_ROOT="$tmpdir/x-" +mkdir -p "$tmpdir/x-/var/lib" "$tmpdir/x-c:" +export RAZOR_NO_ROOT_NAME_CHECKS=1 +../src/razor init || exit 1 +export YUM_URL="file://localhost/`pwd`" +../src/razor import-yum || exit 1 +../src/razor install --relocate /usr=c:/test zap || exit 1 +../src/razor install --relocate /usr=c:/test zip || exit 1 +check_file c:/test/bin/zap +check_file c:/test/bin/zip +rm -rf "$tmpdir"