From: J. Ali Harlow Date: Fri, 12 Jun 2009 15:59:11 +0000 (+0100) Subject: Add basic support for uninstall scripts. X-Git-Tag: 0.1~9 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=89d9f2c1cd3609902b2692e25f849f7a4804daa9;p=razor2.git%2F.git Add basic support for uninstall scripts. RPM_INSTALL_PREFIX{n} is not yet supported and upgrading a package where an uninstall script changes may need more work to ensure the old script doesn't get included in the merged set (when it is too late to remove). I haven't yet tested whether this is a real problem. --- diff --git a/librazor/importer.c b/librazor/importer.c index 2b1a0e1..bb4695a 100644 --- a/librazor/importer.c +++ b/librazor/importer.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -82,6 +83,7 @@ razor_importer_begin_package(struct razor_importer *importer, const char *version, const char *arch) { + uint32_t empty; struct razor_package *p; p = array_add(&importer->set->packages, sizeof *p); @@ -92,6 +94,12 @@ razor_importer_begin_package(struct razor_importer *importer, importer->package = p; array_init(&importer->properties); + + empty = hashtable_tokenize(&importer->details_table, ""); + importer->package->preun.program = empty; + importer->package->preun.body = empty; + importer->package->postun.program = empty; + importer->package->postun.body = empty; } /** @@ -135,6 +143,39 @@ razor_importer_add_details(struct razor_importer *importer, } /** + * razor_importer_add_script: + * @importer: the %razor_importer + * @script: either %RAZOR_PROPERTY_PREUN or %RAZOR_PROPERTY_POSTUN + * @program: the program to run the script + * @body: the body of the script + * + * Provide a script to use when uninstalling the current package. + **/ +RAZOR_EXPORT void +razor_importer_add_script(struct razor_importer *importer, + enum razor_property_flags script, + const char *program, + const char *body) +{ + switch (script) { + case RAZOR_PROPERTY_PREUN: + importer->package->preun.program = + hashtable_tokenize(&importer->table, program); + importer->package->preun.body = + hashtable_tokenize(&importer->table, body); + break; + case RAZOR_PROPERTY_POSTUN: + importer->package->postun.program = + hashtable_tokenize(&importer->table, program); + importer->package->postun.body = + hashtable_tokenize(&importer->table, body); + break; + default: + break; + } +} + +/** * razor_importer_add_property: * @importer: the %razor_importer * @name: name of the property diff --git a/librazor/merger.c b/librazor/merger.c index 44b6ce0..0935e23 100644 --- a/librazor/merger.c +++ b/librazor/merger.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -18,6 +19,7 @@ */ #include +#include #include "razor-internal.h" #include "razor.h" @@ -30,6 +32,7 @@ struct source { }; struct razor_merger { + int committed; struct razor_set *set; struct hashtable table; struct hashtable file_table; @@ -79,6 +82,8 @@ razor_merger_add_package(struct razor_merger *merger, struct source *source; uint32_t flags; + assert(merger->committed == 0); + set1 = merger->source1.set; if (set1->packages.data <= (void *) package && (void *) package < set1->packages.data + set1->packages.size) { @@ -111,6 +116,15 @@ razor_merger_add_package(struct razor_merger *merger, source->file_map[r->data] = 1; r = list_next(r); } + + p->preun.program = hashtable_tokenize(&merger->table, + &pool[package->preun.program]); + p->preun.body = hashtable_tokenize(&merger->table, + &pool[package->preun.body]); + p->postun.program = hashtable_tokenize(&merger->table, + &pool[package->postun.program]); + p->postun.body = hashtable_tokenize(&merger->table, + &pool[package->postun.body]); } static uint32_t @@ -481,9 +495,8 @@ rebuild_file_package_lists(struct razor_set *set) } struct razor_set * -razor_merger_finish(struct razor_merger *merger) +razor_merger_commit(struct razor_merger *merger) { - struct razor_set *result; struct razor_package *p, *pend; /* As we built the package list, we filled out a bitvector of @@ -523,10 +536,49 @@ razor_merger_finish(struct razor_merger *merger) rebuild_property_package_lists(merger->set); rebuild_file_package_lists(merger->set); - result = merger->set; + merger->committed = 1; + + return merger->set; +} + +void +razor_merger_package_add_script(struct razor_merger *merger, + struct razor_package *package, + enum razor_property_flags script, + const char *program, const char *body) +{ + uint32_t p, b; + char *pool; + struct razor_set *set = merger->set; + assert ((void *)package >= set->packages.data && \ + (void *)package < set->packages.data + set->packages.size); + + p = hashtable_tokenize(&merger->table, program); + b = hashtable_tokenize(&merger->table, body); + + pool = merger->set->string_pool.data; + + switch (script) { + case RAZOR_PROPERTY_PREUN: + assert(pool[package->preun.program] == '\0'); + assert(pool[package->preun.body] == '\0'); + package->preun.program = p; + package->preun.body = b; + break; + case RAZOR_PROPERTY_POSTUN: + assert(pool[package->postun.program] == '\0'); + assert(pool[package->postun.body] == '\0'); + package->postun.program = p; + package->postun.body = b; + break; + default: + break; + } +} + +void razor_merger_destroy(struct razor_merger *merger) +{ hashtable_release(&merger->table); hashtable_release(&merger->file_table); free(merger); - - return result; } diff --git a/librazor/razor-internal.h b/librazor/razor-internal.h index ae202dc..0a8fc69 100644 --- a/librazor/razor-internal.h +++ b/librazor/razor-internal.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -67,6 +68,11 @@ struct razor_set_header { #define RAZOR_FILE_POOL "file_pool" #define RAZOR_FILE_STRING_POOL "file_string_pool" +struct razor_script { + uint32_t program; + uint32_t body; +}; + struct razor_package { unsigned int name : 24; unsigned int flags : 8; @@ -78,6 +84,8 @@ struct razor_package { uint32_t license; struct list_head properties; struct list_head files; + struct razor_script preun; + struct razor_script postun; }; @@ -175,17 +183,28 @@ void razor_merger_add_package(struct razor_merger *merger, struct razor_package *package); struct razor_set * -razor_merger_finish(struct razor_merger *merger); +razor_merger_commit(struct razor_merger *merger); +void +razor_merger_package_add_script(struct razor_merger *merger, + struct razor_package *package, + enum razor_property_flags script, + const char *program, const char *body); +void +razor_merger_destroy(struct razor_merger *merger); int run_lua_script(const char *root, const char *name, const char *body, ssize_t len); +int razor_run_script(const char *root, enum razor_property_flags script, + const char *program, const char *body); + /* Utility functions */ void razor_package_get_details_varg(struct razor_set *set, struct razor_package *package, va_list args); +void razor_rpm_get_details_varg(struct razor_rpm *rpm, va_list args); int razor_create_dir(const char *root, const char *path); int razor_write(int fd, const void *data, size_t size); diff --git a/librazor/razor.c b/librazor/razor.c index aed65da..a5e1a37 100644 --- a/librazor/razor.c +++ b/librazor/razor.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -34,6 +35,7 @@ #include #include #include +#include #include #include "razor-internal.h" @@ -410,6 +412,22 @@ razor_package_get_details_type(struct razor_set *set, pool = set->details_string_pool.data; return &pool[package->license]; + case RAZOR_DETAIL_PREUNPROG: + pool = set->string_pool.data; + return &pool[package->preun.program]; + + case RAZOR_DETAIL_PREUN: + pool = set->string_pool.data; + return &pool[package->preun.body]; + + case RAZOR_DETAIL_POSTUNPROG: + pool = set->string_pool.data; + return &pool[package->postun.program]; + + case RAZOR_DETAIL_POSTUN: + pool = set->string_pool.data; + return &pool[package->postun.body]; + default: fprintf(stderr, "type %u not found\n", type); return NULL; @@ -466,6 +484,60 @@ razor_package_get_details(struct razor_set *set, struct razor_package *package, va_end (args); } +/** + * razor_package_remove: + * @set: a %razor_set + * @package: a %razor_package + * @root: the root into which the package is currently installed + * + * Removes an installed package. + **/ +RAZOR_EXPORT int +razor_package_remove(struct razor_set *set, struct razor_package *package, + const char *root) +{ + struct razor_file_iterator *fi; + struct razor_package_iterator *pi; + struct razor_package *p; + char buffer[PATH_MAX]; + const char *name, *program, *script; + int retval = 0, count; + + razor_package_get_details(set, package, + RAZOR_DETAIL_PREUNPROG, &program, + RAZOR_DETAIL_PREUN, &script, + RAZOR_DETAIL_LAST); + + if (razor_run_script(root, RAZOR_PROPERTY_PREUN, program, script)) + return -1; + + fi = razor_file_iterator_create(set, package); + + while (!retval && razor_file_iterator_next(fi, &name)) { + pi = razor_package_iterator_create_for_file(set, name); + count = 0; + while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST)) + count++; + razor_package_iterator_destroy(pi); + if (count <= 1) { + snprintf(buffer, sizeof buffer, "%s%s", root, name); + retval = remove(buffer); + } + } + + razor_file_iterator_destroy(fi); + + if (retval) + return retval; + + razor_package_get_details(set, package, + RAZOR_DETAIL_POSTUNPROG, &program, + RAZOR_DETAIL_POSTUN, &script, + RAZOR_DETAIL_LAST); + + return razor_run_script(root, RAZOR_PROPERTY_POSTUN, program, script); +} + RAZOR_EXPORT const char * razor_property_relation_to_string(struct razor_property *p) { diff --git a/librazor/razor.h b/librazor/razor.h index 64b1536..a2fb076 100644 --- a/librazor/razor.h +++ b/librazor/razor.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -36,7 +37,11 @@ enum razor_detail_type { RAZOR_DETAIL_SUMMARY, RAZOR_DETAIL_DESCRIPTION, RAZOR_DETAIL_URL, - RAZOR_DETAIL_LICENSE + RAZOR_DETAIL_LICENSE, + RAZOR_DETAIL_PREUNPROG, + RAZOR_DETAIL_PREUN, + RAZOR_DETAIL_POSTUNPROG, + RAZOR_DETAIL_POSTUN }; enum razor_property_flags { @@ -103,6 +108,9 @@ razor_set_get_package(struct razor_set *set, const char *package); void razor_package_get_details(struct razor_set *set, struct razor_package *package, ...); +int +razor_package_remove(struct razor_set *set, struct razor_package *package, + const char *root); /** @@ -234,6 +242,8 @@ void razor_install_iterator_destroy(struct razor_install_iterator *ii); * from packages from one or more other package sets. **/ +struct razor_rpm; + struct razor_transaction * razor_transaction_create(struct razor_set *system, struct razor_set *upstream); void razor_transaction_install_package(struct razor_transaction *transaction, @@ -242,10 +252,13 @@ void razor_transaction_remove_package(struct razor_transaction *transaction, struct razor_package *package); void razor_transaction_update_package(struct razor_transaction *trans, struct razor_package *package); +void razor_transaction_fixup_package(struct razor_transaction *trans, + struct razor_package *package, + struct razor_rpm *rpm); void razor_transaction_update_all(struct razor_transaction *transaction); int razor_transaction_resolve(struct razor_transaction *trans); int razor_transaction_describe(struct razor_transaction *trans); -struct razor_set *razor_transaction_finish(struct razor_transaction *trans); +struct razor_set *razor_transaction_commit(struct razor_transaction *trans); void razor_transaction_destroy(struct razor_transaction *trans); /* Temporary helper for test suite. */ @@ -264,7 +277,6 @@ int razor_transaction_unsatisfied_property(struct razor_transaction *trans, **/ struct razor_relocations; -struct razor_rpm; struct razor_relocations *razor_relocations_create(void); void razor_relocations_add(struct razor_relocations *relocations, @@ -276,6 +288,7 @@ const char *razor_relocations_apply(struct razor_relocations *relocations, void razor_relocations_destroy(struct razor_relocations *relocations); struct razor_rpm *razor_rpm_open(const char *filename); +void razor_rpm_get_details(struct razor_rpm *rpm, ...); void razor_rpm_set_relocations(struct razor_rpm *rpm, struct razor_relocations *relocations); int razor_rpm_install(struct razor_rpm *rpm, const char *root); @@ -332,6 +345,10 @@ void razor_importer_add_details(struct razor_importer *importer, const char *description, const char *url, const char *license); +void razor_importer_add_script(struct razor_importer *importer, + enum razor_property_flags script, + const char *program, + const char *body); 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 c3bb5c9..a46a979 100644 --- a/librazor/rpm.c +++ b/librazor/rpm.c @@ -256,6 +256,7 @@ struct razor_rpm { size_t size; void *payload; struct razor_relocations *relocations; + char *evr; }; enum razor_relocation_flags { @@ -491,6 +492,95 @@ import_files(struct razor_importer *importer, struct razor_rpm *rpm) } } +static void +razor_rpm_build_evr(struct razor_rpm *rpm) +{ + const char *version, *release; + const uint32_t *epoch; + char evr[128], buf[16]; + + epoch = razor_rpm_get_indirect(rpm, RPMTAG_EPOCH, NULL); + version = razor_rpm_get_indirect(rpm, RPMTAG_VERSION, NULL); + release = razor_rpm_get_indirect(rpm, RPMTAG_RELEASE, NULL); + if (epoch) + snprintf(buf, sizeof buf, "%lu", (unsigned long)ntohl(*epoch)); + razor_build_evr(evr, sizeof evr, epoch ? buf : NULL, version, release); + rpm->evr = strdup(evr); +} + +static const char * +razor_rpm_get_details_type(struct razor_rpm *rpm, enum razor_detail_type type) +{ + switch(type) { + case RAZOR_DETAIL_NAME: + return razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL); + + case RAZOR_DETAIL_VERSION: + if (!rpm->evr) + razor_rpm_build_evr(rpm); + return rpm->evr; + + case RAZOR_DETAIL_ARCH: + return razor_rpm_get_indirect(rpm, RPMTAG_ARCH, NULL); + + case RAZOR_DETAIL_SUMMARY: + return razor_rpm_get_indirect(rpm, RPMTAG_SUMMARY, NULL); + + case RAZOR_DETAIL_DESCRIPTION: + return razor_rpm_get_indirect(rpm, RPMTAG_DESCRIPTION, NULL); + + case RAZOR_DETAIL_URL: + return razor_rpm_get_indirect(rpm, RPMTAG_URL, NULL); + + case RAZOR_DETAIL_LICENSE: + return razor_rpm_get_indirect(rpm, RPMTAG_LICENSE, NULL); + + case RAZOR_DETAIL_PREUNPROG: + return razor_rpm_get_indirect(rpm, RPMTAG_PREUNPROG, NULL); + + case RAZOR_DETAIL_PREUN: + return razor_rpm_get_indirect(rpm, RPMTAG_PREUN, NULL); + + case RAZOR_DETAIL_POSTUNPROG: + return razor_rpm_get_indirect(rpm, RPMTAG_POSTUNPROG, NULL); + + case RAZOR_DETAIL_POSTUN: + return razor_rpm_get_indirect(rpm, RPMTAG_POSTUN, NULL); + + default: + 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; + + 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); + } +} + +RAZOR_EXPORT void +razor_rpm_get_details(struct razor_rpm *rpm, ...) +{ + va_list args; + + assert(rpm != NULL); + + va_start(args, rpm); + razor_rpm_get_details_varg(rpm, args); + va_end(args); +} + RAZOR_EXPORT struct razor_rpm * razor_rpm_open(const char *filename) { @@ -865,7 +955,7 @@ run_script(struct installer *installer, } } - if (strcmp(program, "") == 0) + if (program && strcmp(program, "") == 0) retval = run_script_lua(installer->root, script_tag, script); else retval = run_script_external(installer->root, program, script); @@ -881,6 +971,47 @@ run_script(struct installer *installer, return retval; } +int +razor_run_script(const char *root, enum razor_property_flags script, + const char *program, const char *body) +{ + int retval; + unsigned int script_tag; + + if (program && !*program) + program = NULL; + if (body && !*body) + body = NULL; + if (program == NULL && body == NULL) + return 0; + + if (program && strcmp(program, "") == 0) + { + switch(script) { + case RAZOR_PROPERTY_PRE: + script_tag = RPMTAG_PREIN; + break; + case RAZOR_PROPERTY_POST: + script_tag = RPMTAG_POSTIN; + break; + case RAZOR_PROPERTY_PREUN: + script_tag = RPMTAG_PREUN; + break; + case RAZOR_PROPERTY_POSTUN: + script_tag = RPMTAG_POSTUN; + break; + default: + script_tag = 0; + break; + } + retval = run_script_lua(root, script_tag, body); + } + else + retval = run_script_external(root, program, body); + + return retval; +} + static int installer_init(struct installer *installer) { @@ -1035,6 +1166,7 @@ razor_rpm_close(struct razor_rpm *rpm) free(rpm->dirs); free(rpm->prefixes); err = razor_file_free_contents(rpm->map, rpm->size); + free(rpm->evr); free(rpm); return err; @@ -1043,32 +1175,23 @@ razor_rpm_close(struct razor_rpm *rpm) RAZOR_EXPORT int razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm) { - const char *name, *version, *release, *arch; + const char *name, *version, *arch; const char *summary, *description, *url, *license; - const uint32_t *epoch; - char evr[128], buf[16]; assert (importer != NULL); assert (rpm != NULL); - name = razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL); - epoch = razor_rpm_get_indirect(rpm, RPMTAG_EPOCH, NULL); - version = razor_rpm_get_indirect(rpm, RPMTAG_VERSION, NULL); - release = razor_rpm_get_indirect(rpm, RPMTAG_RELEASE, NULL); - arch = razor_rpm_get_indirect(rpm, RPMTAG_ARCH, NULL); - - summary = razor_rpm_get_indirect(rpm, RPMTAG_SUMMARY, NULL); - description = razor_rpm_get_indirect(rpm, RPMTAG_DESCRIPTION, NULL); - url = razor_rpm_get_indirect(rpm, RPMTAG_URL, NULL); - license = razor_rpm_get_indirect(rpm, RPMTAG_LICENSE, NULL); - - if (epoch) { - snprintf(buf, sizeof buf, "%lu", ntohl(*epoch)); - razor_build_evr(evr, sizeof evr, buf, version, release); - } else { - razor_build_evr(evr, sizeof evr, NULL, version, release); - } - razor_importer_begin_package(importer, name, evr, arch); + razor_rpm_get_details(rpm, + RAZOR_DETAIL_NAME, &name, + RAZOR_DETAIL_VERSION, &version, + RAZOR_DETAIL_ARCH, &arch, + RAZOR_DETAIL_SUMMARY, &summary, + RAZOR_DETAIL_DESCRIPTION, &description, + RAZOR_DETAIL_URL, &url, + RAZOR_DETAIL_LICENSE, &license, + RAZOR_DETAIL_LAST); + + razor_importer_begin_package(importer, name, version, arch); razor_importer_add_details(importer, summary, description, url, license); diff --git a/librazor/transaction.c b/librazor/transaction.c index e6e9bfb..50d13d6 100644 --- a/librazor/transaction.c +++ b/librazor/transaction.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -100,6 +101,7 @@ struct razor_transaction { int package_count, errors; struct transaction_set system, upstream; int changes; + struct razor_merger *merger; }; static void @@ -854,9 +856,8 @@ razor_transaction_unsatisfied_property(struct razor_transaction *trans, } RAZOR_EXPORT struct razor_set * -razor_transaction_finish(struct razor_transaction *trans) +razor_transaction_commit(struct razor_transaction *trans) { - struct razor_merger *merger; struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs; char *upool, *spool; int cmp; @@ -873,7 +874,8 @@ razor_transaction_finish(struct razor_transaction *trans) trans->upstream.set->packages.size; upool = trans->upstream.set->string_pool.data; - merger = razor_merger_create(trans->system.set, trans->upstream.set); + trans->merger = razor_merger_create(trans->system.set, + trans->upstream.set); while (s < send || u < uend) { if (s < send && u < uend) cmp = strcmp(&spool[s->name], &upool[u->name]); @@ -884,26 +886,46 @@ razor_transaction_finish(struct razor_transaction *trans) if (cmp < 0) { if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT) - razor_merger_add_package(merger, s); + razor_merger_add_package(trans->merger, s); s++; } else if (cmp == 0) { if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT) - razor_merger_add_package(merger, s); + razor_merger_add_package(trans->merger, s); if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT) - razor_merger_add_package(merger, u); + razor_merger_add_package(trans->merger, u); s++; u++; } else { if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT) - razor_merger_add_package(merger, u); + razor_merger_add_package(trans->merger, u); u++; } } - razor_transaction_destroy(trans); + return razor_merger_commit(trans->merger); +} + +RAZOR_EXPORT void +razor_transaction_fixup_package(struct razor_transaction *trans, + struct razor_package *package, + struct razor_rpm *rpm) +{ + const char *preunprog, *preun, *postunprog, *postun; + + razor_rpm_get_details(rpm, + RAZOR_DETAIL_PREUNPROG, &preunprog, + RAZOR_DETAIL_PREUN, &preun, + RAZOR_DETAIL_POSTUNPROG, &postunprog, + RAZOR_DETAIL_POSTUN, &postun, + RAZOR_DETAIL_LAST); - return razor_merger_finish(merger); + razor_merger_package_add_script(trans->merger, package, + RAZOR_PROPERTY_PREUN, + preunprog, preun); + razor_merger_package_add_script(trans->merger, package, + RAZOR_PROPERTY_POSTUN, + postunprog, postun); } RAZOR_EXPORT void @@ -911,6 +933,8 @@ razor_transaction_destroy(struct razor_transaction *trans) { assert (trans != NULL); + if (trans->merger) + razor_merger_destroy(trans->merger); transaction_set_release(&trans->system); transaction_set_release(&trans->upstream); free(trans); diff --git a/src/import-rpmdb.c b/src/import-rpmdb.c index bb69c7b..8ec7cbe 100644 --- a/src/import-rpmdb.c +++ b/src/import-rpmdb.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -79,6 +80,21 @@ add_properties(struct razor_importer *importer, versions.list[i]); } +static void +add_script(struct razor_importer *importer, + uint32_t type_flags, Header h, + int32_t program_tag, int32_t body_tag) +{ + union rpm_entry program, body; + int32_t type, count; + + headerGetEntry(h, program_tag, &type, &program.p, &count); + headerGetEntry(h, body_tag, &type, &body.p, &count); + + razor_importer_add_script(importer, type_flags, + program.string, body.string); +} + struct razor_set * razor_set_create_from_rpmdb(void) { @@ -163,6 +179,12 @@ razor_set_create_from_rpmdb(void) razor_importer_add_file(importer, filename); } + add_script(importer, RAZOR_PROPERTY_PREUN, h, + RPMTAG_PREUNPROG, RPMTAG_PREUN); + + add_script(importer, RAZOR_PROPERTY_POSTUN, h, + RPMTAG_POSTUNPROG, RPMTAG_POSTUN); + razor_importer_finish_package(importer); printf("\rimporting %d", ++imported_count); diff --git a/src/main.c b/src/main.c index db055be..74908e6 100644 --- a/src/main.c +++ b/src/main.c @@ -50,8 +50,8 @@ static const char *yum_url; #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) static int -update_packages(struct razor_set *system, struct razor_set *next, - struct razor_relocations *relocations); +update_packages(struct razor_transaction *trans, struct razor_set *system, + struct razor_set *next, struct razor_relocations *relocations); static struct razor_package_iterator * create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[]) @@ -222,6 +222,44 @@ command_list_conflicts(int argc, const char *argv[]) } static int +command_list_scripts(int argc, const char *argv[]) +{ + struct razor_set *set; + struct razor_package *package; + struct razor_package_iterator *pi; + const char *preunprog, *preun, *postunprog, *postun; + + set = razor_root_open_read_only(install_root); + if (set == NULL) + return 1; + + pi = create_iterator_from_argv(set, argc, argv); + while (razor_package_iterator_next(pi, &package, + RAZOR_DETAIL_PREUNPROG, &preunprog, + RAZOR_DETAIL_PREUN, &preun, + RAZOR_DETAIL_POSTUNPROG, &postunprog, + RAZOR_DETAIL_POSTUN, &postun, + RAZOR_DETAIL_LAST)) { + if (preun && *preun) { + printf("preuninstall scriptlet"); + if (preunprog && *preunprog) + printf(" (using %s)",preunprog); + printf(":\n%s\n",preun); + } + if (postun && *postun) { + printf("postuninstall scriptlet"); + if (postunprog && *postunprog) + printf(" (using %s)",postunprog); + printf(":\n%s\n",postun); + } + } + razor_package_iterator_destroy(pi); + razor_set_destroy(set); + + return 0; +} + +static int command_list_files(int argc, const char *argv[]) { struct razor_set *set; @@ -542,6 +580,7 @@ command_update(int argc, const char *argv[]) for (i = 0; i < argc; i++) { if (mark_packages_for_update(trans, set, argv[i]) == 0) { fprintf(stderr, "no match for %s\n", argv[i]); + razor_transaction_destroy(trans); return 1; } } @@ -550,11 +589,13 @@ command_update(int argc, const char *argv[]) errors = razor_transaction_describe(trans); if (errors) { fprintf(stderr, "unresolved dependencies\n"); + razor_transaction_destroy(trans); return 1; } - set = razor_transaction_finish(trans); + set = razor_transaction_commit(trans); razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN); + razor_transaction_destroy(trans); razor_set_destroy(set); razor_set_destroy(upstream); printf("wrote system-updated.rzdb\n"); @@ -598,10 +639,11 @@ command_remove(int argc, const char *argv[]) return 1; } - next = razor_transaction_finish(trans); - update_packages(system, next, NULL); + next = razor_transaction_commit(trans); + update_packages(trans, system, next, NULL); razor_root_update(root, next); + razor_transaction_destroy(trans); razor_set_destroy(next); razor_set_destroy(upstream); @@ -774,6 +816,7 @@ relocate_packages(struct razor_set *set, struct razor_relocations *relocations) struct razor_property *property; struct razor_rpm *rpm; const char *name, *version, *arch, *summary, *desc, *url, *license; + const char *preunprog, *preun, *postunprog, *postun; char file[PATH_MAX]; uint32_t flags; @@ -788,6 +831,10 @@ relocate_packages(struct razor_set *set, struct razor_relocations *relocations) RAZOR_DETAIL_DESCRIPTION, &desc, RAZOR_DETAIL_URL, &url, RAZOR_DETAIL_LICENSE, &license, + RAZOR_DETAIL_PREUNPROG, &preunprog, + RAZOR_DETAIL_PREUN, &preun, + RAZOR_DETAIL_POSTUNPROG, &postunprog, + RAZOR_DETAIL_POSTUN, &postun, RAZOR_DETAIL_LAST)) { snprintf(file, sizeof file, "rpms/%s", rpm_filename(name, version, arch)); @@ -820,6 +867,11 @@ relocate_packages(struct razor_set *set, struct razor_relocations *relocations) } razor_file_iterator_destroy(file_iter); + razor_importer_add_script(importer, RAZOR_PROPERTY_PREUN, + preunprog, preun); + razor_importer_add_script(importer, RAZOR_PROPERTY_POSTUN, + postunprog, postun); + razor_importer_finish_package(importer); } @@ -828,7 +880,8 @@ relocate_packages(struct razor_set *set, struct razor_relocations *relocations) } static int -install_package(struct razor_set *set, struct razor_package *package, +install_package(struct razor_transaction *trans, struct razor_set *set, + struct razor_package *package, struct razor_relocations *relocations) { int retval; @@ -853,6 +906,7 @@ install_package(struct razor_set *set, struct razor_package *package, } if (relocations) razor_rpm_set_relocations(rpm, relocations); + razor_transaction_fixup_package(trans, package, rpm); retval = razor_rpm_install(rpm, install_root); if (retval < 0) fprintf(stderr, "failed to install rpm %s\n", file); @@ -861,37 +915,8 @@ install_package(struct razor_set *set, struct razor_package *package, } static int -remove_package(struct razor_set *set, struct razor_package *package) -{ - struct razor_file_iterator *fi; - struct razor_package_iterator *pi; - struct razor_package *p; - char buffer[PATH_MAX]; - const char *name; - int retval = 0, count; - - fi = razor_file_iterator_create(set, package); - - while (!retval && razor_file_iterator_next(fi, &name)) { - pi = razor_package_iterator_create_for_file(set, name); - count = 0; - while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST)) - count++; - razor_package_iterator_destroy(pi); - if (count <= 1) { - snprintf(buffer, sizeof buffer, "%s%s", install_root, - name); - retval = remove(buffer); - } - } - - razor_file_iterator_destroy(fi); - return retval; -} - -static int -update_packages(struct razor_set *system, struct razor_set *next, - struct razor_relocations *relocations) +update_packages(struct razor_transaction *trans, struct razor_set *system, + struct razor_set *next, struct razor_relocations *relocations) { struct razor_install_iterator *ii; struct razor_package *package; @@ -903,9 +928,11 @@ update_packages(struct razor_set *system, struct razor_set *next, while (!retval && razor_install_iterator_next(ii, &set, &package, &action, &count)) { if (action == RAZOR_INSTALL_ACTION_ADD) - retval = install_package(set, package, relocations); + retval = install_package(trans, set, package, + relocations); else if (action == RAZOR_INSTALL_ACTION_REMOVE) - retval = remove_package(set, package); + retval = razor_package_remove(set, package, + install_root); } razor_install_iterator_destroy(ii); @@ -974,6 +1001,7 @@ command_install(int argc, const char *argv[]) for (; i < argc; i++) { if (mark_packages_for_update(trans, upstream, argv[i]) == 0) { fprintf(stderr, "no package matched %s\n", argv[i]); + razor_transaction_destroy(trans); razor_root_close(root); return 1; } @@ -982,28 +1010,32 @@ command_install(int argc, const char *argv[]) if (dependencies) { razor_transaction_resolve(trans); if (razor_transaction_describe(trans) > 0) { + razor_transaction_destroy(trans); razor_root_close(root); return 1; } } - next = razor_transaction_finish(trans); - - razor_root_update(root, next); + next = razor_transaction_commit(trans); if (mkdir("rpms", 0777) && errno != EEXIST) { fprintf(stderr, "failed to create rpms directory.\n"); + razor_transaction_destroy(trans); razor_root_close(root); return 1; } if (download_packages(system, next) < 0) { + razor_transaction_destroy(trans); razor_root_close(root); return 1; } - update_packages(system, next, relocations); + update_packages(trans, system, next, relocations); + + razor_root_update(root, next); + razor_transaction_destroy(trans); if (relocations) razor_relocations_destroy(relocations); razor_set_destroy(next); @@ -1167,6 +1199,7 @@ static struct { { "list-provides", "list all provides for the given package", command_list_provides }, { "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes }, { "list-conflicts", "list all conflicts for the given package", command_list_conflicts }, + { "list-scripts", "list all scripts for the given package", command_list_scripts }, { "list-files", "list files for package set", command_list_files }, { "list-file-packages", "list packages owning file", command_list_file_packages }, { "list-package-files", "list files in package", command_list_package_files }, diff --git a/src/rpm.c b/src/rpm.c index 4c288b4..225bb99 100644 --- a/src/rpm.c +++ b/src/rpm.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -602,17 +603,21 @@ command_erase(int argc, const char *argv[]) if (!option_nodeps && razor_transaction_describe(trans) > 0) { printf("unsatisfied dependencies.\n"); + razor_transaction_destroy(trans); exit(1); } - if (option_test) + if (option_test) { + razor_transaction_destroy(trans); exit(0); + } - next = razor_transaction_finish(trans); + next = razor_transaction_commit(trans); if (!option_justdb) razor_set_diff(set, next, update_package, NULL); + razor_transaction_destroy(trans); razor_set_destroy(set); razor_set_destroy(upstream); @@ -644,17 +649,21 @@ command_install(int argc, const char *argv[]) if (!option_nodeps && razor_transaction_describe(trans) > 0) { printf("unsatisfied dependencies.\n"); + razor_transaction_destroy(trans); exit(1); } - if (option_test) + if (option_test) { + razor_transaction_destroy(trans); exit(0); + } - next = razor_transaction_finish(trans); + next = razor_transaction_commit(trans); if (!option_justdb) razor_set_diff(set, next, update_package, NULL); + razor_transaction_destroy(trans); razor_set_destroy(set); razor_set_destroy(upstream); @@ -686,17 +695,21 @@ command_update(int argc, const char *argv[]) if (!option_nodeps && razor_transaction_describe(trans) > 0) { printf("unsatisfied dependencies.\n"); + razor_transaction_destroy(trans); exit(1); } - if (option_test) + if (option_test) { + razor_transaction_destroy(trans); exit(0); + } - next = razor_transaction_finish(trans); + next = razor_transaction_commit(trans); if (!option_justdb) razor_set_diff(set, next, update_package, NULL); + razor_transaction_destroy(trans); razor_set_destroy(set); razor_set_destroy(upstream); diff --git a/src/test-driver.c b/src/test-driver.c index f55049d..160a3ad 100644 --- a/src/test-driver.c +++ b/src/test-driver.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2009 J. Ali Harlow * * 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 @@ -336,7 +337,8 @@ end_transaction(struct test_context *ctx) if (!errors) { struct razor_set *new; - new = razor_transaction_finish(ctx->trans); + new = razor_transaction_commit(ctx->trans); + razor_transaction_destroy(ctx->trans); ctx->trans = NULL; ctx->system_set = new; } diff --git a/test/remove.sh b/test/remove.sh index e08fbb6..5298e6b 100755 --- a/test/remove.sh +++ b/test/remove.sh @@ -1,4 +1,19 @@ #!/bin/sh +fs_check_file() +{ + if [ ! -e "$RAZOR_ROOT$1" ]; then + echo $1: Not in filesystem >&2 + ls -R "$RAZOR_ROOT" >&2 + exit 1 + fi +} +fs_check_no_file() +{ + if [ -e "$RAZOR_ROOT$1" ]; then + echo $1: Still in filesystem >&2 + exit 1 + fi +} check_file() { ../src/razor list-files | grep -x "$1" > /dev/null @@ -28,10 +43,7 @@ check_file() exit 1 fi done - if [ ! -e "$RAZOR_ROOT$1" ]; then - echo $1: Not in filesystem >&2 - exit 1 - fi + fs_check_file $1 } check_no_file() { @@ -40,19 +52,18 @@ check_no_file() echo $1: Still in database >&2 exit 1 fi - if [ -e "$RAZOR_ROOT$1" ]; then - echo $1: Still in filesystem >&2 - exit 1 - fi + fs_check_no_file $1 } 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 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 ../src/razor remove zsh || exit 1 diff --git a/test/zip.spec b/test/zip.spec index c433a8e..ed7a619 100644 --- a/test/zip.spec +++ b/test/zip.spec @@ -43,7 +43,6 @@ if posix.stat(prefix.."/bin/zap")~=nil then end %postun -p -print("zip: postun script\n"); prefix=posix.getenv("RPM_INSTALL_PREFIX0") if prefix==nil then prefix="/usr"