importer->package = p;
array_init(&importer->properties);
+ array_init(&importer->install_prefixes);
empty = hashtable_tokenize(&importer->details_table, "");
importer->package->preun.program = empty;
&importer->properties,
1);
+ list_set_array(&importer->package->install_prefixes,
+ &importer->set->prefix_pool,
+ &importer->install_prefixes,
+ 0);
+
array_release(&importer->properties);
+ array_release(&importer->install_prefixes);
}
/**
}
/**
+ * razor_importer_add_install_prefixes:
+ * @importer: the %razor_importer
+ * @install_prefix: the relocated prefix
+ *
+ * Adds a relocated prefix for the current package.
+ **/
+RAZOR_EXPORT void
+razor_importer_add_install_prefix(struct razor_importer *importer,
+ const char *install_prefix)
+{
+ uint32_t *r;
+
+ r = array_add(&importer->install_prefixes, sizeof *r);
+ *r = hashtable_tokenize(&importer->table, install_prefix);
+}
+
+/**
* razor_importer_add_property:
* @importer: the %razor_importer
* @name: name of the property
razor_merger_add_package(struct razor_merger *merger,
struct razor_package *package)
{
- char *pool;
+ char *pool, *s;
struct list *r;
struct razor_package *p;
struct razor_set *set1;
struct source *source;
- uint32_t flags;
+ uint32_t flags, *prefix;
+ struct array install_prefixes;
assert(merger->committed == 0);
r = list_next(r);
}
+ array_init(&install_prefixes);
+ r = list_first(&package->install_prefixes, &source->set->prefix_pool);
+ while (r) {
+ s = (char *)source->set->string_pool.data + r->data;
+ prefix = array_add(&install_prefixes, sizeof *prefix);
+ *prefix = hashtable_tokenize(&merger->table, s);
+ r = list_next(r);
+ }
+ list_set_array(&p->install_prefixes, &merger->set->prefix_pool,
+ &install_prefixes, 0);
+ array_release(&install_prefixes);
+
p->preun.program = hashtable_tokenize(&merger->table,
&pool[package->preun.program]);
p->preun.body = hashtable_tokenize(&merger->table,
#define RAZOR_PROPERTIES "properties"
#define RAZOR_PACKAGE_POOL "package_pool"
#define RAZOR_PROPERTY_POOL "property_pool"
+#define RAZOR_PREFIX_POOL "prefix_pool"
#define RAZOR_DETAILS_STRING_POOL "details_string_pool"
uint32_t license;
struct list_head properties;
struct list_head files;
+ struct list_head install_prefixes;
struct razor_script preun;
struct razor_script postun;
};
struct array package_pool;
struct array property_pool;
struct array file_pool;
+ struct array prefix_pool;
struct array file_string_pool;
struct array details_string_pool;
struct array properties;
struct array files;
struct array file_requires;
+ struct array install_prefixes;
};
struct razor_package_iterator {
razor_qsort_with_data(void *base, size_t nelem, size_t size,
razor_compare_with_data_func_t compare, void *data);
+struct environment {
+ int is_set;
+ struct array vars, string_pool;
+};
+
+void environment_init(struct environment *env);
+void environment_add_variable(struct environment *env,
+ const char *variable, const char *value);
+void environment_set(struct environment *env);
+void environment_unset(struct environment *env);
+void environment_release(struct environment *env);
+
#endif /* _RAZOR_INTERNAL_H_ */
{ RAZOR_PROPERTIES, offsetof(struct razor_set, properties) },
{ RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
{ RAZOR_PROPERTY_POOL, offsetof(struct razor_set, property_pool) },
+ { RAZOR_PREFIX_POOL, offsetof(struct razor_set, prefix_pool) },
};
struct razor_set_section_index razor_files_sections[] = {
}
static const char *
-razor_package_get_details_type(struct razor_set *set,
- struct razor_package *package,
- enum razor_detail_type type)
+razor_package_get_details_string(struct razor_set *set,
+ struct razor_package *package,
+ enum razor_detail_type type)
{
const char *pool;
}
}
+static const char *const *
+razor_package_get_details_array(struct razor_set *set,
+ struct razor_package *package,
+ enum razor_detail_type type)
+{
+ switch (type) {
+ case RAZOR_DETAIL_PREFIXES:
+ /* We don't track prefixes in packages. Install prefixes
+ * are tracked, but we don't provide an API to get them.
+ */
+ return NULL;
+
+ default:
+ fprintf(stderr, "type %u not found\n", type);
+ return NULL;
+ }
+}
+
/**
* razor_package_get_details_varg:
* @set: a %razor_set
{
int i;
enum razor_detail_type type;
- const char **data;
+ const char **string;
+ const char *const **array;
for (i = 0;; i += 2) {
type = va_arg(args, enum razor_detail_type);
if (type == RAZOR_DETAIL_LAST)
break;
- data = va_arg(args, const char **);
- *data = razor_package_get_details_type(set, package, type);
+ if (type == RAZOR_DETAIL_PREFIXES) {
+ array = va_arg(args, const char *const **);
+ *array = razor_package_get_details_array(set, package,
+ type);
+ } else {
+ string = va_arg(args, const char **);
+ *string = razor_package_get_details_string(set, package,
+ type);
+ }
}
}
struct razor_package *p;
char buffer[PATH_MAX];
const char *name, *program, *script;
- int retval = 0, count;
+ int retval = 0, i, count;
+ struct environment env;
+ struct list *link;
+ const char *prefix;
razor_package_get_details(set, package,
RAZOR_DETAIL_PREUNPROG, &program,
RAZOR_DETAIL_POSTUN, &script,
RAZOR_DETAIL_LAST);
- return razor_run_script(root, RAZOR_PROPERTY_POSTUN, program, script);
+ environment_init(&env);
+ link = list_first(&package->install_prefixes, &set->prefix_pool);
+ for (i = 0; link; i++) {
+ prefix = (const char *)set->string_pool.data + link->data;
+ sprintf(buffer, "RPM_INSTALL_PREFIX%d", i);
+ environment_add_variable(&env, buffer, prefix);
+ link = list_next(link);
+ }
+ environment_set(&env);
+
+ retval = razor_run_script(root, RAZOR_PROPERTY_POSTUN, program, script);
+
+ environment_unset(&env);
+ environment_release(&env);
+
+ return retval;
}
RAZOR_EXPORT const char *
RAZOR_DETAIL_PREUNPROG,
RAZOR_DETAIL_PREUN,
RAZOR_DETAIL_POSTUNPROG,
- RAZOR_DETAIL_POSTUN
+ RAZOR_DETAIL_POSTUN,
+ RAZOR_DETAIL_PREFIXES
};
enum razor_property_flags {
enum razor_property_flags script,
const char *program,
const char *body);
+void razor_importer_add_install_prefix(struct razor_importer *importer,
+ const char *install_prefix);
void razor_importer_add_property(struct razor_importer *importer,
const char *name,
uint32_t flags,
}
static const char *
-razor_rpm_get_details_type(struct razor_rpm *rpm, enum razor_detail_type type)
+razor_rpm_get_details_string(struct razor_rpm *rpm, enum razor_detail_type type)
{
switch(type) {
case RAZOR_DETAIL_NAME:
}
}
+static const char *const *
+razor_rpm_get_details_array(struct razor_rpm *rpm, enum razor_detail_type type)
+{
+ switch(type) {
+ case RAZOR_DETAIL_PREFIXES:
+ return rpm->prefixes;
+
+ default:
+ /* Impossible */
+ fprintf(stderr, "type %u not found\n", type);
+ return NULL;
+ }
+}
+
void
razor_rpm_get_details_varg(struct razor_rpm *rpm, va_list args)
{
int i;
enum razor_detail_type type;
- const char **data;
+ const char **string;
+ const char *const **array;
for (i = 0;; i += 2) {
type = va_arg(args, enum razor_detail_type);
if (type == RAZOR_DETAIL_LAST)
break;
- data = va_arg(args, const char **);
- *data = razor_rpm_get_details_type(rpm, type);
+ if (type == RAZOR_DETAIL_PREFIXES) {
+ array = va_arg(args, const char *const **);
+ *array = razor_rpm_get_details_array(rpm, type);
+ } else {
+ string = va_arg(args, const char **);
+ *string = razor_rpm_get_details_string(rpm, type);
+ }
}
}
prefix = razor_rpm_get_indirect(rpm, RPMTAG_PREFIXES, &count);
if (prefix) {
- rpm->prefixes = calloc(count, sizeof *rpm->prefixes);
+ rpm->prefixes = calloc(count + 1, sizeof *rpm->prefixes);
for (i = 0; i < count; i++) {
rpm->prefixes[i] = prefix;
prefix += strlen(prefix) + 1;
}
+ rpm->prefixes[i] = NULL;
rpm->n_prefixes = count;
} else {
prefix = razor_rpm_get_indirect(rpm, RPMTAG_DEFAULTPREFIX,
struct razor_rpm *rpm = installer->rpm;
const char *script = NULL, *program = NULL, *prefix;
char buf[32], *p;
- struct array prefix_pool;
+ struct environment env;
program = razor_rpm_get_indirect(rpm, program_tag, NULL);
script = razor_rpm_get_indirect(rpm, script_tag, NULL);
return 0;
if (rpm->relocations) {
- array_init(&prefix_pool);
+ environment_init(&env);
for(i = 0; i < rpm->n_prefixes; i++) {
prefix = razor_relocations_apply(rpm->relocations,
rpm->prefixes[i]);
sprintf(buf, "RPM_INSTALL_PREFIX%d", i);
- p = array_add(&prefix_pool,
- strlen(buf) + strlen(prefix) + 2);
- sprintf(p, "%s=%s", buf, prefix);
- putenv(p);
+ environment_add_variable(&env, buf, prefix);
}
+ environment_set(&env);
}
if (program && strcmp(program, "<lua>") == 0)
retval = run_script_external(installer->root, program, script);
if (rpm->relocations) {
- for(i = 0; i < rpm->n_prefixes; i++) {
- sprintf(buf, "RPM_INSTALL_PREFIX%d=", i);
- putenv(buf);
- }
- array_release(&prefix_pool);
+ environment_unset(&env);
+ environment_release(&env);
}
return retval;
#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
+#include <assert.h>
#include "razor.h"
#include "razor-internal.h"
return map;
}
+
+void environment_init(struct environment *env)
+{
+ env->is_set = 0;
+ array_init(&env->string_pool);
+ array_init(&env->vars);
+}
+
+void environment_add_variable(struct environment *env,
+ const char *variable, const char *value)
+{
+ char *s;
+ uint32_t *r;
+ assert(!env->is_set);
+
+ s = array_add(&env->string_pool,
+ strlen(variable) + strlen(value) + 2);
+ sprintf(s, "%s=%s", variable, value);
+ r = array_add(&env->vars, sizeof *r);
+ *r = s - (char *)env->string_pool.data;
+}
+
+void environment_set(struct environment *env)
+{
+ int i, count;
+ char *s;
+ uint32_t *r;
+
+ if (!env->is_set) {
+ count = env->vars.size / sizeof(uint32_t);
+ r = (uint32_t *)env->vars.data;
+ for (i = 0; i < count; i++) {
+ s = env->string_pool.data + *r++;
+ putenv(s);
+ }
+
+ env->is_set = 1;
+ }
+}
+
+void environment_unset(struct environment *env)
+{
+ int i, count;
+ char c, *s, *t;
+ uint32_t *r;
+
+ if (env->is_set) {
+ count = env->vars.size / sizeof(uint32_t);
+ r = (uint32_t *)env->vars.data;
+ for (i = 0; i < count; i++) {
+ s = env->string_pool.data + *r++;
+ t = strchr(s, '=') + 1;
+ c = *t;
+ *t = '\0';
+ putenv(s);
+ *t = c;
+ }
+
+ env->is_set = 0;
+ }
+}
+
+void environment_release(struct environment *env)
+{
+ environment_unset(env);
+ array_release(&env->string_pool);
+ array_release(&env->vars);
+}
union rpm_entry name, epoch, version, release, arch;
union rpm_entry summary, description, url, license;
union rpm_entry basenames, dirnames, dirindexes;
+ union rpm_entry install_prefixes;
char filename[PATH_MAX], evr[128], buf[16];
rpmdb db;
int imported_count = 0;
add_script(importer, RAZOR_PROPERTY_POSTUN, h,
RPMTAG_POSTUNPROG, RPMTAG_POSTUN);
+ headerGetEntry(h, RPMTAG_INSTPREFIXES, &type,
+ &install_prefixes.p, &count);
+ for (i = 0; i < count; i++)
+ razor_importer_add_install_prefix(importer,
+ install_prefixes.list[i]);
+
razor_importer_finish_package(importer);
printf("\rimporting %d", ++imported_count);
static struct razor_set *
relocate_packages(struct razor_set *set, struct razor_relocations *relocations)
{
+ int i;
struct razor_importer *importer;
struct razor_property_iterator *prop_iter;
struct razor_package_iterator *pkg_iter;
struct razor_rpm *rpm;
const char *name, *version, *arch, *summary, *desc, *url, *license;
const char *preunprog, *preun, *postunprog, *postun;
+ const char *install_prefix;
+ const char *const *prefixes;
char file[PATH_MAX];
uint32_t flags;
}
razor_relocations_set_rpm(relocations, rpm);
- razor_rpm_close(rpm);
razor_importer_begin_package(importer, name, version, arch);
razor_importer_add_details(importer,
summary, desc, url, license);
+ razor_rpm_get_details(rpm, RAZOR_DETAIL_PREFIXES, &prefixes,
+ RAZOR_DETAIL_LAST);
+ for (i = 0; prefixes && prefixes[i]; i++) {
+ install_prefix = razor_relocations_apply(relocations,
+ prefixes[i]);
+ razor_importer_add_install_prefix(importer,
+ install_prefix);
+ }
+
+ razor_rpm_close(rpm);
+
prop_iter = razor_property_iterator_create(set, package);
while (razor_property_iterator_next(prop_iter, &property,
&name, &flags, &version))
../src/razor init || exit 1
export YUM_URL="file://localhost/`pwd`"
../src/razor import-yum || exit 1
-../src/razor install zip || exit 1
-fs_check_file /usr/var/lib/zip/data.zap
+../src/razor install --relocate /usr=/opt zip || exit 1
+fs_check_file /opt/var/lib/zip/data.zap
../src/razor remove zip || exit 1
-check_file /usr/bin/zap
-check_no_file /usr/bin/zip
-fs_check_no_file /usr/var/lib/zip/data.zap
-../src/razor install zsh || exit 1
-../src/razor install zsh2 || exit 1
+check_file /opt/bin/zap
+check_no_file /opt/bin/zip
+fs_check_no_file /opt/var/lib/zip/data.zap
+../src/razor install --relocate /usr=/opt zsh || exit 1
+../src/razor install --relocate /usr=/opt zsh2 || exit 1
../src/razor remove zsh || exit 1
check_file /etc/zsh.conf
-check_no_file /usr/bin/zsh
-../src/razor install zsh2 || exit 1
-../src/razor install zsh2 || exit 1
-fs_check_file /usr/var/lib/zip/data.zap
+check_no_file /opt/bin/zsh
+check_no_file /opt/var/lib/zsh/data.zip
+../src/razor install --relocate /usr=/opt zsh2 || exit 1
+fs_check_file /opt/var/lib/zip/data.zap
../src/razor remove zsh2 zip || exit 1
-fs_check_no_file /usr/var/lib/zip/data.zap
+fs_check_no_file /opt/var/lib/zip/data.zap
rm -rf "$RAZOR_ROOT"