From: J. Ali Harlow Date: Fri, 3 Jul 2009 17:02:33 +0000 (+0100) Subject: Support RPM_INSTALL_PREFIX{n} during uninstall X-Git-Tag: 0.1~6 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=5dff2c97cf4a3e73aa85f548e00a3d8757992695;p=razor2.git%2F.git Support RPM_INSTALL_PREFIX{n} during uninstall --- diff --git a/librazor/importer.c b/librazor/importer.c index bb4695a..e3956e0 100644 --- a/librazor/importer.c +++ b/librazor/importer.c @@ -94,6 +94,7 @@ razor_importer_begin_package(struct razor_importer *importer, importer->package = p; array_init(&importer->properties); + array_init(&importer->install_prefixes); empty = hashtable_tokenize(&importer->details_table, ""); importer->package->preun.program = empty; @@ -116,7 +117,13 @@ razor_importer_finish_package(struct razor_importer *importer) &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); } /** @@ -176,6 +183,23 @@ razor_importer_add_script(struct razor_importer *importer, } /** + * 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 diff --git a/librazor/merger.c b/librazor/merger.c index 0935e23..39d8ccc 100644 --- a/librazor/merger.c +++ b/librazor/merger.c @@ -75,12 +75,13 @@ void 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); @@ -117,6 +118,18 @@ razor_merger_add_package(struct razor_merger *merger, 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, diff --git a/librazor/razor-internal.h b/librazor/razor-internal.h index 0a8fc69..31a6b5e 100644 --- a/librazor/razor-internal.h +++ b/librazor/razor-internal.h @@ -61,6 +61,7 @@ struct razor_set_header { #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" @@ -84,6 +85,7 @@ struct razor_package { uint32_t license; struct list_head properties; struct list_head files; + struct list_head install_prefixes; struct razor_script preun; struct razor_script postun; }; @@ -113,6 +115,7 @@ struct razor_set { 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; @@ -147,6 +150,7 @@ struct razor_importer { struct array properties; struct array files; struct array file_requires; + struct array install_prefixes; }; struct razor_package_iterator { @@ -220,4 +224,16 @@ uint32_t * 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_ */ diff --git a/librazor/razor.c b/librazor/razor.c index a5e1a37..3fac1f2 100644 --- a/librazor/razor.c +++ b/librazor/razor.c @@ -67,6 +67,7 @@ struct razor_set_section_index razor_sections[] = { { 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[] = { @@ -377,9 +378,9 @@ razor_versioncmp(const char *s1, const char *s2) } 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; @@ -434,6 +435,24 @@ razor_package_get_details_type(struct razor_set *set, } } +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 @@ -447,14 +466,22 @@ razor_package_get_details_varg(struct razor_set *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); + } } } @@ -501,7 +528,10 @@ razor_package_remove(struct razor_set *set, struct razor_package *package, 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, @@ -535,7 +565,22 @@ razor_package_remove(struct razor_set *set, struct razor_package *package, 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 * diff --git a/librazor/razor.h b/librazor/razor.h index a2fb076..f63b96b 100644 --- a/librazor/razor.h +++ b/librazor/razor.h @@ -41,7 +41,8 @@ enum razor_detail_type { RAZOR_DETAIL_PREUNPROG, RAZOR_DETAIL_PREUN, RAZOR_DETAIL_POSTUNPROG, - RAZOR_DETAIL_POSTUN + RAZOR_DETAIL_POSTUN, + RAZOR_DETAIL_PREFIXES }; enum razor_property_flags { @@ -349,6 +350,8 @@ void razor_importer_add_script(struct razor_importer *importer, 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, diff --git a/librazor/rpm.c b/librazor/rpm.c index 87f910c..f3c2724 100644 --- a/librazor/rpm.c +++ b/librazor/rpm.c @@ -509,7 +509,7 @@ razor_rpm_build_evr(struct razor_rpm *rpm) } 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: @@ -553,19 +553,39 @@ razor_rpm_get_details_type(struct razor_rpm *rpm, enum razor_detail_type type) } } +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); + } } } @@ -635,11 +655,12 @@ razor_rpm_open(const char *filename) 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, @@ -935,7 +956,7 @@ run_script(struct installer *installer, 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); @@ -943,16 +964,14 @@ run_script(struct installer *installer, 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, "") == 0) @@ -961,11 +980,8 @@ run_script(struct installer *installer, 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; diff --git a/librazor/util.c b/librazor/util.c index 5d1bc53..6bc5f6e 100644 --- a/librazor/util.c +++ b/librazor/util.c @@ -36,6 +36,7 @@ #if HAVE_SYS_MMAN_H #include #endif +#include #include "razor.h" #include "razor-internal.h" @@ -293,3 +294,71 @@ razor_qsort_with_data(void *base, size_t nelem, size_t size, 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); +} diff --git a/src/import-rpmdb.c b/src/import-rpmdb.c index 8ec7cbe..530c122 100644 --- a/src/import-rpmdb.c +++ b/src/import-rpmdb.c @@ -105,6 +105,7 @@ razor_set_create_from_rpmdb(void) 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; @@ -185,6 +186,12 @@ razor_set_create_from_rpmdb(void) 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); diff --git a/src/main.c b/src/main.c index 74908e6..43a6612 100644 --- a/src/main.c +++ b/src/main.c @@ -808,6 +808,7 @@ download_packages(struct razor_set *system, struct razor_set *next) 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; @@ -817,6 +818,8 @@ relocate_packages(struct razor_set *set, struct razor_relocations *relocations) 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; @@ -847,12 +850,22 @@ relocate_packages(struct razor_set *set, struct razor_relocations *relocations) } 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)) diff --git a/test/remove.sh b/test/remove.sh index 293b8b4..ce2ceda 100755 --- a/test/remove.sh +++ b/test/remove.sh @@ -58,20 +58,20 @@ export RAZOR_ROOT=`mktemp -dt` || exit 1 ../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"