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;
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
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;
}
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)
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)
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;
}
}
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;
}
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++)
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);
}
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;
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));
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)
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));
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, '/');
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
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_ */
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);
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
+#ifdef MSWIN_API
+#include <direct.h>
+#endif
#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#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)
{
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);
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,
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();
## Process this file with automake to produce Makefile.in
-check_SCRIPTS = relocate
+check_SCRIPTS = relocate named-root
if HAVE_LUA
check_SCRIPTS += lua
endif
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
zsh.spec \
filesystem.spec \
lua.sh \
+ named-root.sh \
relocate.sh
clean-local :
--- /dev/null
+#!/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"