diff options
Diffstat (limited to 'zarb-ml/mageia-sysadm/2011-February/002825.html')
-rw-r--r-- | zarb-ml/mageia-sysadm/2011-February/002825.html | 12989 |
1 files changed, 12989 insertions, 0 deletions
diff --git a/zarb-ml/mageia-sysadm/2011-February/002825.html b/zarb-ml/mageia-sysadm/2011-February/002825.html new file mode 100644 index 000000000..e3014b4dc --- /dev/null +++ b/zarb-ml/mageia-sysadm/2011-February/002825.html @@ -0,0 +1,12989 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<HTML> + <HEAD> + <TITLE> [Mageia-sysadm] [419] Import cleaned perl-URPM + </TITLE> + <LINK REL="Index" HREF="index.html" > + <LINK REL="made" HREF="mailto:mageia-sysadm%40mageia.org?Subject=Re%3A%20%5BMageia-sysadm%5D%20%5B419%5D%20Import%20cleaned%20perl-URPM&In-Reply-To=%3C20110204134150.A7AE93FFE7%40valstar.mageia.org%3E"> + <META NAME="robots" CONTENT="index,nofollow"> + <META http-equiv="Content-Type" content="text/html; charset=us-ascii"> + <LINK REL="Previous" HREF="002554.html"> + <LINK REL="Next" HREF="002555.html"> + </HEAD> + <BODY BGCOLOR="#ffffff"> + <H1>[Mageia-sysadm] [419] Import cleaned perl-URPM</H1> + <B>root at mageia.org</B> + <A HREF="mailto:mageia-sysadm%40mageia.org?Subject=Re%3A%20%5BMageia-sysadm%5D%20%5B419%5D%20Import%20cleaned%20perl-URPM&In-Reply-To=%3C20110204134150.A7AE93FFE7%40valstar.mageia.org%3E" + TITLE="[Mageia-sysadm] [419] Import cleaned perl-URPM">root at mageia.org + </A><BR> + <I>Fri Feb 4 14:43:09 CET 2011</I> + <P><UL> + <LI>Previous message: <A HREF="002554.html">[Mageia-sysadm] [418] add README file +</A></li> + <LI>Next message: <A HREF="002555.html">[Mageia-sysadm] [420] - import cleaned mageia-lxde-config +</A></li> + <LI> <B>Messages sorted by:</B> + <a href="date.html#2825">[ date ]</a> + <a href="thread.html#2825">[ thread ]</a> + <a href="subject.html#2825">[ subject ]</a> + <a href="author.html#2825">[ author ]</a> + </LI> + </UL> + <HR> +<!--beginarticle--> +<PRE>Revision: 419 +Author: dmorgan +Date: 2011-02-04 14:41:50 +0100 (Fri, 04 Feb 2011) +Log Message: +----------- +Import cleaned perl-URPM + +Added Paths: +----------- + rpm/perl-URPM/ + rpm/perl-URPM/trunk/ + rpm/perl-URPM/trunk/.perl_checker + rpm/perl-URPM/trunk/ChangeLog + rpm/perl-URPM/trunk/MANIFEST + rpm/perl-URPM/trunk/META.yml + rpm/perl-URPM/trunk/Makefile.PL + rpm/perl-URPM/trunk/NEWS + rpm/perl-URPM/trunk/README + rpm/perl-URPM/trunk/URPM/ + rpm/perl-URPM/trunk/URPM/.perl_checker + rpm/perl-URPM/trunk/URPM/Build.pm + rpm/perl-URPM/trunk/URPM/Query.pm + rpm/perl-URPM/trunk/URPM/Resolve.pm + rpm/perl-URPM/trunk/URPM/Signature.pm + rpm/perl-URPM/trunk/URPM.pm + rpm/perl-URPM/trunk/URPM.xs + rpm/perl-URPM/trunk/t/ + rpm/perl-URPM/trunk/t/00prepare.t + rpm/perl-URPM/trunk/t/buggy_synthesis.cz + rpm/perl-URPM/trunk/t/empty_synthesis.cz + rpm/perl-URPM/trunk/t/fatal.t + rpm/perl-URPM/trunk/t/parse.t + rpm/perl-URPM/trunk/t/pod.t + rpm/perl-URPM/trunk/t/rpmdb.t + rpm/perl-URPM/trunk/t/sort_graph.t + rpm/perl-URPM/trunk/t/synthesis.t + rpm/perl-URPM/trunk/t/test-rpm.spec + rpm/perl-URPM/trunk/typemap + +Added: rpm/perl-URPM/trunk/.perl_checker +=================================================================== +--- rpm/perl-URPM/trunk/.perl_checker (rev 0) ++++ rpm/perl-URPM/trunk/.perl_checker 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,2 @@ ++Compress::Zlib ++File::Path + +Added: rpm/perl-URPM/trunk/ChangeLog +=================================================================== +--- rpm/perl-URPM/trunk/ChangeLog (rev 0) ++++ rpm/perl-URPM/trunk/ChangeLog 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,4159 @@ ++2010-07-23 02:43 ++ ++ * - fix deferencement on hash (instead hashref), warning triggered ++ by perl 5.12 ++ ++2010-04-23 16:06 ++ ++ * only print debug message if debug callback is defined ++ ++2010-04-23 15:40 ++ ++ * 3.35 ++ ++2010-04-23 15:39 ++ ++ * honour search medias when using --auto-select ++ ++2010-03-23 15:48 ++ ++ * 3.34.1 ++ ++2010-03-23 15:47 ++ ++ * check selected packages for unsatisfied requires when a promoted ++ package is backtracked and no replacement is found ++ ++ (#57224, Anssi Hannula) ++ ++2010-03-23 15:47 ++ ++ * 3.34 ++ ++2010-02-24 11:01 ++ ++ * adjust rpm.org/rpm5.org detection code ++ ++ It used to assume that rpm.org had version numbers < 4.7, but ++ it's ++ no longer true with rpm 4.8 being released. Test against 5.0 ++ since ++ rpm5.org releases started at 5.0 ++ ++2010-02-12 15:58 ++ ++ * check for conflicting selected packages before selecting a ++ package ++ ++ check for conflicting selected packages before selecting a ++ package ++ instead of after selecting it, to avoid having to unselect ++ package ++ in case of conflict (which incorrectly unselected packages with ++ unsatisfied dependencies as well, making the following ++ backtrack_selected ++ call behave wrongly as it simply noticed that the package is no ++ longer ++ required) ++ ++ Here's the second patch again, now with the function comment ++ updated ++ and added _remove_all_rejected_from() call so that prerejections ++ are ++ still cleared (this was previously called from the ++ removed disable_selected() call). Testsuites pass. ++ ++ Patch by Anssi Hannula, fixes #57224 ++ ++2009-10-05 09:48 ++ ++ * 3.33 ++ ++2009-10-03 15:18 ++ ++ * Improve previous fix ++ ++2009-10-03 14:56 ++ ++ * fix lookup of existing pubkeys (#53710) ++ ++2009-08-10 14:37 ++ ++ * update NEWS for 3.32 ++ ++2009-08-10 14:37 ++ ++ * 3.32 ++ ++2009-08-10 14:37 ++ ++ * comment out unused code ++ ++2009-08-10 14:37 ++ ++ * use set_rejected_and_compute_diff_provides for package removal ++ ++ Patch by Anssi Hannula, fixes bug #52667 ++ ++ k1-1 provides k, but not k1-2 ++ l-1 and l-2 requires k ++ m-1 requires k but not m-2 ++ n requires m ++ ++ User has l-1, m-1, n-1, k1-1. ++ ++ There is only one upgrade path: ++ k1-1 -> k1-2 ++ m-1 -> m-2 ++ removal of l-1 ++ ++ When transaction is created with all of them (e.g. what ++ --auto-select does ++ first), the path is resolved correctly. ++ However, when the upgrade is triggered with the upgrade of k1, ++ and l is in RPM ++ db before n, resolving proceeds as follows: ++ 1. k1 selected and old version rejected ++ 2. l is promoted ++ 3. m is promoted ++ 4. l-2 is therefore selected ++ 5. no packages are found for k (as k1-1 was rejected in step 1) ++ 6. backtrack_selected calls resolve_rejected to reject the chain ++ 7. rejection process rejects l, m, n ++ 8. m-2 is selected because of step 3 ++ End result: n is wrongly removed. ++ ++ Therefore, when using --auto-select (with --split-length 1 ++ --split-level 1 in ++ this small case, to force splitting) to trigger the upgrade, the ++ early resolve ++ is done correctly, but the first splitted transaction ("rpms ++ sorted by ++ dependencies" has k1 and m separately, so split is tried) tries ++ to remove n and ++ URPM fallbacks to single big transaction. ++ ++ In reverse, when using "urpmi k1" to trigger the upgrade, urpmi ++ asks user ++ confirmation for n removal, but the transaction is created with ++ both k1 and m ++ ("rpms sorted by dependencies" has k1+m, so they are put in same ++ transaction), ++ thus triggering the correct behaviour and n is not really removed ++ after all, ++ even if user agreed to it. ++ ++ Attached patch fixes this by switching backtrack_selected() to ++ use ++ set_rejected_and_compute_diff_provides() for package removal ++ instead of ++ resolve_rejected_(). The code already contained a comment ++ indicating that ++ diff_provides code should be applied. ++ The patch introduces no regression in the urpmi and perl-URPM ++ testsuites. ++ ++2009-08-05 20:24 ++ ++ * Obey options (keep, nodeps) when unselecting current package in ++ the case ++ that was added in 3.31 (Anssi Hannula). In a simple mistake, ++ %options was ++ not passed to backtrack_selected. ++ ++2009-08-05 20:17 ++ ++ * remove extra newline from NEWS ++ ++2009-08-05 11:15 ++ ++ * remove no longer used SPEC_VERIFY constant ++ ++2009-08-04 16:47 ++ ++ * disttag & distepoch isn't utf8… ++ ++2009-08-04 16:28 ++ ++ * cast (es-s) to U32 (as the hv_fetch prototype expects) rather ++ than casting strlen(s) to signed ++ ++2009-07-28 16:15 ++ ++ * 3.31 ++ ++2009-07-28 16:15 ++ ++ * we need to link with rpmbuild with rpm 4.6 ++ ++2009-07-28 13:16 ++ ++ * update NEWS file ++ ++2009-07-28 13:16 ++ ++ * add a backtrack entry "conflicts" for avoided packages in ++ backtrack_selected ++ ++ Patch from Anssi Hannula, fixes part of bug #52153 ++ ++2009-07-28 13:15 ++ ++ * do not try to promote to an older package ++ ++ Patch by Anssi Hannula, fixes bug #52460 ++ ++ When searching for possible promotions, _handle_diff_provides() ++ allows ++ downgrade as well as upgrade. ++ ++ However, downgrade is not currently supported, and will fail ++ early in ++ _no_more_recent_installed_and_providing(), called from ++ resolve_requested__no_suggests_(). ++ ++ As no backtracking is done for early failures in this function ++ (should it be? ++ dunno), the promotion gets forgotten and a failing transaction ++ will occur. ++ ++ Simple fix is to only allow upgrade before doing the promotion. ++ Patch attached. ++ It introduces no regressions in urpmi or perl-URPM testsuite. ++ ++2009-07-28 13:15 ++ ++ * unselect current package if an avoided package is already ++ selected ++ ++ Patch by Anssi Hannula, fixes bug #52145 ++ ++ If package 'a' Conflicts on 'b', and user (or a dependency chain) ++ tries to ++ install both at the same time, perl-URPM will only detect the ++ conflict if ++ package 'a' gets selected first (this depends on hdlist order), ++ as ++ _set_rejected_from is only called in one direction from ++ _handle_conflicts and ++ it does not detect that a package it is about to reject_from is ++ already ++ selected. ++ ++ This bug currently causes a failure in urpmi ++ handle-conflict-deps2 testcase. ++ ++ This commit checks if avoided package is already selected, and ++ unselects ++ current package in such a case ++ ++2009-07-28 13:15 ++ ++ * move part of _handle_conflicts to _handle_conflicts_with_selected ++ ++ Patch by Anssi Hannula, first step toward fixing bug #52145 ++ ++ If package 'a' Conflicts on 'b', and user (or a dependency chain) ++ tries to ++ install both at the same time, perl-URPM will only detect the ++ conflict if ++ package 'a' gets selected first (this depends on hdlist order), ++ as ++ _set_rejected_from is only called in one direction from ++ _handle_conflicts and ++ it does not detect that a package it is about to reject_from is ++ already ++ selected. ++ ++ This patch moves part of _handle_conflicts to ++ _handle_conflicts_with_selected ++ to be called before dependencies get added, needed by next patch ++ ++2009-07-28 13:14 ++ ++ * _handle_conflicts: check all provides for conflicts, not just ++ package name ++ ++ Patch by Anssi Hannula, fixes bug #52135 ++ ++ If package a has "Conflicts: x" and b has "Provides: x", ++ installing both at the ++ same time creates a failing transaction (instead of producing the ++ "cannot ++ install a (or b), continue?") as perl-URPM does not detect the ++ conflict, as it ++ just checks the conflicts on the package name (it does the ++ correct thing with ++ installed packages, though). ++ ++ _handle_conflicts: call _set_rejected_from if any provides match ++ the conflict, ++ instead of just package name ++ ++2009-07-28 13:13 ++ ++ * keep psel/promote info and remove deadlocked pkg instead of ++ aborting upgrade ++ ++ Patch from Anssi Hannula, fixes bug #52105 ++ ++ lib64gcj9 has to be removed (conflicts), therefore so does ++ libgcj9-src (x86_64) ++ that depends on it. Installed java-1.5.0-gcj-src depends on ++ libgcj9-src, so ++ perl-URPM tries to promote the i586 libgcj9-src for it. However, ++ strict_arch ++ check prohibits changing the arch, so it falls back to ++ backtracking. ++ Backtracking finds libgcj9-src again and tries to select it; ++ however, it drops ++ $dep->{psel} and $dep->{promote}, so when it fails again, ++ perl-URPM does not ++ know java-1.5.0-gcj-src should also be removed due to the failed ++ promotion. ++ ++ This patch changes the code in backtrack_selected in two ways: ++ ++ 1) When a replacement package is found, keep {promote} and {psel} ++ info, so that ++ when backtrack_selected is run the second time it correctly ++ handles the failed ++ promotion. ++ 2) When such a replacement fails as well and the deadlock ++ protection is ++ triggered, do not switch to keep mode for the package that caused ++ the promotion ++ (it would unselect all the packages involved in the update that ++ caused the ++ promotion). Instead proceed to remove it as usual. ++ ++ The patch introduces no failures on the urpmi testsuite. ++ ++2009-07-28 13:12 ++ ++ * keep track of sources for obsoleted/removed levels ++ ++ Patch by Anssi Hannula, fixes bug #50666 ++ ++ removed/obsoleted levels are set in set_rejected() when a package ++ is rejected ++ (i.e. removed) or a rejection reason is added. They keep track on ++ whether the ++ package is removed and/or obsoleted. ++ ++ When the package has both flags and one of the rejection reasons ++ is removed by ++ _remove_rejected_from(), appropriate flags do not get removed. ++ ++ The case I encountered: the package is set for removal when a ++ package it ++ depends on fails upgrade due to unsatisfied dependency and has to ++ be removed ++ (backtrack_selected => resolve_rejected, causing removed=1), and ++ the package is ++ then promoted (causing obsoleted=1). However, the promotion fails ++ due to the ++ same unsatisfied dependency and backtrack_selected => ++ disable_selected_and_unrequested_dependencies => disable_selected ++ => ++ _remove_all_rejected_from => _remove_rejected_from gets called. ++ This removes ++ the latter rejection reason, but leaves flags, including the now ++ wrong ++ obsoleted=1. Thus the package is not explicitely removed as an ++ obsoletion is ++ assumed, therefore failing the transaction. ++ ++2009-07-27 12:42 ++ ++ * use pkg-config for rpm 4.x too ++ ++2009-07-27 12:41 ++ ++ * remove unused variable ++ ++2009-07-26 16:07 ++ ++ * rephrase wording, only support for querying %disttag & %distepoch ++ so far, no support ++ for using %distepoch i version comparisions yet... ++ ++2009-07-26 16:06 ++ ++ * add support for %disttag & %distepoch ++ ++2009-07-26 08:36 ++ ++ * just use (void) rather than assign rpmtsFree() since it seems to ++ cause crashy behaviour certain places... ++ ++2009-07-26 08:07 ++ ++ * bumping version was forgotten for 3.30 release, might as well ++ bump it up to ++ 3.31 now for next release… ++ ++2009-07-26 08:05 ++ ++ * update changelog regarding rpm5 ++ ++2009-07-26 07:08 ++ ++ * oops, put back line that accidentally got removed in the previous ++ commit… ++ ++2009-07-26 06:50 ++ ++ * enable and fix additional (-Wextra) warnings ++ ++2009-07-26 06:38 ++ ++ * fix gcc warnings about values not being used ++ ++2009-07-26 06:23 ++ ++ * * clean out compatibility code for older rpm versions that's not ++ really ++ supported anymore anyways and move out as much as possible ++ rpm5.org ++ compatibility code out of URPM into new rpm46compat.h @ rpm5.org ++ ++2009-07-25 20:50 ++ ++ * add support for specifying custom filter for compression with ++ build_synthesis() ++ ++2009-07-22 18:21 ++ ++ * really clean up temporary files & directories properly ++ ++2009-07-22 18:19 ++ ++ * prevent distepoch & disttag to be added and appended to package ++ filename ++ ++2009-05-11 13:26 ++ ++ * Removed forgotten debugging logs ++ ++2009-05-11 13:22 ++ ++ * Add bug # ++ ++2009-05-11 13:17 ++ ++ * Release 3.30 ++ ++2009-05-11 13:17 ++ ++ * Use key IDs to check if a key is already known or not ++ ++ This has the side-effect that if we get a newer public key ++ corresponding ++ to an already known key id, it won't get updated, but for now RPM ++ doesn't let us do that anyway. If a pubkey file contains multiple ++ keys, ++ we no longer handle this case, but I don't think this has been ++ widely ++ tested, if ever... ++ ++2009-05-11 13:17 ++ ++ * Fix comment ++ ++2009-05-11 13:17 ++ ++ * Introduce get_gpg_fingerprint XS function ++ ++2009-03-27 14:58 ++ ++ * 3.29 ++ ++2009-03-27 14:58 ++ ++ * Fix regression introduced in fix for bug #47803 ++ ++ This reverts the previous commit ++ ++ only compute diff_provides when the package is newly rejected, in ++ set_rejected_and_compute_diff_provides ++ ++ Try this incremental patch. It fixes ++ set_rejected_and_compute_diff_provides to ++ not compute diff_provides if package was already rejected (and ++ thus the ++ dependencies properly handled already). ++ ++2009-03-27 10:28 ++ ++ * Revert part of the fix for bug #47803 since it breaks upgrades ++ from 2008.1 ++ ++2009-03-25 13:41 ++ ++ * 3.28: ++ ++2009-03-25 13:22 ++ ++ * Postpone user choices as much as possible ++ ++ Fixes bug #48100, patch from Anssi Hannula ++ Package A requires D and E. ++ Package B provides D and E. ++ Package C provides E. ++ ++ If the require on E happens to be resolved first, then perl-URPM ++ will ++ prompt the user, even though installing B is enough. ++ ++2009-03-24 16:50 ++ ++ * Change format of "rpm sorted by dependencies" string ++ ++2009-03-24 15:55 ++ ++ * 3.27 ++ ++2009-03-23 10:03 ++ ++ * Don't silently install Suggests:, fixes bug #47934 ++ ++ When installing a package which suggests an uninstalled package, ++ urpmi ++ currently installs both packages without asking the user while it ++ asks ++ when installing a package which requires an uninstalled package. ++ This is ++ because we call resolve_requested__no_suggests to find which ++ suggested ++ package to install, but this mark the package as requested as ++ well (and ++ we don't ask for confirmation before installing a requested ++ package). ++ This patch calls resolve_requested__no_suggests_ (with a trailing ++ '_') ++ instead which is the same as resolve_requested__no_suggests but ++ does not ++ mark the packages as requested. ++ ++2009-03-23 09:40 ++ ++ * fix _handle_diff_provides in case of impossible-to-satisfy ++ selected packages ++ ++ Fixes bug #48223, patch from Anssi Hannula ++ ++ Currently, if _handle_diff_provides finds unsatisfied requires on ++ an already ++ selected package, and cannot find any packages from the repo that ++ satisfy ++ these, it calls resolve_rejected_ (or ++ set_rejected_and_compute_diff_provides ++ after fix to bug #47803) (as it does when those unsatisfied ++ requires are on an ++ installed package, which was always the case before r242656). ++ However, those should be called with installed packages only. ++ ++ Attached patch makes _handle_diff_provides call ++ disable_selected_and_unrequested_dependencies and ++ _set_rejected_from in case of ++ selected packages. ++ ++2009-03-20 18:32 ++ ++ * check rep for another pkg providing X if the prev pkg gets ++ removed due to a conflict ++ ++ Fixes bug #47803, patch from Anssi Hannula ++ ++ Closer look at urpmi revealed it only does this if a provide X is ++ removed from ++ an upgraded package, not when a package providing X has to be ++ removed. ++ ++ i.e. this works: ++ ++ A provides foo ++ B provides foo ++ C requires foo ++ ++ Installed A,C. ++ ++ A is upgraded and Provides:foo is dropped, B gets installed in ++ order to ++ keep C. ++ ++ But this won't: ++ ++ A provides foo ++ A requires dep ++ B provides foo ++ C requires foo ++ D provides dep ++ ++ Installed A,C,D. ++ ++ D is upgraded and Provides:dep is dropped, A gets removed, C gets ++ removed. ++ ++2009-03-05 11:14 ++ ++ * 3.26 ++ ++2009-03-05 11:13 ++ ++ * (verify_signature) make checking urpmi signatures works in ++ chrooted environments ++ (especially important for installer where there's no rpmdb in / ++ (really ++ /var/lib/rpm) and thus no keys to check against) ++ ++2009-01-16 14:48 ++ ++ * Release 3.25 ++ ++2009-01-16 14:48 ++ ++ * Really fix bug #46874 ++ ++2009-01-13 14:27 ++ ++ * Version 3.24 - 13 January 2009, by Christophe Fergeau ++ ++ - fix sorting choices on provided version (feature introduced in ++ 3.08, ++ but was not working if packages were coming from different ++ repository) ++ - when a "Requires:" can be fullfilled by several different ++ packages and ++ one of those packages is explicitly required by another package ++ which ++ is also being installed, silently choose this package instead of ++ letting ++ the choice up to perl-URPM user (fixes bug #46874) ++ ++2009-01-12 08:04 ++ ++ * add comments ++ ++2009-01-12 08:03 ++ ++ * - drop parse_rpms (unused, parse_rpms_build_headers or parse_rpm ++ are used instead) ++ - add a comment ++ ++2009-01-12 07:59 ++ ++ * add a comment ++ ++2009-01-12 07:56 ++ ++ * - drop function fuzzy_parse() (it is unused) ++ - add some comment ++ ++2009-01-09 14:40 ++ ++ * add a comment ++ ++2009-01-09 14:39 ++ ++ * add some comment ++ ++2009-01-09 14:24 ++ ++ * - @unsatisfied is a better var name than @l ++ - add some comment ++ ++2009-01-08 13:46 ++ ++ * make it clear the func is local ++ ++2009-01-08 13:45 ++ ++ * add a comment ++ ++2009-01-08 09:24 ++ ++ * Favour required packages when we have several choices to fulfill ++ a "requires", fixes bug #46874 ++ ++2009-01-06 15:55 ++ ++ * - add some comment ++ - enhance a comment ++ ++2009-01-06 14:05 ++ ++ * document a "hack" ++ ++2008-12-15 17:02 ++ ++ * - fix sorting choices on provided version (feature introduced in ++ 3.08, ++ but was not working if packages were coming from different ++ repository) ++ ++2008-12-15 11:08 ++ ++ * 3.23 ++ ++2008-12-15 11:05 ++ ++ * - fix bad free() (thanks to glibc for detecting it) ++ ++2008-12-12 11:04 ++ ++ * 3.22 ++ ++2008-12-12 09:19 ++ ++ * - fix scriptlet failing: ++ adapt to librpm4.6, rpmtsSetRootDir(ts, "") is forbidden ++ ++2008-12-09 16:40 ++ ++ * revert wrong commit ++ ++2008-12-09 16:33 ++ ++ * correctly clean temp directories ++ ++2008-12-09 16:05 ++ ++ * 3.21 ++ ++2008-12-09 16:04 ++ ++ * - adapt to librpm4.6 ++ ++2008-12-09 16:03 ++ ++ * - adapt to rpm 4.6 changes: ++ - headerNextIterator -> headerNext ++ - headerAddEntry -> headerPut ++ - headerModifyEntry -> headerMod ++ ++2008-12-09 16:02 ++ ++ * - adapt to rpm 4.6 changes: headerGetEntry -> headerGet ++ ++2008-12-09 16:00 ++ ++ * - adapt to some easy rpm 4.6 changes: ++ - headerSprintf -> headerFormat ++ - headerAddEntry -> headerPutString ++ - headerRemoveEntry -> headerDel ++ - rpmProblemGetLong -> rpmProblemGetDiskNeed ++ ++2008-12-09 15:55 ++ ++ * free the iterator *after* use ++ (otherwise it segfaults with 4.6.0-rc1, and i wonder how it ++ worked before...) ++ ++2008-12-09 15:52 ++ ++ * do free the ts after user, this is especially needed since ++ rpmVerifySignature ++ (wrongly) called in rpmReadPackageFile can open the rpmdb which ++ won't get ++ closed if ts is not closed ++ ++2008-12-09 15:50 ++ ++ * - don't handle %_sourcedir specially, it's not needed ++ - use an absolute filename for %_topdir, it seems to help ++ (bug in rpm 4.6.0-rc1?) ++ ++2008-12-09 15:49 ++ ++ * - list_rpm_tag() is no more ++ - remove a failing test (old) ++ ++2008-12-09 15:47 ++ ++ * - drop list_rpm_tag() ++ ++2008-12-09 15:45 ++ ++ * adapt types to rpm-4.6.x ++ ++2008-12-08 17:35 ++ ++ * fix rpmRelocation usage with rpm 5.2 ++ ++2008-10-14 17:35 ++ ++ * 3.20 ++ ++2008-10-14 17:35 ++ ++ * - $trans->run can now return both the translated errors, and some ++ parsable ++ errors (useful for example to detect diskspace issues) ++ ++2008-10-14 08:51 ++ ++ * use rpmuint64_t rather than long long, we know that it should ++ stay compatible:) ++ ++2008-10-10 09:14 ++ ++ * fix build with rpm5.org HEAD ++ ++2008-10-07 10:47 ++ ++ * 3.19 ++ ++2008-10-07 10:46 ++ ++ * - handle flag "replacefiles" ++ ++2008-07-18 18:09 ++ ++ * add filelinktos() & dirnames() to URPM::Package ++ ++2008-07-17 20:03 ++ ++ * ensure that initSourceHeader gets run for rpm5.org, otherwise ++ querying of spec files won't work ++ ++2008-07-14 16:49 ++ ++ * fix build with rpm5.org HEAD ++ ++2008-07-07 21:53 ++ ++ * 3.18 ++ ++2008-07-07 14:08 ++ ++ * - revert change introduced in 3.16 (it breaks too much, eg ++ superuser--priority-upgrade.t test case), and introduce ++ $state->{rejected_already_installed} instead ++ ++2008-07-07 13:23 ++ ++ * fix typo in description ++ ++2008-07-04 13:06 ++ ++ * 3.17 ++ ++2008-07-04 13:05 ++ ++ * add removed_or_obsoleted_packages() ++ ++2008-07-04 13:04 ++ ++ * - handle $state->{orphans_to_remove} in selected_size() and ++ build_transaction_set() ++ ++2008-07-04 11:25 ++ ++ * - add traverse_tag_find() ++ ++2008-07-03 11:25 ++ ++ * perl_checker compliance ++ ++2008-07-03 11:23 ++ ++ * remove unused vars ++ ++2008-07-03 11:22 ++ ++ * create packages_to_remove() and use it to factorize code ++ ++2008-07-01 15:26 ++ ++ * create rpmtag_from_string() out of Db_traverse_tag ++ ++2008-06-26 12:47 ++ ++ * 3.16 ++ ++2008-06-26 09:46 ++ ++ * - when not selecting a package because already installed, ++ but it in $state->{rejected} with flags {installed} ++ ++2008-06-24 09:06 ++ ++ * adapt tests to ->compare change ++ ++2008-06-23 08:42 ++ ++ * 3.15 ++ ++2008-06-17 09:39 ++ ++ * add Anssi name in the log ++ ++2008-06-17 09:38 ++ ++ * - fix urpmi wrongly considering epochless conflicts to match any ++ epoch in a ++ case when urpmi should upgrade a conflicting package to an ++ actually ++ non-conflicting version (cf epochless-conflict-with-promotion ++ urpmi test) ++ ++ from Anssi. ++ ++ i tested various upgrades from some chroot with 2008.0, 2007.1, ++ 2007.0, and it ++ didn't change the result, so it should be quite safe :) ++ ++2008-05-23 08:24 ++ ++ * 3.14 ++ ++2008-05-23 08:23 ++ ++ * - add is_package_installed() in URPM/Resolve.pm ++ (to be used in urpmi 5.20) ++ ++2008-05-20 09:54 ++ ++ * 3.13 ++ ++2008-05-19 15:17 ++ ++ * - do not ignore dropped provide from updated package ++ (mdvbz#40842) ++ ++2008-05-15 12:04 ++ ++ * enhance error message ++ ++2008-04-14 17:11 ++ ++ * un-revert rpm5.org cosmetics now that cooker has reopened ++ ++2008-04-10 08:16 ++ ++ * update authors and copyright notic ++ ++2008-03-25 13:15 ++ ++ * revert unneeded commit for now ++ ++2008-03-19 04:37 ++ ++ * fix a typo in a comment </pedanticlamer> ++ ++2008-03-19 04:34 ++ ++ * make URPM more portable by using standard %{_target_vendor} & ++ %{_target_cpu} macros in stead of Mandriva specific ++ %{_real_vendor} & (now dead) %{_real_arch} ++ ++2008-03-19 04:18 ++ ++ * change x,y check to y,x. More intuitive, for me at least, other ++ order frequently confuses me ;p ++ ++2008-03-19 03:24 ++ ++ * d'oh, argument to hexversion() must of course be passed as ++ strings ++ ++2008-03-19 03:12 ++ ++ * improve rpm version detection ++ really fix callback size for rpm5.org versions ++ ++2008-03-07 16:50 ++ ++ * 3.12 ++ ++2008-03-07 16:49 ++ ++ * - do allow to promoting a pkg even if it has unsatisfied require ++ (since the ++ code will then fix the unsatisfied require). fixes "big ++ transaction" ++ (cf urpmi split-transactions--strict-require.t test_efgh()) ++ ++ this code was introduced long ago (*), the code has ++ changed quite a lot, and it's hard to tell for which reason it ++ was introduced. ++ Maybe the check "obsoletes_overlap" replaces it for good? ++ ++ (*) in "r11064 | fpons | 2002-06-13", search for "try if ++ upgrading the package ++ will be satisfying all the requires" ++ ++2008-03-06 16:59 ++ ++ * ouch, add back 'case RPMPROB_DISKNODES:' removed by mistake :/ ++ ++2008-03-06 15:25 ++ ++ * revert back to long long since they're of same size anyways and ++ we avoid warnings that way :) ++ ++2008-03-06 14:24 ++ ++ * simplify as pixel suggested ++ use uint64_t in stead of unsigned long long (which is really the ++ same, but nicer and more consistent with rpm5:) ++ ++2008-03-03 12:06 ++ ++ * minor cosmetics ++ ++2008-03-03 00:50 ++ ++ * move compatibility wrapper to rpm5.org upstream ++ ++2008-03-02 23:29 ++ ++ * more fixes, makes apt-get build succesfully :D ++ ++2008-03-02 22:22 ++ ++ * make all functions inline functions ++ ++2008-03-02 22:02 ++ ++ * some more functions for apt-get.. ++ ++2008-03-02 18:18 ++ ++ * make C++ compliant ++ add som function wrappers for apt-get ++ ++2008-03-01 12:33 ++ ++ * define WITH_DB in rpm5compat.h in stead of in Makefile ++ drop useless conditionals for headers as they're already ++ conditional in themself ;) ++ ++2008-03-01 12:29 ++ ++ * do better "detection" of callback size without having to define ++ it in Makefile (inspired by apt) ++ ++2008-02-29 21:26 ++ ++ * try improve on freeing up memory ++ ++2008-02-29 19:06 ++ ++ * be sure to return NULL in case of RPMRC_NOTFOUND ++ ++2008-02-29 19:00 ++ ++ * provide function name in logging ++ ++2008-02-29 18:45 ++ ++ * be sure to always initialize in headerGetEntry ++ ++2008-02-29 15:36 ++ ++ * add rpm5.org support to NEWS :) ++ ++2008-02-29 15:33 ++ ++ * rpm 4.5 and newer uses unsigned long long ulong1 in stead of ++ unsigned long ulong1 for rpmProblemGetLong, therefore use %lld in ++ stead of %ld ++ ++2008-02-29 15:03 ++ ++ * add back copyright field manually since svn wouldn't set it.. ++ ++2008-02-29 14:57 ++ ++ * try add svn properties to top of file ++ ++2008-02-29 14:42 ++ ++ * add svn keywords properties ++ ++2008-02-29 14:40 ++ ++ * make inclusion of headers conditional ++ ++2008-02-29 14:29 ++ ++ * be sure to set return value to NULL in headerGetEntry when Epoch ++ isn't set ++ ++2008-02-29 14:24 ++ ++ * fix assignment from incompatible pointer type in ++ Urpm_list_rpm_tag for rpm5 ++ ++2008-02-29 14:14 ++ ++ * be sure to use same data type for check_flag ++ ++2008-02-28 17:07 ++ ++ * make sure to use same type (signess) in pack_rpm_header ++ ++2008-02-28 16:45 ++ ++ * do not define RPM_CALLBACK_LONGLONG for rpm 5.0 ++ ++2008-02-28 16:20 ++ ++ * add copyright notice ++ ++2008-02-28 15:30 ++ ++ * fix return type and variable of headerRead() ++ ++2008-02-28 13:29 ++ ++ * 3.11 ++ ++2008-02-28 13:29 ++ ++ * - restore FILENAME_TAG in generated hdlist (to be compatible with ++ older ++ distros where ->filename can rely on it) (thanks to Nanar) ++ ++2008-02-28 11:04 ++ ++ * fix double _free of msg in headerWrite() & headerRead() ++ do rpmlog for headerWrite() & headerRead() ++ drop unused variable in cointainer for headerNextIterator() ++ ++2008-02-28 02:35 ++ ++ * drop unused variable ++ ++2008-02-28 02:28 ++ ++ * get rid of some warnings ++ ++2008-02-28 02:03 ++ ++ * add wrapper function for rpmMachineScore ++ ++2008-02-28 01:38 ++ ++ * add wrapper function for headerRead ++ ++2008-02-28 01:24 ++ ++ * add wrapper function for headerModifyEntry ++ ++2008-02-28 01:06 ++ ++ * fix define of _RPMTAG_INTERNAL at right place and drop redundant ++ include of rpmtag.h ++ ++2008-02-28 00:56 ++ ++ * add rpm5 wrapper functions, work in progress, URPM builds now at ++ least :o) ++ ++2008-02-27 21:45 ++ ++ * fix building with rpm5 DEVEL version ++ ++2008-02-25 23:39 ++ ++ * do not mark as deprecated ->filename and ++ URPM::Build::build_hdlist() ++ ++2008-02-25 23:22 ++ ++ * 3.10 ++ ++2008-02-25 21:57 ++ ++ * adding filesize to synthesis on @info@ will break backward ++ compatibility for ++ no good reason, so switching to a new @filesize@ line ++ ++2008-02-25 21:37 ++ ++ * make ->filename work (again) on header ++ ++2008-02-25 21:17 ++ ++ * 3.09 ++ ++2008-02-25 21:13 ++ ++ * do not do "uniq" on "fullname" since gpg-pubkey-xxxxxxxx-xxxxxxxx ++ can be installed twice ++ ++2008-02-25 21:05 ++ ++ * since ->filename is deprecated, do not use it, esp where not ++ needed ++ ++2008-02-25 20:43 ++ ++ * - add filesize to synthesis, add ->filesize to get it, and add ++ selected_size_filesize() to compute the sum ++ ++2008-02-25 20:41 ++ ++ * fix previous commit (XS comments are perl-style, not C-style) ++ ++2008-02-25 19:17 ++ ++ * - do not add FILENAME_TAG and FILESIZE_TAG to hdlist anymore, ++ deprecate ->filename and ->header_filename, ++ deprecate URPM::Build build_hdlist and parse_rpms_build_headers ++ ++2008-02-25 16:18 ++ ++ * - allow fixing "using one big transaction" that occurs when using ++ --keep ++ (#30198) ++ ++ nb: since build_transaction_set calls resolve_requested, it must ++ use the same ++ options to select the same packages ++ ++2008-02-25 16:16 ++ ++ * - allow urpmi to know a package was not selected because a newer ++ version is ++ installed (#29838) ++ ++2008-02-25 13:34 ++ ++ * - fix sort choices changed in perl-URPM 3.08 ++ ++2008-02-25 13:33 ++ ++ * - handle new package providing xxx which conflicts with an ++ installed package (#17106) ++ ++2008-02-25 09:20 ++ ++ * 3.08 ++ ++2008-02-25 09:19 ++ ++ * - sort choices on virtual package by provided version (#12645) ++ ++2007-09-12 15:11 Pixel <pixel at mandriva.com> ++ ++ * : better indicate the test case in urpmi ++ ++2007-09-12 15:04 Pixel <pixel at mandriva.com> ++ ++ * : update doc ++ ++2007-09-12 15:04 Pixel <pixel at mandriva.com> ++ ++ * : update doc ++ ++2007-09-12 15:01 Pixel <pixel at mandriva.com> ++ ++ * : update doc ++ ++2007-09-12 15:00 Pixel <pixel at mandriva.com> ++ ++ * : create _remove_all_rejected_from() out of disable_selected() ++ ++2007-09-12 14:57 Pixel <pixel at mandriva.com> ++ ++ * : create _remove_rejected_from() ++ ++2007-09-12 14:47 Pixel <pixel at mandriva.com> ++ ++ * : update doc ++ ++2007-09-12 14:44 Pixel <pixel at mandriva.com> ++ ++ * : factorize code into _set_rejected_from() ++ ++2007-09-12 14:38 Pixel <pixel at mandriva.com> ++ ++ * : replacing {backtrack}{closure} with {closure} since it looks ++ like it was a typo ++ ++2007-09-12 14:27 Pixel <pixel at mandriva.com> ++ ++ * : adapt doc to is really done (may kill {backtrack}{closure} ++ later) ++ ++2007-09-12 13:16 Pixel <pixel at mandriva.com> ++ ++ * : update doc ++ ++2007-09-12 13:12 Pixel <pixel at mandriva.com> ++ ++ * : - fix typo in previous commit: pass $urpm to set_selected() for ++ debug message ++ - {from} options to resolve_rejected_ and set_selected is now a ++ pkg object ++ instead of a fullname string ++ ++2007-09-12 13:08 Pixel <pixel at mandriva.com> ++ ++ * : add debug message ++ ++2007-09-12 13:07 Pixel <pixel at mandriva.com> ++ ++ * : simplify ++ ++2007-09-12 13:06 Pixel <pixel at mandriva.com> ++ ++ * : handle {size} in set_rejected() ++ ++2007-09-12 12:59 Pixel <pixel at mandriva.com> ++ ++ * : - add ability to merge {closure} fields in set_rejected (from ++ $options{why}) ++ - {from} is a fullname here ++ - {why} is a hash ++ - use set_rejected() to factorize code ++ ++2007-09-12 12:12 Pixel <pixel at mandriva.com> ++ ++ * : cleanup ++ ++2007-09-12 12:11 Pixel <pixel at mandriva.com> ++ ++ * : fix typo in previous commit ++ ++2007-09-12 12:03 Pixel <pixel at mandriva.com> ++ ++ * : create set_rejected() out of resolve_rejected_() ++ ++2007-09-12 11:03 Pixel <pixel at mandriva.com> ++ ++ * : dep field "choices" is here for debug purpose, rename it ++ _choices ++ ++2007-09-12 11:00 Pixel <pixel at mandriva.com> ++ ++ * : create _dep_to_name() and use it ++ ++2007-09-12 10:50 Pixel <pixel at mandriva.com> ++ ++ * : drop unused option "closure_as_removed" ++ ++2007-09-12 10:14 Pixel <pixel at mandriva.com> ++ ++ * : backtrack_selected() was always returning empty list, so ++ backtrack_selected_psel_keep() should return empty list. but it's ++ simply to ++ modify callers to take into account the return value is () ++ ++2007-09-12 10:07 Pixel <pixel at mandriva.com> ++ ++ * : move var declaration where it's used ++ ++2007-09-12 10:06 Pixel <pixel at mandriva.com> ++ ++ * : move function created in previous commit ++ ++2007-09-12 10:04 Pixel <pixel at mandriva.com> ++ ++ * : create _choose_required() out of ++ resolve_requested__no_suggests_() ++ ++2007-09-12 09:50 Pixel <pixel at mandriva.com> ++ ++ * : this is good to have in NEWS ++ ++2007-09-11 16:27 Pixel <pixel at mandriva.com> ++ ++ * : document side-effects of each functions ++ ++2007-09-11 15:41 Pixel <pixel at mandriva.com> ++ ++ * : add some doc ++ ++2007-09-11 15:35 Pixel <pixel at mandriva.com> ++ ++ * : rename disable_selected_unrequested_dependencies() into ++ disable_selected_and_unrequested_dependencies() ++ ++2007-09-11 15:09 Pixel <pixel at mandriva.com> ++ ++ * : don't keep a hash when we really want its values ++ ++2007-09-11 15:03 Pixel <pixel at mandriva.com> ++ ++ * : - create strict_arch_check() out of find_required_package() ++ - and factorize some more code into $may_add_to_packages ++ ++2007-09-11 14:46 Pixel <pixel at mandriva.com> ++ ++ * : create backtrack_selected_psel_keep() out of ++ backtrack_selected() and use it ++ ++2007-09-11 14:12 Pixel <pixel at mandriva.com> ++ ++ * : drop keep_unrequested_dependencies option (it is unused) ++ ++2007-09-11 14:10 Pixel <pixel at mandriva.com> ++ ++ * : drop keep_requested_flag by creating ++ resolve_requested__no_suggests_() ++ ++2007-09-11 14:04 Pixel <pixel at mandriva.com> ++ ++ * : simplify ++ ++2007-09-11 14:00 Pixel <pixel at mandriva.com> ++ ++ * : define var where it's needed ++ ++2007-09-11 13:59 Pixel <pixel at mandriva.com> ++ ++ * : rename var, $dep will only be used as an element from ++ @properties ++ ++2007-09-11 13:58 Pixel <pixel at mandriva.com> ++ ++ * : rename var, $dep will only be used as an element from ++ @properties ++ ++2007-09-11 13:52 Pixel <pixel at mandriva.com> ++ ++ * : add doc ++ ++2007-09-11 13:37 Pixel <pixel at mandriva.com> ++ ++ * : add some doc ++ ++2007-09-11 13:37 Pixel <pixel at mandriva.com> ++ ++ * : simplify ++ ++2007-09-11 13:32 Pixel <pixel at mandriva.com> ++ ++ * : simplify ++ ++2007-09-11 13:24 Pixel <pixel at mandriva.com> ++ ++ * : simplify: make find_candidate_packages() the wrapper around ++ find_candidate_packages_() instead of the other way round ++ ++2007-09-11 13:21 Pixel <pixel at mandriva.com> ++ ++ * : create find_candidate_packages_(), wrapper around ++ find_candidate_packages() ++ ++2007-09-11 13:16 Pixel <pixel at mandriva.com> ++ ++ * : drop callback_backtrack, unused for a long time ++ ++2007-09-11 11:54 Pixel <pixel at mandriva.com> ++ ++ * : fix old typo in comment ++ ++2007-09-11 11:51 Pixel <pixel at mandriva.com> ++ ++ * : add a comment ++ ++2007-09-11 10:54 Pixel <pixel at mandriva.com> ++ ++ * : fix old typo (rejected field is unused anyway afaik) ++ ++2007-09-11 10:00 Pixel <pixel at mandriva.com> ++ ++ * : fix typo in previous typo fix ++ ++2007-09-11 10:00 Pixel <pixel at mandriva.com> ++ ++ * : fix typo in previous commit :-/ ++ ++2007-09-11 09:58 Pixel <pixel at mandriva.com> ++ ++ * : - speedup is_arch_compat (x7) by keeping the platform in a ++ cache ++ ++2007-09-11 09:55 Pixel <pixel at mandriva.com> ++ ++ * : add missing free() ++ ++2007-09-11 08:44 Pixel <pixel at mandriva.com> ++ ++ * : move doc where it belongs ++ ++2007-09-11 07:28 Pixel <pixel at mandriva.com> ++ ++ * : add comment ++ ++2007-09-10 16:58 Pixel <pixel at mandriva.com> ++ ++ * : simplify prototype of find_candidate_packages() ++ ++2007-09-10 16:56 Pixel <pixel at mandriva.com> ++ ++ * : rename find_chosen_packages() into find_required_package() ++ (better name) ++ ++2007-09-10 16:49 Pixel <pixel at mandriva.com> ++ ++ * : - pass the prefered choices to {callback_choices}: this allows ++ urpmi to select ++ all the prefered packages according to installed locales ++ ++2007-09-10 15:48 Pixel <pixel at mandriva.com> ++ ++ * : - do not propose packages for non installed locales ++ ++2007-09-10 15:48 Pixel <pixel at mandriva.com> ++ ++ * : - do not propose packages for non installed locales ++ - cleanup code ++ ++2007-09-10 15:46 Pixel <pixel at mandriva.com> ++ ++ * : fix typo in previous commit ++ ++2007-09-10 15:16 Pixel <pixel at mandriva.com> ++ ++ * : create _find_chosen_packages__sort() out of ++ find_chosen_packages() ++ ++2007-09-08 20:29 Pixel <pixel at mandriva.com> ++ ++ * : more detailed doc ++ ++2007-09-08 09:24 Pixel <pixel at mandriva.com> ++ ++ * : typo in comment ++ ++2007-09-08 09:16 Pixel <pixel at mandriva.com> ++ ++ * : rename lists with "closure" in the name to things like ++ "xxx_todo" or ++ "all_xxx", i find it more readable, and it helps making the ++ difference with ++ {closure} field ++ ++2007-09-08 09:10 Pixel <pixel at mandriva.com> ++ ++ * : rename local var for clarity ++ ++2007-09-08 09:07 Pixel <pixel at mandriva.com> ++ ++ * : rename local var ++ ++2007-09-08 09:05 Pixel <pixel at mandriva.com> ++ ++ * : document $state fields ++ ++2007-09-08 08:10 Pixel <pixel at mandriva.com> ++ ++ * : rename a local variable for clarity ++ ++2007-09-08 08:09 Pixel <pixel at mandriva.com> ++ ++ * : create _handle_conflicts() out of ++ resolve_requested__no_suggests() ++ ++2007-09-08 07:39 Pixel <pixel at mandriva.com> ++ ++ * : fix typo in older commit ++ ++2007-09-08 07:38 Pixel <pixel at mandriva.com> ++ ++ * : use function calls instead of method calls (it allows ++ perl_checker checks when ++ temporarilly renaming URPM/Resolve.pm package name to URPM) ++ ++2007-09-07 21:56 Pixel <pixel at mandriva.com> ++ ++ * : create _handle_diff_provides() out of ++ resolve_requested__no_suggests() ++ ++2007-09-07 20:49 Pixel <pixel at mandriva.com> ++ ++ * : create _compute_diff_provides() and ++ _compute_diff_provides_one() out of ++ resolve_requested__no_suggests() ++ ++2007-09-07 20:31 Pixel <pixel at mandriva.com> ++ ++ * : factorize regexps into functions ++ ++2007-09-07 19:45 Pixel <pixel at mandriva.com> ++ ++ * : make it more clear ++ ++2007-09-07 19:35 Pixel <pixel at mandriva.com> ++ ++ * : cleanup ++ ++2007-09-07 19:32 Pixel <pixel at mandriva.com> ++ ++ * : create _ids_to_fullnames() and _ids_to_names() ++ ++2007-09-07 19:19 Pixel <pixel at mandriva.com> ++ ++ * : fix typo in recent commit ++ ++2007-09-07 19:18 Pixel <pixel at mandriva.com> ++ ++ * : make it clear that resolve_rejected_ is modifying @properties ++ from ++ resolve_requested() ++ ++2007-09-07 18:39 Pixel <pixel at mandriva.com> ++ ++ * : revert previous commit: compute_deps() is still used by mkcd ++ ++2007-09-07 17:55 Pixel <pixel at mandriva.com> ++ ++ * : remove unused compute_deps() \o/ ++ ++2007-09-07 17:49 Pixel <pixel at mandriva.com> ++ ++ * : simplify: nopromoteepoch is always 1 (no caller ever define it) ++ ++2007-09-07 17:43 Pixel <pixel at mandriva.com> ++ ++ * : cleanup: nopromoteepoch is 1 by default in ++ find_candidate_packages ++ ++2007-09-07 15:44 Pixel <pixel at mandriva.com> ++ ++ * : factorize code in functions whatrequires() and ++ whatrequires_id() ++ ++2007-09-07 15:30 Pixel <pixel at mandriva.com> ++ ++ * : simplify: whatrequires is a hash with provides_nosense as key, ++ don't need to ++ use ->provides then remove the sense ++ ++2007-09-07 15:19 Pixel <pixel at mandriva.com> ++ ++ * : hoist a debug message so that it occurs for other uses of ++ with_db_unsatisfied_requires() ++ ++2007-09-07 15:06 Pixel <pixel at mandriva.com> ++ ++ * : re-use same code for conflict from installed package as is used ++ for conflict ++ from selected package. this fixes test_gh() from urpmi ++ split-transactions--promote test case ++ ++2007-09-07 14:44 Pixel <pixel at mandriva.com> ++ ++ * : move code from resolve_requested__no_suggests() into new ++ function _handle_provides_overlap() ++ ++2007-09-07 14:30 Pixel <pixel at mandriva.com> ++ ++ * : prepare to factorize code handling property becoming ++ unavailable. ++ ++ it really seems {why}{conflicts} is only used for debugging ++ purpose, so this ++ change won't break. ++ ++2007-09-07 14:24 Pixel <pixel at mandriva.com> ++ ++ * : one more debug message ++ ++2007-09-07 11:26 Pixel <pixel at mandriva.com> ++ ++ * : small cleanup ++ ++2007-09-07 11:26 Pixel <pixel at mandriva.com> ++ ++ * : add some debug messages ++ ++2007-09-05 15:19 Pixel <pixel at mandriva.com> ++ ++ * : - fix displaying @sorted whereas some elements have been ++ removed from it ++ - more complete error message ++ ++2007-09-05 09:37 Pixel <pixel at mandriva.com> ++ ++ * : add debug code ++ ++2007-09-03 15:21 Pixel <pixel at mandriva.com> ++ ++ * : 1.80, bugfix release ++ ++2007-09-03 15:21 Pixel <pixel at mandriva.com> ++ ++ * : - fix bug in sort_graph (used by build_transaction_set) ++ ++2007-09-03 15:20 Pixel <pixel at mandriva.com> ++ ++ * : 1.79 ++ ++2007-09-03 12:59 Pixel <pixel at mandriva.com> ++ ++ * : add a test ++ ++2007-09-03 08:08 Pixel <pixel at mandriva.com> ++ ++ * : - fix bug in sort_graph (used by build_transaction_set) ++ ++2007-09-03 08:07 Pixel <pixel at mandriva.com> ++ ++ * : 1.78 ++ ++2007-08-31 15:54 Pixel <pixel at mandriva.com> ++ ++ * : fix dead-loop in build_transaction_set (#33020) ++ ++ and ensure the resulting graph is correct by checking it ++ ++2007-08-31 07:02 Pixel <pixel at mandriva.com> ++ ++ * : add a comment ++ ++2007-08-29 09:33 Pixel <pixel at mandriva.com> ++ ++ * : 1.77 ++ ++2007-08-29 09:33 Pixel <pixel at mandriva.com> ++ ++ * : - disable "dropping tags from rpm header" until we can safely ++ use it ++ ++2007-08-29 09:32 Pixel <pixel at mandriva.com> ++ ++ * : 1.76 ++ ++2007-08-28 14:12 Pixel <pixel at mandriva.com> ++ ++ * : ensure #31969 doesn't occur anymore. if somethings goes wrong: ++ - display error message ++ - then default to one big transaction ++ ++ also display error message "using one big transaction" in the old ++ check (which ++ i don't really know what it does) ++ ++2007-08-28 13:54 Pixel <pixel at mandriva.com> ++ ++ * : - build_transaction_set: new sort algorithm which allow ++ returning sets of ++ circular dependent packages, taking into account obsoleted ++ packages ++ (fixes #31969). It may still fail in presence of conflicts ++ ++ a better fix would be to make ->resolve_requested__no_suggests ++ handle ++ obsolete. ie: ++ - a requires b : bb or b ++ - bb requires c-1 ++ - b requires c-2 ++ - b obsoletes bb ++ => with a, bb and c-1 installed, "urpmi c" should upgrade bb into ++ b instead of ++ removing a and bb. ++ ++2007-08-28 11:03 Pixel <pixel at mandriva.com> ++ ++ * : - spec2srcheader: workaround parseSpec returning a header where ++ ->arch is set ++ to %{_target_cpu} whereas we really want a header similar to ++ .src.rpm ++ (see #32824) ++ ++2007-08-24 12:01 Pixel <pixel at mandriva.com> ++ ++ * : - fix split_length > 1 ++ (eg: "urpmi --split-length 2 a b c" will only install 2 pkgs) ++ (this bug has not been reported, just discovered it while reading ++ the code) ++ ++ - cleanup ++ ++2007-08-24 11:50 Pixel <pixel at mandriva.com> ++ ++ * : - more debug messages ++ - little rewrite ++ ++2007-08-23 13:22 Pixel <pixel at mandriva.com> ++ ++ * : - allow running transaction with justdb option ++ ++2007-08-12 20:45 Pixel <pixel at mandriva.com> ++ ++ * : 1.75 ++ ++2007-08-12 20:44 Pixel <pixel at mandriva.com> ++ ++ * : - fix dropping tags from rpm header. ++ it hasn't work since MDK8.1 and rpm 4.0. ++ it may break urpmi!! but potentially allows a much smaller ++ hdlist.cz :) ++ ++2007-08-12 11:32 Pixel <pixel at mandriva.com> ++ ++ * : 1.74 ++ ++2007-08-12 11:29 Pixel <pixel at mandriva.com> ++ ++ * : - sort choices per media, then per version ++ ++ nb: ++ ++ on 2004-12-13, rgs replaced "$a->id <=> $b->id" with ++ "$b->compare_pkg($a) || $a->id <=> $b->id" ++ ++ Return the list of chosen packages sorted by descending ++ version (bug #12645). ++ ++ the end result is the sorting by media was dropped :-/ ++ ++2007-08-12 10:15 Pixel <pixel at mandriva.com> ++ ++ * : cleanup (easier to read) ++ ++2007-08-11 12:21 Pixel <pixel at mandriva.com> ++ ++ * : 1.73 ++ ++2007-08-11 12:21 Pixel <pixel at mandriva.com> ++ ++ * : - allow running transaction with replagekgs option ++ ++2007-08-10 18:01 Pixel <pixel at mandriva.com> ++ ++ * : 1.72 ++ ++2007-08-10 17:50 Pixel <pixel at mandriva.com> ++ ++ * : - modify parse_hdlist so that partial hdlist reading can be ++ used ++ (needed when some stuff is already done in the callback) ++ ++2007-08-10 17:35 Pixel <pixel at mandriva.com> ++ ++ * : add documentation ++ ++2007-08-10 17:34 Pixel <pixel at mandriva.com> ++ ++ * : there is no use retrying after a headerRead failure since ++ headerRead may have ++ consumed part of the input, and so next headerRead will read in ++ the middle of ++ a header, and so always fail. The only real solution is to ensure ++ rpmlib don't ++ timeout too quickly (and fd->rd_timeoutsecs is rpmlib internal ++ only, so we ++ can't hint it from here. in any case 1sec timeout is really too ++ low) ++ ++2007-08-09 15:25 Pixel <pixel at mandriva.com> ++ ++ * : 1.71 ++ ++2007-08-09 15:24 Pixel <pixel at mandriva.com> ++ ++ * : - compilation fixes on rpm < 4.4.8 ++ ++2007-08-09 14:58 Pixel <pixel at mandriva.com> ++ ++ * : 1.70 ++ ++2007-08-09 14:58 Pixel <pixel at mandriva.com> ++ ++ * : compilation fixes on rpm < 4.4.8 ++ ++2007-08-09 13:24 Pixel <pixel at mandriva.com> ++ ++ * : 1.69 ++ ++2007-08-09 13:24 Pixel <pixel at mandriva.com> ++ ++ * : - "suggests" are no more handled as "requires" ++ - resolve_requested support "suggests": a newly suggested package ++ is installed ++ as if required (can be disabled with option no_suggests) ++ ++ nb: URPM.xs change is quite complex since suggests are mostly ++ seen as requires ++ inside rpmlib. ++ ++2007-08-08 18:18 Pixel <pixel at mandriva.com> ++ ++ * : factorize some code into with_db_unsatisfied_requires: ++ ++ #- this function is "suggests vs requires" safe: ++ #- 'whatrequires' will give both requires & suggests, but ++ unsatisfied_requires ++ #- will check $p->requires and so filter out suggests ++ ++2007-08-08 17:38 Pixel <pixel at mandriva.com> ++ ++ * : "nopromoteepoch => 1" is the default option in ++ ->unsatisfied_requires ++ ++2007-08-03 14:43 Pixel <pixel at mandriva.com> ++ ++ * : 1.68 ++ ++2007-08-03 14:42 Pixel <pixel at mandriva.com> ++ ++ * : - add $trans->Element_version and $trans->Element_release ++ ++2007-07-05 13:36 nanardon ++ ++ * : - 0.67 ++ ++2007-07-04 22:26 nanardon ++ ++ * : - Urpm_read_config_files properly return the value to perl ++ - kill useless var dcl ++ ++2007-07-04 22:21 nanardon ++ ++ * : - fix parseSpec argument ++ ++2007-07-04 16:43 nanardon ++ ++ * : - add osscore() and archscore() function to evaluate computer ++ compatiblity to an arbitrary value ++ ++2007-07-04 15:53 nanardon ++ ++ * : - add Pkg_is_platform_compat() and Urpm_platformscore() coming ++ with rpm 4.4.8 ++ ++2007-07-02 15:14 Pixel <pixel at mandriva.com> ++ ++ * : 1.66 ++ ++2007-07-02 15:11 Pixel <pixel at mandriva.com> ++ ++ * : - fix --auto-select skipping some packages because of other ++ packages providing ++ a more recent version, but no obsolete between those packages. ++ the fix is to revert commit from Aug 2002: ++ "fixed propable old package (according provides) requested by ++ request_packages_to_upgrade." ++ ++ hopefully this change won't break too much... ++ ++ for the record, a few issues: ++ - skipping java-1.5.0-gcj-1.5.0.0-14.7mdv2008.0.i586 since ++ java-1.7.0-icedtea-1.7.0.0-1.3mdv2008.0.i586 provides a more ++ recent version of jre (1.7.0 vs 1.5.0) ++ - skipping emacs-common-22.1-2mdv2008.0.i586 since ++ gnus-emacs-5.10.8-1mdv2007.0.noarch provides a more recent vers ++ whereas java-1.5.0-gcj-1.5.0.0-14.6mdv and emacs-common-22.1-1mdv ++ are installed ++ ++2007-07-02 15:05 Pixel <pixel at mandriva.com> ++ ++ * : help perl_checker ++ ++2007-07-02 14:38 Pixel <pixel at mandriva.com> ++ ++ * : help debugging the strange behaviour of this code ++ ++2007-06-21 14:13 nanardon ++ ++ * : - 1.42 ++ ++2007-06-19 14:44 nanardon ++ ++ * : - make is_arch_compat rpm 4.4.8 compliant ++ ++2007-06-15 20:00 Pixel <pixel at mandriva.com> ++ ++ * : document the fact that build_synthesis returns true on success ++ ++2007-06-12 14:03 Pixel <pixel at mandriva.com> ++ ++ * : fix release date ++ ++2007-06-12 13:57 Pixel <pixel at mandriva.com> ++ ++ * : 1.64 ++ ++2007-06-12 13:56 Pixel <pixel at mandriva.com> ++ ++ * : - hack on $pkg->is_arch_compat to make it return true for ++ noarch packages ++ when using rpm 4.4.8 (#31314) ++ ++2007-05-09 16:00 Pixel <pixel at mandriva.com> ++ ++ * : - new release, 1.63 ++ - add $trans->Element_fullname ++ ++2007-05-03 14:51 Pixel <pixel at mandriva.com> ++ ++ * : 1.61 has not been released ++ ++2007-05-03 14:49 Pixel <pixel at mandriva.com> ++ ++ * : 1.62 ++ ++2007-05-03 14:49 Pixel <pixel at mandriva.com> ++ ++ * : - pass the virtual package name as a parameter to ++ {callback_choices} in ++ ->resolve_requested ++ ++2007-04-27 12:37 Pixel <pixel at mandriva.com> ++ ++ * : re-sync after the big svn loss ++ ++2007-04-27 12:37 Pixel <pixel at mandriva.com> ++ ++ * : re-sync after the big svn loss ++ ++2007-04-27 12:31 Pixel <pixel at mandriva.com> ++ ++ * : - 1.61 ++ - add $trans->NElements and $trans->Element_name ++ to be able to display name of uninstalled package in ++ callback_uninst ++ - fix b--obsoletes-->a and c--conflicts-->a prompting for ++ upgrading a ++ (need a fix in urpmi which rely on the $state->{rejected} ++ to upgrade (-U) b instead of installing (-i) it) ++ ++2007-04-27 12:30 Pixel <pixel at mandriva.com> ++ ++ * : re-sync after the big svn loss ++ ++2007-04-24 19:11 Pixel <pixel at mandriva.com> ++ ++ * : re-sync after the big svn loss ++ ++2006-12-04 10:28 Pixel <pixel at mandriva.com> ++ ++ * URPM.xs: correctly set "\0" ++ ++2006-12-04 10:23 Pixel <pixel at mandriva.com> ++ ++ * t/parse.t: remove temp file ++ ++2006-12-04 09:43 Pixel <pixel at mandriva.com> ++ ++ * URPM.xs: correctly handle gzread error code ++ ++2006-12-01 16:21 Pixel <pixel at mandriva.com> ++ ++ * URPM.xs: rpmReadPackageFile() can return ok but no header :-/ ++ ++2006-12-01 16:14 Pixel <pixel at mandriva.com> ++ ++ * URPM.pm, URPM.xs: rpmReadPackageFile() can return ok but no ++ header :-/ ++ ++2006-11-29 22:24 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.xs: (Trans_add) factorize size to allocate ++ ++2006-11-29 22:23 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.xs: (Trans_add) adjust allocated memory ++ ++2006-11-29 22:22 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.xs: (Trans_add) remove guard, proper fix is now enough ++ ++2006-11-29 22:21 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.xs: (Trans_add) fix segfault on ia32 (when one replace ++ "struct foobar" by ++ "foobar*", he should expect sizeof() to *slightly* differ in ++ results) ++ ++2006-11-29 17:08 Pixel <pixel at mandriva.com> ++ ++ * URPM.pm: 1.50 new release ++ ++2006-11-29 16:59 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.xs: (Trans_add) fix segfault when using --excludepath ++ ++2006-11-29 15:36 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.xs: (Trans_add) fix the segfault when using --excludepath ++ (introduced in ++ r32435:32440). however, using --excludepath will still ++ segfaults, but ++ later, in rpmtsAddInstallElement() ... ++ ++2006-11-29 13:56 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.xs: (Trans_add) fix segfault ++ ++2006-11-24 10:12 Pixel <pixel at mandriva.com> ++ ++ * URPM.pm, URPM/Resolve.pm: strict-arch should not imply that ++ noarch can't upgrade the real arch (#22558) ++ ++2006-11-21 07:59 Pixel <pixel at mandriva.com> ++ ++ * ChangeLog: - default to strict-arch on 64bits (tvignaud) ++ - handle empty hdlist.cz/synthesis.cz (in build_hdlist, ++ build_synthesis, parse_hdlist, parse_synthesis) ++ - parse_rpms_build_headers: allow asking for packing (and so ++ fixing an error in urpmi) ++ - documentation & comments enhancement ++ - release 1.48 ++ ++2006-11-21 07:54 Pixel <pixel at mandriva.com> ++ ++ * URPM/Resolve.pm: resolve_rejected: nodeps is also recognised ++ (through backtrack_selected) ++ ++2006-11-21 07:54 Pixel <pixel at mandriva.com> ++ ++ * URPM/Resolve.pm: resolve_rejected: nodeps is also recognised ++ (through backtrack_selected) ++ ++2006-11-17 17:46 Pixel <pixel at mandriva.com> ++ ++ * URPM/Build.pm: parse_rpms_build_headers: allow asking for ++ packing (fixes an error in urpmi) ++ ++2006-11-17 16:43 Pixel <pixel at mandriva.com> ++ ++ * t/parse.t: add some tests on empty header, buggy header, empty ++ hdlist ++ ++2006-11-17 16:42 Pixel <pixel at mandriva.com> ++ ++ * URPM.xs: at least one good header is needed for non compressed ++ hdlist and non empty file ++ * URPM/Build.pm: allow building empty hdlist & synthesis ++ ++2006-11-17 16:25 Pixel <pixel at mandriva.com> ++ ++ * URPM.xs, t/parse.t: - parse_hdlist on a simple header was broken ++ because pid was left unset, ++ - add some tests for this ++ ++2006-11-15 12:21 Pixel <pixel at mandriva.com> ++ ++ * t/rpmdb.t: do display on which pkgs the 2 sorted lists disagree ++ ++2006-11-15 11:49 Pixel <pixel at mandriva.com> ++ ++ * URPM.pm, URPM.xs: add a wrapper in perl around parse_hdlist and ++ parse_synthesis ++ ++2006-11-15 11:47 Pixel <pixel at mandriva.com> ++ ++ * t/rpmdb.t: remove debug stuff ++ ++2006-11-15 11:28 Pixel <pixel at mandriva.com> ++ ++ * URPM.pm: make the prototype of parse_synthesis more clear in the ++ pod ++ ++2006-11-15 11:14 Pixel <pixel at mandriva.com> ++ ++ * URPM.xs: parse_synthesis, parse_hdlist: handle gzip error status ++ instead of relying on ++ wether we did read at least one header. This allow "empty" ++ hdlist/synthesis. ++ But it means it is getting stricter, and the headers added to ++ {depslist} would ++ need to be removed if an error occured. Alas i don't know how to ++ do it (a ++ simple splice) in XS. If no better solution, i'll create a ++ wrapper function in ++ perl. ++ ++2006-11-10 14:18 Pixel <pixel at mandriva.com> ++ ++ * URPM/Build.pm: use the documented way to call ->parse_hdlist, ++ not the deprecated one ++ ++2006-11-09 15:05 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM/Resolve.pm: (find_chosen_packages) default to strict-arch ++ on 64bits ++ ++2006-11-07 13:27 Pixel <pixel at mandriva.com> ++ ++ * ChangeLog, URPM.pm: new release, no real change except ++ perl_checker compliant ++ ++2006-11-03 15:41 Pixel <pixel at mandriva.com> ++ ++ * URPM/Resolve.pm: perl_checker compliance ++ ++2006-11-03 15:21 Pixel <pixel at mandriva.com> ++ ++ * .perl_checker, URPM.pm, URPM/.perl_checker, URPM/Build.pm, ++ URPM/Resolve.pm: perl_checker compliance ++ ++2006-11-03 15:41 Pixel <pixel at mandriva.com> ++ ++ * URPM/Resolve.pm: perl_checker compliance ++ ++2006-11-03 15:21 Pixel <pixel at mandriva.com> ++ ++ * .perl_checker, URPM.pm, URPM/.perl_checker, URPM/Build.pm, ++ URPM/Resolve.pm: perl_checker compliance ++ ++2006-10-16 10:11 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Patch by Pixel to ignore self-obsoletes ++ ++2006-09-21 09:49 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Invert bogus check ++ ++2006-09-07 09:12 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * MANIFEST, URPM/Build.pm, t/pod.t: Add POD test, remove sole pod ++ fragment in URPM::Build ++ ++2006-09-06 11:37 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm: Bump version to 1.46 ++ ++2006-09-06 09:15 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Oops, remove debug code ++ ++2006-09-06 09:13 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: prefer kernel-source-stripped over kernel-source ++ ++2006-09-05 16:14 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Micro-optimisation, and make comments more ++ explicit ++ ++2006-08-07 14:44 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm: Bump version, regen changelog ++ ++2006-08-07 14:40 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * MANIFEST, perl-URPM.spec: Remove perl-URPM.spec, checked in in ++ repsys ++ ++2006-08-07 14:30 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - cleanup useless imported rpm dcl ++ ++2006-08-07 14:25 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - remove useless declaration ++ ++2006-08-07 14:30 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - cleanup useless imported rpm dcl ++ ++2006-08-07 14:25 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - remove useless declaration ++ ++2006-08-04 09:41 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix a FD leak (patch by Pascal Terjan, bug #24112) ++ ++2006-08-01 13:21 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: strict-arch doesn't apply to src packages ++ ++2006-07-25 21:50 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - add comment into code, need review ++ ++2006-07-04 12:35 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: One might have an undefined package in the ++ depslist (not sure why) ++ ++2006-06-14 10:08 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM/Signature.pm: Verify if we can open the rpmdb, and ++ abort if we can't (bug #22527) ++ ++2006-06-12 10:41 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: That wasn't actually necessary ++ ++2006-06-12 10:31 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: Bump version number ++ ++2006-06-12 10:29 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix passing of rpmRelocation structure with new layout ++ in 4.4.6 ++ ++2006-06-12 10:20 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Fix rpm version detection. Generate ChangeLog under ++ C locale. ++ ++2006-06-07 09:41 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * .cvsignore: Remove cvsignore file ++ ++2006-06-07 09:39 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, Makefile.PL: Use svn2cl to generate ChangeLog, and ++ regenerate it ++ ++2006-06-01 11:47 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL, URPM.xs: It's nice to be able to compile with rpm ++ 4.4.6, but it's nice to be able to ++ compile with older rpms too. ++ ++2006-05-31 21:10 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - rpm 4.4.6 fixes ++ ++2006-05-23 21:53 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * META.yml: Add metafile ++ ++2006-05-23 21:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.43 ++ ++2006-05-23 21:32 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - fix urpmi .spec: aka ensure the rpm config is read ++ with all macros before parsing a spec ++ ++2006-05-22 13:43 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Don't clobber rpm's changelog with too many ++ details, there is a real changelog for that ++ ++2006-05-22 13:32 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * perl-URPM.spec: add bug reference in 1.42-1mdk's changelog ++ ++2006-05-22 11:41 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.42 ++ ++2006-05-22 10:22 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Patch by Pascal Terjan to fix a FD leak (bug #22632) ++ ++2006-05-02 08:33 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.41 ++ ++2006-04-07 10:07 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Add function to traverse transactions ++ ++2006-04-02 23:02 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: RPMTAG_SOURCEPACKAGE is going to be obsolete. Replace ++ it by RPMTAG_SOURCERPM. ++ ++2006-03-15 12:42 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.40 ++ ++2006-03-13 16:51 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Get version comparison right ++ ++2006-03-13 16:40 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Define new symbol in Makefile.PL depending on ++ detected rpm version ++ (no simpler way to get it from the C preprocessor, it seems) ++ ++2006-03-13 16:37 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix for undocumented ABI changes in rpm 4.4.5 callback ++ interface ++ ++2006-03-13 15:56 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Protection when no data is passed to transaction ++ callbacks ++ ++2006-03-13 14:44 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix misplaced break in switch statement ++ ++2006-03-10 16:07 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: "triggeredby" in traverse_tag never worked. ++ ++2006-03-08 15:51 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix small memleak on db open error ++ ++2006-03-07 10:35 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.39 ++ ++2006-03-07 10:27 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Clean up gcc options ++ ++2006-03-07 10:07 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Protect rpmtsRun with a new link to the transaction ++ object ++ ++2006-03-06 14:11 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Spec file nit. ++ * URPM.xs: Also, increase refcounts. ++ ++2006-03-06 13:59 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.38 ++ ++2006-03-06 13:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * t/rpmdb.t: Perform this test faster ++ ++2006-03-06 13:45 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * t/parse.t: Be more Test::More-ish, add a TODO test ++ ++2006-03-06 13:31 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: It wasn't a good idea to completely remove the ++ refcount, because it's used to ++ free the underlying C glue structure. ++ Also, and rpmtsLink was misplaced. ++ ++2006-03-06 11:09 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Don't use our own reference counter, but the rpmlib's, ++ for transactions. ++ ++2006-03-03 15:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.37 ++ ++2006-03-03 15:08 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Document URPM::verify_signature() ++ ++2006-03-03 15:05 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Include key id in verify_signature()'s OK output. Also, ++ avoid a header leak. ++ ++2006-03-03 14:44 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: New function verify_signature ++ ++2006-03-03 13:50 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Don't display error messages from rpmVerifySignatures ++ ++2006-03-03 13:14 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Document (new-ish) return value of verify_rpm() ++ ++2006-03-03 13:00 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Reimplement verify_rpm, using the rpm cli ++ interface ++ ++2006-03-03 10:22 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Remove support for the (broken) db option to ++ verify_rpm ++ ++2006-03-03 09:26 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Use a smaller buffer for the return value of ++ verify_rpm, and guard against overflows ++ ++2006-03-02 17:40 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Honor verification flags in verif_rpm() even when ++ reading from a file without ++ having open the rpmdb ++ ++2006-03-02 17:22 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Nits in verify_rpm. ++ ++2006-03-01 11:44 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix a couple of compilation warnings. URPM.xs is now ++ warning-clean. ++ ++2006-03-01 11:40 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Make sure -fno-strict-aliasing is used (gcc option) ++ ++2006-02-13 13:17 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Document the is_arch_compat package method ++ ++2006-02-13 10:40 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: 1.36-1mdk ++ ++2006-02-13 10:39 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Document new ignorearch flag ++ ++2006-02-13 10:22 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Add ignorearch option to run transactions ++ ++2006-02-10 17:07 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.35-1mdk ++ ++2006-02-10 17:06 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: repackage also when only the rpm macro is defined. ++ Maybe rpm ought to do this, ++ but obviously, as of 4.4.4, it does not. ++ ++2006-02-10 09:03 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.34-1mdk ++ ++2006-02-10 08:55 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Doc nits ++ ++2006-02-10 08:53 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Remove unused variable ++ ++2006-02-09 17:33 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Fix code example in URPM's synopsis ++ ++2006-02-09 17:29 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Add installtid method ++ ++2006-02-09 14:47 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Document keep_all_tags option to parse rpms ++ ++2006-02-09 13:57 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: No need to make an explicit dependency on ++ perl-base ++ ++2006-02-09 13:56 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog: Update Changelog ++ ++2006-02-09 13:52 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, perl-URPM.spec: 1.33-1mdk ++ ++2006-02-09 13:50 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Document new flag repackage in run() ++ ++2006-02-09 13:25 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix repackage option, oops ++ ++2006-02-09 12:57 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Add repackage flag to run transactions ++ ++2006-01-25 14:21 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, URPM.xs, perl-URPM.spec: 1.32-1mdk ++ ++2006-01-25 14:18 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Flag headers returned by spec2srcheader() as source ++ packages ++ ++2006-01-24 11:38 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Pod formatting fix ++ ++2006-01-19 13:39 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.31 ++ ++2006-01-19 13:31 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Rewrite and relocate doc at a more proper place. Update ++ copyright notice. ++ ++2006-01-19 13:24 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs, t/parse.t: In spec2srcheader(): extend stack; fudge ++ with errno. ++ ++2006-01-19 13:05 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs, t/parse.t: Return undef on spec parsing failure ++ ++2006-01-19 12:52 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.pm: - add doc for Urpm_spec2srcheader ++ ++2006-01-19 11:36 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * Makefile.PL, URPM.xs, t/parse.t: - add Urpm_spec2srcheader(): ++ return header of src.rpm from a specfile ++ ++2006-01-06 16:22 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.30-2mdk ++ ++2006-01-06 11:12 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, t/rpmdb.t: Use --qf in test to accomodate variations ++ in %_query_all_fmt values ++ ++2005-12-08 09:29 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Update copyrights ++ ++2005-12-07 16:54 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.30 ++ ++2005-12-07 16:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm, perl-URPM.spec: Fix longstanding epoch ++ promotion bug, caused by braindead API design ++ ++2005-12-07 16:44 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Document trap in that braindead stupid API. ++ ++2005-12-01 16:53 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Be verbose about the detected RPM version ++ ++2005-12-01 13:57 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: RPMTAG_SERIAL (old name of RPMTAG_EPOCH) has been ++ removed in rpm 4.4.3 ++ ++2005-11-30 13:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix a couple of compilation warnings ++ ++2005-11-30 13:45 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Fix cast error ++ ++2005-11-30 13:21 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: libbzip2 is actually not used by URPM. ++ ++2005-11-15 16:14 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Add an URPM::Package::dump_flags method, to help ++ debugging the depsolver ++ ++2005-11-15 10:45 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ., .cvsignore: Ignore MakeMaker build files ++ ++2005-11-02 14:44 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.29-1mdk ++ ++2005-11-02 10:42 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Mention noscripts option in docs ++ ++2005-10-28 14:30 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Doc neatification ++ ++2005-10-28 14:15 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Require MDV::Packdrakeng in Makefile.PL ++ ++2005-10-28 14:10 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm, t/parse.t: Use new MDV namespace ++ ++2005-10-18 16:46 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: More docs for confusing method names ++ ++2005-10-10 18:21 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Add the RPMPROB_FILTER_DISKNODES flag for running ++ transactions with the ++ nosize option. Although rpm doesn't seem to use it internally, ++ it sets ++ it on the --ignoresize command-line option. ++ ++2005-10-04 12:19 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * t/parse.t: Don't require Packdrakeng for running tests ++ ++2005-10-04 12:00 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Remove buildrequires on bzip2. ++ Simplify buildreq_perl_devel conditional dependency per Buchan's ++ suggestion. ++ ++2005-10-03 09:25 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.28-1mdk ++ ++2005-10-03 09:19 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Documentation encoding fix ++ ++2005-10-03 09:17 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * MANIFEST, Makefile.PL, t/00prepare.t, t/parse.t, ++ test-rpm-1.0-1mdk.noarch.rpm: Rebuild test rpm when running ++ tests. Add cleanup to files. ++ ++2005-10-03 08:40 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * MANIFEST: Update MANIFEST ++ ++2005-10-03 08:38 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * build_rpm: Remove obsolete script ++ ++2005-10-03 08:36 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Add an rpm makefile target ++ ++2005-10-03 08:20 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Makefile.PL cleanup ++ ++2005-09-14 13:17 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - add some options to parse_rpm (nomd5, nopayload) ++ ++2005-09-12 15:13 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Minor comment fixes ++ ++2005-09-09 12:54 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: 1.27-1mdk ++ ++2005-09-09 12:53 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Make URPM::add_macro expand literal \n to \\\n ++ in macro definitions. ++ add URPM::add_macro_noexpand to get the old (rpmlib like) ++ behaviour ++ ++2005-09-01 16:19 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, perl-URPM.spec: 1.26-1mdk ++ ++2005-09-01 15:43 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Add a "noscripts" option to run transactions. Inhibits ++ pre, preun, post and ++ postun scritps. ++ ++2005-08-23 12:22 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.25-1mdk ++ ++2005-08-23 12:15 Pixel <pixel at mandriva.com> ++ ++ * URPM.xs: correctly handle -1 fileno returned by callback_open ++ ++2005-08-23 10:33 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Doc fixes ++ ++2005-08-18 15:54 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.24-3mdk ++ ++2005-08-18 15:32 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Allow to rebuild URPM under non-C locales (Boris ++ Filipovic) ++ ++2005-07-28 05:06 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.24-2mdk ++ ++2005-07-28 02:26 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Doc bits ++ ++2005-07-28 02:12 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * README, URPM.pm, URPM.xs: update copyright and maintainer ++ ++2005-07-04 09:32 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Documentation fix ++ ++2005-06-30 05:01 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.24 ++ ++2005-06-30 04:58 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Add function rpmErrorWriteTo($fd) ++ ++2005-06-30 04:32 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: add rpmErrorString function ++ ++2005-06-29 09:02 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Doclet ++ ++2005-06-16 10:27 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Forgot to commit changelog ++ ++2005-06-16 10:05 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.23-1mdk ++ ++2005-06-16 10:03 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Add a binding for rpm internal debugging ++ function setVerbosity() ++ ++2005-06-07 01:43 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.22-1mdk ++ ++2005-06-01 09:39 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Warning fixes and documentation ++ ++2005-06-01 03:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Ensure archs are identical ++ ++2005-06-01 03:29 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Integrate a function to produce deltarpms ++ ++2005-05-31 09:33 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.21-1mdk ++ ++2005-05-31 08:45 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Removes obsolete code ++ ++2005-05-30 09:37 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Add the URPM::Package::payload_format method ++ ++2005-05-11 06:58 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Remove the return value of ++ compute_installed_flags, it's not used anywhere ++ ++2005-05-10 13:11 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * perl-URPM.spec: - 0.3 for amd64 ++ ++2005-05-09 10:09 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.20-mdk ++ ++2005-05-09 06:32 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Update buildrequires ++ ++2005-05-09 05:37 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Make spec mandriva-compliant ++ ++2005-05-04 03:06 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Don't hardcode distribution name ++ ++2005-05-04 03:01 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.20-1mdk ++ ++2005-05-02 10:58 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL, URPM.xs: Remove rpm 4.0 support ++ ++2005-05-02 10:41 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Remove dead code ++ ++2005-05-02 10:39 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Patch by Olivier Thauvin to adapt URPM for rpm 4.4 ++ ++2005-04-28 23:50 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * perl-URPM.spec: - use mkrel ++ ++2005-04-28 16:44 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Fix bug 15628 : when no preferred locale is ++ found, put locales-en in front of ++ choice list ++ ++2005-03-09 16:39 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: More RPMSENSE_PREREQ deprecation. (this should do ++ nothing with rpm 4.2) ++ ++2005-03-07 09:32 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.11-1mdk ++ ++2005-03-03 09:37 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Speed optimisation for updating media ++ ++2005-03-02 15:13 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.10-1mdk ++ ++2005-03-02 14:38 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Prepare for obsolescence of PREREQ, introduce ++ equivalent RPMSENSE_SCRIPT_* tags ++ ++2005-02-15 12:54 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.09-1mdk ++ ++2005-02-15 12:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Comments and indentation ++ ++2005-02-15 11:29 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Force recomputation of rejected packages when ++ deleting some in installation ++ dependency resolution ++ ++2005-02-11 14:17 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: POD fix. ++ ++2005-02-11 14:07 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.08-1mdk ++ ++2005-02-11 13:59 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Add macro handling code from Olivier Thauvin ++ ++2005-02-02 09:12 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.07-4mdk ++ ++2005-02-02 09:00 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Ooops, missing epoch ++ ++2005-01-21 09:53 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.07-3mdk ++ ++2005-01-20 20:35 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Require perl-base >= 5.8.6, so perl will be ++ upgraded early in the process ++ 10.1 to 10.2 ++ ++2005-01-04 11:06 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Croak if build_base_files can't write files ++ ++2004-12-21 15:38 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Typos in documentation ++ ++2004-12-21 14:25 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Indentation and comments ++ ++2004-12-13 17:21 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.07-2mdk ++ ++2004-12-13 13:43 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.07-1mdk ++ ++2004-12-13 13:34 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Return the list of chosen packages sorted by ++ descending version ++ (bug #12645). ++ ++2004-12-09 15:29 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.06-1mdk ++ ++2004-12-09 15:16 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: trust packdrake's defaults ++ ++2004-12-09 15:10 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Remove external call to packdrake. ++ ++2004-12-09 14:27 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * t/parse.t: Silence warnings ++ ++2004-12-09 14:24 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * t/parse.t: Adjust test count ++ ++2004-11-26 07:45 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.05-1mdk ++ ++2004-11-25 19:18 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM/Build.pm: Inspired changes on top of Olivier's ++ changes ++ ++2004-11-25 14:28 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.pm, URPM/Build.pm, URPM/Resolve.pm: - allow to use an array ++ of id instead (start .. end) in functions. ++ ++2004-11-10 17:31 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.04-1mdk ++ ++2004-11-10 17:26 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm: Version bump ++ ++2004-11-10 17:14 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: When resolving dependencies, keep track of the ++ packages that we just ++ deselected because newer versions were found, but that were not ++ actually ++ installed. ++ ++2004-11-10 14:17 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Indentation, documentation ++ ++2004-10-27 09:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: Release for amd64 ++ ++2004-10-27 08:18 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Support for the 'strict-arch' option : upgrade ++ only packages that have ++ the same architecture than the one of the already-installed ++ version. ++ ++2004-10-25 12:04 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Comments ++ ++2004-10-19 14:47 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, perl-URPM.spec: 1.03-2mdk ++ ++2004-10-18 08:34 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: A few perl_checker fixes ++ ++2004-10-18 08:31 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Patch by Gwenole Beauchesne to prefer packages ++ which have the closest ++ architecture compatibility over others when version/release are ++ the same ++ (using rpm's scoring system). ++ ++2004-10-14 03:22 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Fix method description ++ ++2004-10-13 02:35 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Small comment fixes ++ ++2004-09-03 05:06 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: If $TMPDIR is not writable, don't use it ++ ++2004-08-29 12:33 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * ChangeLog: Rebuild ++ ++2004-08-29 12:29 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.pm, perl-URPM.spec: - 1.03 ++ ++2004-08-29 11:56 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs, t/parse.t: - backport rpmvercmp binding from perl-Hdlist ++ ++2004-08-24 09:43 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.02-1mdk ++ ++2004-08-24 09:29 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: From now, the nopromoteepoch argument will always ++ default to 1 ++ ++2004-08-24 08:12 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, URPM.xs: Minor doc fixes ++ ++2004-08-11 05:07 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.01-1mdk ++ ++2004-08-11 04:57 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Don't panic on bad rpm fullnames ++ ++2004-08-02 10:42 Fançois Pons ++ ++ * URPM/Resolve.pm: fixed deadlock caused with libgc1 obsoleting ++ itself ;-) and in the case were an ++ older package is already installed and an older package is ++ present in urpmi ++ db. The problems comes with a badly interpreted comparison ++ without an operator ++ checked. ++ ++2004-08-02 09:24 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 1.00 ! ++ ++2004-08-02 09:01 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Protection against packages that obsolete ++ themselves. ++ ++2004-08-02 08:42 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs, t/parse.t: - remove test that can't works ++ ++2004-08-02 07:22 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - backward compatibility with perl 5.6 ++ ++2004-08-02 07:14 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * Makefile.PL: - don't check rpm rpm version but rpm binary version ++ ++2004-08-02 00:27 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Silence a compilation warning ++ ++2004-08-02 00:03 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm, URPM/Query.pm, URPM/Resolve.pm: Make perl_checker ++ a bit more happy ++ ++2004-07-30 09:03 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * perl-URPM.spec: put back lost 0.98-2mdk's changelog ++ ++2004-07-30 07:48 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: 0.99-1mdk ++ ++2004-07-30 06:10 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Resolution of requested packages: by default, ++ don't propose a choice when ++ multiple found packages are already installed. ++ ++2004-07-28 08:47 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Build.pm: Use lexical filehandles. ++ ++2004-07-22 09:39 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: Version 0.98 ++ ++2004-07-22 03:15 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs, t/parse.t: Add URPM::stream2header (borrowed from ++ perl-Hdlist, thanks to Olivier ++ Thauvin) ++ ++2004-07-14 09:14 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * Makefile.PL, URPM.pm, perl-URPM.spec: - generate the manpage ++ - 0.97 ++ ++2004-07-12 06:12 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * ChangeLog, URPM.pm, perl-URPM.spec: Version 0.96 ++ ++2004-07-12 01:23 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Don't use keys() in scalar context ++ ++2004-07-12 01:04 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Add a ChangeLog target in the makefile ++ ++2004-07-09 08:56 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Simplify the compute_flags function (used for ++ the {skip,inst}.list files) ++ ++2004-06-27 18:31 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - fix segfault in queryformat if tag does not exist ++ (return nothing instead) ++ ++2004-06-23 06:47 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs, t/fatal.t: Clarify error message when a synthesis file ++ can't be read or gunzipped ++ ++2004-05-21 11:33 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: 0.95-2mdk ++ ++2004-05-21 11:19 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: Allow urpmi to downgrade packages if it was ++ invoked with --allow-force ++ ++2004-05-19 15:28 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Resolve.pm: When an rpm installed locally had a version ++ greater than the one found ++ in the update media, urpmi was trying to downgrade it. ++ ++2004-05-06 09:42 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, perl-URPM.spec: Version 0.95 ++ ++2004-05-06 09:22 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * MANIFEST, URPM.pm, URPM.xs, URPM/Resolve.pm, t/fatal.t: Add a ++ way to downgrade some errors (file not found) to non-fatal ++ ++2004-04-30 08:32 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: 0.94-13mdk ++ ++2004-04-27 05:56 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM/Query.pm: - fix tag2id on old mdk, ensure all test are ok ++ on 9.1 ++ ++2004-04-26 14:40 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * t/parse.t: Silence warnings ++ ++2004-04-25 21:33 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs, t/parse.t: - make parse.t pass all test ++ - add $pkg->queryformat test ++ ++2004-04-25 10:44 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.pm, URPM.xs, URPM/Query.pm: - add $pkg->queryformat() ++ function ++ - $ûrpm->list_rpm_tag show all tag, value for unparsable tag is ++ 'undef' in hash ++ ++2004-04-23 13:55 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * ChangeLog: *** empty log message *** ++ ++2004-04-23 08:01 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - urpm optional arg to Urpm_list_rpm_tag function ++ ++2004-04-22 14:14 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Better diagnostics in $package->build_info() ++ ++2004-04-22 09:54 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * t/parse.t: - test rpm parsing and hdlist generation ++ ++2004-04-22 09:28 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * MANIFEST: Add missing files in the MANIFEST ++ * perl-URPM.spec: Remove hardcoded packager ++ ++2004-04-22 06:40 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM/Build.pm: - Don't pass whole %options to parse_rpm in ++ parse_rpms_build_headers ++ ++2004-04-22 06:34 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.xs: (return_list_tag) factorize common local variables ++ declaration (though ++ it wastes 4 pointer slots on stack in RPMTAG_SUMMARY case) ++ ++2004-04-22 05:43 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM/Query.pm, t/parse.t, test-rpm-1.0-1mdk.noarch.rpm, ++ test-rpm.spec: - remove unusefull function ++ - start to add parsing test ++ ++2004-04-22 05:33 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM/Build.pm: - export keep_all_tags trought function in ++ parse_rpm_build_headers ++ ++2004-04-22 05:32 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - return_list_tag is able to return some basic tags ++ from synthesis ++ ++2004-04-21 13:13 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.xs: - cleaning return_list_tag ++ ++2004-04-21 09:25 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM.pm, URPM.xs, URPM/Query.pm: - add list_rpm_tag function ++ ++2004-04-21 09:17 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * perl-URPM.spec: 0.94-12mdk ++ ++2004-04-21 09:16 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Signature.pm: More cleanup. ++ ++2004-04-21 09:15 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Don't install manpages. ++ ++2004-04-21 08:08 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM/Signature.pm: Minor cleanup ++ ++2004-04-18 23:15 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM/Build.pm, URPM/Query.pm: - add query_pkg function ++ - transmit %options to parse_rpm in parse_rpms_build_headers ++ ++2004-04-17 23:31 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM/Build.pm, URPM/Query.pm: - add Query.pm (starting to code) ++ - add fuzzy_parse function, transparency parse hdlist, ++ synthesis, rpms or dir (dir/*.rpm) ++ - add parse_rpms function to have same behaviours than ++ parse_{hdlists,synthesis} ++ ++2004-04-15 09:34 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.xs: Improve some diagnostics ++ ++2004-04-09 15:51 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * Makefile.PL: Force INSTALLDIRS=vendor in the Makefile.PL, for ++ local testing ++ ++2004-04-06 14:41 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * URPM.pm, t/rpmdb.t, t/synthesis.t: Deprecate the pseudo-packages ++ URPM::Build, URPM::Resolve and URPM::Signature. ++ Documentation fixes. Tidy up the tests (and add a few ones.) ++ ++2004-04-02 14:02 Rafael Garcia-Suarez <rgarciasuarez at mandriva.com> ++ ++ * MANIFEST, Makefile.PL, URPM.pm, t/synthesis.t: Add some API ++ documentation for the URPM module. ++ Plus, some minor nits in auxiliary files. ++ ++2004-04-01 10:40 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * ChangeLog: *** empty log message *** ++ ++2004-02-25 22:35 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * perl-URPM.spec: 0.94-11mdk ++ ++2004-01-18 02:25 Olivier Thauvin <thauvin at aerov.jussieu.fr> ++ ++ * URPM/Build.pm: - parse_rpm_build_headers have same behaviour ++ with dontdie and callback ++ when using cache or the rpm ++ ++2004-01-15 18:20 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * ChangeLog: *** empty log message *** ++ ++2003-12-09 19:40 Fançois Pons ++ ++ * URPM.xs, URPM/Resolve.pm, perl-URPM.spec: added support for RH ++ 7.3 ++ ++2003-11-17 21:01 Fançois Pons ++ ++ * perl-URPM.spec: 0.98-9mdk ++ ++2003-11-17 20:59 Fançois Pons ++ ++ * URPM/Build.pm: fixed bad use of option idlist for checking its ++ presence ++ ++2003-11-15 19:47 Fançois Pons ++ ++ * perl-URPM.spec: 0.94-8mdk ++ ++2003-11-15 19:44 Fançois Pons ++ ++ * URPM.xs, URPM/Build.pm: fixed indentation and reworked code to ++ be simpler ++ ++2003-11-15 19:33 Fançois Pons ++ ++ * URPM.xs, URPM/Build.pm: applied patch from Olivier Thauvin ++ ++2003-10-13 12:36 Fançois Pons ++ ++ * perl-URPM.spec: 0.94-7mdk ++ ++2003-10-13 12:34 Fançois Pons ++ ++ * URPM/Resolve.pm: fixed to find package with full provides on ++ whatrequires obsoleted, so that ++ pam-devel is upgraded correctly for example. ++ ++2003-09-10 15:12 Fançois Pons ++ ++ * perl-URPM.spec: 0.94-6mdk ++ ++2003-09-10 15:11 Fançois Pons ++ ++ * URPM/Resolve.pm: removed STDERR log. ++ * URPM/Resolve.pm: diff_provides on obsoleted provides are needed. ++ ++2003-09-10 11:46 Fançois Pons ++ ++ * perl-URPM.spec: 0.94-5mdk ++ ++2003-09-10 11:45 Fançois Pons ++ ++ * URPM/Resolve.pm: fixed bad ARRAY reference (promote). ++ ++2003-09-05 10:33 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.94-4mdk ++ ++2003-09-02 17:19 Fançois Pons ++ ++ * perl-URPM.spec: 0.94-3mdk ++ * URPM/Resolve.pm: removed log. ++ ++2003-09-02 17:18 Fançois Pons ++ ++ * URPM/Resolve.pm: fixed package badly removed. ++ ++2003-08-22 13:53 Fançois Pons ++ ++ * perl-URPM.spec: 0.94-2mdk ++ ++2003-08-22 13:52 Fançois Pons ++ ++ * URPM/Resolve.pm: removed potential deadlock. ++ ++2003-08-21 13:04 Fançois Pons ++ ++ * URPM.pm, URPM/Signature.pm, perl-URPM.spec: 0.94-1mdk ++ (URPM::Signature fixes and changes) ++ ++2003-08-21 11:25 Fançois Pons ++ ++ * URPM/Signature.pm: fixed with gc suggestion which are really ++ fine (and right). ++ ++2003-08-20 16:17 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: final 0.93-7mdk ++ ++2003-08-20 15:10 Fançois Pons ++ ++ * URPM.pm, URPM/Signature.pm, perl-URPM.spec: 0.93-7mdk (signature ++ comparison workaround) ++ ++2003-08-19 16:33 Fançois Pons ++ ++ * perl-URPM.spec: 0.93-6mdk ++ ++2003-08-19 16:32 Fançois Pons ++ ++ * URPM.xs: added URPM::import_pubkey to import a key (only one) ++ directly to opened rpm ++ database or by opening the database on the fly. ++ ++2003-08-19 16:31 Fançois Pons ++ ++ * URPM/Signature.pm: fixed URPM::import_armored_file to use ++ internal XS function to import directly ++ to database, handle importation of multiple keys by file. ++ ++2003-08-18 15:29 Pixel <pixel at mandriva.com> ++ ++ * URPM/Resolve.pm, perl-URPM.spec: perl_checker compliance ++ ++2003-08-13 12:04 Guillaume Cottenceau ++ ++ * perl-URPM.spec: provide URPM::Signature as well ++ ++2003-08-11 15:27 Fançois Pons ++ ++ * perl-URPM.spec: 0.93-3mdk ++ * URPM.xs: fixed files_md5sum returning not the same number as ++ files method. ++ removed unsatisfied_requires2 not used (and doing nothing ++ usefull). ++ ++2003-08-11 14:04 Fançois Pons ++ ++ * URPM/Signature.pm, perl-URPM.spec: 0.93-2mdk ++ ++2003-08-06 17:45 Fançois Pons ++ ++ * URPM/Signature.pm: final 0.93-1mdk ++ ++2003-08-06 15:54 Fançois Pons ++ ++ * URPM.pm, URPM/Build.pm, URPM/Signature.pm, perl-URPM.spec: ++ 0.93-1mdk ++ ++2003-08-06 09:52 Fançois Pons ++ ++ * MANIFEST: added signature management. ++ ++2003-08-06 09:50 Fançois Pons ++ ++ * URPM/Signature.pm: initial support for parsing armored file ++ (without gpg) and registering rpmdb pubkeys. ++ ++2003-08-04 17:51 Fançois Pons ++ ++ * MANIFEST, URPM/Resolve.pm, perl-URPM.spec: 0.92-4mdk ++ ++2003-08-01 19:29 Pixel <pixel at mandriva.com> ++ ++ * perl-URPM.spec: - rebuild for new perl (it helps DrakX build ++ script) ++ - use DESTDIR ++ ++2003-07-30 16:59 Fançois Pons ++ ++ * perl-URPM.spec: 0.92-2mdk ++ ++2003-07-30 16:57 Fançois Pons ++ ++ * URPM/Resolve.pm: fixed some missing unsatisfied in reason of ++ rejected packages. ++ fixed provide obsoleted which should not be taken into account ++ when looking for ++ obsoletes. ++ ++2003-07-28 15:13 Fançois Pons ++ ++ * URPM.pm, URPM/Resolve.pm, perl-URPM.spec: 0.92-1mdk ++ ++2003-07-24 15:28 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-14mdk ++ ++2003-07-24 10:10 Fançois Pons ++ ++ * URPM.xs, URPM/Build.pm, URPM/Resolve.pm, perl-URPM.spec: ++ 0.91-13mdk ++ ++2003-07-16 13:34 Fançois Pons ++ ++ * perl-URPM.spec: 0.91-12mdk ++ ++2003-07-16 13:10 Fançois Pons ++ ++ * URPM/Build.pm: fixed cache not taken into account. ++ ++2003-07-16 12:07 Fançois Pons ++ ++ * URPM/Resolve.pm: fixed small typo on regex for ++ URPM::compute_flags ++ ++2003-07-10 16:09 Fançois Pons ++ ++ * URPM.xs: fixed SvPV typos. ++ ++2003-07-10 16:05 Fançois Pons ++ ++ * perl-URPM.spec: 0.91-11mdk ++ ++2003-07-10 16:04 Fançois Pons ++ ++ * Makefile.PL: removed -f-no-rtti as no C++ code is used. ++ ++2003-07-10 16:03 Fançois Pons ++ ++ * URPM.xs: starting coding unsatisfied_requires in C, incomplete. ++ modified return_list_str to allow getting strings list in C ++ easily and quickly. ++ ++2003-07-10 16:02 Fançois Pons ++ ++ * URPM/Resolve.pm: optimized URPM::compute_flags method by an ++ almost unlimited factor. ++ ++2003-07-07 17:28 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-10mdk ++ ++2003-07-07 15:14 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-9mdk ++ ++2003-07-04 12:18 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-8mdk ++ ++2003-06-26 15:26 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-7mdk ++ ++2003-06-19 14:24 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-6mdk ++ ++2003-06-19 11:12 Fançois Pons ++ ++ * URPM.xs: make sure a callback parameter is taken into account ++ only if a reference is ++ used. ++ ++2003-06-19 10:31 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-5mdk ++ ++2003-06-18 17:02 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: added missing fix on bad ++ conflicts listing, ++ removed stderr logs. ++ ++2003-06-18 16:53 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-4mdk ++ ++2003-06-18 16:14 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-4mdk ++ ++2003-06-18 11:52 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.91-3mdk ++ ++2003-06-17 15:59 Fançois Pons ++ ++ * perl-URPM.spec: added compilable on rpm-4.0.4 of rpm. ++ ++2003-06-17 15:54 Fançois Pons ++ ++ * URPM.xs: fixed compilation on rpm 4.0.4. ++ ++2003-06-17 15:35 Fançois Pons ++ ++ * URPM.xs, URPM/Resolve.pm, perl-URPM.spec: fixed 0.91-2mdk ++ ++2003-06-17 13:39 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.91-2mdk ++ ++2003-06-16 17:57 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Resolve.pm, perl-URPM.spec, t/rpmdb.t: ++ 0.91-1mdk ++ ++2003-06-12 15:52 Fançois Pons ++ ++ * perl-URPM.spec: 0.90-10mdk ++ * URPM.xs: improved return value of verify_rpm. ++ ++2003-06-11 15:42 Fançois Pons ++ ++ * URPM/Resolve.pm: removed $v-> (for rejected hash value) by $rv ++ in order to avoid name clash ++ with $v (version). ++ ++2003-06-11 11:34 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.90-9mdk ++ ++2003-06-05 18:41 Fançois Pons ++ ++ * URPM.xs: fixed memory leak in parse_rpm. ++ ++2003-06-05 17:46 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.90-8mdk ++ ++2003-06-05 13:53 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.90-7mdk ++ ++2003-06-05 08:47 Fançois Pons ++ ++ * URPM/Build.pm, URPM/Resolve.pm: added clever cache header ++ management during build of hdlist. ++ removed no_flag_update obsoleted. ++ ++2003-06-04 09:47 Warly <warly at mandriva.com> ++ ++ * URPM.xs, perl-URPM.spec: Add Pkg_buildtime to get ++ RPMTAG_BUILDTIME ++ ++2003-06-03 10:21 Fançois Pons ++ ++ * perl-URPM.spec: a newer version for a newer package. ++ ++2003-06-03 10:14 Fançois Pons ++ ++ * URPM.xs: fixed sutpid typo (strange compiler didn't notice ++ anything) ++ ++2003-06-02 16:38 Fançois Pons ++ ++ * URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.90-4mdk ++ ++2003-05-30 11:32 Warly <warly at mandriva.com> ++ ++ * URPM.xs: move packing and keep_all_tags declaration in ++ Urpm_parse_rpm to the begining of the function in order to get ++ the argument initialisation correctly working (otherwize they ++ were overriden and systematically set to 0). ++ ++2003-05-30 10:11 Warly <warly at mandriva.com> ++ ++ * URPM.xs, perl-URPM.spec: add Pkg_license function to URPM.xs ++ (URPM::Package) ++ ++2003-05-26 15:13 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.90-2mdk ++ ++2003-05-23 15:26 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.90-1mdk ++ first backtrackable method, still lacking backtrack of remove and ++ better handling of choices during backtrack, too much simplist. ++ ++2003-05-16 15:11 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.84-1mdk ++ ++2003-05-14 17:43 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.83-4mdk ++ ++2003-05-13 21:02 Fançois Pons ++ ++ * URPM.xs, URPM/Build.pm, perl-URPM.spec: 0.83-3mdk ++ ++2003-05-13 20:46 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM/Build.pm: perl_checker fixes ++ ++2003-05-13 20:35 Thierry Vignaud <tvignaud at mandriva.com> ++ ++ * URPM.pm: perl_checker fix ++ ++2003-05-12 16:43 Guillaume Cottenceau ++ ++ * perl-URPM.spec: - rebuild for new perl requires/provides ++ - provide perl packages URPM::Resolve and URPM::Build since the ++ perl packages are URPM for object export ++ ++2003-04-29 17:16 Fançois Pons ++ ++ * Makefile.PL, URPM.pm, URPM.xs, build_rpm, perl-URPM.spec: first ++ try of 4.2 compatible perl-URPM, ++ missing verify_signature, ++ new version 0.83 ++ ++2003-04-24 15:51 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.82-4mdk ++ ++2003-04-22 14:35 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.82-3mdk ++ ++2003-04-14 13:07 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.82-2mdk ++ ++2003-04-11 16:29 Fançois Pons ++ ++ * URPM/Resolve.pm: fixed stupid typo in compute_skip_flags ++ ++2003-04-11 16:06 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Resolve.pm, perl-URPM.spec: brand new ++ 0.82 version (flag_skip, excludedocs, fix NULL get_name) ++ ++2003-03-12 18:16 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.81-13mdk ++ ++2003-03-10 16:44 Fançois Pons ++ ++ * URPM.pm, URPM/Build.pm, URPM/Resolve.pm, perl-URPM.spec: ++ 0.81-12mdk ++ ++2003-03-03 13:09 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.81-11mdk ++ ++2003-02-27 13:22 Fançois Pons ++ ++ * perl-URPM.spec: 0.81-10mdk ++ ++2003-02-27 13:13 Fançois Pons ++ ++ * URPM/Resolve.pm: allow choices to return multiple selection. ++ ++2003-02-19 13:28 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.81-9mdk ++ ++2003-02-13 18:37 Fançois Pons ++ ++ * perl-URPM.spec: 0.81-8mdk ++ ++2003-02-13 17:53 Fançois Pons ++ ++ * URPM/Resolve.pm: fix rpmdrake woes on incompatible arch. ++ ++2003-01-23 14:29 Fançois Pons ++ ++ * URPM/Build.pm, URPM/Resolve.pm, perl-URPM.spec: 0.81-7mdk ++ ++2003-01-06 16:33 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.81-6mdk ++ ++2003-01-06 11:25 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.81-5mdk ++ ++2002-12-20 11:05 Pixel <pixel at mandriva.com> ++ ++ * URPM/Resolve.pm, perl-URPM.spec: perl_checker fixes (syntax only) ++ ++2002-12-18 14:57 Pixel <pixel at mandriva.com> ++ ++ * URPM.pm, perl-URPM.spec: help perl_checker recognise packages ++ used as classes ++ ++2002-12-18 12:54 Pixel <pixel at mandriva.com> ++ ++ * URPM.pm, perl-URPM.spec: perl_checker fixes ++ ++2002-12-17 13:57 Fançois Pons ++ ++ * URPM.pm, perl-URPM.spec: added very faster code, 3 times faster ++ on traverse_tag with --env. ++ ++2002-12-17 13:46 Fançois Pons ++ ++ * URPM.pm, URPM/Resolve.pm, perl-URPM.spec: 0.81-1mdk ++ ++2002-12-11 11:27 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.80-2mdk ++ ++2002-12-05 17:58 Fançois Pons ++ ++ * URPM.pm, URPM.xs, perl-URPM.spec: 0.80-1mdk ++ ++2002-12-03 14:43 Fançois Pons ++ ++ * URPM.pm, URPM.xs, perl-URPM.spec: 0.71-1mdk ++ ++2002-09-17 13:16 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.70-10mdk ++ ++2002-09-09 14:25 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.70-9mdk ++ ++2002-09-02 14:46 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.70-8mdk ++ ++2002-08-30 15:52 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.70-7mdk ++ ++2002-08-30 13:08 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.70-6mdk ++ ++2002-08-29 15:48 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.70-5mdk ++ ++2002-08-29 09:41 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.70-4mdk ++ ++2002-08-28 14:15 Fançois Pons ++ ++ * perl-URPM.spec: added URL (cvsweb at least). ++ ++2002-08-28 14:06 Fançois Pons ++ ++ * URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.70-3mdk ++ ++2002-08-26 18:29 Fançois Pons ++ ++ * URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.70-2mdk ++ ++2002-08-23 13:08 Fançois Pons ++ ++ * URPM.pm: fixed VERSION to 0.70. ++ ++2002-08-23 13:06 Fançois Pons ++ ++ * URPM.pm, perl-URPM.spec: 0.70-1mdk. ++ ++2002-08-13 10:05 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.60-8mdk ++ ++2002-08-12 16:00 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.60-7mdk ++ ++2002-08-12 13:34 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.60-6mdk ++ ++2002-08-09 17:12 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.60-5mdk ++ ++2002-08-09 16:47 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.60-4mdk ++ ++2002-08-07 14:25 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.60-3mdk ++ ++2002-08-06 15:04 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.60-2mdk ++ ++2002-08-05 16:57 Fançois Pons ++ ++ * URPM.pm, URPM/Resolve.pm, perl-URPM.spec: 0.60-1mdk ++ ++2002-07-25 11:19 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.50-6mdk ++ ++2002-07-25 07:27 Fançois Pons ++ ++ * perl-URPM.spec: 0.50-5mdk ++ ++2002-07-25 07:08 Fançois Pons ++ ++ * URPM/Build.pm: fixed typo (stupid). ++ ++2002-07-24 12:36 Fançois Pons ++ ++ * URPM.xs, URPM/Build.pm, URPM/Resolve.pm, perl-URPM.spec: ++ 0.50-4mdk ++ ++2002-07-24 09:18 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.50-3mdk ++ ++2002-07-23 15:14 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.50-2mdk ++ ++2002-07-23 13:17 Fançois Pons ++ ++ * URPM.pm, URPM/Resolve.pm, perl-URPM.spec: 0.50-1mdk ++ ++2002-07-23 11:59 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.20-2mdk ++ ++2002-07-22 17:53 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.20-1mdk ++ ++2002-07-22 08:35 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.11-2mdk ++ ++2002-07-19 08:50 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.11-1mdk ++ ++2002-07-16 18:07 Fançois Pons ++ ++ * URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.10-2mdk ++ ++2002-07-15 16:53 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.10-1mdk ++ ++2002-07-11 13:14 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.09-2mdk ++ ++2002-07-10 10:19 Fançois Pons ++ ++ * URPM.pm, URPM/Resolve.pm, perl-URPM.spec: 0.09-1mdk ++ ++2002-07-09 15:06 Fançois Pons ++ ++ * URPM.xs, URPM/Build.pm, perl-URPM.spec: 0.08-4mdk ++ ++2002-07-09 10:55 Pixel <pixel at mandriva.com> ++ ++ * perl-URPM.spec: adapt to perl 5.8.0 ++ ++2002-07-08 14:47 Fançois Pons ++ ++ * URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.08-2mdk ++ ++2002-07-08 09:55 Fançois Pons ++ ++ * URPM.pm, URPM.xs, perl-URPM.spec: 0.08-1mdk ++ ++2002-07-05 15:25 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.07-2mdk ++ ++2002-07-04 17:53 Fançois Pons ++ ++ * URPM.pm, URPM.xs, perl-URPM.spec, typemap: 0.07-1mdk ++ ++2002-07-03 16:11 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.06-2mdk ++ ++2002-07-03 12:40 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Build.pm, URPM/Resolve.pm, ++ perl-URPM.spec: 0.06-1mdk ++ ++2002-07-01 11:55 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.05-2mdk ++ ++2002-06-28 08:44 Fançois Pons ++ ++ * URPM.pm, URPM/Resolve.pm, perl-URPM.spec: 0.05-1mdk ++ ++2002-06-26 12:37 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.04-6mdk ++ ++2002-06-18 14:17 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.04-5mdk ++ ++2002-06-13 17:56 Fançois Pons ++ ++ * URPM/Resolve.pm, perl-URPM.spec: 0.04-4mdk ++ ++2002-06-13 16:16 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec: 0.04-3mdk ++ ++2002-06-13 15:19 Fançois Pons ++ ++ * URPM/Resolve.pm: added compute_installed_flags for yoyotte. ++ ++2002-06-13 10:48 Fançois Pons ++ ++ * perl-URPM.spec: 0.04-2mdk ++ ++2002-06-13 10:24 Fançois Pons ++ ++ * URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.04-1mdk ++ ++2002-06-11 18:02 Fançois Pons ++ ++ * MANIFEST: added missing entry Resolve.pm ++ ++2002-06-11 17:59 Fançois Pons ++ ++ * URPM.pm, URPM.xs, URPM/Resolve.pm, perl-URPM.spec: 0.04-1mdk ++ ++2002-06-06 15:44 Fançois Pons ++ ++ * URPM.pm, URPM.xs, perl-URPM.spec: 0.03-2mdk ++ ++2002-06-06 09:57 Fançois Pons ++ ++ * URPM.pm, URPM.xs, build_rpm, perl-URPM.spec: 0.03-1mdk ++ ++2002-06-05 16:44 Fançois Pons ++ ++ * URPM.xs, perl-URPM.spec, t/rpmdb.t: 0.02-3mdk ++ ++2002-06-05 08:03 Fançois Pons ++ ++ * URPM.xs, URPM/Build.pm, perl-URPM.spec: log on rpmdb open/close. ++ ++2002-06-03 11:00 Fançois Pons ++ ++ * URPM.pm, URPM/Build.pm, perl-URPM.spec: cleaned URPM::Build to ++ accept extended parameter list and -w clean. ++ 0.02. ++ ++2002-05-31 10:48 Fançois Pons ++ ++ * perl-URPM.spec: added Packager field. ++ ++2002-05-31 10:45 Fançois Pons ++ ++ * build_rpm, perl-URPM.spec: initial revision. ++ ++2002-05-31 10:21 Fançois Pons ++ ++ * MANIFEST, Makefile.PL, README, URPM, URPM.pm, URPM.xs, ++ URPM/Build.pm, t, t/rpmdb.t, t/synthesis.t, typemap: initial ++ revision. ++ ++2002-05-31 10:21 ++ ++ * soft/rpm/perl-URPM/branches, soft/rpm/perl-URPM/tags, .: New ++ repository initialized by cvs2svn. ++ + +Added: rpm/perl-URPM/trunk/MANIFEST +=================================================================== +--- rpm/perl-URPM/trunk/MANIFEST (rev 0) ++++ rpm/perl-URPM/trunk/MANIFEST 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,22 @@ ++README ++MANIFEST ++Makefile.PL ++typemap ++URPM.xs ++URPM.pm ++URPM/Build.pm ++URPM/Query.pm ++URPM/Resolve.pm ++URPM/Signature.pm ++t/00prepare.t ++t/buggy_synthesis.cz ++t/empty_synthesis.cz ++t/fatal.t ++t/parse.t ++t/pod.t ++t/rpmdb.t ++t/sort_graph.t ++t/synthesis.t ++t/test-rpm.spec ++ChangeLog ++META.yml Module meta-data (added by MakeMaker) + +Added: rpm/perl-URPM/trunk/META.yml +=================================================================== +--- rpm/perl-URPM/trunk/META.yml (rev 0) ++++ rpm/perl-URPM/trunk/META.yml 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,11 @@ ++# <A HREF="http://module-build.sourceforge.net/META-spec.html">http://module-build.sourceforge.net/META-spec.html</A> ++#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# ++name: URPM ++version: 1.43 ++version_from: URPM.pm ++installdirs: site ++requires: ++ MDV::Packdrakeng: 1.00 ++ ++distribution_type: module ++generated_by: ExtUtils::MakeMaker version 6.30_01 + +Added: rpm/perl-URPM/trunk/Makefile.PL +=================================================================== +--- rpm/perl-URPM/trunk/Makefile.PL (rev 0) ++++ rpm/perl-URPM/trunk/Makefile.PL 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,74 @@ ++use strict; ++use ExtUtils::MakeMaker; ++ ++# where to find the rpm utility ++ ++my $rpm_path = $ENV{RPM_PATH}; # this overrides ++ ++unless (defined $rpm_path) { ++ for (qw(/bin/rpm /usr/bin/rpm)) { ++ if (-x) { ++ $rpm_path = $_; ++ last; ++ } ++ } ++} ++ ++defined $rpm_path or die "Can't find rpm on this system\n"; ++ ++sub hexversion { ++ my ($major, $minor, $micro) = (@_[0] =~ /(\d+)\.(\d+)\.?(\d+)?/); ++ return int($major<<16) + int($minor<<8) + int($micro<<0) ++} ++ ++my $version = `LC_ALL=C $rpm_path --version`; ++# fix compiling with RCs: ++$version =~ s/(-.*)|(\.DEVEL)//; ++chomp $version; ++$version =~ s/(RPM version )|(rpm \(RPM\) )//; ++my $hversion = hexversion($version); ++$hversion ge hexversion("4.2") or die "Unable to build URPM with too old (or undetected) rpm version $version\n"; ++ ++# to generate the ChangeLog depending on the checkout layout ++my $commonusername = "../common/"; ++-d $commonusername or do { ++ $commonusername = "../../common/"; ++ -d $commonusername or do { ++ $commonusername = "../../../common/"; ++ -d $commonusername or $commonusername = ""; ++ }; ++}; ++ ++sub MY::postamble { ++ <<"**MM**"; ++.PHONY: ChangeLog ++ ++ChangeLog: ++ LC_ALL=C svn2cl --accum --strip-prefix=soft/rpm/perl-URPM/trunk --authors ${commonusername}username.xml ++ rm -f *.bak ++**MM** ++} ++ ++my @rpmflags; ++my $ldflags = `pkg-config --libs rpm`; ++if ($hversion ge hexversion("4.4.90") && $hversion lt hexversion("5.0")) { ++ # rpm.org version ++ push @rpmflags, "-DRPM_ORG"; ++ $ldflags .= ' -lrpmbuild'; ++} ++my $ccflags = join(' ', '-Wall -Wextra -fno-strict-aliasing', @rpmflags); ++ ++print "Found RPM version $version (compiling with flags: $ccflags)\n"; ++ ++WriteMakefile( ++ NAME => 'URPM', ++ PREREQ_PM => { ++ 'MDV::Packdrakeng' => '1.00', ++ }, ++ CCFLAGS => $ccflags, ++ VERSION_FROM => 'URPM.pm', ++ LIBS => [ $ldflags ], ++ INC => '-I/usr/include/rpm', ++ dist => { COMPRESS => "bzip2", SUFFIX => ".bz2" }, ++ realclean => { FILES => "t/RPMS/noarch/*" }, ++); + +Added: rpm/perl-URPM/trunk/NEWS +=================================================================== +--- rpm/perl-URPM/trunk/NEWS (rev 0) ++++ rpm/perl-URPM/trunk/NEWS 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,426 @@ ++Version 3.38 - 16 November 2010 ++ ++- fix the key parsing to handle PEM encapsulated header portion (bug ++#61636) ++ ++Version 3.37 - 20 September 2010 ++ ++- fix crashing on undefined packages (#54521) ++ ++Version 3.36 - 23 July 2010 ++ ++- Fix wrong deferencement on HASH (warning triggered by perl 5.12) ++ ++Version 3.35 - 23 April 2010 ++ ++- when using auto-select, honour search-medias if some were specified ++ ++Version 3.34.1 - 23 March 2010 ++ ++- check selected packages for unsatisfied requires when a promoted package is ++ backtracked and no replacement is found (#57224, Anssi Hannula) ++ ++Version 3.34 - 24 February 2010 ++ ++- check for conflicting selected packages before selecting a package (#57224) ++ (by Anssi Hannula) ++ ++Version 3.33 - 5 October 2009, by Christophe Fergeau ++ ++- fix lookup of existing pubkeys (#53710) (by Pascal Terjan) ++ ++Version 3.32 - 10 August 2009, by Christophe Fergeau ++ ++- backtrack_selected: use set_rejected_and_compute_diff_provides for package ++ removal (Anssi Hannula) ++- obey options (keep, nodeps) when unselecting current package in the case ++ that was added in 3.31 (Anssi Hannula) ++ ++Version 3.31 - 28 July 2009, by Christophe Fergeau ++ ++- add support for querying %disttag & %distepoch (by Per Øyvind Karlsen) ++- clean up and bring back rpm5.org support (by Per Øyvind Karlsen) ++- keep track of sources for obsoleted/removed levels (#50666) Anssi Hannula) ++- keep psel/promote info and remove deadlocked pkg instead of aborting upgrade ++ (#52105, Anssi Hannula) ++- _handle_conflicts: check all provides for conflicts, not just package name ++ (#52135, Anssi Hannula) ++- unselect current package if an avoided package is already selected (#52145, ++ Anssi Hannula) ++- do not try to promote to an older package (#52460, Anssi Hannula) ++- add a backtrack entry "conflicts" for avoided packages in backtrack_selected ++ (#52153, Anssi Hannula) ++ ++Version 3.30 - 11 May 2009, by Christophe Fergeau ++ ++- rework public key handling since librpm behaviour has changed. It's no longer ++ possible to tell it to add the same key multiple times which was causing ++ weird "unable to import pubkey" messages when a mirror contains different ++ pubkeys for the same key, fixes #50383 ++ ++Version 3.29 - 27 March 2009, by Christophe Fergeau ++ ++- fix regression introduced by fix for bug #47803 (fix by Anssi Hannula). ++ Without this patch, urpmi got stuck in an infinite loop when trying ++ to upgrade from 2008.1. ++ ++Version 3.28 - 25 March 2009, by Christophe Fergeau ++ ++- postpone user choices as much as possible to avoid asking the user ++ unnecessary questions, (bug #48100, Anssi Hannula) ++ ++Version 3.27 - 24 March 2009, by Christophe Fergeau ++ ++- don't silently install suggests (bug #47934) ++- fix _handle_diff_provides in case of impossible-to-satisfy selected ++ packages (bug #48223, Anssi Hannula) ++- check rep for another pkg providing X if the prev pkg gets removed ++ due to a conflict (bug #47803, Anssi Hannula) ++ ++Version 3.26 - 5 March 2009, by Thierry Vignaud ++ ++- verify_signature: enable to check signatures against a chrooted rpmdb ++ (especially important for installer where there's no rpmdb in / and thus no ++ keys to check against) ++ ++Version 3.25 - 16 January 2009, by Christophe Fergeau ++ ++- previous fix for bug #46874 was bogus, really fix it this time ++ ++Version 3.24 - 13 January 2009, by Christophe Fergeau ++ ++- fix sorting choices on provided version (feature introduced in 3.08, ++ but was not working if packages were coming from different repository) ++- when a "Requires:" can be fullfilled by several different packages and ++ one of those packages is explicitly required by another package which ++ is also being installed, silently choose this package instead of letting ++ the choice up to perl-URPM user (fixes bug #46874) ++ ++Version 3.23 - 12 December 2008, by Pascal "Pixel" Rigaux ++ ++- fix bad free() (thanks to glibc for detecting it) ++ ++Version 3.22 - 12 December 2008, by Pascal "Pixel" Rigaux ++ ++- fix scriptlet failing: ++ adapt to librpm4.6, rpmtsSetRootDir(ts, "") is forbidden ++ ++Version 3.21 - 9 December 2008, by Pascal "Pixel" Rigaux ++ ++- adapt to librpm4.6 ++- drop list_rpm_tag() ++ ++Version 3.20 - 14 October 2008, by Pascal "Pixel" Rigaux ++ ++- $trans->run can now return both the translated errors, and some parsable ++ errors (useful for example to detect diskspace issues) ++ ++Version 3.19 - 7 October 2008, by Pascal "Pixel" Rigaux ++ ++- handle flag "replacefiles" ++ ++Version 3.18 - 7 July 2008, by Pascal "Pixel" Rigaux ++ ++- revert change introduced in 3.16 (it breaks too much, eg ++ superuser--priority-upgrade.t test case), and introduce ++ $state->{rejected_already_installed} instead ++ ++Version 3.17 - 4 July 2008, by Pascal "Pixel" Rigaux ++ ++- add traverse_tag_find(), removed_or_obsoleted_packages() ++- handle $state->{orphans_to_remove} in selected_size() and ++ build_transaction_set() ++ ++Version 3.16 - 26 June 2008, by Pascal "Pixel" Rigaux ++ ++- when not selecting a package because already installed, ++ put it in $state->{rejected} with flags {installed} ++ ++Version 3.15 - 23 June 2008, by Pascal "Pixel" Rigaux ++ ++- fix urpmi wrongly considering epochless conflicts to match any epoch in a ++ case when urpmi should upgrade a conflicting package to an actually ++ non-conflicting version (cf epochless-conflict-with-promotion urpmi test) ++ (Anssi) ++ ++Version 3.14 - 23 May 2008, by Pascal "Pixel" Rigaux ++ ++- add is_package_installed() in URPM/Resolve.pm ++ (to be used in urpmi 5.20) ++ ++Version 3.13 - 20 May 2008, by Pascal "Pixel" Rigaux ++ ++- do not ignore dropped provide from updated package (mdvbz#40842) ++ ++Version 3.12 - 7 March 2008, by Pascal "Pixel" Rigaux ++ ++- do allow to promoting a pkg even if it has unsatisfied require (since the ++ code will then fix the unsatisfied require). fixes "big transaction" ++ (cf urpmi split-transactions--strict-require.t test_efgh()) ++- rpm5.org port done (by Per Øyvind Karlsen) ++ ++Version 3.11 - 26 February 2008, by Pascal "Pixel" Rigaux ++ ++- restore FILENAME_TAG in generated hdlist (to be compatible with older ++ distros where ->filename can rely on it) (thanks to Nanar) ++ ++Version 3.10 - 26 February 2008, by Pascal "Pixel" Rigaux ++ ++- add filesize to synthesis, add ->filesize to get it, and add ++ selected_size_filesize() to compute the sum ++- allow urpmi to know a package was not selected because a newer version is ++ installed (#29838) ++- handle new package providing xxx which conflicts with an installed package (#17106) ++- fix sort choices changed in perl-URPM 3.08 ++- allow fixing "using one big transaction" that occurs when using --keep ++ (#30198) ++- do not add FILENAME_TAG and FILESIZE_TAG to hdlist anymore, ++ deprecate ->header_filename, ++ deprecate URPM::Build::parse_rpms_build_headers ++ ++Version 3.08 - 25 February 2008, by Pascal "Pixel" Rigaux ++ ++- sort choices on virtual package by provided version (#12645) ++ ++Version 3.07 - 11 January 2008, by Pascal "Pixel" Rigaux ++ ++- add URPM::Package->changelogs, a wrapper around ->changelog_time, ->changelog_name, ->changelog_text ++- resolve kmod requires even if first choice is a source dkms ++ ++Version 3.05 - 8 January 2008, by Pascal "Pixel" Rigaux ++ ++- fix regression in ->parse_rpm (introduced in 3.00) ++ (was breaking genhdlist2 and mkcd) ++ ++Version 3.04 - 20 December 2007, by Pascal "Pixel" Rigaux ++ ++- fix regression in parse_pubkeys() (introduced in 3.00) (#36121) ++ ++Version 3.03 - 14 December 2007, by Pascal "Pixel" Rigaux ++ ++- suggests: ++ handle both RPMTAG_SUGGESTSNAME (as done in SuSE and in Mandriva > 2008.0) ++ and RPMTAG_REQUIRENAME + RPMSENSE_MISSINGOK (as done in Mandriva 2008.0) ++ ++Version 3.02 - 14 December 2007, by Pascal "Pixel" Rigaux ++ ++- fix "make test" on rpm 4.4.2.2 ++- fix rpm 4.5 support ++ ++Version 3.01 - 11 December 2007, by Pascal "Pixel" Rigaux ++ ++- add URPM::DB::verify() ++ ++Version 3.00 - 11 December 2007, by Pascal "Pixel" Rigaux ++ ++- replace ->import_needed_pubkeys and ->import_pubkey in favor of ++ import_needed_pubkeys_from_file() and ->import_pubkey_file ++ (! this breaks API !) ++- drop $package->upgrade_files() (unused for a long time afaik) ++- rpm.org HEAD support ++ ++Version 2.10 - 22 November 2007, by Pascal "Pixel" Rigaux ++ ++- much simpler --auto-select algorithm ++ (fixes #35718, ie auto-selecting with strict-arch) ++ (!! DANGEROUS CHANGE !!) ++- rpm 4.5 support (thanks to peroyvind) (#35323) ++ ++Version 2.09 - 8 November 2007, by Pascal "Pixel" Rigaux ++ ++- use a simple function to return simple string list from header ++ (fixes getting >4096 long rpm changelogs) ++ (!! static buffer size limitation in callback_list_str_xpush() should be fixed !!) ++ ++Version 2.08 - 24 October 2007, by Pascal "Pixel" Rigaux ++ ++- fix build on rpm 4.4.2.2 ++ ++Version 2.07 - 1 October 2007, by Pascal "Pixel" Rigaux ++ ++- prefer precompiled kmod packages corresponding to installed kernels ++- don't resolve suggested virtual packages if already installed (#34376) ++ ++Version 2.06 - 28 September 2007, by Pascal "Pixel" Rigaux ++ ++- also handle promotion via obsolete for conflicts ++ ++Version 2.05 - 28 September 2007, by Pascal "Pixel" Rigaux ++ ++- package promotion must respect strict_arch ++- enhance sorted graph by better taking into account conflicts from state->{rejected} ++ (fixes "big transaction" in urpmi split-transactions--strict-require.t test) ++ ++Version 2.04 - 27 September 2007, by Pascal "Pixel" Rigaux ++ ++- handle promotion via obsolete, not only provides ++ ++Version 2.03 - 20 September 2007, by Pascal "Pixel" Rigaux ++ ++- fix bug doing "urpmi kernel-source" ++ ++Version 2.02 - 18 September 2007, by Pascal "Pixel" Rigaux ++ ++- prefer every kernel-<flavor>-devel-<version> packages for which ++ kernel-<flavor>-<version> is selected ++- fix regression in 2.00: we can't cache the platform, cache the result of ++ is_arch_compat instead ++ ++Version 2.01 - 14 September 2007, by Pascal "Pixel" Rigaux ++ ++- fix bug occurring with --keep ++- fix regression in 2.00: keep_unrequested_dependencies is still used by ++ installer. restore it, but must now be set trough ++ $urpm->{keep_unrequested_dependencies} ++ ++Version 2.00 - 13 September 2007, by Pascal "Pixel" Rigaux ++ ++- speedup is_arch_compat (7 times faster) by keeping the platform in a cache ++- do not propose packages for non installed locales ++- pass the prefered choices to {callback_choices}: this allows urpmi to select ++ all the prefered packages according to installed locales ++- handle promote for conflict from installed package ++ (fixes test_gh() from urpmi split-transactions--promote test case) ++- handle promote from installed package which require a unselected package, ++ whereas new package does not require it anymore ++ (cf test_d & test_e from split-transactions--conflict urpmi test case) ++ ++Version 1.80 - 3 September 2007, by Pascal "Pixel" Rigaux ++ ++- fix bug in sort_graph (used by build_transaction_set) ++ ++Version 1.78 - 31 August 2007, by Pascal "Pixel" Rigaux ++ ++- fix dead-loop in build_transaction_set (#33020) ++ ++Version 1.77 - 29 August 2007, by Pascal "Pixel" Rigaux ++ ++- disable "dropping tags from rpm header" until we can safely use it ++ ++Version 1.76 - 28 August 2007, by Pascal "Pixel" Rigaux ++ ++- build_transaction_set: new sort algorithm which allow returning sets of ++ circular dependent packages, taking into account obsoleted packages ++ (fixes #31969). It may still fail in presence of conflicts ++- allow running transaction with justdb option ++- fix split_length > 1 ++ (eg: "urpmi --split-length 2 a b c" will only install 2 pkgs) ++- spec2srcheader: workaround parseSpec returning a header where ->arch is set ++ to %{_target_cpu} whereas we really want a header similar to .src.rpm ++ (see #32824) ++ ++Version 1.75 - 12 August 2007, by Pascal "Pixel" Rigaux ++ ++- fix dropping tags from rpm header. ++ it hasn't work since MDK8.1 and rpm 4.0. ++ it may break urpmi!! but potentially allows a much smaller hdlist.cz :) ++ ++Version 1.74 - 12 August 2007, by Pascal "Pixel" Rigaux ++ ++- sort choices per media, then per version ++ ++Version 1.73 - 11 August 2007, by Pascal "Pixel" Rigaux ++ ++- allow running transaction with replagekgs option ++ ++Version 1.72 - 10 August 2007, by Pascal "Pixel" Rigaux ++ ++- modify parse_hdlist so that partial hdlist reading can be used ++ (needed when some stuff is already done in the callback) ++ ++Version 1.71 - 9 August 2007, by Pascal "Pixel" Rigaux ++ ++- compilation fixes on rpm < 4.4.8 ++ ++Version 1.69 - 9 August 2007, by Pascal "Pixel" Rigaux ++ ++- "suggests" are no more handled as "requires" ++- resolve_requested support "suggests": a newly suggested package is installed ++ as if required (can be disabled with option no_suggests) ++ ++Version 1.68 - 3 August 2007, by Pascal "Pixel" Rigaux ++ ++- add $trans->Element_version and $trans->Element_release ++ ++Version 1.67 - 22 June 2007, by Olivier "Nanar" Thauvin ++ ++- add osscore, archscore and platformscore function to URPM ++- is_platform_compat function to Pkg object ++- fix call to rpm function in spec2header() ++- fix some compilation warnings ++ ++Version 1.66 - 2 July 2007, by Pascal "Pixel" Rigaux ++ ++- fix --auto-select skipping some packages because of other packages providing ++ a more recent version, but no obsolete between those packages. ++ the fix is to revert commit from Aug 2002: ++ "fixed propable old package (according provides) requested by ++ request_packages_to_upgrade." ++ ++Version 1.65 - 22 June 2007, by Olivier Thauvin ++ ++- really fix arch_score evaluation ++ ++Version 1.64 - 12 June 2007, by Pascal "Pixel" Rigaux ++ ++- hack on $pkg->is_arch_compat to make it return true for noarch packages ++ when using rpm 4.4.8 (#31314) ++ ++Version 1.63 - 9 May 2007, by Pascal "Pixel" Rigaux ++ ++- add $trans->Element_fullname ++ ++Version 1.62 - 3 May 2007, by Pascal "Pixel" Rigaux ++ ++- pass the virtual package name as a parameter to {callback_choices} in ++ ->resolve_requested ++- add $trans->NElements and $trans->Element_name ++ to be able to display name of uninstalled package in callback_uninst ++- fix b--obsoletes-->a and c--conflicts-->a prompting for upgrading a ++ (need a fix in urpmi which rely on the $state->{rejected} ++ to upgrade (-U) b instead of installing (-i) it) ++ ++Version 1.60 - 8 March 2007, by Pascal "Pixel" Rigaux ++ ++- more debugging hooks ++- create $urpm->packages_providing($name) and use it ++- create $urpm->packages_by_name($name) ++ ++Version 1.59 - 1 March 2007, by Olivier Thauvin ++ ++- rpm 4.4.8 adaptions ++- load rpm config files at module load, improve the mechanism ++ ++Version 1.58 - 14 February 2007, by Pascal "Pixel" Rigaux ++ ++- don't check signature and digest in ->traverse and ->traverse_tag ++ (=> x15 speedup, ie 2.5 speedup on urpmi --auto-select and rpmdrake) ++ ++Version 1.57 - 9 February 2007, by Pascal "Pixel" Rigaux ++ ++- allow upgrading from noarch to x86_64 even if strict-arch ++ ++Version 1.56 - 19 January 2007, by Pascal "Pixel" Rigaux ++ ++- tell perl that strings from rpm headers are utf8 ++- add URPM::bind_rpm_textdomain_codeset() to set encoding of messages returned ++ by rpmlib, and tell perl that those strings are utf8 ++- really use strict-arch by default on x86_64 ++ ++Version 1.55 - 10 January 2007, by Pascal "Pixel" Rigaux ++ ++- bug fix release ++- fix "not selecting foo-1 since the more recent foo-1 is installed" causing ++ urpmi to try to remove the package it wants to install (#28076) ++ ++Version 1.54 - 9 January 2007, by Pascal "Pixel" Rigaux ++ ++- if we have a choice between foo-1 and bar-1 and foo-2 is installed, ++ prefering bar-1 instead of foo-1 ++ (otherwise we can hit: "the more recent foo-2 is installed, but does not ++ provide xxx whereas foo-1 does", cf bug #27991) ++- bar is needed, foo-1 does provide bar, installed foo-2 does not provide bar: ++ do not let the algorithm use foo-2 as if it also provides bar ++- allow understanding what ->resolve_requested is doing through a callback ($urpm->{debug_URPM}) ++- cleanup some code in ->resolve_requested ++- make the documentation for ->is_arch_compat more clear + +Added: rpm/perl-URPM/trunk/README +=================================================================== +--- rpm/perl-URPM/trunk/README (rev 0) ++++ rpm/perl-URPM/trunk/README 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,7 @@ ++The URPM module allows you to manipulate rpm files, rpm header files and ++hdlist files and manage them in memory. ++ ++Copyright 2002-2007 Mandrakesoft ++ ++This library is free software; you can redistribute it and/or ++modify it under the same terms as Perl itself. + +Added: rpm/perl-URPM/trunk/URPM/.perl_checker +=================================================================== +--- rpm/perl-URPM/trunk/URPM/.perl_checker (rev 0) ++++ rpm/perl-URPM/trunk/URPM/.perl_checker 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1 @@ ++Basedir .. + +Added: rpm/perl-URPM/trunk/URPM/Build.pm +=================================================================== +--- rpm/perl-URPM/trunk/URPM/Build.pm (rev 0) ++++ rpm/perl-URPM/trunk/URPM/Build.pm 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,528 @@ ++package URPM; ++ ++# $Id: Build.pm 270395 2010-07-30 00:55:59Z nanardon $ ++ ++use strict; ++use warnings; ++ ++sub _get_tmp_dir () { ++ my $t = $ENV{TMPDIR}; ++ $t && -w $t or $t = '/tmp'; ++ "$t/.build_hdlist"; ++} ++ ++# DEPRECATED. ONLY USED BY MKCD ++# ++#- prepare build of an hdlist from a list of files. ++#- it can be used to start computing depslist. ++#- parameters are : ++#- rpms : array of all rpm file name to parse (mandatory) ++#- dir : directory which will contain headers (defaults to /tmp/.build_hdlist) ++#- callback : perl code to be called for each package read (defaults pack_header) ++#- clean : bool to clean cache before (default no). ++#- packing : bool to create info (default is weird) ++# ++# deprecated ++sub parse_rpms_build_headers { ++ my ($urpm, %options) = @_; ++ my ($dir, %cache, @headers); ++ ++ #- check for mandatory options. ++ if (@{$options{rpms} || []} > 0) { ++ #- build a working directory which will hold rpm headers. ++ $dir = $options{dir} || _get_tmp_dir(); ++ $options{clean} and system($ENV{LD_LOADER} ? $ENV{LD_LOADER} : @{[]}, "rm", "-rf", $dir); ++ -d $dir or mkdir $dir, 0755 or die "cannot create directory $dir\n"; ++ ++ #- examine cache if it contains any headers which will be much faster to read ++ #- than parsing rpm file directly. ++ unless ($options{clean}) { ++ my $dirh; ++ opendir $dirh, $dir; ++ while (defined (my $file = readdir $dirh)) { ++ my ($fullname, $filename) = $file =~ /(.+?-[^:\-]+-[^:\-]+\.[^:\-\.]+)(?::(\S+))?$/ or next; ++ my @stat = stat "$dir/$file"; ++ $cache{$filename || $fullname} = { ++ file => $file, ++ size => $stat[7], ++ 'time' => $stat[9], ++ }; ++ } ++ closedir $dirh; ++ } ++ ++ foreach (@{$options{rpms}}) { ++ my ($key) = m!([^/]*)\.rpm$! or next; #- get rpm filename. ++ my ($id, $filename); ++ ++ if ($cache{$key} && $cache{$key}{time} > 0 && $cache{$key}{time} >= (stat $_)[9]) { ++ ($id, undef) = $urpm->parse_hdlist("$dir/$cache{$key}{file}", packing => $options{packing}, keep_all_tags => $options{keep_all_tags}); ++ unless (defined $id) { ++ if ($options{dontdie}) { ++ print STDERR "bad header $dir/$cache{$key}{file}\n"; ++ next; ++ } else { ++ die "bad header $dir/$cache{$key}{file}\n"; ++ } ++ } ++ ++ $options{callback} and $options{callback}->($urpm, $id, %options, (file => $_)); ++ ++ $filename = $cache{$key}{file}; ++ } else { ++ ($id, undef) = $urpm->parse_rpm($_, keep_all_tags => $options{keep_all_tags}); ++ unless (defined $id) { ++ if ($options{dontdie}) { ++ print STDERR "bad rpm $_\n"; ++ next; ++ } else { ++ die "bad rpm $_\n"; ++ } ++ } ++ ++ my $pkg = $urpm->{depslist}[$id]; ++ ++ $filename = $pkg->fullname; ++ ++ unless (-s "$dir/$filename") { ++ open my $fh, ">$dir/$filename" or die "unable to open $dir/$filename for writing\n"; ++ $pkg->build_header(fileno $fh); ++ close $fh; ++ } ++ -s "$dir/$filename" or unlink("$dir/$filename"), die "can create header $dir/$filename\n"; ++ ++ #- make smart use of memory (no need to keep header in memory now). ++ if ($options{callback}) { ++ $options{callback}->($urpm, $id, %options, (file => $_)); ++ } else { ++ $pkg->pack_header; ++ } ++ ++ # Olivier Thauvin <<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">thauvin at aerov.jussieu.fr</A>> ++ # isn't this code better, but maybe it will break some tools: ++ # $options{callback}->($urpm, $id, %options, (file => $_)) if ($options{callback}); ++ # $pkg->pack_header; ++ } ++ ++ #- keep track of header associated (to avoid rereading rpm filename directly ++ #- if rereading has been made neccessary). ++ push @headers, $filename; ++ } ++ } ++ @headers; ++} ++ ++# DEPRECATED. ONLY USED BY MKCD ++# ++#- allow rereading of hdlist and clean. ++sub unresolved_provides_clean { ++ my ($urpm) = @_; ++ $urpm->{depslist} = []; ++ $urpm->{provides}{$_} = undef foreach keys %{$urpm->{provides} || {}}; ++} ++ ++# DEPRECATED. ONLY USED BY MKCD ++# ++#- read a list of headers (typically when building an hdlist when provides have ++#- been cleaned). ++#- parameters are : ++#- headers : array containing all headers filenames to parse (mandatory) ++#- dir : directory which contains headers (defaults to /tmp/.build_hdlist) ++#- callback : perl code to be called for each package read (defaults to pack_header) ++sub parse_headers { ++ my ($urpm, %options) = @_; ++ my ($dir, $start, $id); ++ ++ $dir = $options{dir} || _get_tmp_dir(); ++ -d $dir or die "no directory $dir\n"; ++ ++ $start = @{$urpm->{depslist} || []}; ++ foreach (@{$options{headers} || []}) { ++ #- make smart use of memory (no need to keep header in memory now). ++ ($id, undef) = $urpm->parse_hdlist("$dir/$_", packing => !$options{callback}); ++ defined $id or die "bad header $dir/$_\n"; ++ $options{callback} and $options{callback}->($urpm, $id, %options); ++ } ++ defined $id ? ($start, $id) : @{[]}; ++} ++ ++# DEPRECATED. ONLY USED BY MKCD ++#- compute dependencies, result in stored in info values of urpm. ++#- operations are incremental, it is possible to read just one hdlist, compute ++#- dependencies and read another hdlist, and again. ++#- parameters are : ++#- callback : callback to relocate reference to package id. ++sub compute_deps { ++ my ($urpm, %options) = @_; ++ my %propagated_weight = ( ++ basesystem => 10000, ++ msec => 20000, ++ filesystem => 50000, ++ ); ++ my ($locales_weight, $step_weight, $fixed_weight) = (-5000, 10000, $propagated_weight{basesystem}); ++ ++ #- avoid recomputing already present infos, take care not to modify ++ #- existing entries, as the array here is used instead of values of infos. ++ my $start = @{$urpm->{deps} ||= []}; ++ my $end = $#{$urpm->{depslist} || []}; ++ ++ #- check if something has to be done. ++ $start > $end and return; ++ ++ #- keep track of prereqs. ++ my %prereqs; ++ ++ #- take into account in which hdlist a package has been found. ++ #- this can be done by an incremental take into account generation ++ #- of depslist.ordered part corresponding to the hdlist. ++ #- compute closed requires, do not take into account choices. ++ foreach ($start .. $end) { ++ my $pkg = $urpm->{depslist}[$_]; ++ ++ my %required_packages; ++ my @required_packages; ++ my %requires; ++ ++ foreach ($pkg->requires) { ++ my ($n, $prereq) = /^([^\s\[]*)(\[\*\])?/; ++ $requires{$n} = $prereq && 1; ++ } ++ my @requires = keys %requires; ++ ++ while (my $req = shift @requires) { ++ $req =~ /^basesystem/ and next; #- never need to requires basesystem directly as always required! what a speed up! ++ my $treq = ( ++ $req =~ /^\d+$/ ? [ $req ] ++ : $urpm->{provides}{$req} ? [ keys %{$urpm->{provides}{$req}} ] ++ : [ ($req !~ /NOTFOUND_/ ? "NOTFOUND_" : "") . $req ] ++ ); ++ if (@$treq > 1) { ++ #- this is a choice, no closure need to be done here. ++ push @required_packages, $treq; ++ } else { ++ #- this could be nothing if the provides is a file not found. ++ #- and this has been fixed above. ++ foreach (@$treq) { ++ my $pkg_ = /^\d+$/ && $urpm->{depslist}[$_]; ++ exists $required_packages{$_} and $pkg_ = undef; ++ $required_packages{$_} ||= $requires{$req}; $pkg_ or next; ++ foreach ($pkg_->requires_nosense) { ++ exists $requires{$_} or push @requires, $_; ++ $requires{$_} ||= $requires{$req}; ++ } ++ } ++ } ++ } ++ #- examine choice to remove those which are not mandatory. ++ foreach (@required_packages) { ++ unless (grep { exists $required_packages{$_} } @$_) { ++ $required_packages{join '|', sort { $a <=> $b } @$_} = undef; ++ } ++ } ++ ++ #- store a short representation of requires. ++ $urpm->{requires}[$_] = join ' ', keys %required_packages; ++ foreach my $d (keys %required_packages) { ++ $required_packages{$d} or next; ++ $prereqs{$d}{$_} = undef; ++ } ++ } ++ ++ #- expand choices and closure again. ++ my %ordered; ++ foreach ($start .. $end) { ++ my @requires = $_; ++ my ($dep, %requires); ++ while (defined ($dep = shift @requires)) { ++ exists $requires{$dep} || /^[^\d\|]*$/ and next; ++ foreach ($dep, split ' ', (defined $urpm->{deps}[$dep] ? $urpm->{deps}[$dep] : $urpm->{requires}[$dep])) { ++ if (/\|/) { ++ push @requires, split /\|/, $_; ++ } else { ++ /^\d+$/ and $requires{$_} = undef; ++ } ++ } ++ } ++ ++ my $pkg = $urpm->{depslist}[$_]; ++ my $delta = 1 + $propagated_weight{$pkg->name}; ++ foreach (keys %requires) { ++ $ordered{$_} += $delta; ++ } ++ } ++ ++ #- some package should be sorted at the beginning. ++ foreach (qw(basesystem msec rpm locales filesystem setup glibc sash bash libtermcap2 termcap readline ldconfig)) { ++ foreach (keys %{$urpm->{provides}{$_} || {}}) { ++ /^\d+$/ and $ordered{$_} = $fixed_weight; ++ } ++ /locales/ and $locales_weight += $fixed_weight; ++ $fixed_weight += $step_weight; ++ } ++ foreach ($start .. $end) { ++ my $pkg = $urpm->{depslist}[$_]; ++ ++ $pkg->name =~ /locales-[a-zA-Z]/ and $ordered{$_} = $locales_weight; ++ } ++ ++ #- compute base flag, consists of packages which are required without ++ #- choices of basesystem and are ALWAYS installed. these packages can ++ #- safely be removed from requires of others packages. ++ foreach (qw(basesystem glibc kernel)) { ++ foreach (keys %{$urpm->{provides}{$_} || {}}) { ++ foreach ($_, split ' ', (defined $urpm->{deps}[$_] ? $urpm->{deps}[$_] : $urpm->{requires}[$_])) { ++ /^\d+$/ and $urpm->{depslist}[$_] and $urpm->{depslist}[$_]->set_flag_base(1); ++ } ++ } ++ } ++ ++ #- give an id to each packages, start from number of package already ++ #- registered in depslist. ++ my %remap_ids; @remap_ids{sort { ++ exists $prereqs{$b}{$a} && ! exists $prereqs{$a}{$b} ? 1 : ++ $ordered{$b} <=> $ordered{$a} or do { ++ my ($na, $nb) = map { $urpm->{depslist}[$_]->name } ($a, $b); ++ my ($sa, $sb) = map { /^lib(.*)/ ? $1 : '' } ($na, $nb); ++ $sa && $sb ? $sa cmp $sb : $sa ? -1 : $sb ? 1 : $na cmp $nb; ++ } } ($start .. $end)} = ($start .. $end); ++ ++ #- now it is possible to clean ordered and prereqs. ++ %ordered = %prereqs = (); ++ ++ #- recompute requires to use packages id, drop any base packages or ++ #- reference of a package to itself. ++ my @depslist; ++ foreach ($start .. $end) { ++ my $pkg = $urpm->{depslist}[$_]; ++ ++ #- set new id. ++ $pkg->set_id($remap_ids{$_}); ++ ++ my ($id, $base, %requires_id, %not_founds); ++ foreach (split ' ', $urpm->{requires}[$_]) { ++ if (/\|/) { ++ #- all choices are grouped together at the end of requires, ++ #- this allow computation of dropable choices. ++ my ($to_drop, @choices_base_id, @choices_id); ++ foreach (split /\|/, $_) { ++ my ($id, $base) = (exists($remap_ids{$_}) ? $remap_ids{$_} : $_, $urpm->{depslist}[$_]->flag_base); ++ $base and push @choices_base_id, $id; ++ $base &&= ! $pkg->flag_base; ++ $to_drop ||= $id == $pkg->id || exists $requires_id{$id} || $base; ++ push @choices_id, $id; ++ } ++ ++ #- package can safely be dropped as it will be selected in requires directly. ++ $to_drop and next; ++ ++ #- if a base package is in a list, keep it instead of the choice. ++ if (@choices_base_id) { ++ @choices_id = @choices_base_id; ++ $base = 1; ++ } ++ if (@choices_id == 1) { ++ $id = $choices_id[0]; ++ } else { ++ my $choices_key = join '|', sort { $a <=> $b } @choices_id; ++ $requires_id{$choices_key} = undef; ++ next; ++ } ++ } elsif (/^\d+$/) { ++ ($id, $base) = (exists($remap_ids{$_}) ? $remap_ids{$_} : $_, $urpm->{depslist}[$_]->flag_base); ++ } else { ++ $not_founds{$_} = undef; ++ next; ++ } ++ ++ #- select individual package from choices or defined package. ++ $base &&= ! $pkg->flag_base; ++ $base || $id == $pkg->id or $requires_id{$id} = undef; ++ } ++ #- be smart with memory usage. ++ delete $urpm->{requires}[$_]; ++ $urpm->{deps}[$remap_ids{$_}] = join ' ', ((sort { ($a =~ /^(\d+)/)[0] <=> ($b =~ /^(\d+)/)[0] } keys %requires_id), ++ keys %not_founds); ++ $depslist[$remap_ids{$_}-$start] = $pkg; ++ } ++ ++ #- remap all provides ids for new package position and update depslist. ++ delete $urpm->{requires}; ++ @{$urpm->{depslist}}[$start .. $end] = @depslist; ++ foreach my $h (values %{$urpm->{provides}}) { ++ my %provided; ++ foreach (keys %{$h || {}}) { ++ $provided{exists($remap_ids{$_}) ? $remap_ids{$_} : $_} = delete $h->{$_}; ++ } ++ $h = \%provided; ++ } ++ $options{callback} and $options{callback}->($urpm, \%remap_ids, %options); ++ ++ ($start, $end); ++} ++ ++# DEPRECATED. ONLY USED BY MKCD ++# ++#- build an hdlist from existing depslist, from start to end inclusive. ++#- parameters are : ++#- hdlist : hdlist file to use. ++#- dir : directory which contains headers (defaults to /tmp/.build_hdlist) ++#- start : index of first package (defaults to first index of depslist). ++#- end : index of last package (defaults to last index of depslist). ++#- idlist : id list of rpm to compute (defaults is start .. end) ++#- ratio : compression ratio (default 4). ++#- split : split ratio (default 400kb, see MDV::Packdrakeng). ++sub build_hdlist { ++ my ($urpm, %options) = @_; ++ my ($dir, $ratio, @idlist); ++ ++ $dir = $options{dir} || _get_tmp_dir(); ++ -d $dir or die "no directory $dir\n"; ++ ++ @idlist = $urpm->build_listid($options{start}, $options{end}, $options{idlist}); ++ ++ #- compression ratio are not very high, sample for cooker ++ #- gives the following (main only and cache fed up): ++ #- ratio compression_time size ++ #- 9 21.5 sec 8.10Mb -> good for installation CD ++ #- 6 10.7 sec 8.15Mb ++ #- 5 9.5 sec 8.20Mb ++ #- 4 8.6 sec 8.30Mb -> good for urpmi ++ #- 3 7.6 sec 8.60Mb ++ $ratio = $options{ratio} || 4; ++ ++ require MDV::Packdrakeng; ++ my $pack = MDV::Packdrakeng->new( ++ archive => $options{hdlist}, ++ compress => "gzip", ++ uncompress => "gzip -d", ++ block_size => $options{split}, ++ comp_level => $ratio, ++ ) or die "Can't create archive"; ++ foreach my $pkg (@{$urpm->{depslist}}[@idlist]) { ++ my $filename = $pkg->fullname; ++ -s "$dir/$filename" or die "bad header $dir/$filename\n"; ++ $pack->add($dir, $filename); ++ } ++} ++ ++#- build synthesis file. ++#- used by genhdlist2 and mkcd ++#- ++#- parameters are : ++#- synthesis : synthesis file to create (mandatory if fd not given). ++#- fd : file descriptor (mandatory if synthesis not given). ++#- start : index of first package (defaults to first index of depslist). ++#- end : index of last package (defaults to last index of depslist). ++#- idlist : id list of rpm to compute (defaults is start .. end) ++#- ratio : compression ratio (default 9). ++#- filter : program to filter through (default is 'gzip -$ratio'). ++#- returns true on success ++sub build_synthesis { ++ my ($urpm, %options) = @_; ++ my ($ratio, $filter, @idlist); ++ ++ @idlist = $urpm->build_listid($options{start}, $options{end}, $options{idlist}); ++ ++ $ratio = $options{ratio} || 9; ++ $filter = $options{filter} ? $options{filter} : "gzip -$ratio"; ++ $options{synthesis} || defined $options{fd} or die "invalid parameters given"; ++ ++ #- first pass: traverse provides to find files provided. ++ my %provided_files; ++ foreach (keys %{$urpm->{provides}}) { ++ m!^/! or next; ++ foreach my $id (keys %{$urpm->{provides}{$_} || {}}) { ++ push @{$provided_files{$id} ||= []}, $_; ++ } ++ } ++ ++ ++ #- second pass: write each info including files provided. ++ $options{synthesis} and open my $fh, "| " . ($ENV{LD_LOADER} || '') . " $filter >'$options{synthesis}'"; ++ foreach (@idlist) { ++ my $pkg = $urpm->{depslist}[$_]; ++ my %files; ++ ++ if ($provided_files{$_}) { ++ @files{@{$provided_files{$_}}} = undef; ++ delete @files{$pkg->provides_nosense}; ++ } ++ ++ $pkg->build_info($options{synthesis} ? fileno $fh : $options{fd}, join('@', keys %files)); ++ } ++ close $fh; # returns true on success ++} ++ ++# DEPRECATED. ONLY USED BY MKCD ++#- write depslist.ordered file according to info in params. ++#- parameters are : ++#- depslist : depslist.ordered file to create. ++#- provides : provides file to create. ++#- compss : compss file to create. ++sub build_base_files { ++ my ($urpm, %options) = @_; ++ ++ if ($options{depslist}) { ++ open my $fh, ">", $options{depslist} or die "Can't write to $options{depslist}: $!\n"; ++ foreach (0 .. $#{$urpm->{depslist}}) { ++ my $pkg = $urpm->{depslist}[$_]; ++ ++ printf $fh ("%s-%s-%s.%s%s %s %s\n", $pkg->fullname, ++ ($pkg->epoch ? ':' . $pkg->epoch : ''), $pkg->size || 0, $urpm->{deps}[$_]); ++ } ++ close $fh; ++ } ++ ++ if ($options{provides}) { ++ open my $fh, ">", $options{provides} or die "Can't write to $options{provides}: $!\n"; ++ while (my ($k, $v) = each %{$urpm->{provides}}) { ++ printf $fh "%s\n", join '@', $k, map { scalar $urpm->{depslist}[$_]->fullname } keys %{$v || {}}; ++ } ++ close $fh; ++ } ++ ++ if ($options{compss}) { ++ my %p; ++ ++ open my $fh, ">", $options{compss} or die "Can't write to $options{compss}: $!\n"; ++ foreach (@{$urpm->{depslist}}) { ++ $_->group or next; ++ push @{$p{$_->group} ||= []}, $_->name; ++ } ++ foreach (sort keys %p) { ++ print $fh $_, "\n"; ++ foreach (@{$p{$_}}) { ++ print $fh "\t", $_, "\n"; ++ } ++ print $fh "\n"; ++ } ++ close $fh; ++ } ++ ++ 1; ++} ++ ++our $MAKEDELTARPM = '/usr/bin/makedeltarpm'; ++ ++#- make_delta_rpm($old_rpm_file, $new_rpm_file) ++# Creates a delta rpm in the current directory. ++ ++# DEPRECATED. UNUSED ++sub make_delta_rpm ($$) { ++ @_ == 2 or return 0; ++ -e $_[0] && -e $_[1] && -x $MAKEDELTARPM or return 0; ++ my @id; ++ my $urpm = new URPM; ++ foreach my $i (0, 1) { ++ ($id[$i]) = $urpm->parse_rpm($_[$i]); ++ defined $id[$i] or return 0; ++ } ++ my $oldpkg = $urpm->{depslist}[$id[0]]; ++ my $newpkg = $urpm->{depslist}[$id[1]]; ++ $oldpkg->arch eq $newpkg->arch or return 0; ++ #- construct filename of the deltarpm ++ my $patchrpm = $oldpkg->name . '-' . $oldpkg->version . '-' . $oldpkg->release . '_' . $newpkg->version . '-' . $newpkg->release . '.' . $oldpkg->arch . '.delta.rpm'; ++ !system($MAKEDELTARPM, @_, $patchrpm); ++} ++ ++1; + +Added: rpm/perl-URPM/trunk/URPM/Query.pm +=================================================================== +--- rpm/perl-URPM/trunk/URPM/Query.pm (rev 0) ++++ rpm/perl-URPM/trunk/URPM/Query.pm 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,40 @@ ++package URPM; ++ ++use strict; ++use warnings; ++ ++# Olivier Thauvin <<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">thauvin at aerov.jussieu.fr</A>> ++# This package extend URPM functions to permit ++# URPM low level query on rpm header ++# $Id: Query.pm 270395 2010-07-30 00:55:59Z nanardon $ ++ ++# tag2id ++# INPUT array of rpm tag name ++# Return an array of ID tag ++ ++sub tag2id { ++ my @l = @_; ++ my %taglist = URPM::list_rpm_tag(); ++ map { $taglist{uc($_)} || undef } @l; ++} ++ ++sub query_pkg { ++ my (undef, $pkg, $query) = @_; ++ my @tags = map { ++ [ $pkg->get_tag(tag2id($_)) ] ++ } $query =~ m/\%\{([^{}]*)\}*/g; ++ ++ $query =~ s/\%\{[^{}]*\}/%s/g; ++ $query =~ s/\\n/\n/g; ++ $query =~ s/\\t/\t/g; ++ my ($max, @res) = 0; ++ ++ foreach (@tags) { $max < $#{$_} and $max = $#{$_} }; ++ ++ foreach my $i (0 .. $max) { ++ push(@res, sprintf($query, map { ${$_}[ $#{$_} < $i ? $#{$_} : $i ] } @tags)); ++ } ++ @res ++} ++ ++1; + +Added: rpm/perl-URPM/trunk/URPM/Resolve.pm +=================================================================== +--- rpm/perl-URPM/trunk/URPM/Resolve.pm (rev 0) ++++ rpm/perl-URPM/trunk/URPM/Resolve.pm 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,2003 @@ ++package URPM; ++#package URPM::Resolve; ++#use URPM; ++ ++# $Id: Resolve.pm 270395 2010-07-30 00:55:59Z nanardon $ ++ ++use strict; ++use warnings; ++use Config; ++ ++ ++#- a few functions from MDK::Common copied here: ++sub listlength { scalar @_ } ++sub min { my $n = shift; $_ < $n and $n = $_ foreach @_; $n } ++sub uniq { my %l; $l{$_} = 1 foreach @_; grep { delete $l{$_} } @_ } ++sub find(&@) { ++ my $f = shift; ++ $f->($_) and return $_ foreach @_; ++ undef; ++} ++ ++#- property2name* functions below parse things like "mageia-release[>= 1]" ++#- which is the format returned by URPM.xs for ->requires, ->provides, ->conflicts... ++sub property2name { ++ $_[0] =~ /^([^\s\[]*)/ && $1; ++} ++sub property2name_range { ++ $_[0] =~ /^([^\s\[]*)(?:\[\*\])?\[?([^\s\]]*\s*[^\s\]]*)/; ++} ++sub property2name_op_version { ++ $_[0] =~ /^([^\s\[]*)(?:\[\*\])?\s*\[?([^\s\]]*)\s*([^\s\]]*)/; ++} ++ ++#- wrappers around $state (cf "The $state object" in "perldoc URPM") ++sub packages_to_remove { ++ my ($state) = @_; ++ grep { ++ $state->{rejected}{$_}{removed} && !$state->{rejected}{$_}{obsoleted}; ++ } keys %{$state->{rejected} || {}}; ++} ++sub removed_or_obsoleted_packages { ++ my ($state) = @_; ++ grep { ++ $state->{rejected}{$_}{removed} || $state->{rejected}{$_}{obsoleted}; ++ } keys %{$state->{rejected} || {}}; ++} ++ ++#- Find candidates packages from a require string (or id). ++#- Takes care of choices using the '|' separator. ++#- (nb: see also find_required_package()) ++#- ++#- side-effects: none ++sub find_candidate_packages_ { ++ my ($urpm, $id_prop, $o_rejected) = @_; ++ my @packages; ++ ++ foreach (split /\|/, $id_prop) { ++ if (/^\d+$/) { ++ my $pkg = $urpm->{depslist}[$_]; ++ $pkg->flag_skip and next; ++ $pkg->arch eq 'src' || $pkg->is_arch_compat or next; ++ $o_rejected && exists $o_rejected->{$pkg->fullname} and next; ++ push @packages, $pkg; ++ } elsif (my $name = property2name($_)) { ++ my $property = $_; ++ foreach (keys %{$urpm->{provides}{$name} || {}}) { ++ my $pkg = $urpm->{depslist}[$_]; ++ $pkg->flag_skip and next; ++ $pkg->is_arch_compat or next; ++ $o_rejected && exists $o_rejected->{$pkg->fullname} and next; ++ #- check if at least one provide of the package overlap the property. ++ !$urpm->{provides}{$name}{$_} || $pkg->provides_overlap($property, 1) ++ and push @packages, $pkg; ++ } ++ } ++ } ++ @packages; ++} ++ ++#- deprecated, use find_candidate_packages_() directly ++#- ++#- side-effects: none ++sub find_candidate_packages { ++ my ($urpm, $id_prop, $o_rejected) = @_; ++ ++ my %packages; ++ foreach (find_candidate_packages_($urpm, $id_prop, $o_rejected)) { ++ push @{$packages{$_->name}}, $_; ++ } ++ \%packages; ++} ++ ++#- returns the "arch" of package $n in rpm db ++sub get_installed_arch { ++ my ($db, $n) = @_; ++ my $arch; ++ $db->traverse_tag('name', [ $n ], sub { $arch = $_[0]->arch }); ++ $arch; ++} ++ ++#- is "strict-arch" wanted? (cf "man urpmi") ++#- since it's slower we only force it on bi-arch ++sub strict_arch { ++ my ($urpm) = @_; ++ defined $urpm->{options}{'strict-arch'} ? $urpm->{options}{'strict-arch'} : $Config{archname} =~ /x86_64|sparc64|ppc64/; ++} ++my %installed_arch; ++ ++#- checks wether $pkg could be installed under strict-arch policy ++#- (ie check wether $pkg->name with different arch is not installed) ++#- ++#- side-effects: none (but uses a cache) ++sub strict_arch_check_installed { ++ my ($db, $pkg) = @_; ++ if ($pkg->arch ne 'src' && $pkg->arch ne 'noarch') { ++ my $n = $pkg->name; ++ defined $installed_arch{$n} or $installed_arch{$n} = get_installed_arch($db, $n); ++ if ($installed_arch{$n} && $installed_arch{$n} ne 'noarch') { ++ $pkg->arch eq $installed_arch{$n} or return; ++ } ++ } ++ 1; ++} ++ ++#- check wether $installed_pkg and $pkg have same arch ++#- (except for src/noarch of course) ++#- ++#- side-effects: none ++sub strict_arch_check { ++ my ($installed_pkg, $pkg) = @_; ++ if ($pkg->arch ne 'src' && $pkg->arch ne 'noarch') { ++ if ($installed_pkg->arch ne 'noarch') { ++ $pkg->arch eq $installed_pkg->arch or return; ++ } ++ } ++ 1; ++} ++ ++#- is $pkg->name installed? ++#- ++#- side-effects: none ++sub is_package_installed { ++ my ($db, $pkg) = @_; ++ ++ my $found; ++ $db->traverse_tag('name', [ $pkg->name ], sub { ++ my ($p) = @_; ++ $found ||= $p->fullname eq $pkg->fullname; ++ }); ++ $found; ++} ++ ++sub _is_selected_or_installed { ++ my ($urpm, $db, $name) = @_; ++ ++ (grep { $_->flag_available } $urpm->packages_providing($name)) > 0 || ++ $db->traverse_tag('name', [ $name ], undef) > 0; ++} ++ ++#- finds $pkg "provides" that matches $provide_name, and returns the version provided ++#- eg: $pkg provides "a = 3", $provide_name is "a > 1", returns "3" ++sub provided_version_that_overlaps { ++ my ($pkg, $provide_name) = @_; ++ ++ my $version; ++ foreach my $property ($pkg->provides) { ++ my ($n, undef, $v) = property2name_op_version($property) or next; ++ $n eq $provide_name or next; ++ ++ if ($version) { ++ $version = $v if URPM::rpmvercmp($v, $version) > 0; ++ } else { ++ $version = $v; ++ } ++ } ++ $version; ++} ++ ++#- deprecated function, use find_required_package() ++sub find_chosen_packages { &find_required_package } ++ ++#- find the package (or packages) to install matching $id_prop ++#- returns (list ref of matches, list ref of preferred matches) ++#- (see also find_candidate_packages_()) ++#- ++#- side-effects: flag_install, flag_upgrade (and strict_arch_check_installed cache) ++sub find_required_package { ++ my ($urpm, $db, $state, $id_prop) = @_; ++ my (%packages, %provided_version); ++ my $strict_arch = strict_arch($urpm); ++ ++ my $may_add_to_packages = sub { ++ my ($pkg) = @_; ++ ++ if (my $p = $packages{$pkg->name}) { ++ $pkg->flag_requested > $p->flag_requested || ++ $pkg->flag_requested == $p->flag_requested && $pkg->compare_pkg($p) > 0 and $packages{$pkg->name} = $pkg; ++ } else { ++ $packages{$pkg->name} = $pkg; ++ } ++ }; ++ ++ #- search for possible packages, try to be as fast as possible, backtrack can be longer. ++ foreach (split /\|/, $id_prop) { ++ if (/^\d+$/) { ++ my $pkg = $urpm->{depslist}[$_]; ++ $pkg->arch eq 'src' || $pkg->is_arch_compat or next; ++ $pkg->flag_skip || $state->{rejected}{$pkg->fullname} and next; ++ #- determine if this package is better than a possibly previously chosen package. ++ $pkg->flag_selected || exists $state->{selected}{$pkg->id} and return [$pkg]; ++ !$strict_arch || strict_arch_check_installed($db, $pkg) or next; ++ $may_add_to_packages->($pkg); ++ } elsif (my $name = property2name($_)) { ++ my $property = $_; ++ foreach (keys %{$urpm->{provides}{$name} || {}}) { ++ my $pkg = $urpm->{depslist}[$_]; ++ $pkg->is_arch_compat or next; ++ $pkg->flag_skip || $state->{rejected}{$pkg->fullname} and next; ++ #- check if at least one provide of the package overlaps the property ++ if (!$urpm->{provides}{$name}{$_} || $pkg->provides_overlap($property)) { ++ #- determine if this package is better than a possibly previously chosen package. ++ $pkg->flag_selected || exists $state->{selected}{$pkg->id} and return [$pkg]; ++ !$strict_arch || strict_arch_check_installed($db, $pkg) or next; ++ $provided_version{$pkg} = provided_version_that_overlaps($pkg, $name); ++ $may_add_to_packages->($pkg); ++ } ++ } ++ } ++ } ++ my @packages = values %packages; ++ ++ if (@packages > 1) { ++ #- packages should be preferred if one of their provides is referenced ++ #- in the "requested" hash, or if the package itself is requested (or ++ #- required). ++ #- If there is no preference, choose the first one by default (higher ++ #- probability of being chosen) and ask the user. ++ #- Packages with more compatibles architectures are always preferred. ++ #- Puts the results in @chosen. Other are left unordered. ++ foreach my $pkg (@packages) { ++ _set_flag_installed_and_upgrade_if_no_newer($db, $pkg); ++ } ++ ++ if (my @kernel_source = _find_required_package__kernel_source($urpm, $db, \@packages)) { ++ $urpm->{debug_URPM}("packageCallbackChoices: kernel source chosen " . join(",", map { $_->name } @kernel_source) . " in " . join(",", map { $_->name } @packages)) if $urpm->{debug_URPM}; ++ return \@kernel_source, \@kernel_source; ++ } ++ if (my @kmod = _find_required_package__kmod($urpm, $db, \@packages)) { ++ $urpm->{debug_URPM}("packageCallbackChoices: kmod packages " . join(",", map { $_->name } @kmod) . " in " . join(",", map { $_->name } @packages)) if $urpm->{debug_URPM}; ++ return \@kmod, \@kmod; ++ } ++ ++ _find_required_package__sort($urpm, $db, \@packages, \%provided_version); ++ } else { ++ \@packages; ++ } ++} ++ ++# nb: _set_flag_installed_and_upgrade_if_no_newer must be done on $packages ++sub _find_required_package__sort { ++ my ($urpm, $db, $packages, $provided_version) = @_; ++ ++ my ($best, @other) = sort { ++ $a->[1] <=> $b->[1] #- we want the lowest (ie preferred arch) ++ || $b->[2] <=> $a->[2]; #- and the higher score ++ } map { ++ my $score = 0; ++ $score += 2 if $_->flag_requested; ++ $score += $_->flag_upgrade ? 1 : -1 if $_->flag_installed; ++ [ $_, $_->is_arch_compat, $score ]; ++ } @$packages; ++ ++ my @chosen_with_score = ($best, grep { $_->[1] == $best->[1] && $_->[2] == $best->[2] } @other); ++ my @chosen = map { $_->[0] } @chosen_with_score; ++ ++ #- return immediately if there is only one chosen package ++ if (@chosen == 1) { return \@chosen } ++ ++ #- if several packages were selected to match a requested installation, ++ #- and if --more-choices wasn't given, trim the choices to the first one. ++ if (!$urpm->{options}{morechoices} && $chosen_with_score[0][2] == 3) { ++ return [ $chosen[0] ]; ++ } ++ ++ if ($urpm->{media}) { ++ @chosen_with_score = sort { ++ $a->[2] != $b->[2] ? ++ $a->[0]->id <=> $b->[0]->id : ++ $b->[1] <=> $a->[1] || $b->[0]->compare_pkg($a->[0]); ++ } map { [ $_, _score_for_locales($urpm, $db, $_), pkg2media($urpm->{media}, $_) ] } @chosen; ++ } else { ++ # obsolete code which should not happen, kept just in case ++ $urpm->{debug_URPM}("can't sort choices by media") if $urpm->{debug_URPM}; ++ @chosen_with_score = sort { ++ $b->[1] <=> $a->[1] || ++ $b->[0]->compare_pkg($a->[0]) || $a->[0]->id <=> $b->[0]->id; ++ } map { [ $_, _score_for_locales($urpm, $db, $_) ] } @chosen; ++ } ++ if (!$urpm->{options}{morechoices}) { ++ if (my @valid_locales = grep { $_->[1] } @chosen_with_score) { ++ #- get rid of invalid locales ++ @chosen_with_score = @valid_locales; ++ } ++ } ++ # propose to select all packages for installed locales ++ my @prefered = grep { $_->[1] == 3 } @chosen_with_score; ++ ++ @chosen = map { $_->[0] } @chosen_with_score; ++ if (%$provided_version) { ++ # highest provided version first ++ # (nb: this sort overrules the sort on media (cf ->id above)) ++ @chosen = sort { URPM::rpmvercmp($provided_version->{$b} || 0, $provided_version->{$a} || 0) } @chosen; ++ } ++ \@chosen, [ map { $_->[0] } @prefered ]; ++} ++ ++#- prefer the pkgs corresponding to installed/selected kernels ++sub _find_required_package__kernel_source { ++ my ($urpm, $db, $choices) = @_; ++ ++ $choices->[0]->name =~ /^kernel-(.*source-|.*-devel-)/ or return; ++ ++ grep { ++ if ($_->name =~ /^kernel-.*source-stripped-(.*)/) { ++ my $version = quotemeta($1); ++ find { ++ $_->name =~ /-$version$/ && ($_->flag_installed || $_->flag_selected); ++ } $urpm->packages_providing('kernel'); ++ } elsif ($_->name =~ /(kernel-.*)-devel-(.*)/) { ++ my $kernel = "$1-$2"; ++ _is_selected_or_installed($urpm, $db, $kernel); ++ } elsif ($_->name =~ /^kernel-.*source-/) { ++ #- hopefully we don't have a media with kernel-source but not kernel-source-stripped nor kernel-.*-devel ++ 0; ++ } else { ++ $urpm->{debug_URPM}("unknown kernel-source package " . $_->fullname) if $urpm->{debug_URPM}; ++ 0; ++ } ++ } @$choices; ++} ++ ++#- prefer the pkgs corresponding to installed/selected kernels ++sub _find_required_package__kmod { ++ my ($urpm, $db, $choices) = @_; ++ ++ $choices->[0]->name =~ /^dkms-|-kernel-2\./ or return; ++ ++ grep { ++ if (my ($_name, $version, $flavor, $release) = $_->name =~ /(.*)-kernel-(2\..*)-(.*)-(.*)/) { ++ my $kernel = "kernel-$flavor-$version-$release"; ++ _is_selected_or_installed($urpm, $db, $kernel); ++ } elsif ($_->name =~ /^dkms-/) { ++ 0; # we prefer precompiled dkms ++ } else { ++ $urpm->{debug_URPM}("unknown kmod package " . $_->fullname) if $urpm->{debug_URPM}; ++ 0; ++ } ++ } @$choices; ++} ++ ++#- Packages that require locales-xxx when the corresponding locales are ++#- already installed should be preferred over packages that require locales ++#- which are not installed. ++#- ++#- eg: locales-fr & locales-de are installed, ++#- prefer firefox-fr & firefox-de which respectively require locales-fr & locales-de ++sub _score_for_locales { ++ my ($urpm, $db, $pkg) = @_; ++ ++ my @r = $pkg->requires_nosense; ++ ++ if (my ($specific_locales) = grep { /locales-(?!en)/ } @r) { ++ if (_is_selected_or_installed($urpm, $db, $specific_locales)) { ++ 3; # good locale ++ } else { ++ 0; # bad locale ++ } ++ } elsif (grep { /locales-en/ } @r) { ++ 2; # ++ } else { ++ 1; ++ } ++} ++ ++#- side-effects: $properties, $choices ++#- + those of backtrack_selected ($state->{backtrack}, $state->{rejected}, $state->{selected}, $state->{whatrequires}, flag_requested, flag_required) ++sub _choose_required { ++ my ($urpm, $db, $state, $dep, $properties, $choices, $diff_provides, %options) = @_; ++ ++ #- take the best choice possible. ++ my ($chosen, $prefered) = find_required_package($urpm, $db, $state, $dep->{required}); ++ ++ #- If no choice is found, this means that nothing can be possibly selected ++ #- according to $dep, so we need to retry the selection, allowing all ++ #- packages that conflict or anything similar to see which strategy can be ++ #- tried. Backtracking is used to avoid trying multiple times the same ++ #- packages. If multiple packages are possible and properties is not ++ #- empty, postpone the choice for a later time as one of the packages ++ #- may be selected for another reason. Otherwise simply ask the user which ++ #- one to choose; else take the first one available. ++ if (!@$chosen) { ++ $urpm->{debug_URPM}("no packages match " . _dep_to_name($urpm, $dep) . " (it is either in skip.list or already rejected)") if $urpm->{debug_URPM}; ++ unshift @$properties, backtrack_selected($urpm, $db, $state, $dep, $diff_provides, %options); ++ return; #- backtrack code choose to continue with same package or completely new strategy. ++ } elsif (@$chosen > 1) { ++ if (@$properties) { ++ unshift @$choices, $dep; ++ return; ++ } elsif ($options{callback_choices}) { ++ my @l = grep { ref $_ } $options{callback_choices}->($urpm, $db, $state, $chosen, _dep_to_name($urpm, $dep), $prefered); ++ $urpm->{debug_URPM}("replacing " . _dep_to_name($urpm, $dep) . " with " . ++ join(' ', map { $_->name } @l)) if $urpm->{debug_URPM}; ++ unshift @$properties, map { ++ +{ ++ required => $_->id, ++ _choices => $dep->{required}, ++ exists $dep->{from} ? (from => $dep->{from}) : @{[]}, ++ exists $dep->{requested} ? (requested => $dep->{requested}) : @{[]}, ++ }; ++ } @l; ++ return; #- always redo according to choices. ++ } ++ } ++ ++ ++ #- now do the real work, select the package. ++ my $pkg = shift @$chosen; ++ if ($urpm->{debug_URPM} && $pkg->name ne _dep_to_name($urpm, $dep)) { ++ $urpm->{debug_URPM}("chosen " . $pkg->fullname . " for " . _dep_to_name($urpm, $dep)); ++ @$chosen and $urpm->{debug_URPM}(" (it could also have chosen " . join(' ', map { scalar $_->fullname } @$chosen)); ++ } ++ ++ $pkg; ++} ++ ++sub pkg2media { ++ my ($mediums, $p) = @_; ++ my $id = $p->id; ++ #- || 0 to avoid undef, but is it normal to have undef ? ++ find { $id >= ($_->{start} || 0) && $id <= ($_->{end} || 0) } @$mediums; ++} ++ ++sub whatrequires { ++ my ($urpm, $state, $property_name) = @_; ++ ++ map { $urpm->{depslist}[$_] } whatrequires_id($state, $property_name); ++} ++sub whatrequires_id { ++ my ($state, $property_name) = @_; ++ ++ keys %{$state->{whatrequires}{$property_name} || {}}; ++} ++ ++#- return unresolved requires of a package (a new one or an existing one). ++#- ++#- side-effects: none (but uses a $state->{cached_installed}) ++sub unsatisfied_requires { ++ my ($urpm, $db, $state, $pkg, %options) = @_; ++ my %unsatisfied; ++ ++ #- all requires should be satisfied according to selected packages or installed packages, ++ #- or the package itself. ++ REQUIRES: foreach my $prop ($pkg->requires) { ++ my ($n, $s) = property2name_range($prop) or next; ++ ++ if (defined $options{name} && $n ne $options{name}) { ++ #- allow filtering on a given name (to speed up some search). ++ } elsif (exists $unsatisfied{$prop}) { ++ #- avoid recomputing the same all the time. ++ } else { ++ #- check for installed packages in the installed cache. ++ foreach (keys %{$state->{cached_installed}{$n} || {}}) { ++ exists $state->{rejected}{$_} and next; ++ next REQUIRES; ++ } ++ ++ #- check on the selected package if a provide is satisfying the resolution (need to do the ops). ++ foreach (grep { exists $state->{selected}{$_} } keys %{$urpm->{provides}{$n} || {}}) { ++ my $p = $urpm->{depslist}[$_]; ++ !$urpm->{provides}{$n}{$_} || $p->provides_overlap($prop, 1) and next REQUIRES; ++ } ++ ++ #- check if the package itself provides what is necessary. ++ $pkg->provides_overlap($prop) and next REQUIRES; ++ ++ #- check on installed system if a package which is not obsoleted is satisfying the require. ++ my $satisfied = 0; ++ if ($n =~ m!^/!) { ++ $db->traverse_tag('path', [ $n ], sub { ++ my ($p) = @_; ++ exists $state->{rejected}{$p->fullname} and return; ++ $state->{cached_installed}{$n}{$p->fullname} = undef; ++ ++$satisfied; ++ }); ++ } else { ++ $db->traverse_tag('whatprovides', [ $n ], sub { ++ my ($p) = @_; ++ exists $state->{rejected}{$p->fullname} and return; ++ foreach ($p->provides) { ++ if (my ($pn, $ps) = property2name_range($_)) { ++ $ps or $state->{cached_installed}{$pn}{$p->fullname} = undef; ++ $pn eq $n or next; ++ URPM::ranges_overlap($ps, $s, 1) and ++$satisfied; ++ } ++ } ++ }); ++ } ++ #- if nothing can be done, the require should be resolved. ++ $satisfied or $unsatisfied{$prop} = undef; ++ } ++ } ++ ++ keys %unsatisfied; ++} ++ ++#- this function is "suggests vs requires" safe: ++#- 'whatrequires' will give both requires & suggests, but unsatisfied_requires ++#- will check $p->requires and so filter out suggests ++ ++#- side-effects: only those done by $do ++sub with_db_unsatisfied_requires { ++ my ($urpm, $db, $state, $name, $do) = @_; ++ ++ $db->traverse_tag('whatrequires', [ $name ], sub { ++ my ($p) = @_; ++ if (my @l = unsatisfied_requires($urpm, $db, $state, $p, name => $name)) { ++ $urpm->{debug_URPM}("installed " . $p->fullname . " is conflicting because of unsatisfied @l") if $urpm->{debug_URPM}; ++ $do->($p, @l); ++ } ++ }); ++} ++ ++#- side-effects: only those done by $do ++sub with_state_unsatisfied_requires { ++ my ($urpm, $db, $state, $name, $do) = @_; ++ ++ foreach (whatrequires_id($state, $name)) { ++ $state->{selected}{$_} or next; ++ my $p = $urpm->{depslist}[$_]; ++ if (my @l = unsatisfied_requires($urpm, $db, $state, $p, name => $name)) { ++ $urpm->{debug_URPM}("selected " . $p->fullname . " is conflicting because of unsatisfied @l") if $urpm->{debug_URPM}; ++ $do->($p, @l); ++ } ++ } ++} ++ ++sub with_any_unsatisfied_requires { ++ my ($urpm, $db, $state, $name, $do) = @_; ++ with_db_unsatisfied_requires($urpm, $db, $state, $name, sub { my ($p, @l) = @_; $do->($p, 0, @l)}); ++ with_state_unsatisfied_requires($urpm, $db, $state, $name, sub { my ($p, @l) = @_; $do->($p, 1, @l)}); ++} ++ ++ ++# used when a require is not available ++# ++#- side-effects: $state->{backtrack}, $state->{selected} ++#- + those of disable_selected_and_unrequested_dependencies ($state->{whatrequires}, flag_requested, flag_required) ++#- + those of _set_rejected_from ($state->{rejected}) ++#- + those of set_rejected_and_compute_diff_provides ($state->{rejected}, $diff_provides_h) ++#- + those of _add_rejected_backtrack ($state->{rejected}) ++sub backtrack_selected { ++ my ($urpm, $db, $state, $dep, $diff_provides, %options) = @_; ++ ++ if (defined $dep->{required}) { ++ #- avoid deadlock here... ++ if (!exists $state->{backtrack}{deadlock}{$dep->{required}}) { ++ $state->{backtrack}{deadlock}{$dep->{required}} = undef; ++ ++ #- search for all possible packages, first is to try the selection, then if it is ++ #- impossible, backtrack the origin. ++ my @packages = find_candidate_packages_($urpm, $dep->{required}); ++ ++ foreach (@packages) { ++ #- avoid dead loop. ++ exists $state->{backtrack}{selected}{$_->id} and next; ++ #- a package if found is problably rejected or there is a problem. ++ if ($state->{rejected}{$_->fullname}) { ++ #- keep in mind a backtrack has happening here... ++ exists $dep->{promote} and _add_rejected_backtrack($state, $_, { promote => [ $dep->{promote} ] }); ++ ++ my $closure = $state->{rejected}{$_->fullname}{closure} || {}; ++ foreach my $p (grep { exists $closure->{$_}{avoid} } keys %$closure) { ++ _add_rejected_backtrack($state, $_, { conflicts => [ $p ] }) ++ } ++ #- backtrack callback should return a strictly positive value if the selection of the new ++ #- package is prefered over the currently selected package. ++ next; ++ } ++ $state->{backtrack}{selected}{$_->id} = undef; ++ ++ #- in such case, we need to drop the problem caused so that rejected condition is removed. ++ #- if this is not possible, the next backtrack on the same package will be refused above. ++ my @l = map { $urpm->search($_, strict_fullname => 1) } ++ keys %{($state->{rejected}{$_->fullname} || {})->{closure}}; ++ ++ disable_selected_and_unrequested_dependencies($urpm, $db, $state, @l); ++ ++ return { required => $_->id, ++ exists $dep->{from} ? (from => $dep->{from}) : @{[]}, ++ exists $dep->{requested} ? (requested => $dep->{requested}) : @{[]}, ++ exists $dep->{promote} ? (promote => $dep->{promote}) : @{[]}, ++ exists $dep->{psel} ? (psel => $dep->{psel}) : @{[]}, ++ }; ++ } ++ } ++ } ++ ++ if (defined $dep->{from}) { ++ if ($options{nodeps}) { ++ #- try to keep unsatisfied dependencies in requested. ++ if ($dep->{required} && exists $state->{selected}{$dep->{from}->id}) { ++ push @{$state->{selected}{$dep->{from}->id}{unsatisfied}}, $dep->{required}; ++ } ++ } else { ++ #- at this point, dep cannot be resolved, this means we need to disable ++ #- all selection tree, re-enabling removed and obsoleted packages as well. ++ unless (exists $state->{rejected}{$dep->{from}->fullname}) { ++ #- package is not currently rejected, compute the closure now. ++ my @l = disable_selected_and_unrequested_dependencies($urpm, $db, $state, $dep->{from}); ++ foreach (@l) { ++ #- disable all these packages in order to avoid selecting them again. ++ _set_rejected_from($state, $_, $dep->{from}); ++ } ++ } ++ #- the package is already rejected, we assume we can add another reason here! ++ $urpm->{debug_URPM}("adding a reason to already rejected package " . $dep->{from}->fullname . ": unsatisfied " . $dep->{required}) if $urpm->{debug_URPM}; ++ ++ _add_rejected_backtrack($state, $dep->{from}, { unsatisfied => [ $dep->{required} ] }); ++ } ++ } ++ ++ my @properties; ++ if (defined $dep->{psel}) { ++ if ($options{keep}) { ++ backtrack_selected_psel_keep($urpm, $db, $state, $dep->{psel}, $dep->{keep}); ++ ++ #- the package is already rejected, we assume we can add another reason here! ++ defined $dep->{promote} and _add_rejected_backtrack($state, $dep->{psel}, { promote => [ $dep->{promote} ] }); ++ } else { ++ #- the backtrack need to examine diff_provides promotion on $n. ++ with_db_unsatisfied_requires($urpm, $db, $state, $dep->{promote}, sub { ++ my ($p, @unsatisfied) = @_; ++ my %diff_provides_h; ++ set_rejected_and_compute_diff_provides($urpm, $state, \%diff_provides_h, { ++ rejected_pkg => $p, removed => 1, ++ from => $dep->{psel}, ++ why => { unsatisfied => \@unsatisfied } ++ }); ++ push @$diff_provides, map { +{ name => $_, pkg => $dep->{psel} } } keys %diff_provides_h; ++ }); ++ with_state_unsatisfied_requires($urpm, $db, $state, $dep->{promote}, sub { ++ my ($p) = @_; ++ _set_rejected_from($state, $p, $dep->{psel}); ++ disable_selected_and_unrequested_dependencies($urpm, $db, $state, $p); ++ }); ++ } ++ } ++ ++ #- some packages may have been removed because of selection of this one. ++ #- the rejected flags should have been cleaned by disable_selected above. ++ @properties; ++} ++ ++#- side-effects: ++#- + those of _set_rejected_from ($state->{rejected}) ++#- + those of _add_rejected_backtrack ($state->{rejected}) ++#- + those of disable_selected_and_unrequested_dependencies ($state->{selected}, $state->{whatrequires}, flag_requested, flag_required) ++sub backtrack_selected_psel_keep { ++ my ($urpm, $db, $state, $psel, $keep) = @_; ++ ++ #- we shouldn't try to remove packages, so psel which leads to this need to be unselected. ++ unless (exists $state->{rejected}{$psel->fullname}) { ++ #- package is not currently rejected, compute the closure now. ++ my @l = disable_selected_and_unrequested_dependencies($urpm, $db, $state, $psel); ++ foreach (@l) { ++ #- disable all these packages in order to avoid selecting them again. ++ _set_rejected_from($state, $_, $psel); ++ } ++ } ++ #- to simplify, a reference to list or standalone elements may be set in keep. ++ $keep and _add_rejected_backtrack($state, $psel, { keep => $keep }); ++} ++ ++#- side-effects: $state->{rejected} ++sub _remove_all_rejected_from { ++ my ($state, $from_fullname) = @_; ++ ++ grep { ++ _remove_rejected_from($state, $_, $from_fullname); ++ } keys %{$state->{rejected}}; ++} ++ ++#- side-effects: $state->{rejected} ++sub _remove_rejected_from { ++ my ($state, $fullname, $from_fullname) = @_; ++ ++ my $rv = $state->{rejected}{$fullname} or return; ++ ++ foreach (qw(removed obsoleted)) { ++ if (exists $rv->{$_} && exists $rv->{$_}{$from_fullname}) { ++ delete $rv->{$_}{$from_fullname}; ++ delete $rv->{$_} if !%{$rv->{$_}}; ++ } ++ } ++ ++ exists $rv->{closure}{$from_fullname} or return; ++ delete $rv->{closure}{$from_fullname}; ++ if (%{$rv->{closure}}) { ++ 0; ++ } else { ++ delete $state->{rejected}{$fullname}; ++ 1; ++ } ++} ++ ++#- side-effects: $state->{rejected} ++sub _add_rejected_backtrack { ++ my ($state, $pkg, $backtrack) = @_; ++ ++ my $bt = $state->{rejected}{$pkg->fullname}{backtrack} ||= {}; ++ ++ foreach (keys %$backtrack) { ++ push @{$bt->{$_}}, @{$backtrack->{$_}}; ++ } ++} ++ ++#- useful to reject packages in advance ++#- eg when selecting "a" which conflict with "b", ensure we won't select "b" ++#- but it's somewhat dangerous because it's sometimes called on installed packages, ++#- and in that case, a real resolve_rejected_ must be done ++#- (that's why set_rejected ignores the effect of _set_rejected_from) ++#- ++#- side-effects: $state->{rejected} ++sub _set_rejected_from { ++ my ($state, $pkg, $from_pkg) = @_; ++ ++ $pkg->fullname ne $from_pkg->fullname or return; ++ ++ $state->{rejected}{$pkg->fullname}{closure}{$from_pkg->fullname}{avoid} ||= undef; ++} ++ ++#- side-effects: $state->{rejected} ++sub _set_rejected_old_package { ++ my ($state, $pkg, $new_pkg) = @_; ++ ++ if ($pkg->fullname eq $new_pkg->fullname) { ++ $state->{rejected_already_installed}{$pkg->id} = $pkg; ++ } else { ++ push @{$state->{rejected}{$pkg->fullname}{backtrack}{keep}}, scalar $new_pkg->fullname; ++ } ++} ++ ++#- side-effects: $state->{rejected} ++sub set_rejected { ++ my ($urpm, $state, $rdep) = @_; ++ ++ my $fullname = $rdep->{rejected_pkg}->fullname; ++ my $rv = $state->{rejected}{$fullname} ||= {}; ++ ++ my $newly_rejected = !exists $rv->{size}; ++ ++ if ($newly_rejected) { ++ $urpm->{debug_URPM}("set_rejected: $fullname") if $urpm->{debug_URPM}; ++ #- keep track of size of package which are finally removed. ++ $rv->{size} = $rdep->{rejected_pkg}->size; ++ } ++ ++ #- keep track of what causes closure. ++ if ($rdep->{from}) { ++ my $closure = $rv->{closure}{scalar $rdep->{from}->fullname} ||= {}; ++ if (my $l = delete $rdep->{why}{unsatisfied}) { ++ my $unsatisfied = $closure->{unsatisfied} ||= []; ++ @$unsatisfied = uniq(@$unsatisfied, @$l); ++ } ++ $closure->{$_} = $rdep->{why}{$_} foreach keys %{$rdep->{why}}; ++ } ++ ++ #- set removed and obsoleted level. ++ foreach (qw(removed obsoleted)) { ++ if ($rdep->{$_}) { ++ if ($rdep->{from}) { ++ $rv->{$_}{scalar $rdep->{from}->fullname} = undef; ++ } else { ++ $rv->{$_}{asked} = undef; ++ } ++ } ++ } ++ ++ $newly_rejected; ++} ++ ++#- side-effects: ++#- + those of set_rejected ($state->{rejected}) ++#- + those of _compute_diff_provides_of_removed_pkg ($diff_provides_h) ++sub set_rejected_and_compute_diff_provides { ++ my ($urpm, $state, $diff_provides_h, $rdep) = @_; ++ ++ my $newly_rejected = set_rejected($urpm, $state, $rdep); ++ ++ #- no need to compute diff_provides if package was already rejected ++ $newly_rejected or return; ++ ++ _compute_diff_provides_of_removed_pkg($urpm, $state, $diff_provides_h, $rdep->{rejected_pkg}); ++} ++ ++#- see resolve_rejected_ below ++sub resolve_rejected { ++ my ($urpm, $db, $state, $pkg, %rdep) = @_; ++ $rdep{rejected_pkg} = $pkg; ++ resolve_rejected_($urpm, $db, $state, $rdep{unsatisfied}, \%rdep); ++} ++ ++#- close rejected (as urpme previously) for package to be removable without error. ++#- ++#- side-effects: $properties ++#- + those of set_rejected ($state->{rejected}) ++sub resolve_rejected_ { ++ my ($urpm, $db, $state, $properties, $rdep) = @_; ++ ++ $urpm->{debug_URPM}("resolve_rejected: " . $rdep->{rejected_pkg}->fullname) if $urpm->{debug_URPM}; ++ ++ #- check if the package has already been asked to be rejected (removed or obsoleted). ++ #- this means only add the new reason and return. ++ my $newly_rejected = set_rejected($urpm, $state, $rdep); ++ ++ $newly_rejected or return; ++ ++ my @pkgs_todo = $rdep->{rejected_pkg}; ++ ++ while (my $cp = shift @pkgs_todo) { ++ #- close what requires this property, but check with selected package requiring old properties. ++ foreach my $n ($cp->provides_nosense) { ++ foreach my $pkg (whatrequires($urpm, $state, $n)) { ++ if (my @l = unsatisfied_requires($urpm, $db, $state, $pkg, name => $n)) { ++ #- a selected package requires something that is no more available ++ #- and should be tried to be re-selected if possible. ++ if ($properties) { ++ push @$properties, map { ++ { required => $_, rejected => scalar $pkg->fullname }; # rejected is only there for debugging purpose (??) ++ } @l; ++ } ++ } ++ } ++ with_db_unsatisfied_requires($urpm, $db, $state, $n, sub { ++ my ($p, @unsatisfied) = @_; ++ ++ my $newly_rejected = set_rejected($urpm, $state, { ++ rejected_pkg => $p, ++ from => $rdep->{rejected_pkg}, ++ why => { unsatisfied => \@unsatisfied }, ++ obsoleted => $rdep->{obsoleted}, ++ removed => $rdep->{removed}, ++ }); ++ ++ #- continue the closure unless already examined. ++ $newly_rejected or return; ++ ++ $p->pack_header; #- need to pack else package is no longer visible... ++ push @pkgs_todo, $p; ++ }); ++ } ++ } ++} ++ ++# see resolve_requested__no_suggests below for information about usage ++sub resolve_requested { ++ my ($urpm, $db, $state, $requested, %options) = @_; ++ ++ my @selected = resolve_requested__no_suggests($urpm, $db, $state, $requested, %options); ++ ++ if (!$options{no_suggests}) { ++ my @todo = @selected; ++ while (@todo) { ++ my $pkg = shift @todo; ++ my %suggests = map { $_ => 1 } $pkg->suggests or next; ++ ++ #- do not install a package that has already been suggested ++ $db->traverse_tag('name', [ $pkg->name ], sub { ++ my ($p) = @_; ++ delete $suggests{$_} foreach $p->suggests; ++ }); ++ ++ # workaround: if you do "urpmi virtual_pkg" and one virtual_pkg is already installed, ++ # it will ask anyway for the other choices ++ foreach my $suggest (keys %suggests) { ++ $db->traverse_tag('whatprovides', [ $suggest ], sub { ++ delete $suggests{$suggest}; ++ }); ++ } ++ ++ %suggests or next; ++ ++ $urpm->{debug_URPM}("requested " . join(', ', keys %suggests) . " suggested by " . $pkg->fullname) if $urpm->{debug_URPM}; ++ ++ my %new_requested = map { $_ => undef } keys %suggests; ++ my @new_selected = resolve_requested__no_suggests_($urpm, $db, $state, \%new_requested, %options); ++ $state->{selected}{$_->id}{suggested} = 1 foreach @new_selected; ++ push @selected, @new_selected; ++ push @todo, @new_selected; ++ } ++ } ++ @selected; ++} ++ ++#- Resolve dependencies of requested packages; keep resolution state to ++#- speed up process. ++#- A requested package is marked to be installed; once done, an upgrade flag or ++#- an installed flag is set according to the needs of the installation of this ++#- package. ++#- Other required packages will have a required flag set along with an upgrade ++#- flag or an installed flag. ++#- Base flag should always be "installed" or "upgraded". ++#- The following options are recognized : ++#- callback_choices : subroutine to be called to ask the user to choose ++#- between several possible packages. Returns an array of URPM::Package ++#- objects, or an empty list eventually. ++#- keep : ++#- nodeps : ++#- ++#- side-effects: flag_requested ++#- + those of resolve_requested__no_suggests_ ++sub resolve_requested__no_suggests { ++ my ($urpm, $db, $state, $requested, %options) = @_; ++ ++ foreach (keys %$requested) { ++ #- keep track of requested packages by propating the flag. ++ foreach (find_candidate_packages_($urpm, $_)) { ++ $_->set_flag_requested; ++ } ++ } ++ ++ resolve_requested__no_suggests_($urpm, $db, $state, $requested, %options); ++} ++ ++# same as resolve_requested__no_suggests, but do not modify requested_flag ++#- ++#- side-effects: $state->{selected}, flag_required, flag_installed, flag_upgrade ++#- + those of backtrack_selected (flag_requested, $state->{rejected}, $state->{whatrequires}, $state->{backtrack}) ++#- + those of _unselect_package_deprecated_by (flag_requested, $state->{rejected}, $state->{whatrequires}, $state->{oldpackage}, $state->{unselected_uninstalled}) ++#- + those of _handle_conflicts ($state->{rejected}) ++#- + those of _handle_conflict ($state->{rejected}) ++#- + those of backtrack_selected_psel_keep (flag_requested, $state->{whatrequires}) ++#- + those of _handle_diff_provides (flag_requested, $state->{rejected}, $state->{whatrequires}) ++#- + those of _no_more_recent_installed_and_providing ($state->{rejected}) ++sub resolve_requested__no_suggests_ { ++ my ($urpm, $db, $state, $requested, %options) = @_; ++ ++ my @properties = map { ++ { required => $_, requested => $requested->{$_} }; ++ } keys %$requested; ++ ++ my (@diff_provides, @selected, @choices); ++ ++ #- for each dep property evaluated, examine which package will be obsoleted on $db, ++ #- then examine provides that will be removed (which need to be satisfied by another ++ #- package present or by a new package to upgrade), then requires not satisfied and ++ #- finally conflicts that will force a new upgrade or a remove. ++ do { ++ while (my $dep = shift @properties) { ++ #- we need to avoid selecting packages if the source has been disabled. ++ if (exists $dep->{from} && !$urpm->{keep_unrequested_dependencies}) { ++ exists $state->{selected}{$dep->{from}->id} or next; ++ } ++ ++ my $pkg = _choose_required($urpm, $db, $state, $dep, \@properties, \@choices, \@diff_provides, %options) or next; ++ ++ !$pkg || exists $state->{selected}{$pkg->id} and next; ++ ++ if ($pkg->arch eq 'src') { ++ $pkg->set_flag_upgrade; ++ } else { ++ _set_flag_installed_and_upgrade_if_no_newer($db, $pkg); ++ ++ if ($pkg->flag_installed && !$pkg->flag_upgrade) { ++ _no_more_recent_installed_and_providing($urpm, $db, $state, $pkg, $dep->{required}) or next; ++ } ++ } ++ ++ _handle_conflicts_with_selected($urpm, $db, $state, $pkg, $dep, \@properties, \@diff_provides, %options) or next; ++ ++ $urpm->{debug_URPM}("selecting " . $pkg->fullname) if $urpm->{debug_URPM}; ++ ++ #- keep in mind the package has be selected, remove the entry in requested input hash, ++ #- this means required dependencies have undef value in selected hash. ++ #- requested flag is set only for requested package where value is not false. ++ push @selected, $pkg; ++ $state->{selected}{$pkg->id} = { exists $dep->{requested} ? (requested => $dep->{requested}) : @{[]}, ++ exists $dep->{from} ? (from => $dep->{from}) : @{[]}, ++ exists $dep->{promote} ? (promote => $dep->{promote}) : @{[]}, ++ exists $dep->{psel} ? (psel => $dep->{psel}) : @{[]}, ++ $pkg->flag_disable_obsolete ? (install => 1) : @{[]}, ++ }; ++ ++ $pkg->set_flag_required; ++ ++ #- check if the package is not already installed before trying to use it, compute ++ #- obsoleted packages too. This is valable only for non source packages. ++ my %diff_provides_h; ++ if ($pkg->arch ne 'src' && !$pkg->flag_disable_obsolete) { ++ _unselect_package_deprecated_by($urpm, $db, $state, \%diff_provides_h, $pkg); ++ } ++ ++ #- all requires should be satisfied according to selected package, or installed packages. ++ if (my @l = unsatisfied_requires($urpm, $db, $state, $pkg)) { ++ $urpm->{debug_URPM}("requiring " . join(',', sort @l) . " for " . $pkg->fullname) if $urpm->{debug_URPM}; ++ unshift @properties, map { +{ required => $_, from => $pkg, ++ exists $dep->{promote} ? (promote => $dep->{promote}) : @{[]}, ++ exists $dep->{psel} ? (psel => $dep->{psel}) : @{[]}, ++ } } @l; ++ } ++ ++ #- keep in mind what is requiring each item (for unselect to work). ++ foreach ($pkg->requires_nosense) { ++ $state->{whatrequires}{$_}{$pkg->id} = undef; ++ } ++ ++ #- cancel flag if this package should be cancelled but too late (typically keep options). ++ my @keep; ++ ++ _handle_conflicts($urpm, $db, $state, $pkg, \@properties, \%diff_provides_h, $options{keep} && \@keep); ++ ++ #- examine if an existing package does not conflict with this one. ++ $db->traverse_tag('whatconflicts', [ $pkg->provides_nosense ], sub { ++ @keep and return; ++ my ($p) = @_; ++ foreach my $property ($p->conflicts) { ++ if ($pkg->provides_overlap($property)) { ++ _handle_conflict($urpm, $state, $pkg, $p, $property, $property, \@properties, \%diff_provides_h, $options{keep} && \@keep); ++ } ++ } ++ }); ++ ++ #- keep existing package and therefore cancel current one. ++ if (@keep) { ++ backtrack_selected_psel_keep($urpm, $db, $state, $pkg, \@keep); ++ } ++ ++ push @diff_provides, map { +{ name => $_, pkg => $pkg } } keys %diff_provides_h; ++ } ++ if (my $diff = shift @diff_provides) { ++ _handle_diff_provides($urpm, $db, $state, \@properties, \@diff_provides, $diff->{name}, $diff->{pkg}, %options); ++ } elsif (my $dep = shift @choices) { ++ push @properties, $dep; ++ } ++ } while @diff_provides || @properties || @choices; ++ ++ #- return what has been selected by this call (not all selected hash which may be not empty ++ #- previously. avoid returning rejected packages which weren't selectable. ++ grep { exists $state->{selected}{$_->id} } @selected; ++} ++ ++#- pre-disables packages that $pkg has conflict entries for, and ++#- unselects $pkg if such a package is already selected ++#- side-effects: ++#- + those of _set_rejected_from ($state->{rejected}) ++#- + those of _remove_all_rejected_from ($state->{rejected}) ++#- + those of backtrack_selected ($state->{backtrack}, $state->{rejected}, $state->{selected}, $state->{whatrequires}, flag_requested, flag_required) ++sub _handle_conflicts_with_selected { ++ my ($urpm, $db, $state, $pkg, $dep, $properties, $diff_provides, %options) = @_; ++ foreach ($pkg->conflicts) { ++ if (my ($n, $o, $v) = property2name_op_version($_)) { ++ foreach my $p ($urpm->packages_providing($n)) { ++ $pkg == $p and next; ++ $p->provides_overlap($_) or next; ++ if (exists $state->{selected}{$p->id}) { ++ $urpm->{debug_URPM}($pkg->fullname . " conflicts with already selected package " . $p->fullname) if $urpm->{debug_URPM}; ++ _remove_all_rejected_from($state, $pkg); ++ _set_rejected_from($state, $pkg, $p); ++ unshift @$properties, backtrack_selected($urpm, $db, $state, $dep, $diff_provides, %options); ++ return; ++ } ++ _set_rejected_from($state, $p, $pkg); ++ } ++ } ++ } ++ 1; ++} ++ ++#- side-effects: ++#- + those of set_rejected_and_compute_diff_provides ($state->{rejected}, $diff_provides_h) ++#- + those of _handle_conflict ($properties, $keep, $diff_provides_h) ++sub _handle_conflicts { ++ my ($urpm, $db, $state, $pkg, $properties, $diff_provides_h, $keep) = @_; ++ ++ #- examine conflicts, an existing package conflicting with this selection should ++ #- be upgraded to a new version which will be safe, else it should be removed. ++ foreach ($pkg->conflicts) { ++ $keep && @$keep and last; ++ if (my ($file) = m!^(/[^\s\[]*)!) { ++ $db->traverse_tag('path', [ $file ], sub { ++ $keep && @$keep and return; ++ my ($p) = @_; ++ if ($keep) { ++ push @$keep, scalar $p->fullname; ++ } else { ++ #- all these package should be removed. ++ set_rejected_and_compute_diff_provides($urpm, $state, $diff_provides_h, { ++ rejected_pkg => $p, removed => 1, ++ from => $pkg, ++ why => { conflicts => $file }, ++ }); ++ } ++ }); ++ } elsif (my $name = property2name($_)) { ++ my $property = $_; ++ $db->traverse_tag('whatprovides', [ $name ], sub { ++ $keep && @$keep and return; ++ my ($p) = @_; ++ if ($p->provides_overlap($property)) { ++ _handle_conflict($urpm, $state, $pkg, $p, $property, scalar($pkg->fullname), $properties, $diff_provides_h, $keep); ++ } ++ }); ++ } ++ } ++} ++ ++#- side-effects: ++#- + those of _unselect_package_deprecated_by_property (flag_requested, flag_required, $state->{selected}, $state->{rejected}, $state->{whatrequires}, $state->{oldpackage}, $state->{unselected_uninstalled}) ++sub _unselect_package_deprecated_by { ++ my ($urpm, $db, $state, $diff_provides_h, $pkg) = @_; ++ ++ _unselect_package_deprecated_by_property($urpm, $db, $state, $pkg, $diff_provides_h, $pkg->name, '<', $pkg->epoch . ":" . $pkg->version . "-" . $pkg->release); ++ ++ foreach ($pkg->obsoletes) { ++ my ($n, $o, $v) = property2name_op_version($_) or next; ++ ++ #- ignore if this package obsoletes itself ++ #- otherwise this can cause havoc if: to_install=v3, installed=v2, v3 obsoletes < v2 ++ if ($n ne $pkg->name) { ++ _unselect_package_deprecated_by_property($urpm, $db, $state, $pkg, $diff_provides_h, $n, $o, $v); ++ } ++ } ++} ++ ++#- side-effects: $state->{oldpackage}, $state->{unselected_uninstalled} ++#- + those of set_rejected ($state->{rejected}) ++#- + those of _set_rejected_from ($state->{rejected}) ++#- + those of disable_selected (flag_requested, flag_required, $state->{selected}, $state->{rejected}, $state->{whatrequires}) ++sub _unselect_package_deprecated_by_property { ++ my ($urpm, $db, $state, $pkg, $diff_provides_h, $n, $o, $v) = @_; ++ ++ #- populate avoided entries according to what is selected. ++ foreach my $p ($urpm->packages_providing($n)) { ++ if ($p->name eq $pkg->name) { ++ #- all packages with the same name should now be avoided except when chosen. ++ } else { ++ #- in case of obsoletes, keep track of what should be avoided ++ #- but only if package name equals the obsolete name. ++ $p->name eq $n && (!$o || eval($p->compare($v) . $o . 0)) or next; ++ } ++ #- these packages are not yet selected, if they happen to be selected, ++ #- they must first be unselected. ++ _set_rejected_from($state, $p, $pkg); ++ } ++ ++ #- examine rpm db too (but only according to package names as a fix in rpm itself) ++ $db->traverse_tag('name', [ $n ], sub { ++ my ($p) = @_; ++ ++ #- without an operator, anything (with the same name) is matched. ++ #- with an operator, check package EVR with the obsoletes EVR. ++ #- $satisfied is true if installed package has version newer or equal. ++ my $comparison = $p->compare($v); ++ my $satisfied = !$o || eval($comparison . $o . 0); ++ ++ my $obsoleted; ++ if ($p->name eq $pkg->name) { ++ #- all packages older than the current one are obsoleted, ++ #- the others are simply removed (the result is the same). ++ if ($o && $comparison > 0) { ++ #- installed package is newer ++ #- remove this package from the list of packages to install, ++ #- unless urpmi was invoked with --allow-force (in which ++ #- case rpm could be invoked with --oldpackage) ++ if (!$urpm->{options}{'allow-force'}) { ++ #- since the originally requested packages (or other ++ #- non-installed ones) could be unselected by the following ++ #- operation, remember them, to warn the user ++ $state->{unselected_uninstalled} = [ grep { ++ !$_->flag_installed; ++ } disable_selected($urpm, $db, $state, $pkg) ]; ++ ++ return; ++ } ++ } elsif ($satisfied) { ++ $obsoleted = 1; ++ } ++ } elsif ($satisfied) { ++ $obsoleted = 1; ++ } else { ++ return; ++ } ++ ++ set_rejected_and_compute_diff_provides($urpm, $state, $diff_provides_h, { ++ rejected_pkg => $p, ++ obsoleted => $obsoleted, removed => !$obsoleted, ++ from => $pkg, why => $obsoleted ? undef : { old_requested => 1 }, ++ }); ++ $obsoleted or ++$state->{oldpackage}; ++ }); ++} ++ ++#- side-effects: $diff_provides ++sub _compute_diff_provides_of_removed_pkg { ++ my ($urpm, $state, $diff_provides_h, $p) = @_; ++ ++ foreach ($p->provides) { ++ #- check differential provides between obsoleted package and newer one. ++ my ($pn, $ps) = property2name_range($_) or next; ++ ++ my $not_provided = 1; ++ foreach (grep { exists $state->{selected}{$_} } ++ keys %{$urpm->{provides}{$pn} || {}}) { ++ my $pp = $urpm->{depslist}[$_]; ++ foreach ($pp->provides) { ++ my ($ppn, $pps) = property2name_range($_) or next; ++ $ppn eq $pn && $pps eq $ps ++ and $not_provided = 0; ++ } ++ } ++ $not_provided and $diff_provides_h->{$pn} = undef; ++ } ++} ++ ++#- side-effects: none ++sub _find_packages_obsoleting { ++ my ($urpm, $state, $p) = @_; ++ ++ grep { ++ !$_->flag_skip ++ && $_->is_arch_compat ++ && !exists $state->{rejected}{$_->fullname} ++ && $_->obsoletes_overlap($p->name . " == " . $p->epoch . ":" . $p->version . "-" . $p->release) ++ && $_->fullname ne $p->fullname ++ && (!strict_arch($urpm) || strict_arch_check($p, $_)); ++ } $urpm->packages_obsoleting($p->name); ++} ++ ++#- side-effects: $properties ++#- + those of backtrack_selected_psel_keep ($state->{rejected}, $state->{selected}, $state->{whatrequires}, flag_requested, flag_required) ++#- + those of resolve_rejected_ ($state->{rejected}, $properties) ++#- + those of disable_selected_and_unrequested_dependencies (flag_requested, flag_required, $state->{selected}, $state->{whatrequires}, $state->{rejected}) ++#- + those of _set_rejected_from ($state->{rejected}) ++sub _handle_diff_provides { ++ my ($urpm, $db, $state, $properties, $diff_provides, $n, $pkg, %options) = @_; ++ ++ with_any_unsatisfied_requires($urpm, $db, $state, $n, sub { ++ my ($p, $from_state, @unsatisfied) = @_; ++ ++ #- try if upgrading the package will be satisfying all the requires... ++ #- there is no need to avoid promoting epoch as the package examined is not ++ #- already installed. ++ my @packages = find_candidate_packages_($urpm, $p->name, $state->{rejected}); ++ @packages = ++ grep { ($_->name eq $p->name ? $p->compare_pkg($_) < 0 : ++ $_->obsoletes_overlap($p->name . " == " . $p->epoch . ":" . $p->version . "-" . $p->release)) ++ && (!strict_arch($urpm) || strict_arch_check($p, $_)) ++ } @packages; ++ ++ if (!@packages) { ++ @packages = _find_packages_obsoleting($urpm, $state, $p); ++ } ++ ++ if (@packages) { ++ my $best = join('|', map { $_->id } @packages); ++ $urpm->{debug_URPM}("promoting " . $urpm->{depslist}[$best]->fullname . " because of conflict above") if $urpm->{debug_URPM}; ++ push @$properties, { required => $best, promote => $n, psel => $pkg }; ++ } else { ++ #- no package have been found, we may need to remove the package examined unless ++ #- there exists enough packages that provided the unsatisfied requires. ++ my @best; ++ foreach (@unsatisfied) { ++ my @packages = find_candidate_packages_($urpm, $_, $state->{rejected}); ++ if (@packages = grep { $_->fullname ne $p->fullname } @packages) { ++ push @best, join('|', map { $_->id } @packages); ++ } ++ } ++ ++ if (@best == @unsatisfied) { ++ $urpm->{debug_URPM}("promoting " . join(' ', _ids_to_fullnames($urpm, @best)) . " because of conflict above") if $urpm->{debug_URPM}; ++ push @$properties, map { +{ required => $_, promote => $n, psel => $pkg } } @best; ++ } else { ++ if ($from_state) { ++ disable_selected_and_unrequested_dependencies($urpm, $db, $state, $p); ++ _set_rejected_from($state, $p, $pkg); ++ } elsif ($options{keep}) { ++ backtrack_selected_psel_keep($urpm, $db, $state, $pkg, [ scalar $p->fullname ]); ++ } else { ++ my %diff_provides_h; ++ set_rejected_and_compute_diff_provides($urpm, $state, \%diff_provides_h, { ++ rejected_pkg => $p, removed => 1, ++ from => $pkg, ++ why => { unsatisfied => \@unsatisfied }, ++ }); ++ push @$diff_provides, map { +{ name => $_, pkg => $pkg } } keys %diff_provides_h; ++ } ++ } ++ } ++ }); ++} ++ ++#- side-effects: $properties, $keep ++#- + those of set_rejected_and_compute_diff_provides ($state->{rejected}, $diff_provides_h) ++sub _handle_conflict { ++ my ($urpm, $state, $pkg, $p, $property, $reason, $properties, $diff_provides_h, $keep) = @_; ++ ++ $urpm->{debug_URPM}("installed package " . $p->fullname . " is conflicting with " . $pkg->fullname . " (Conflicts: $property)") if $urpm->{debug_URPM}; ++ ++ #- the existing package will conflict with the selection; check ++ #- whether a newer version will be ok, else ask to remove the old. ++ my $need_deps = $p->name . " > " . ($p->epoch ? $p->epoch . ":" : "") . ++ $p->version . "-" . $p->release; ++ my @packages = grep { $_->name eq $p->name } find_candidate_packages_($urpm, $need_deps, $state->{rejected}); ++ @packages = grep { ! $_->provides_overlap($property) } @packages; ++ ++ if (!@packages) { ++ @packages = _find_packages_obsoleting($urpm, $state, $p); ++ @packages = grep { ! $_->provides_overlap($property) } @packages; ++ } ++ ++ if (@packages) { ++ my $best = join('|', map { $_->id } @packages); ++ $urpm->{debug_URPM}("promoting " . join('|', map { scalar $_->fullname } @packages) . " because of conflict above") if $urpm->{debug_URPM}; ++ unshift @$properties, { required => $best, promote_conflicts => $reason }; ++ } else { ++ if ($keep) { ++ push @$keep, scalar $p->fullname; ++ } else { ++ #- no package has been found, we need to remove the package examined. ++ set_rejected_and_compute_diff_provides($urpm, $state, $diff_provides_h, { ++ rejected_pkg => $p, removed => 1, ++ from => $pkg, ++ why => { conflicts => $reason }, ++ }); ++ } ++ } ++} ++ ++#- side-effects: none ++sub _dep_to_name { ++ my ($urpm, $dep) = @_; ++ join('|', map { _id_to_name($urpm, $_) } split('\|', $dep->{required})); ++} ++#- side-effects: none ++sub _id_to_name { ++ my ($urpm, $id_prop) = @_; ++ if ($id_prop =~ /^\d+/) { ++ my $pkg = $urpm->{depslist}[$id_prop]; ++ $pkg && $pkg->name; ++ } else { ++ $id_prop; ++ } ++} ++#- side-effects: none ++sub _ids_to_names { ++ my $urpm = shift; ++ ++ map { $urpm->{depslist}[$_]->name } @_; ++} ++#- side-effects: none ++sub _ids_to_fullnames { ++ my $urpm = shift; ++ ++ map { scalar $urpm->{depslist}[$_]->fullname } @_; ++} ++ ++#- side-effects: flag_installed, flag_upgrade ++sub _set_flag_installed_and_upgrade_if_no_newer { ++ my ($db, $pkg) = @_; ++ ++ !$pkg->flag_upgrade && !$pkg->flag_installed or return; ++ ++ my $upgrade = 1; ++ $db->traverse_tag('name', [ $pkg->name ], sub { ++ my ($p) = @_; ++ $pkg->set_flag_installed; ++ $upgrade &&= $pkg->compare_pkg($p) > 0; ++ }); ++ $pkg->set_flag_upgrade($upgrade); ++} ++ ++#- side-effects: ++#- + those of _set_rejected_old_package ($state->{rejected}) ++sub _no_more_recent_installed_and_providing { ++ my ($urpm, $db, $state, $pkg, $required) = @_; ++ ++ my $allow = 1; ++ $db->traverse_tag('name', [ $pkg->name ], sub { ++ my ($p) = @_; ++ #- allow if a less recent package is installed, ++ if ($allow && $pkg->compare_pkg($p) <= 0) { ++ if ($required =~ /^\d+/ || $p->provides_overlap($required)) { ++ $urpm->{debug_URPM}("not selecting " . $pkg->fullname . " since the more recent " . $p->fullname . " is installed") if $urpm->{debug_URPM}; ++ _set_rejected_old_package($state, $pkg, $p); ++ $allow = 0; ++ } else { ++ $urpm->{debug_URPM}("the more recent " . $p->fullname . ++ " is installed, but does not provide $required whereas " . ++ $pkg->fullname . " does") if $urpm->{debug_URPM}; ++ } ++ } ++ }); ++ $allow; ++} ++ ++#- do the opposite of the resolve_requested: ++#- unselect a package and extend to any package not requested that is no ++#- longer needed by any other package. ++#- return the packages that have been deselected. ++#- ++#- side-effects: flag_requested, flag_required, $state->{selected}, $state->{whatrequires} ++#- + those of _remove_all_rejected_from ($state->{rejected}) ++sub disable_selected { ++ my ($urpm, $db, $state, @pkgs_todo) = @_; ++ my @unselected; ++ ++ #- iterate over package needing unrequested one. ++ while (my $pkg = shift @pkgs_todo) { ++ exists $state->{selected}{$pkg->id} or next; ++ ++ #- keep a trace of what is deselected. ++ push @unselected, $pkg; ++ ++ #- perform a closure on rejected packages (removed, obsoleted or avoided). ++ my @rejected_todo = scalar $pkg->fullname; ++ while (my $fullname = shift @rejected_todo) { ++ push @rejected_todo, _remove_all_rejected_from($state, $fullname); ++ } ++ ++ #- the package being examined has to be unselected. ++ $urpm->{debug_URPM}("unselecting " . $pkg->fullname) if $urpm->{debug_URPM}; ++ $pkg->set_flag_requested(0); ++ $pkg->set_flag_required(0); ++ delete $state->{selected}{$pkg->id}; ++ ++ #- determine package that requires properties no longer available, so that they need to be ++ #- unselected too. ++ foreach my $n ($pkg->provides_nosense) { ++ foreach my $p (whatrequires($urpm, $state, $n)) { ++ exists $state->{selected}{$p->id} or next; ++ if (unsatisfied_requires($urpm, $db, $state, $p, name => $n)) { ++ #- this package has broken dependencies and is selected. ++ push @pkgs_todo, $p; ++ } ++ } ++ } ++ ++ #- clean whatrequires hash. ++ foreach ($pkg->requires_nosense) { ++ delete $state->{whatrequires}{$_}{$pkg->id}; ++ %{$state->{whatrequires}{$_}} or delete $state->{whatrequires}{$_}; ++ } ++ } ++ ++ #- return all unselected packages. ++ @unselected; ++} ++ ++#- determine dependencies that can safely been removed and are not requested ++#- return the packages that have been deselected. ++#- ++#- side-effects: ++#- + those of disable_selected (flag_requested, flag_required, $state->{selected}, $state->{whatrequires}, $state->{rejected}) ++sub disable_selected_and_unrequested_dependencies { ++ my ($urpm, $db, $state, @pkgs_todo) = @_; ++ my @all_unselected; ++ ++ #- disable selected packages, then extend unselection to all required packages ++ #- no longer needed and not requested. ++ while (my @unselected = disable_selected($urpm, $db, $state, @pkgs_todo)) { ++ my %required; ++ ++ #- keep in the packages that had to be unselected. ++ @all_unselected or push @all_unselected, @unselected; ++ ++ if ($urpm->{keep_unrequested_dependencies}) { ++ last; ++ } ++ ++ #- search for unrequested required packages. ++ foreach (@unselected) { ++ foreach ($_->requires_nosense) { ++ foreach my $pkg (grep { $_ } $urpm->packages_providing($_)) { ++ $state->{selected}{$pkg->id} or next; ++ $state->{selected}{$pkg->id}{psel} && $state->{selected}{$state->{selected}{$pkg->id}{psel}->id} and next; ++ $pkg->flag_requested and next; ++ $required{$pkg->id} = undef; ++ } ++ } ++ } ++ ++ #- check required packages are not needed by another selected package. ++ foreach (keys %required) { ++ my $pkg = $urpm->{depslist}[$_] or next; ++ foreach ($pkg->provides_nosense) { ++ foreach my $p_id (whatrequires_id($state, $_)) { ++ exists $required{$p_id} and next; ++ $state->{selected}{$p_id} and $required{$pkg->id} = 1; ++ } ++ } ++ } ++ ++ #- now required values still undefined indicates packages than can be removed. ++ @pkgs_todo = map { $urpm->{depslist}[$_] } grep { !$required{$_} } keys %required; ++ } ++ ++ @all_unselected; ++} ++ ++#- compute selected size by removing any removed or obsoleted package. ++#- ++#- side-effects: none ++sub selected_size { ++ my ($urpm, $state) = @_; ++ my ($size) = _selected_size_filesize($urpm, $state, 0); ++ $size; ++} ++#- side-effects: none ++sub selected_size_filesize { ++ my ($urpm, $state) = @_; ++ _selected_size_filesize($urpm, $state, 1); ++} ++#- side-effects: none ++sub _selected_size_filesize { ++ my ($urpm, $state, $compute_filesize) = @_; ++ my ($size, $filesize, $bad_filesize); ++ ++ foreach (keys %{$state->{selected} || {}}) { ++ my $pkg = $urpm->{depslist}[$_]; ++ $size += $pkg->size; ++ $compute_filesize or next; ++ ++ if (my $n = $pkg->filesize) { ++ $filesize += $n; ++ } elsif (!$bad_filesize) { ++ $urpm->{debug} and $urpm->{debug}("no filesize for package " . $pkg->fullname); ++ $bad_filesize = 1; ++ } ++ } ++ ++ foreach (values %{$state->{rejected} || {}}) { ++ $_->{removed} || $_->{obsoleted} or next; ++ $size -= $_->{size}; ++ } ++ ++ foreach (@{$state->{orphans_to_remove} || []}) { ++ $size -= $_->size; ++ } ++ ++ $size, $bad_filesize ? 0 : $filesize; ++} ++ ++#- compute installed flags for all packages in depslist. ++#- ++#- side-effects: flag_upgrade, flag_installed ++sub compute_installed_flags { ++ my ($urpm, $db) = @_; ++ ++ #- first pass to initialize flags installed and upgrade for all packages. ++ foreach (@{$urpm->{depslist}}) { ++ $_->is_arch_compat or next; ++ $_->flag_upgrade || $_->flag_installed or $_->set_flag_upgrade; ++ } ++ ++ #- second pass to set installed flag and clean upgrade flag according to installed packages. ++ $db->traverse(sub { ++ my ($p) = @_; ++ #- compute flags. ++ foreach my $pkg ($urpm->packages_providing($p->name)) { ++ next if !defined $pkg; ++ $pkg->is_arch_compat && $pkg->name eq $p->name or next; ++ #- compute only installed and upgrade flags. ++ $pkg->set_flag_installed; #- there is at least one package installed (whatever its version). ++ $pkg->flag_upgrade and $pkg->set_flag_upgrade($pkg->compare_pkg($p) > 0); ++ } ++ }); ++} ++ ++#- side-effects: flag_skip, flag_disable_obsolete ++sub compute_flag { ++ my ($urpm, $pkg, %options) = @_; ++ foreach (qw(skip disable_obsolete)) { ++ if ($options{$_} && !$pkg->flag($_)) { ++ $pkg->set_flag($_, 1); ++ $options{callback} and $options{callback}->($urpm, $pkg, %options); ++ } ++ } ++} ++ ++#- Adds packages flags according to an array containing packages names. ++#- $val is an array reference (as returned by get_packages_list) containing ++#- package names, or a regular expression matching against the fullname, if ++#- enclosed in slashes. ++#- %options : ++#- callback : sub to be called for each package where the flag is set ++#- skip : if true, set the 'skip' flag ++#- disable_obsolete : if true, set the 'disable_obsolete' flag ++#- ++#- side-effects: ++#- + those of compute_flag (flag_skip, flag_disable_obsolete) ++sub compute_flags { ++ my ($urpm, $val, %options) = @_; ++ if (ref $val eq 'HASH') { $val = [ keys %$val ] } #- compatibility with urpmi <= 4.5-13mdk ++ my @regex; ++ ++ #- unless a regular expression is given, search in provides ++ foreach my $name (@$val) { ++ if ($name =~ m,^/(.*)/$,) { ++ push @regex, $1; ++ } else { ++ foreach my $pkg ($urpm->packages_providing($name)) { ++ compute_flag($urpm, $pkg, %options); ++ } ++ } ++ } ++ ++ #- now search packages which fullname match given regexps ++ if (@regex) { ++ #- very costly :-( ++ foreach my $pkg (@{$urpm->{depslist}}) { ++ if (grep { $pkg->fullname =~ /$_/ } @regex) { ++ compute_flag($urpm, $pkg, %options); ++ } ++ } ++ } ++} ++ ++#- side-effects: none ++sub _choose_best_pkg { ++ my ($urpm, $pkg_installed, @pkgs) = @_; ++ ++ _choose_best_pkg_($urpm, $pkg_installed, grep { ++ $_->compare_pkg($pkg_installed) > 0; ++ } @pkgs); ++} ++ ++#- side-effects: none ++sub _choose_best_pkg_ { ++ my ($urpm, $pkg_installed, @pkgs) = @_; ++ ++ my $best; ++ foreach my $pkg (grep { ++ !strict_arch($urpm) || strict_arch_check($pkg_installed, $_); ++ } @pkgs) { ++ if (!$best || ($pkg->compare_pkg($best) || $pkg->id < $best->id) > 0) { ++ $best = $pkg; ++ } ++ } ++ $best; ++} ++ ++#- side-effects: none ++sub _choose_bests_obsolete { ++ my ($urpm, $db, $pkg_installed, @pkgs) = @_; ++ ++ _set_flag_installed_and_upgrade_if_no_newer($db, $_) foreach @pkgs; ++ ++ my %by_name; ++ push @{$by_name{$_->name}}, $_ foreach grep { $_->flag_upgrade } @pkgs; ++ ++ map { _choose_best_pkg_($urpm, $pkg_installed, @$_) } values %by_name; ++} ++ ++#- select packages to upgrade, according to package already registered. ++#- by default, only takes best package and its obsoleted and compute ++#- all installed or upgrade flag. ++#- (used for --auto-select) ++#- ++#- side-effects: $requisted, flag_installed, flag_upgrade ++sub request_packages_to_upgrade { ++ my ($urpm, $db, $state, $requested, %options) = @_; ++ ++ my %by_name; ++ ++ #- now we can examine all existing packages to find packages to upgrade. ++ $db->traverse(sub { ++ my ($pkg_installed) = @_; ++ my $name = $pkg_installed->name; ++ my $pkg; ++ if (exists $by_name{$name}) { ++ if (my $p = $by_name{$name}) { ++ #- here a pkg with the same name is installed twice ++ if ($p->compare_pkg($pkg_installed) > 0) { ++ #- we selected $p, and it is still a valid choice ++ $pkg = $p; ++ } else { ++ #- $p is no good since $pkg_installed is higher version, ++ } ++ } ++ } elsif ($pkg = _choose_best_pkg($urpm, $pkg_installed, $urpm->packages_by_name($name))) { ++ #- first try with package using the same name. ++ $pkg->set_flag_installed; ++ $pkg->set_flag_upgrade; ++ } ++ if (my @pkgs = _choose_bests_obsolete($urpm, $db, $pkg_installed, _find_packages_obsoleting($urpm, $state, $pkg_installed))) { ++ if (@pkgs == 1) { ++ $pkg and $urpm->{debug_URPM}("auto-select: prefering " . $pkgs[0]->fullname . " obsoleting " . $pkg_installed->fullname . " over " . $pkg->fullname) if $urpm->{debug_URPM}; ++ $pkg = $pkgs[0]; ++ } elsif (@pkgs > 1) { ++ $urpm->{debug_URPM}("auto-select: multiple packages (" . join(' ', map { scalar $_->fullname } @pkgs) . ") obsoleting " . $pkg_installed->fullname) if $urpm->{debug_URPM}; ++ $pkg = undef; ++ } ++ } ++ if ($pkg && $options{idlist} && !grep { $pkg->id == $_ } @{$options{idlist}}) { ++ $urpm->{debug_URPM}("not auto-selecting $pkg->fullname because it's not in search medias") if $urpm->{debug_URPM}; ++ $pkg = undef; ++ } ++ ++ $pkg and $urpm->{debug_URPM}("auto-select: adding " . $pkg->fullname . " replacing " . $pkg_installed->fullname) if $urpm->{debug_URPM}; ++ ++ $by_name{$name} = $pkg; ++ }); ++ ++ foreach my $pkg (values %by_name) { ++ $pkg or next; ++ $pkg->set_flag_upgrade; ++ $requested->{$pkg->id} = $options{requested}; ++ } ++ ++ $requested; ++} ++ ++#- side-effects: none ++sub _sort_by_dependencies_get_graph { ++ my ($urpm, $state, $l) = @_; ++ my %edges; ++ foreach my $id (@$l) { ++ my $pkg = $urpm->{depslist}[$id]; ++ my @provides = map { whatrequires_id($state, $_) } $pkg->provides_nosense; ++ if (my $from = $state->{selected}{$id}{from}) { ++ unshift @provides, $from->id; ++ } ++ $edges{$id} = [ uniq(@provides) ]; ++ } ++ \%edges; ++} ++ ++#- side-effects: none ++sub reverse_multi_hash { ++ my ($h) = @_; ++ my %r; ++ my ($k, $v); ++ while (($k, $v) = each %$h) { ++ push @{$r{$_}}, $k foreach @$v; ++ } ++ \%r; ++} ++ ++sub _merge_2_groups { ++ my ($groups, $l1, $l2) = @_; ++ my $l = [ @$l1, @$l2 ]; ++ $groups->{$_} = $l foreach @$l; ++ $l; ++} ++sub _add_group { ++ my ($groups, $group) = @_; ++ ++ my ($main, @other) = uniq(grep { $_ } map { $groups->{$_} } @$group); ++ $main ||= []; ++ if (@other) { ++ $main = _merge_2_groups($groups, $main, $_) foreach @other; ++ } ++ foreach (grep { !$groups->{$_} } @$group) { ++ $groups->{$_} ||= $main; ++ push @$main, $_; ++ my @l_ = uniq(@$main); ++ @l_ == @$main or die ''; ++ } ++ # warn "# groups: ", join(' ', map { join('+', @$_) } uniq(values %$groups)), "\n"; ++} ++ ++#- nb: this handles $nodes list not containing all $nodes that can be seen in $edges ++#- ++#- side-effects: none ++sub sort_graph { ++ my ($nodes, $edges) = @_; ++ ++ #require Data::Dumper; ++ #warn Data::Dumper::Dumper($nodes, $edges); ++ ++ my %nodes_h = map { $_ => 1 } @$nodes; ++ my (%loops, %added, @sorted); ++ ++ my $recurse; $recurse = sub { ++ my ($id, @ids) = @_; ++# warn "# recurse $id @ids\n"; ++ ++ my $loop_ahead; ++ foreach my $p_id (@{$edges->{$id}}) { ++ if ($p_id == $id) { ++ # don't care ++ } elsif (exists $added{$p_id}) { ++ # already done ++ } elsif (grep { $_ == $p_id } @ids) { ++ my $begin = 1; ++ my @l = grep { $begin &&= $_ != $p_id } @ids; ++ $loop_ahead = 1; ++ _add_group(\%loops, [ $p_id, $id, @l ]); ++ } elsif ($loops{$p_id}) { ++ my $take; ++ if (my @l = grep { $take ||= $loops{$_} && $loops{$_} == $loops{$p_id} } reverse @ids) { ++ $loop_ahead = 1; ++# warn "# loop to existing one $p_id, $id, @l\n"; ++ _add_group(\%loops, [ $p_id, $id, @l ]); ++ } ++ } else { ++ $recurse->($p_id, $id, @ids); ++ #- we would need to compute loop_ahead. we will do it below only once, and if not already set ++ } ++ } ++ if (!$loop_ahead && $loops{$id} && grep { exists $loops{$_} && $loops{$_} == $loops{$id} } @ids) { ++ $loop_ahead = 1; ++ } ++ ++ if (!$loop_ahead) { ++ #- it's now a leaf or a loop we're done with ++ my @toadd = $loops{$id} ? @{$loops{$id}} : $id; ++ $added{$_} = undef foreach @toadd; ++# warn "# adding ", join('+', @toadd), " for $id\n"; ++ push @sorted, [ uniq(grep { $nodes_h{$_} } @toadd) ]; ++ } ++ }; ++ !exists $added{$_} and $recurse->($_) foreach @$nodes; ++ ++# warn "# result: ", join(' ', map { join('+', @$_) } @sorted), "\n"; ++ ++ check_graph_is_sorted(\@sorted, $nodes, $edges) or die "sort_graph failed"; ++ ++ @sorted; ++} ++ ++#- side-effects: none ++sub check_graph_is_sorted { ++ my ($sorted, $nodes, $edges) = @_; ++ ++ my $i = 1; ++ my %nb; ++ foreach (@$sorted) { ++ $nb{$_} = $i foreach @$_; ++ $i++; ++ } ++ my $nb_errors = 0; ++ my $error = sub { $nb_errors++; warn "error: $_[0]\n" }; ++ ++ foreach my $id (@$nodes) { ++ $nb{$id} or $error->("missing $id in sort_graph list"); ++ } ++ foreach my $id (keys %$edges) { ++ my $id_i = $nb{$id} or next; ++ foreach my $req (@{$edges->{$id}}) { ++ my $req_i = $nb{$req} or next; ++ $req_i <= $id_i or $error->("$req should be before $id ($req_i $id_i)"); ++ } ++ } ++ $nb_errors == 0; ++} ++ ++ ++#- side-effects: none ++sub _sort_by_dependencies__add_obsolete_edges { ++ my ($urpm, $state, $l, $requires) = @_; ++ ++ my @obsoletes = grep { $_->{obsoleted} } values %{$state->{rejected}} or return; ++ my @groups = grep { @$_ > 1 } map { [ keys %{$_->{closure}} ] } @obsoletes; ++ my %groups; ++ foreach my $group (@groups) { ++ _add_group(\%groups, $group); ++ foreach (@$group) { ++ my $rej = $state->{rejected}{$_} or next; ++ _add_group(\%groups, [ $_, keys %{$rej->{closure}} ]); ++ } ++ } ++ ++ my %fullnames = map { scalar($urpm->{depslist}[$_]->fullname) => $_ } @$l; ++ foreach my $group (uniq(values %groups)) { ++ my @group = grep { defined $_ } map { $fullnames{$_} } @$group; ++ foreach (@group) { ++ @{$requires->{$_}} = uniq(@{$requires->{$_}}, @group); ++ } ++ } ++} ++ ++#- side-effects: none ++sub sort_by_dependencies { ++ my ($urpm, $state, @list_unsorted) = @_; ++ @list_unsorted = sort { $a <=> $b } @list_unsorted; # sort by ids to be more reproductable ++ $urpm->{debug_URPM}("getting graph of dependencies for sorting") if $urpm->{debug_URPM}; ++ my $edges = _sort_by_dependencies_get_graph($urpm, $state, \@list_unsorted); ++ my $requires = reverse_multi_hash($edges); ++ ++ _sort_by_dependencies__add_obsolete_edges($urpm, $state, \@list_unsorted, $requires); ++ ++ $urpm->{debug_URPM}("sorting graph of dependencies") if $urpm->{debug_URPM}; ++ sort_graph(\@list_unsorted, $requires); ++} ++ ++sub sorted_rpms_to_string { ++ my ($urpm, @sorted) = @_; ++ ++ "rpms sorted by dependencies:\n" . join("\n", map { ++ join('+', _ids_to_names($urpm, @$_)); ++ } @sorted); ++} ++ ++#- build transaction set for given selection ++#- options: start, end, idlist, split_length, keep ++#- ++#- side-effects: $state->{transaction}, $state->{transaction_state} ++sub build_transaction_set { ++ my ($urpm, $db, $state, %options) = @_; ++ ++ #- clean transaction set. ++ $state->{transaction} = []; ++ ++ my %selected_id; ++ @selected_id{$urpm->build_listid($options{start}, $options{end}, $options{idlist})} = (); ++ ++ if ($options{split_length}) { ++ #- first step consists of sorting packages according to dependencies. ++ my @sorted = sort_by_dependencies($urpm, $state, ++ keys(%selected_id) > 0 ? ++ (grep { exists($selected_id{$_}) } keys %{$state->{selected}}) : ++ keys %{$state->{selected}}); ++ $urpm->{debug_URPM}(sorted_rpms_to_string($urpm, @sorted)) if $urpm->{debug_URPM}; ++ ++ #- second step consists of re-applying resolve_requested in the same ++ #- order computed in first step and to update a list of packages to ++ #- install, to upgrade and to remove. ++ my %examined; ++ my @todo = @sorted; ++ while (@todo) { ++ my @ids; ++ while (@todo && @ids < $options{split_length}) { ++ my $l = shift @todo; ++ push @ids, @$l; ++ } ++ my %requested = map { $_ => undef } @ids; ++ ++ resolve_requested__no_suggests_($urpm, ++ $db, $state->{transaction_state} ||= {}, ++ \%requested, ++ defined $options{start} ? (start => $options{start}) : @{[]}, ++ defined $options{end} ? (end => $options{end}) : @{[]}, ++ keep => $options{keep}, ++ ); ++ ++ my @upgrade = grep { ! exists $examined{$_} } keys %{$state->{transaction_state}{selected}}; ++ my @remove = grep { ! exists $examined{$_} } packages_to_remove($state->{transaction_state}); ++ ++ @upgrade || @remove or next; ++ ++ if (my @bad_remove = grep { !$state->{rejected}{$_}{removed} || $state->{rejected}{$_}{obsoleted} } @remove) { ++ $urpm->{error}(sorted_rpms_to_string($urpm, @sorted)) if $urpm->{error}; ++ $urpm->{error}('transaction is too small: ' . join(' ', @bad_remove) . ' is rejected but it should not (current transaction: ' . join(' ', _ids_to_fullnames($urpm, @upgrade)) . ', requested: ' . join('+', _ids_to_fullnames($urpm, @ids)) . ')') if $urpm->{error}; ++ $state->{transaction} = []; ++ last; ++ } ++ ++ $urpm->{debug_URPM}(sprintf('transaction valid: remove=%s update=%s', ++ join(',', @remove), ++ join(',', _ids_to_names($urpm, @upgrade)))) if $urpm->{debug_URPM}; ++ ++ $examined{$_} = undef foreach @upgrade, @remove; ++ push @{$state->{transaction}}, { upgrade => \@upgrade, remove => \@remove }; ++ } ++ ++ #- check that the transaction set has been correctly created. ++ #- (ie that no other package was removed) ++ if (keys(%{$state->{selected}}) == keys(%{$state->{transaction_state}{selected}}) && ++ listlength(packages_to_remove($state)) == listlength(packages_to_remove($state->{transaction_state})) ++ ) { ++ foreach (keys(%{$state->{selected}})) { ++ exists $state->{transaction_state}{selected}{$_} and next; ++ $urpm->{error}('using one big transaction') if $urpm->{error}; ++ $state->{transaction} = []; last; ++ } ++ foreach (packages_to_remove($state)) { ++ $state->{transaction_state}{rejected}{$_}{removed} && ++ !$state->{transaction_state}{rejected}{$_}{obsoleted} and next; ++ $urpm->{error}('using one big transaction') if $urpm->{error}; ++ $state->{transaction} = []; last; ++ } ++ } ++ } ++ ++ #- fallback if something can be selected but nothing has been allowed in transaction list. ++ if (%{$state->{selected} || {}} && !@{$state->{transaction}}) { ++ $urpm->{debug_URPM}('using one big transaction') if $urpm->{debug_URPM}; ++ push @{$state->{transaction}}, { ++ upgrade => [ keys %{$state->{selected}} ], ++ remove => [ packages_to_remove($state) ], ++ }; ++ } ++ ++ if ($state->{orphans_to_remove}) { ++ my @l = map { scalar $_->fullname } @{$state->{orphans_to_remove}}; ++ push @{$state->{transaction}}, { remove => \@l }; ++ } ++ ++ $state->{transaction}; ++} ++ ++1; + +Added: rpm/perl-URPM/trunk/URPM/Signature.pm +=================================================================== +--- rpm/perl-URPM/trunk/URPM/Signature.pm (rev 0) ++++ rpm/perl-URPM/trunk/URPM/Signature.pm 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,91 @@ ++package URPM; ++ ++use strict; ++use warnings; ++ ++#- parse from rpmlib db. ++#- ++#- side-effects: $urpm ++sub parse_pubkeys { ++ my ($urpm, %options) = @_; ++ ++ my $db = $options{db}; ++ $db ||= URPM::DB::open($options{root}) or die "Can't open RPM DB, aborting\n"; ++ my @keys = parse_pubkeys_($db); ++ ++ $urpm->{keys}{$_->{id}} = $_ foreach @keys; ++} ++ ++#- side-effects: none ++sub parse_pubkeys_ { ++ my ($db) = @_; ++ ++ my ($block, $content); ++ my %keys; ++ ++ $db->traverse_tag('name', [ 'gpg-pubkey' ], sub { ++ my ($p) = @_; ++ # the first blank separates the PEM headers from key data, this ++ # flags we found it: ++ my $found_blank = 0; ++ foreach (split "\n", $p->description) { ++ if ($block) { ++ if (/^$/ and not $found_blank) { ++ # All content until now were the encapsulated pem ++ # headers... ++ $content = ''; ++ $found_blank = 1; ++ } ++ elsif (/^-----END PGP PUBLIC KEY BLOCK-----$/) { ++ $keys{$p->version} = { ++ $p->summary =~ /^gpg\((.*)\)$/ ? (name => $1) : @{[]}, ++ id => $p->version, ++ content => $content, ++ block => $p->description, ++ }; ++ $block = undef; ++ $content = ''; ++ } ++ else { ++ $content .= $_; ++ } ++ } ++ $block ||= /^-----BEGIN PGP PUBLIC KEY BLOCK-----$/; ++ } ++ }); ++ ++ values %keys; ++} ++ ++#- obsoleted ++sub import_needed_pubkeys { ++ warn "import_needed_pubkeys prototype has changed, please give a file directly\n"; ++ return; ++} ++ ++#- import pubkeys only if it is needed. ++sub import_needed_pubkeys_from_file { ++ my ($db, $pubkey_file, $o_callback) = @_; ++ ++ my @keys = parse_pubkeys_($db); ++ ++ my $keyid = substr get_gpg_fingerprint($pubkey_file), 8; ++ my ($kv) = grep { (hex($keyid) == hex($_->{id})) } @keys; ++ my $imported; ++ if (!$kv) { ++ if (!import_pubkey_file($db, $pubkey_file)) { ++ #$urpm->{debug_URPM}("Couldn't import public key from ".$pubkey_file) if $urpm->{debug_URPM}; ++ $imported = 0; ++ } else { ++ $imported = 1; ++ } ++ @keys = parse_pubkeys_($db); ++ ($kv) = grep { (hex($keyid) == hex($_->{id})) } @keys; ++ } ++ ++ #- let the caller know about what has been found. ++ #- this is an error if the key is not found. ++ $o_callback and $o_callback->($kv?$kv->{id}:undef, $imported); ++} ++ ++1; + +Added: rpm/perl-URPM/trunk/URPM.pm +=================================================================== +--- rpm/perl-URPM/trunk/URPM.pm (rev 0) ++++ rpm/perl-URPM/trunk/URPM.pm 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,879 @@ ++package URPM; ++ ++use strict; ++use warnings; ++use DynaLoader; ++ ++# different files, but same package ++# require them here to avoid dependencies ++use URPM::Build; ++use URPM::Resolve; ++use URPM::Signature; ++ ++our @ISA = qw(DynaLoader); ++our $VERSION = '3.38'; ++ ++URPM->bootstrap($VERSION); ++ ++sub new { ++ my ($class, %options) = @_; ++ my $self = bless { ++ depslist => [], ++ provides => {}, ++ obsoletes => {}, ++ }, $class; ++ $self->{nofatal} = 1 if $options{nofatal}; ++ $self; ++} ++ ++sub set_nofatal { $_[0]{nofatal} = $_[1] } ++ ++sub packages_providing { ++ my ($urpm, $name) = @_; ++ grep { $_ } map { $urpm->{depslist}[$_] } keys %{$urpm->{provides}{$name} || {}}; ++} ++ ++sub packages_obsoleting { ++ my ($urpm, $name) = @_; ++ map { $urpm->{depslist}[$_] } keys %{$urpm->{obsoletes}{$name} || {}}; ++} ++ ++sub packages_by_name { ++ my ($urpm, $name) = @_; ++ grep { $name eq $_->name } packages_providing($urpm, $name); ++} ++ ++sub search { ++ my ($urpm, $name, %options) = @_; ++ my $best; ++ ++ #- tries other alternative if no strict searching. ++ unless ($options{strict_name}) { ++ if ($name =~ /^(.*)-([^\-]*)-([^\-]*)\.([^\.\-]*)$/) { ++ foreach my $pkg (packages_providing($urpm, $1)) { ++ $pkg->fullname eq $name and return $pkg; ++ } ++ } ++ unless ($options{strict_fullname}) { ++ if ($name =~ /^(.*)-([^\-]*)-([^\-]*)$/) { ++ foreach my $pkg (packages_providing($urpm, $1)) { ++ my ($n, $v, $r, $a) = $pkg->fullname; ++ $options{src} && $a eq 'src' || $pkg->is_arch_compat or next; ++ "$n-$v-$r" eq $name or next; ++ !$best || $pkg->compare_pkg($best) > 0 and $best = $pkg; ++ } ++ $best and return $best; ++ } ++ if ($name =~ /^(.*)-([^\-]*)$/) { ++ foreach my $pkg (packages_providing($urpm, $1)) { ++ my ($n, $v, undef, $a) = $pkg->fullname; ++ $options{src} && $a eq 'src' || $pkg->is_arch_compat or next; ++ "$n-$v" eq $name or next; ++ !$best || $pkg->compare_pkg($best) > 0 and $best = $pkg; ++ } ++ $best and return $best; ++ } ++ } ++ } ++ ++ unless ($options{strict_fullname}) { ++ foreach my $pkg (packages_providing($urpm, $name)) { ++ my ($n, undef, undef, $a) = $pkg->fullname; ++ $options{src} && $a eq 'src' || $pkg->is_arch_compat or next; ++ $n eq $name or next; ++ !$best || $pkg->compare_pkg($best) > 0 and $best = $pkg; ++ } ++ } ++ ++ return $best; ++} ++ ++#- Olivier Thauvin: ++#- Returns @$listid, $start .. $end or the whole deplist id ++#- according to the given args ++sub build_listid { ++ my ($urpm, $start, $end, $listid) = @_; ++ ++ @{$listid || []} > 0 ? @$listid : ++ (($start || 0) .. (defined($end) ? $end : $#{$urpm->{depslist}})); ++} ++ ++#- this is used when faking a URPM::DB: $urpm can be used as-a $db ++#- (used for urpmi --env) ++sub traverse { ++ my ($urpm, $callback) = @_; ++ ++ if ($callback) { ++ foreach my $p (@{$urpm->{depslist} || []}) { ++ $callback->($p); ++ } ++ } ++ ++ scalar @{$urpm->{depslist} || []}; ++} ++ ++ ++#- this is used when faking a URPM::DB: $urpm can be used as-a $db ++#- (used for urpmi --env) ++sub traverse_tag { ++ my ($urpm, $tag, $names, $callback) = @_; ++ my $count = 0; ++ my %names; ++ ++ if (@{$names || []}) { ++ if ($tag eq 'name') { ++ foreach my $n (@$names) { ++ foreach my $p (packages_providing($urpm, $n)) { ++ $p->name eq $n or next; ++ $callback and $callback->($p); ++ ++$count; ++ } ++ } ++ } elsif ($tag eq 'whatprovides') { ++ foreach (@$names) { ++ foreach (keys %{$urpm->{provides}{$_} || {}}) { ++ $callback and $callback->($urpm->{depslist}[$_]); ++ ++$count; ++ } ++ } ++ } else { ++ @names{@$names} = (); ++ if ($tag eq 'whatrequires') { ++ foreach (@{$urpm->{depslist} || []}) { ++ if (grep { exists $names{$_} } $_->requires_nosense) { ++ $callback and $callback->($_); ++ ++$count; ++ } ++ } ++ } elsif ($tag eq 'whatconflicts') { ++ foreach (@{$urpm->{depslist} || []}) { ++ if (grep { exists $names{$_} } $_->conflicts_nosense) { ++ $callback and $callback->($_); ++ ++$count; ++ } ++ } ++ } elsif ($tag eq 'group') { ++ foreach (@{$urpm->{depslist} || []}) { ++ if (exists $names{$_->group}) { ++ $callback and $callback->($_); ++ ++$count; ++ } ++ } ++ } elsif ($tag eq 'triggeredby' || $tag eq 'path') { ++ foreach (@{$urpm->{depslist} || []}) { ++ if (grep { exists $names{$_} } $_->files, grep { m!^/! } $_->provides_nosense) { ++ $callback and $callback->($_); ++ ++$count; ++ } ++ } ++ } else { ++ die "unknown tag"; ++ } ++ } ++ } ++ ++ $count; ++} ++ ++# wrapper around XS functions ++# it handles error cases ++sub _parse_hdlist_or_synthesis { ++ my ($parse_func, $urpm, $file, %options) = @_; ++ ++ my $previous_indice = @{$urpm->{depslist}}; ++ if (my ($start, $end) = $parse_func->($urpm, $file, %options)) { ++ ($start, $end); ++ } elsif (!$options{callback}) { ++ #- parse_hdlist__XS may have added some pkgs to {depslist}, ++ #- but we don't want those pkgs since reading hdlist failed later. ++ #- so we need to drop them ++ #- FIXME: {provides} would need to be reverted too! ++ splice(@{$urpm->{depslist}}, $previous_indice); ++ (); ++ } else { ++ #- we need to keep them since the callback has been used ++ #- and we can't pretend we didn't parse anything ++ #- (needed for genhdlist2) ++ (); ++ } ++} ++sub parse_synthesis { _parse_hdlist_or_synthesis(\&parse_synthesis__XS, @_) } ++sub parse_hdlist { _parse_hdlist_or_synthesis(\&parse_hdlist__XS, @_) } ++ ++sub add_macro { ++ my ($s) = @_; ++ #- quote for rpmlib, *sigh* ++ $s =~ s/\n/\\\n/g; ++ add_macro_noexpand($s); ++} ++ ++package URPM::Package; ++our @ISA = qw(); # help perl_checker ++ ++#- debug help for urpmi ++sub dump_flags { ++ my ($pkg) = @_; ++ <<EODUMP; ++available: ${\($pkg->flag_available)} ++base: ${\($pkg->flag_base)} ++disable_obsolete: ${\($pkg->flag_disable_obsolete)} ++installed: ${\($pkg->flag_installed)} ++requested: ${\($pkg->flag_requested)} ++required: ${\($pkg->flag_required)} ++selected: ${\($pkg->flag_selected)} ++skip: ${\($pkg->flag_skip)} ++upgrade: ${\($pkg->flag_upgrade)} ++EODUMP ++} ++ ++my %arch_cache; ++sub is_arch_compat { ++ my ($pkg) = @_; ++ my $arch = $pkg->arch; ++ exists $arch_cache{$arch} and return $arch_cache{$arch}; ++ ++ $arch_cache{$arch} = is_arch_compat__XS($pkg); ++} ++ ++sub changelogs { ++ my ($pkg) = @_; ++ ++ my @ti = $pkg->changelog_time or return; ++ my @na = $pkg->changelog_name or return; ++ my @tx = $pkg->changelog_text or return; ++ map { ++ { time => $ti[$_], name => $na[$_], text => $tx[$_] }; ++ } 0 .. $#ti; ++} ++ ++package URPM::Transaction; ++our @ISA = qw(); # help perl_checker ++ ++package URPM::DB; ++our @ISA = qw(); # help perl_checker ++ ++1; ++ ++__END__ ++ ++=head1 NAME ++ ++URPM - Manipulate RPM files and headers ++ ++=head1 SYNOPSIS ++ ++ use URPM; ++ ++ # using the local RPM database ++ my $db = URPM::DB::open(); ++ $db->traverse(sub { ++ my ($package) = @_; # this is a URPM::Package object ++ print $package->name, "\n"; ++ # ... ++ }); ++ ++ # loading and parsing a synthesis file ++ my $urpm = new URPM; ++ $urpm->parse_synthesis("synthesis.sample.cz"); ++ $urpm->traverse(sub { ++ # retrieve all packages from the dependency list ++ # ... ++ }); ++ ++=head1 DESCRIPTION ++ ++The URPM module allows you to manipulate RPM files, RPM header files and ++hdlist files and manage them in memory. It is notably used by the C<urpmi> ++utility. It provides four classes : C<URPM>, C<URPM::DB>, C<URPM::Package>, ++and C<URPM::Transaction>. ++ ++=head2 The URPM class ++ ++=over 4 ++ ++=item URPM->new() ++ ++The constructor creates a new, empty URPM object. It's a blessed hash that ++contains two fields: ++ ++B<depslist> is an arrayref containing the list of depending packages (which are ++C<URPM::Package> objects). ++ ++B<provides> is an hashref containing as keys the list of property names ++provided by the URPM object. The associated value is true if the property is ++versioned. ++ ++If the constructor is called with the arguments C<< nofatal => 1 >>, various ++fatal error messages are suppressed (file not found in parse_hdlist() and ++parse_synthesis()). ++ ++=item URPM::read_config_files() ++ ++Force the re-reading of the RPM configuration files. ++ ++=item URPM::ranges_overlap($range1, $range2 [, $nopromoteepoch]) ++ ++This utility function compares two version ranges, in order to calculate ++dependencies properly. The ranges have roughly the form ++ ++ [<|<=|==|=>|>] [epoch:]version[-release] ++ ++where epoch, version and release are RPM-style version numbers. ++ ++If the optional parameter $nopromoteepoch is true, and if the 2nd range has no ++epoch while the first one has one, then the 2nd range is assumed to have an ++epoch C<== 0>. ++ ++B<Warning>: $nopromoteepoch actually defaults to 1, so if you're going to ++pass a variable, make sure undef is treated like 1, not 0. ++ ++=item $urpm->parse_synthesis($file [, callback => sub {...} ]) ++ ++This method gets the B<depslist> and the B<provides> from a synthesis file ++and adds them to the URPM object. ++ ++=item $urpm->parse_hdlist($file, %options) ++ ++This method loads rpm informations from rpm headers contained in an hdlist ++file and adds them to the URPM object. Allowed options are ++ ++ packing => 0 / 1 ++ callback => sub { ... } ++ keep_all_tags => 0 / 1 ++ ++The return value is a two-element array containing the first and the last id ++parsed. ++ ++=item $urpm->parse_rpm($file, %options) ++ ++This method gets the B<depslist> and the B<provides> from an RPM file ++and adds them to the URPM object. Allowed options are ++ ++ packing => 0 / 1 ++ keep_all_tags => 0 / 1 ++ callback => sub { ... } ++ ++If C<keep_all_tags> isn't specified, URPM will drop all memory-consuming tags ++(notably changelogs, filelists, scriptlets). ++ ++=item $urpm->packages_providing($name) ++ ++Returns a list of C<URPM::Package> providing <$name> ++ ++=item $urpm->packages_by_name($name) ++ ++Returns a list of C<URPM::Package> corresponding to the wanted <$name> ++ ++=item $urpm->search($name, %options) ++ ++Search an RPM by name or by part of name in the list of RPMs represented by ++this $urpm. The behaviour of the search is influenced by several options: ++ ++ strict_name => 0 / 1 ++ strict_fullname => 0 / 1 ++ src => 0 / 1 ++ ++=item $urpm->traverse($callback) ++ ++Executes the callback for each package in the depslist, passing a ++C<URPM::Package> object as argument the callback. ++ ++This is used when faking a URPM::DB: $urpm can be used as-a $db ++ ++=item $urpm->traverse_tag($tag, $names, $callback) ++ ++$tag may be one of C<name>, C<whatprovides>, C<whatrequires>, C<whatconflicts>, ++C<group>, C<triggeredby>, or C<path>. ++$names is a reference to an array, holding the acceptable values of the said ++tag for the searched variables. ++Then, $callback is called for each matching package in the depslist. ++ ++This is used when faking a URPM::DB: $urpm can be used as-a $db ++ ++=item URPM::verify_rpm($file, %options) ++ ++Verifies an RPM file. ++Returns 0 on failure, 1 on success. ++Recognized options are: ++ ++ nodigests => 0 / 1 ++ nosignatures => 0 / 1 ++ ++=item URPM::verify_signature($file) ++ ++Verifies the signature of an RPM file. Returns a string that will contain "OK" ++or "NOT OK" as well as a description of the found key (if successful) or of the ++error (if signature verification failed.) ++ ++=item $urpm->import_pubkey(%options) ++ ++Imports a key in the RPM database. ++ ++ db => $urpm_db ++ root => '...' ++ block => '...' ++ filename => '...' ++ ++=item URPM::spec2srcheader($specfile) ++ ++Returns a URPM::Package object containing the header of the source rpm produced ++by the evaluation of the specfile whose path is given as argument. All ++dependencies stored in this header are exactly the one needed to build the ++specfile. ++ ++=back ++ ++=head2 The URPM::DB class ++ ++=over 4 ++ ++=item open($prefix, $write_perm) ++ ++Returns a new C<URPM::DB> object pointing on the local RPM database (or ++C<undef> on failure). ++ ++$prefix defaults to C<""> and indicates the RPM DB root directory prefix if ++any. (See the B<--root> option to rpm(1)). ++ ++$write_perm is a boolean that defaults to false, and that indicates whether ++the RPM DB should be open in read/write mode. ++ ++=item rebuild($prefix) ++ ++Rebuilds the RPM database (like C<rpm --rebuilddb>). $prefix defaults to C<"">. ++ ++=item $db->traverse($callback) ++ ++Executes the specified callback (a code reference) for each package ++in the DB, passing a C<URPM::Package> object as argument the callback. ++ ++=item $db->traverse_tag($tag,$names,$callback) ++ ++$tag may be one of C<name>, C<whatprovides>, C<whatrequires>, C<whatconflicts>, ++C<group>, C<triggeredby>, or C<path>. ++$names is a reference to an array, holding the acceptable values of the said ++tag for the searched variables. ++Then, $callback is called for each matching package in the DB. ++ ++=item $db->traverse_tag_find($tag,$name,$callback) ++ ++Quite similar to C<traverse_tag>, but stops when $callback returns true. ++ ++(also note that only one $name is handled) ++ ++=item $db->create_transaction($prefix) ++ ++Creates and returns a new transaction (an C<URPM::Transaction> object) on the ++specified DB. For $prefix, cf L<open>. ++ ++=back ++ ++=head2 The URPM::Package class ++ ++Most methods of C<URPM::Package> are accessors for the various properties ++of an RPM package. ++ ++=over 4 ++ ++=item $package->arch() ++ ++Gives the package architecture ++ ++=item $package->build_header($fileno) ++ ++Writes the rpm header to the specified file ($fileno being an integer). ++ ++=item $package->build_info($fileno, [$provides_files]) ++ ++Writes a line of information in a synthesis file. ++ ++=item $package->buildarchs() ++ ++=item $package->buildhost() ++ ++=item $package->buildtime() ++ ++=item $package->changelog_name() ++ ++=item $package->changelog_text() ++ ++=item $package->changelog_time() ++ ++=item $package->compare($evr) ++ ++=item $package->compare_pkg($other_pkg) ++ ++=item $package->conf_files() ++ ++=item $package->conflicts() ++ ++=item $package->conflicts_nosense() ++ ++=item $package->description() ++ ++=item $package->dirnames() ++ ++=item $package->distribution() ++ ++=item $package->epoch() ++ ++=item $package->excludearchs() ++ ++=item $package->exclusivearchs() ++ ++=item $package->filelinktos() ++ ++=item $package->files() ++ ++List of files in this rpm. ++ ++=item $package->files_flags() ++ ++=item $package->files_gid() ++ ++=item $package->files_group() ++ ++=item $package->files_md5sum() ++ ++=item $package->files_mode() ++ ++=item $package->files_mtime() ++ ++=item $package->files_owner() ++ ++=item $package->files_size() ++ ++=item $package->files_uid() ++ ++=item $package->flag($name) ++ ++=item $package->flag_available() ++ ++=item $package->flag_base() ++ ++=item $package->flag_disable_obsolete() ++ ++=item $package->flag_installed() ++ ++=item $package->flag_requested() ++ ++=item $package->flag_required() ++ ++=item $package->flag_selected() ++ ++=item $package->flag_skip() ++ ++=item $package->flag_upgrade() ++ ++=item $package->free_header() ++ ++=item $package->fullname() ++ ++Returns a 4 element list: name, version, release and architecture in an array ++context. Returns a string NAME-VERSION-RELEASE.ARCH in scalar context. ++ ++=item $package->get_tag($tagid) ++ ++Returns an array containing values of $tagid. $tagid is the numerical value of ++rpm tags. See rpmlib.h. ++ ++=item $package->queryformat($format) ++ ++Querying the package like rpm --queryformat do. ++ ++The function calls directly the rpmlib, then use header informations, so it ++silently failed if you use synthesis instead of hdlist/rpm/header files or rpmdb. ++ ++=item $package->get_tag_modifiers($tagid) ++ ++Return an array of human readable view of tag values. $tagid is the numerical value of rpm tags. ++ ++=item $package->group() ++ ++=item $package->id() ++ ++=item $package->installtid() ++ ++=item $package->is_arch_compat() ++ ++Returns whether this package is compatible with the current machine's ++architecture. 0 means not compatible. The lower the result is, the preferred ++the package is. ++ ++=item $package->is_platform_compat() ++ ++Return whether this package is compatible with the current machine's ++platform configuration (/etc/rpm/platform). 0 mean not compatible. ++The lower the result is the preferred the package is. ++ ++=item $package->license() ++ ++=item $package->name() ++ ++The rpm's bare name. ++ ++=item $package->obsoletes() ++ ++=item $package->obsoletes_nosense() ++ ++=item $package->obsoletes_overlap($s, [$nopromoteepoch, [$direction] ]) ++ ++=item $package->os() ++ ++=item $package->pack_header() ++ ++=item $package->packager() ++ ++=item $package->payload_format() ++ ++=item $package->provides() ++ ++=item $package->provides_nosense() ++ ++=item $package->provides_overlap($s, [$nopromoteepoch,] [$direction]) ++ ++=item $package->rate() ++ ++=item $package->release() ++ ++=item $package->requires() ++ ++=item $package->requires_nosense() ++ ++=item $package->rflags() ++ ++=item $package->filesize() ++ ++Size of the rpm file (ie the rpm header + cpio body) ++ ++=item $package->set_flag($name, $value) ++ ++=item $package->set_flag_base($value) ++ ++=item $package->set_flag_disable_obsolete($value) ++ ++=item $package->set_flag_installed($value) ++ ++=item $package->set_flag_requested($value) ++ ++=item $package->set_flag_required($value) ++ ++=item $package->set_flag_skip($value) ++ ++=item $package->set_flag_upgrade($value) ++ ++=item $package->set_id($id) ++ ++=item $package->set_rate($rate) ++ ++=item $package->set_rflags(...) ++ ++=item $package->size() ++ ++=item $package->sourcerpm() ++ ++=item $package->summary() ++ ++=item $package->update_header($filename, ...) ++ ++=item $package->url() ++ ++=item $package->vendor() ++ ++=item $package->version() ++ ++=back ++ ++=head2 The URPM::Transaction class ++ ++=over 4 ++ ++=item $trans->set_script_fd($fileno) ++ ++Sets the transaction output filehandle. ++ ++=item $trans->add($pkg, %options) ++ ++Adds a package to be installed to the transaction represented by $trans. ++$pkg is an C<URPM::Package> object. ++ ++Options are: ++ ++ update => 0 / 1 : indicates whether this is an upgrade ++ excludepath => [ ... ] ++ ++=item $trans->remove($name) ++ ++Adds a package to be erased to the transaction represented by $trans. ++$name is the name of the package. ++ ++=item $trans->check(%options) ++ ++Checks that all dependencies can be resolved in this transaction. ++ ++Options are: ++ ++ translate_message => 0 / 1 (currently ignored.) ++ ++In list context, returns an array of problems (an empty array indicates ++success). ++ ++=item $trans->order() ++ ++Determines package order in a transaction set according to dependencies. In ++list context, returns an array of problems (an empty array indicates success). ++ ++=item $trans->run($data, %options) ++ ++Runs the transaction. ++ ++$data is an arbitrary user-provided piece of data to be passed to callbacks. ++ ++Recognized options are: ++ ++ callback_close => sub { ... } ++ callback_inst => sub { ... } ++ callback_open => sub { ... } ++ callback_trans => sub { ... } ++ callback_uninst => sub { ... } ++ delta => used for progress callbacks (trans, uninst, inst) ++ excludedocs => 0 / 1 ++ force => 0 / 1 ++ ignorearch => 0 / 1 ++ nosize => 0 / 1 ++ noscripts => 0 / 1 ++ oldpackage => 0 / 1 ++ repackage => 0 / 1 ++ test => 0 / 1 ++ translate_message => 1 ++ ++They roughly correspond to command-line options to rpm(1). ++ ++=item $trans->traverse($callback) ++ ++Executes the specified callback (a code reference) for each package in the ++transaction, passing a C<URPM::Package> object as argument the callback. ++ ++=back ++ ++=head2 Macro handling functions ++ ++=over ++ ++=item loadmacrosfile($filename) ++ ++Load the specified macro file. Sets $! if the file can't be read. ++ ++=item expand($name) ++ ++Expands the specified macro. ++ ++=item add_macro($macro_definition) ++ ++=item add_macro_noexpand($macro_definition) ++ ++Define a macro. For example, ++ ++ URPM::add_macro("vendor Mageia"); ++ my $vendor = URPM::expand("%vendor"); ++ ++The 'noexpand' version doesn't expand literal newline characters in the ++macro definition. ++ ++=item del_macro($name) ++ ++Delete a macro. ++ ++=item resetmacros() ++ ++Destroys macros. ++ ++=item setVerbosity($level) ++ ++Sets rpm verbosity level. $level is an integer between 2 (RPMMESS_CRIT) and 7 ++(RPMMESS_DEBUG). ++ ++=item rpmErrorString() ++ ++=item rpmErrorWriteTo($fd) ++ ++=item platformscore($platform) ++ ++Return the score of $platform according computer's configuration. ++0 mean not compatible, lower is prefered. ++ ++=item archscore($arch) ++ ++Return the score of the given arch. 0 mean not compatible, ++lower is prefered. ++ ++=item osscore($os) ++ ++Return the score of the given os. 0 mean not compatible, ++lower is prefered. ++ ++=back ++ ++=head2 The $state object ++ ++It has the following fields: ++ ++B<backtrack>: { ++ selected => { id => undef }, ++ deadlock => { id|property => undef }, ++ } ++ ++B<cached_installed>: { property_name => { fullname => undef } } ++ ++B<oldpackage>: int ++ # will be passed to $trans->run to set RPMPROB_FILTER_OLDPACKAGE ++ ++B<selected>: { id => { ++ requested => bool, install => bool, ++ from => pkg, psel => pkg, ++ promote => name, unsatisfied => [ id|property ] ++ } } ++ ++B<rejected>: { fullname => { ++ size => int, removed => { fullname|"asked" => undef }, ++ obsoleted => { fullname|"asked" => undef }, ++ backtrack => { # those info are only used to display why package is unselected ++ promote => [ name ], keep => [ fullname ], ++ unsatisfied => [ id|property ], ++ conflicts => [ fullname ], ++ }, ++ closure => { fullname => { old_requested => bool, ++ unsatisfied => [ id|property ], ++ conflicts => property }, ++ avoid => bool }, ++ }, ++ } } ++ ++B<rejected_already_installed>: { id => pkg } ++ ++B<orphans_to_remove>: [ pkg ] ++ ++B<whatrequires>: { name => { id => undef } } ++ # reversed requires_nosense for selected packages ++ ++B<unselected_uninstalled>: [ pkg ] ++ # (old) packages which are needed, but installed package is newer ++ ++more fields only used in build_transaction_set and its callers): ++ ++B<transaction>: [ { upgrade => [ id ], remove => [ fullname ] } ] ++ ++B<transaction_state>: $state object ++ ++=head1 COPYRIGHT ++ ++Copyright 2002, 2003, 2004, 2005 MandrakeSoft SA ++ ++Copyright 2005, 2006, 2007, 2008 Mandriva SA ++ ++FranE<ccedil>ois Pons (original author), Rafael Garcia-Suarez, Pixel <<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">pixel at mandriva.com</A>> (current maintainer) ++ ++This library is free software; you can redistribute it and/or modify it under ++the same terms as Perl itself. ++ ++=cut + +Added: rpm/perl-URPM/trunk/URPM.xs +=================================================================== +--- rpm/perl-URPM/trunk/URPM.xs (rev 0) ++++ rpm/perl-URPM/trunk/URPM.xs 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,3995 @@ ++/* Copyright (c) 2002, 2003, 2004, 2005 MandrakeSoft SA ++ * Copyright (c) 2005, 2006, 2007, 2008 Mandriva SA ++ * ++ * All rights reserved. ++ * This program is free software; you can redistribute it and/or ++ * modify it under the same terms as Perl itself. ++ * ++ * $Id: URPM.xs 259125 2009-08-10 14:37:07Z cfergeau $ ++ * ++ */ ++#include "EXTERN.h" ++#include "perl.h" ++#include "XSUB.h" ++ ++#include <sys/utsname.h> ++#include <sys/select.h> ++#include <sys/time.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <sys/wait.h> ++#include <fcntl.h> ++#include <unistd.h> ++#include <zlib.h> ++#include <libintl.h> ++ ++#undef Fflush ++#undef Mkdir ++#undef Stat ++#undef Fstat ++ ++#ifdef RPM_ORG ++static inline void *_free(const void * p) { ++ if (p != NULL) free((void *)p); ++ return NULL; ++} ++typedef struct rpmSpec_s * Spec; ++#else ++#include <rpm/rpm46compat.h> ++#endif ++ ++#include <rpm/rpmio.h> ++#include <rpm/rpmdb.h> ++#include <rpm/rpmts.h> ++#include <rpm/rpmte.h> ++#include <rpm/rpmps.h> ++#include <rpm/rpmpgp.h> ++#include <rpm/rpmcli.h> ++#include <rpm/rpmbuild.h> ++#include <rpm/rpmlog.h> ++ ++struct s_Package { ++ char *info; ++ int filesize; ++ char *requires; ++ char *suggests; ++ char *obsoletes; ++ char *conflicts; ++ char *provides; ++ char *rflags; ++ char *summary; ++ unsigned flag; ++ Header h; ++}; ++ ++struct s_Transaction { ++ rpmts ts; ++ int count; ++}; ++ ++struct s_TransactionData { ++ SV* callback_open; ++ SV* callback_close; ++ SV* callback_trans; ++ SV* callback_uninst; ++ SV* callback_inst; ++ long min_delta; ++ SV *data; /* chain with another data user provided */ ++}; ++ ++typedef struct s_Transaction* URPM__DB; ++typedef struct s_Transaction* URPM__Transaction; ++typedef struct s_Package* URPM__Package; ++ ++#define FLAG_ID 0x001fffffU ++#define FLAG_RATE 0x00e00000U ++#define FLAG_BASE 0x01000000U ++#define FLAG_SKIP 0x02000000U ++#define FLAG_DISABLE_OBSOLETE 0x04000000U ++#define FLAG_INSTALLED 0x08000000U ++#define FLAG_REQUESTED 0x10000000U ++#define FLAG_REQUIRED 0x20000000U ++#define FLAG_UPGRADE 0x40000000U ++#define FLAG_NO_HEADER_FREE 0x80000000U ++ ++#define FLAG_ID_MAX 0x001ffffe ++#define FLAG_ID_INVALID 0x001fffff ++ ++#define FLAG_RATE_POS 21 ++#define FLAG_RATE_MAX 5 ++#define FLAG_RATE_INVALID 0 ++ ++ ++#define FILENAME_TAG 1000000 ++#define FILESIZE_TAG 1000001 ++ ++#define FILTER_MODE_ALL_FILES 0 ++#define FILTER_MODE_CONF_FILES 2 ++ ++/* promote epoch sense should be : ++ 0 for compability with old packages ++ 1 for rpm 4.2 and better new approach. */ ++#define PROMOTE_EPOCH_SENSE 1 ++ ++static ssize_t write_nocheck(int fd, const void *buf, size_t count) { ++ return write(fd, buf, count); ++} ++static const void* unused_variable(const void *p) { ++ return p; ++} ++ ++static int rpmError_callback_data; ++ ++int rpmError_callback() { ++ write_nocheck(rpmError_callback_data, rpmlogMessage(), strlen(rpmlogMessage())); ++ return RPMLOG_DEFAULT; ++} ++ ++static int rpm_codeset_is_utf8 = 0; ++ ++static SV* ++newSVpv_utf8(const char *s, STRLEN len) ++{ ++ SV *sv = newSVpv(s, len); ++ SvUTF8_on(sv); ++ return sv; ++} ++ ++static void ++get_fullname_parts(URPM__Package pkg, char **name, char **version, char **release, char **arch, char **eos) { ++ char *_version = NULL, *_release = NULL, *_arch = NULL, *_eos = NULL; ++ ++ if ((_eos = strchr(pkg->info, '@')) != NULL) { ++ *_eos = 0; /* mark end of string to enable searching backwards */ ++ if ((_arch = strrchr(pkg->info, '.')) != NULL) { ++ *_arch = 0; ++ if ((release != NULL || version != NULL || name != NULL) && (_release = strrchr(pkg->info, '-')) != NULL) { ++ *_release = 0; ++ if ((version != NULL || name != NULL) && (_version = strrchr(pkg->info, '-')) != NULL) { ++ if (name != NULL) *name = pkg->info; ++ if (version != NULL) *version = _version + 1; ++ } ++ if (release != NULL) *release = _release + 1; ++ *_release = '-'; ++ } ++ if (arch != NULL) *arch = _arch + 1; ++ *_arch = '.'; ++ } ++ if (eos != NULL) *eos = _eos; ++ *_eos = '@'; ++ } ++} ++ ++static char * ++get_name(Header header, int32_t tag) { ++ struct rpmtd_s val; ++ ++ headerGet(header, tag, &val, HEADERGET_MINMEM); ++ char *name = (char *) rpmtdGetString(&val); ++ return name ? name : ""; ++} ++ ++static int ++get_int(Header header, int32_t tag) { ++ struct rpmtd_s val; ++ ++ headerGet(header, tag, &val, HEADERGET_DEFAULT); ++ uint32_t *ep = rpmtdGetUint32(&val); ++ return ep ? *ep : 0; ++} ++ ++static int ++sigsize_to_filesize(int sigsize) { ++ return sigsize + 440; /* 440 is the rpm header size (?) empirical, but works */ ++} ++ ++static int ++print_list_entry(char *buff, int sz, const char *name, uint32_t flags, const char *evr) { ++ int len = strlen(name); ++ char *p = buff; ++ ++ if (len >= sz || !strncmp(name, "rpmlib(", 7)) return -1; ++ memcpy(p, name, len); p += len; ++ ++ if (flags & (RPMSENSE_PREREQ|RPMSENSE_SCRIPT_PREUN|RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POSTUN|RPMSENSE_SCRIPT_POST)) { ++ if (p - buff + 3 >= sz) return -1; ++ memcpy(p, "[*]", 4); p += 3; ++ } ++ if (evr != NULL) { ++ len = strlen(evr); ++ if (len > 0) { ++ if (p - buff + 6 + len >= sz) return -1; ++ *p++ = '['; ++ if (flags & RPMSENSE_LESS) *p++ = '<'; ++ if (flags & RPMSENSE_GREATER) *p++ = '>'; ++ if (flags & RPMSENSE_EQUAL) *p++ = '='; ++ if ((flags & (RPMSENSE_LESS|RPMSENSE_EQUAL|RPMSENSE_GREATER)) == RPMSENSE_EQUAL) *p++ = '='; ++ *p++ = ' '; ++ memcpy(p, evr, len); p+= len; ++ *p++ = ']'; ++ } ++ } ++ *p = 0; /* make sure to mark null char, Is it really necessary ? */ ++ ++ return p - buff; ++} ++ ++static int ++ranges_overlap(uint32_t aflags, char *sa, uint32_t bflags, char *sb, int b_nopromote) { ++ if (!aflags || !bflags) ++ return 1; /* really faster to test it there instead of later */ ++ else { ++ int sense = 0; ++ char *eosa = strchr(sa, ']'); ++ char *eosb = strchr(sb, ']'); ++ char *ea, *va, *ra, *eb, *vb, *rb; ++ ++ if (eosa) *eosa = 0; ++ if (eosb) *eosb = 0; ++ /* parse sa as an [epoch:]version[-release] */ ++ for (ea = sa; *sa >= '0' && *sa <= '9'; ++sa); ++ if (*sa == ':') { ++ *sa++ = 0; /* ea could be an empty string (should be interpreted as 0) */ ++ va = sa; ++ } else { ++ va = ea; /* no epoch */ ++ ea = NULL; ++ } ++ if ((ra = strrchr(sa, '-'))) *ra++ = 0; ++ /* parse sb as an [epoch:]version[-release] */ ++ for (eb = sb; *sb >= '0' && *sb <= '9'; ++sb); ++ if (*sb == ':') { ++ *sb++ = 0; /* ea could be an empty string (should be interpreted as 0) */ ++ vb = sb; ++ } else { ++ vb = eb; /* no epoch */ ++ eb = NULL; ++ } ++ if ((rb = strrchr(sb, '-'))) *rb++ = 0; ++ /* now compare epoch */ ++ if (ea && eb) ++ sense = rpmvercmp(*ea ? ea : "0", *eb ? eb : "0"); ++ else if (ea && *ea && atol(ea) > 0) ++ sense = b_nopromote ? 1 : 0; ++ else if (eb && *eb && atol(eb) > 0) ++ sense = -1; ++ /* now compare version and release if epoch has not been enough */ ++ if (sense == 0) { ++ sense = rpmvercmp(va, vb); ++ if (sense == 0 && ra && *ra && rb && *rb) ++ sense = rpmvercmp(ra, rb); ++ } ++ /* restore all character that have been modified inline */ ++ if (rb) rb[-1] = '-'; ++ if (ra) ra[-1] = '-'; ++ if (eb) vb[-1] = ':'; ++ if (ea) va[-1] = ':'; ++ if (eosb) *eosb = ']'; ++ if (eosa) *eosa = ']'; ++ /* finish the overlap computation */ ++ if (sense < 0 && ((aflags & RPMSENSE_GREATER) || (bflags & RPMSENSE_LESS))) ++ return 1; ++ else if (sense > 0 && ((aflags & RPMSENSE_LESS) || (bflags & RPMSENSE_GREATER))) ++ return 1; ++ else if (sense == 0 && (((aflags & RPMSENSE_EQUAL) && (bflags & RPMSENSE_EQUAL)) || ++ ((aflags & RPMSENSE_LESS) && (bflags & RPMSENSE_LESS)) || ++ ((aflags & RPMSENSE_GREATER) && (bflags & RPMSENSE_GREATER)))) ++ return 1; ++ else ++ return 0; ++ } ++} ++ ++static int has_old_suggests; ++int32_t is_old_suggests(int32_t flags) { ++ int is = flags & RPMSENSE_MISSINGOK; ++ if (is) has_old_suggests = is; ++ return is; ++} ++int32_t is_not_old_suggests(int32_t flags) { ++ return !is_old_suggests(flags); ++} ++ ++typedef int (*callback_list_str)(char *s, int slen, const char *name, const uint32_t flags, const char *evr, void *param); ++ ++static int ++callback_list_str_xpush(char *s, int slen, const char *name, uint32_t flags, const char *evr, __attribute__((unused)) void *param) { ++ dSP; ++ if (s) { ++ XPUSHs(sv_2mortal(newSVpv(s, slen))); ++ } else { ++ char buff[4096]; ++ int len = print_list_entry(buff, sizeof(buff)-1, name, flags, evr); ++ if (len >= 0) ++ XPUSHs(sv_2mortal(newSVpv(buff, len))); ++ } ++ PUTBACK; ++ /* returning zero indicates to continue processing */ ++ return 0; ++} ++static int ++callback_list_str_xpush_requires(char *s, int slen, const char *name, const uint32_t flags, const char *evr, __attribute__((unused)) void *param) { ++ dSP; ++ if (s) { ++ XPUSHs(sv_2mortal(newSVpv(s, slen))); ++ } else if (is_not_old_suggests(flags)) { ++ char buff[4096]; ++ int len = print_list_entry(buff, sizeof(buff)-1, name, flags, evr); ++ if (len >= 0) ++ XPUSHs(sv_2mortal(newSVpv(buff, len))); ++ } ++ PUTBACK; ++ /* returning zero indicates to continue processing */ ++ return 0; ++} ++static int ++callback_list_str_xpush_old_suggests(char *s, int slen, const char *name, uint32_t flags, const char *evr, __attribute__((unused)) void *param) { ++ dSP; ++ if (s) { ++ XPUSHs(sv_2mortal(newSVpv(s, slen))); ++ } else if (is_old_suggests(flags)) { ++ char buff[4096]; ++ int len = print_list_entry(buff, sizeof(buff)-1, name, flags, evr); ++ if (len >= 0) ++ XPUSHs(sv_2mortal(newSVpv(buff, len))); ++ } ++ PUTBACK; ++ /* returning zero indicates to continue processing */ ++ return 0; ++} ++ ++struct cb_overlap_s { ++ char *name; ++ int32_t flags; ++ char *evr; ++ int direction; /* indicate to compare the above at left or right to the iteration element */ ++ int b_nopromote; ++}; ++ ++static int ++callback_list_str_overlap(char *s, int slen, const char *name, uint32_t flags, const char *evr, void *param) { ++ struct cb_overlap_s *os = (struct cb_overlap_s *)param; ++ int result = 0; ++ char *eos = NULL; ++ char *eon = NULL; ++ char eosc = '\0'; ++ char eonc = '\0'; ++ ++ /* we need to extract name, flags and evr from a full sense information, store result in local copy */ ++ if (s) { ++ if (slen) { eos = s + slen; eosc = *eos; *eos = 0; } ++ name = s; ++ while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; ++ if (*s) { ++ eon = s; ++ while (*s) { ++ if (*s == ' ' || *s == '[' || *s == '*' || *s == ']'); ++ else if (*s == '<') flags |= RPMSENSE_LESS; ++ else if (*s == '>') flags |= RPMSENSE_GREATER; ++ else if (*s == '=') flags |= RPMSENSE_EQUAL; ++ else break; ++ ++s; ++ } ++ evr = s; ++ } else ++ evr = ""; ++ } ++ ++ /* mark end of name */ ++ if (eon) { eonc = *eon; *eon = 0; } ++ /* names should be equal, else it will not overlap */ ++ if (!strcmp(name, os->name)) { ++ /* perform overlap according to direction needed, negative for left */ ++ if (os->direction < 0) ++ result = ranges_overlap(os->flags, os->evr, flags, (char *) evr, os->b_nopromote); ++ else ++ result = ranges_overlap(flags, (char *) evr, os->flags, os->evr, os->b_nopromote); ++ } ++ ++ /* fprintf(stderr, "cb_list_str_overlap result=%d, os->direction=%d, os->name=%s, os->evr=%s, name=%s, evr=%s\n", ++ result, os->direction, os->name, os->evr, name, evr); */ ++ ++ /* restore s if needed */ ++ if (eon) *eon = eonc; ++ if (eos) *eos = eosc; ++ ++ return result; ++} ++ ++static int ++return_list_str(char *s, Header header, int32_t tag_name, int32_t tag_flags, int32_t tag_version, callback_list_str f, void *param) { ++ int count = 0; ++ ++ if (s != NULL) { ++ char *ps = strchr(s, '@'); ++ if (tag_flags && tag_version) { ++ while(ps != NULL) { ++ ++count; ++ if (f(s, ps-s, NULL, 0, NULL, param)) return -count; ++ s = ps + 1; ps = strchr(s, '@'); ++ } ++ ++count; ++ if (f(s, 0, NULL, 0, NULL, param)) return -count; ++ } else { ++ char *eos; ++ while(ps != NULL) { ++ *ps = 0; eos = strchr(s, '['); if (!eos) eos = strchr(s, ' '); ++ ++count; ++ if (f(s, eos ? eos-s : ps-s, NULL, 0, NULL, param)) { *ps = '@'; return -count; } ++ *ps = '@'; /* restore in memory modified char */ ++ s = ps + 1; ps = strchr(s, '@'); ++ } ++ eos = strchr(s, '['); if (!eos) eos = strchr(s, ' '); ++ ++count; ++ if (f(s, eos ? eos-s : 0, NULL, 0, NULL, param)) return -count; ++ } ++ } else if (header) { ++ struct rpmtd_s list, flags, list_evr; ++ ++ if (headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) { ++ if (tag_flags) headerGet(header, tag_flags, &flags, HEADERGET_DEFAULT); ++ if (tag_version) headerGet(header, tag_version, &list_evr, HEADERGET_DEFAULT); ++ while (rpmtdNext(&list) >= 0) { ++ ++count; ++ uint32_t *flag = rpmtdNextUint32(&flags); ++ if (f(NULL, 0, rpmtdGetString(&list), flag ? *flag : 0, ++ rpmtdNextString(&list_evr), param)) { ++ rpmtdFreeData(&list); ++ if (tag_flags) rpmtdFreeData(&flags); ++ if (tag_version) rpmtdFreeData(&list_evr); ++ return -count; ++ } ++ } ++ rpmtdFreeData(&list); ++ if (tag_flags) rpmtdFreeData(&flags); ++ if (tag_version) rpmtdFreeData(&list_evr); ++ } ++ } ++ return count; ++} ++ ++static int ++xpush_simple_list_str(Header header, int32_t tag_name) { ++ dSP; ++ if (header) { ++ struct rpmtd_s list; ++ const char *val; ++ int size; ++ ++ if (!headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) return 0; ++ size = rpmtdCount(&list); ++ ++ while ((val = rpmtdNextString(&list))) { ++ XPUSHs(sv_2mortal(newSVpv(val, 0))); ++ } ++ rpmtdFreeData(&list); ++ PUTBACK; ++ return size; ++ } else return 0; ++} ++ ++void ++return_list_int32_t(Header header, int32_t tag_name) { ++ dSP; ++ if (header) { ++ struct rpmtd_s list; ++ ++ if (headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) { ++ uint32_t *val; ++ while ((val = rpmtdNextUint32(&list))) ++ XPUSHs(sv_2mortal(newSViv(*val))); ++ rpmtdFreeData(&list); ++ } ++ } ++ PUTBACK; ++} ++ ++void ++return_list_uint_16(Header header, int32_t tag_name) { ++ dSP; ++ if (header) { ++ struct rpmtd_s list; ++ if (headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) { ++ int count = rpmtdCount(&list); ++ int i; ++ uint16_t *list_ = list.data; ++ for(i = 0; i < count; i++) { ++ XPUSHs(sv_2mortal(newSViv(list_[i]))); ++ } ++ rpmtdFreeData(&list); ++ } ++ } ++ PUTBACK; ++} ++ ++void ++return_list_tag_modifier(Header header, int32_t tag_name) { ++ dSP; ++ int i; ++ struct rpmtd_s td; ++ if (!headerGet(header, tag_name, &td, HEADERGET_DEFAULT)) return; ++ int count = rpmtdCount(&td); ++ int32_t *list = td.data; ++ ++ for (i = 0; i < count; i++) { ++ char buff[15]; ++ char *s = buff; ++ switch (tag_name) { ++ case RPMTAG_FILEFLAGS: ++ if (list[i] & RPMFILE_CONFIG) *s++ = 'c'; ++ if (list[i] & RPMFILE_DOC) *s++ = 'd'; ++ if (list[i] & RPMFILE_GHOST) *s++ = 'g'; ++ if (list[i] & RPMFILE_LICENSE) *s++ = 'l'; ++ if (list[i] & RPMFILE_MISSINGOK) *s++ = 'm'; ++ if (list[i] & RPMFILE_NOREPLACE) *s++ = 'n'; ++ if (list[i] & RPMFILE_SPECFILE) *s++ = 'S'; ++ if (list[i] & RPMFILE_README) *s++ = 'R'; ++ if (list[i] & RPMFILE_EXCLUDE) *s++ = 'e'; ++ if (list[i] & RPMFILE_ICON) *s++ = 'i'; ++ if (list[i] & RPMFILE_UNPATCHED) *s++ = 'u'; ++ if (list[i] & RPMFILE_PUBKEY) *s++ = 'p'; ++ break; ++ default: ++ rpmtdFreeData(&td); ++ return; ++ } ++ *s = '\0'; ++ XPUSHs(sv_2mortal(newSVpv(buff, strlen(buff)))); ++ } ++ rpmtdFreeData(&td); ++ PUTBACK; ++} ++ ++void ++return_list_tag(URPM__Package pkg, int32_t tag_name) { ++ dSP; ++ if (pkg->h != NULL) { ++ struct rpmtd_s td; ++ if (headerGet(pkg->h, tag_name, &td, HEADERGET_DEFAULT)) { ++ void *list = td.data; ++ int32_t count = rpmtdCount(&td); ++ if (tag_name == RPMTAG_ARCH) { ++ XPUSHs(sv_2mortal(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? (char *) list : "src", 0))); ++ } else ++ switch (rpmtdType(&td)) { ++ case RPM_NULL_TYPE: ++ break; ++#ifdef RPM_ORG ++ case RPM_CHAR_TYPE: ++#endif ++ case RPM_INT8_TYPE: ++ case RPM_INT16_TYPE: ++ case RPM_INT32_TYPE: ++ { ++ int i; ++ int *r; ++ r = (int *)list; ++ for (i=0; i < count; i++) { ++ XPUSHs(sv_2mortal(newSViv(r[i]))); ++ } ++ } ++ break; ++ case RPM_STRING_TYPE: ++ XPUSHs(sv_2mortal(newSVpv((char *) list, 0))); ++ break; ++ case RPM_BIN_TYPE: ++ break; ++ case RPM_STRING_ARRAY_TYPE: ++ { ++ int i; ++ char **s; ++ ++ s = (char **)list; ++ for (i = 0; i < count; i++) { ++ XPUSHs(sv_2mortal(newSVpv(s[i], 0))); ++ } ++ } ++ break; ++ case RPM_I18NSTRING_TYPE: ++ break; ++ case RPM_INT64_TYPE: ++ break; ++ } ++ } ++ } else { ++ char *name; ++ char *version; ++ char *release; ++ char *arch; ++ char *eos; ++ switch (tag_name) { ++ case RPMTAG_NAME: ++ { ++ get_fullname_parts(pkg, &name, &version, &release, &arch, &eos); ++ if (version - name < 1) croak("invalid fullname"); ++ XPUSHs(sv_2mortal(newSVpv(name, version-name - 1))); ++ } ++ break; ++ case RPMTAG_VERSION: ++ { ++ get_fullname_parts(pkg, &name, &version, &release, &arch, &eos); ++ if (release - version < 1) croak("invalid fullname"); ++ XPUSHs(sv_2mortal(newSVpv(version, release-version - 1))); ++ } ++ break; ++ case RPMTAG_RELEASE: ++ { ++ get_fullname_parts(pkg, &name, &version, &release, &arch, &eos); ++ if (arch - release < 1) croak("invalid fullname"); ++ XPUSHs(sv_2mortal(newSVpv(release, arch-release - 1))); ++ } ++ break; ++ case RPMTAG_ARCH: ++ { ++ get_fullname_parts(pkg, &name, &version, &release, &arch, &eos); ++ XPUSHs(sv_2mortal(newSVpv(arch, eos-arch))); ++ } ++ break; ++ case RPMTAG_SUMMARY: ++ XPUSHs(sv_2mortal(newSVpv(pkg->summary, 0))); ++ break; ++ } ++ } ++ PUTBACK; ++} ++ ++ ++void ++return_files(Header header, int filter_mode) { ++ dSP; ++ if (header) { ++ char buff[4096]; ++ char *p, *s; ++ STRLEN len; ++ unsigned int i; ++ ++ struct rpmtd_s td_flags, td_fmodes; ++ int32_t *flags = NULL; ++ uint16_t *fmodes = NULL; ++ if (filter_mode) { ++ headerGet(header, RPMTAG_FILEFLAGS, &td_flags, HEADERGET_DEFAULT); ++ headerGet(header, RPMTAG_FILEMODES, &td_fmodes, HEADERGET_DEFAULT); ++ flags = td_flags.data; ++ fmodes = td_fmodes.data; ++ } ++ ++ struct rpmtd_s td_baseNames, td_dirIndexes, td_dirNames, td_list; ++ headerGet(header, RPMTAG_BASENAMES, &td_baseNames, HEADERGET_DEFAULT); ++ headerGet(header, RPMTAG_DIRINDEXES, &td_dirIndexes, HEADERGET_DEFAULT); ++ headerGet(header, RPMTAG_DIRNAMES, &td_dirNames, HEADERGET_DEFAULT); ++ ++ char **baseNames = td_baseNames.data; ++ char **dirNames = td_dirNames.data; ++ int32_t *dirIndexes = td_dirIndexes.data; ++ ++ char **list = NULL; ++ if (!baseNames || !dirNames || !dirIndexes) { ++ if (!headerGet(header, RPMTAG_OLDFILENAMES, &td_list, HEADERGET_DEFAULT)) return; ++ list = td_list.data; ++ } ++ ++ for(i = 0; i < rpmtdCount(&td_baseNames); i++) { ++ if (list) { ++ s = list[i]; ++ len = strlen(list[i]); ++ } else { ++ len = strlen(dirNames[dirIndexes[i]]); ++ if (len >= sizeof(buff)) continue; ++ memcpy(p = buff, dirNames[dirIndexes[i]], len + 1); p += len; ++ len = strlen(baseNames[i]); ++ if (p - buff + len >= sizeof(buff)) continue; ++ memcpy(p, baseNames[i], len + 1); p += len; ++ s = buff; ++ len = p-buff; ++ } ++ ++ if (filter_mode) { ++ if ((filter_mode & FILTER_MODE_CONF_FILES) && flags && (flags[i] & RPMFILE_CONFIG) == 0) continue; ++ } ++ ++ XPUSHs(sv_2mortal(newSVpv(s, len))); ++ } ++ ++ free(baseNames); ++ free(dirNames); ++ free(list); ++ } ++ PUTBACK; ++} ++ ++void ++return_problems(rpmps ps, int translate_message, int raw_message) { ++ dSP; ++ if (ps && rpmpsNumProblems(ps) > 0) { ++ rpmpsi iterator = rpmpsInitIterator(ps); ++ while (rpmpsNextIterator(iterator) >= 0) { ++ rpmProblem p = rpmpsGetProblem(iterator); ++ ++ if (translate_message) { ++ /* translate error using rpm localization */ ++ const char *buf = rpmProblemString(p); ++ SV *sv = newSVpv(buf, 0); ++ if (rpm_codeset_is_utf8) SvUTF8_on(sv); ++ XPUSHs(sv_2mortal(sv)); ++ _free(buf); ++ } ++ if (raw_message) { ++ const char *pkgNEVR = rpmProblemGetPkgNEVR(p) ? rpmProblemGetPkgNEVR(p) : ""; ++ const char *altNEVR = rpmProblemGetAltNEVR(p) ? rpmProblemGetAltNEVR(p) : ""; ++ const char *s = rpmProblemGetStr(p) ? rpmProblemGetStr(p) : ""; ++ SV *sv; ++ ++ switch (rpmProblemGetType(p)) { ++ case RPMPROB_BADARCH: ++ sv = newSVpvf("badarch@%s", pkgNEVR); break; ++ ++ case RPMPROB_BADOS: ++ sv = newSVpvf("bados@%s", pkgNEVR); break; ++ ++ case RPMPROB_PKG_INSTALLED: ++ sv = newSVpvf("installed@%s", pkgNEVR); break; ++ ++ case RPMPROB_BADRELOCATE: ++ sv = newSVpvf("badrelocate@%s@%s", pkgNEVR, s); break; ++ ++ case RPMPROB_NEW_FILE_CONFLICT: ++ case RPMPROB_FILE_CONFLICT: ++ sv = newSVpvf("conflicts@%s@%s@%s", pkgNEVR, altNEVR, s); break; ++ ++ case RPMPROB_OLDPACKAGE: ++ sv = newSVpvf("installed@%s@%s", pkgNEVR, altNEVR); break; ++ ++ case RPMPROB_DISKSPACE: ++ sv = newSVpvf("diskspace@%s@%s@%lld", pkgNEVR, s, (long long)rpmProblemGetDiskNeed(p)); break; ++ case RPMPROB_DISKNODES: ++ sv = newSVpvf("disknodes@%s@%s@%lld", pkgNEVR, s, (long long)rpmProblemGetDiskNeed(p)); break; ++ case RPMPROB_REQUIRES: ++ sv = newSVpvf("requires@%s@%s", pkgNEVR, altNEVR+2); break; ++ ++ case RPMPROB_CONFLICT: ++ sv = newSVpvf("conflicts@%s@%s", pkgNEVR, altNEVR+2); break; ++ ++ default: ++ sv = newSVpvf("unknown@%s", pkgNEVR); break; ++ } ++ XPUSHs(sv_2mortal(sv)); ++ } ++ } ++ rpmpsFreeIterator(iterator); ++ } ++ PUTBACK; ++} ++ ++static char * ++pack_list(Header header, int32_t tag_name, int32_t tag_flags, int32_t tag_version, int32_t (*check_flag)(int32_t)) { ++ char buff[65536]; ++ int32_t *flags = NULL; ++ char **list_evr = NULL; ++ unsigned int i; ++ char *p = buff; ++ ++ struct rpmtd_s td; ++ if (headerGet(header, tag_name, &td, HEADERGET_DEFAULT)) { ++ char **list = td.data; ++ ++ struct rpmtd_s td_flags, td_list_evr; ++ if (tag_flags && headerGet(header, tag_flags, &td_flags, HEADERGET_DEFAULT)) flags = td_flags.data; ++ if (tag_version && headerGet(header, tag_version, &td_list_evr, HEADERGET_DEFAULT)) list_evr = td_list_evr.data; ++ for(i = 0; i < rpmtdCount(&td); i++) { ++ if (check_flag && !check_flag(flags[i])) continue; ++ int len = print_list_entry(p, sizeof(buff)-(p-buff)-1, list[i], flags ? flags[i] : 0, list_evr ? list_evr[i] : NULL); ++ if (len < 0) continue; ++ p += len; ++ *p++ = '@'; ++ } ++ if (p > buff) p[-1] = 0; ++ ++ free(list); ++ free(list_evr); ++ } ++ ++ return p > buff ? memcpy(malloc(p-buff), buff, p-buff) : NULL; ++} ++ ++static void ++pack_header(URPM__Package pkg) { ++ if (pkg->h) { ++ if (pkg->info == NULL) { ++ char buff[1024]; ++ char *p = buff; ++ char *name = get_name(pkg->h, RPMTAG_NAME); ++ char *version = get_name(pkg->h, RPMTAG_VERSION); ++ char *release = get_name(pkg->h, RPMTAG_RELEASE); ++ char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src"; ++ ++ p += 1 + snprintf(buff, sizeof(buff), "%s-%s-%s.%s@%d@%d@%s", name, version, release, arch, ++ get_int(pkg->h, RPMTAG_EPOCH), get_int(pkg->h, RPMTAG_SIZE), ++ get_name(pkg->h, RPMTAG_GROUP)); ++ pkg->info = memcpy(malloc(p-buff), buff, p-buff); ++ } ++ if (pkg->filesize == 0) pkg->filesize = sigsize_to_filesize(get_int(pkg->h, RPMTAG_SIGSIZE)); ++ if (pkg->requires == NULL && pkg->suggests == NULL) ++ has_old_suggests = 0; ++ pkg->requires = pack_list(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION, is_not_old_suggests); ++ if (has_old_suggests) ++ pkg->suggests = pack_list(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION, is_old_suggests); ++ else ++ pkg->suggests = pack_list(pkg->h, RPMTAG_SUGGESTSNAME, 0, 0, NULL); ++ if (pkg->obsoletes == NULL) ++ pkg->obsoletes = pack_list(pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION, NULL); ++ if (pkg->conflicts == NULL) ++ pkg->conflicts = pack_list(pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION, NULL); ++ if (pkg->provides == NULL) ++ pkg->provides = pack_list(pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION, NULL); ++ if (pkg->summary == NULL) { ++ char *summary = get_name(pkg->h, RPMTAG_SUMMARY); ++ int len = 1 + strlen(summary); ++ ++ pkg->summary = memcpy(malloc(len), summary, len); ++ } ++ ++ if (!(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h =headerFree(pkg->h); ++ pkg->h = 0; ++ } ++} ++ ++static void ++update_hash_entry(HV *hash, char *name, STRLEN len, int force, IV use_sense, URPM__Package pkg) { ++ SV** isv; ++ ++ if (!len) len = strlen(name); ++ if ((isv = hv_fetch(hash, name, len, force))) { ++ /* check if an entry has been found or created, it should so be updated */ ++ if (!SvROK(*isv) || SvTYPE(SvRV(*isv)) != SVt_PVHV) { ++ SV* choice_set = (SV*)newHV(); ++ if (choice_set) { ++ SvREFCNT_dec(*isv); /* drop the old as we are changing it */ ++ if (!(*isv = newRV_noinc(choice_set))) { ++ SvREFCNT_dec(choice_set); ++ *isv = &PL_sv_undef; ++ } ++ } ++ } ++ if (isv && *isv != &PL_sv_undef) { ++ char id[8]; ++ STRLEN id_len = snprintf(id, sizeof(id), "%d", pkg->flag & FLAG_ID); ++ SV **sense = hv_fetch((HV*)SvRV(*isv), id, id_len, 1); ++ if (sense && use_sense) sv_setiv(*sense, use_sense); ++ } ++ } ++} ++ ++static void ++update_provide_entry(char *name, STRLEN len, int force, IV use_sense, URPM__Package pkg, HV *provides) { ++ update_hash_entry(provides, name, len, force, use_sense, pkg); ++} ++ ++static void ++update_provides(URPM__Package pkg, HV *provides) { ++ if (pkg->h) { ++ int len; ++ struct rpmtd_s td, td_flags; ++ int32_t *flags = NULL; ++ unsigned int i; ++ ++ /* examine requires for files which need to be marked in provides */ ++ if (headerGet(pkg->h, RPMTAG_REQUIRENAME, &td, HEADERGET_DEFAULT)) { ++ char **list = td.data; ++ for (i = 0; i < rpmtdCount(&td); ++i) { ++ len = strlen(list[i]); ++ if (list[i][0] == '/') (void)hv_fetch(provides, list[i], len, 1); ++ } ++ } ++ ++ /* update all provides */ ++ if (headerGet(pkg->h, RPMTAG_PROVIDENAME, &td, HEADERGET_DEFAULT)) { ++ char **list = td.data; ++ if (headerGet(pkg->h, RPMTAG_PROVIDEFLAGS, &td_flags, HEADERGET_DEFAULT)) ++ flags = td_flags.data; ++ for (i = 0; i < rpmtdCount(&td); ++i) { ++ len = strlen(list[i]); ++ if (!strncmp(list[i], "rpmlib(", 7)) continue; ++ update_provide_entry(list[i], len, 1, flags && flags[i] & (RPMSENSE_PREREQ|RPMSENSE_SCRIPT_PREUN|RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POSTUN|RPMSENSE_SCRIPT_POST|RPMSENSE_LESS|RPMSENSE_EQUAL|RPMSENSE_GREATER), ++ pkg, provides); ++ } ++ } ++ } else { ++ char *ps, *s, *es; ++ ++ if ((s = pkg->requires) != NULL && *s != 0) { ++ ps = strchr(s, '@'); ++ while(ps != NULL) { ++ if (s[0] == '/') { ++ *ps = 0; es = strchr(s, '['); if (!es) es = strchr(s, ' '); *ps = '@'; ++ (void)hv_fetch(provides, s, es != NULL ? es-s : ps-s, 1); ++ } ++ s = ps + 1; ps = strchr(s, '@'); ++ } ++ if (s[0] == '/') { ++ es = strchr(s, '['); if (!es) es = strchr(s, ' '); ++ (void)hv_fetch(provides, s, es != NULL ? (U32)(es-s) : strlen(s), 1); ++ } ++ } ++ ++ if ((s = pkg->provides) != NULL && *s != 0) { ++ char *es; ++ ++ ps = strchr(s, '@'); ++ while(ps != NULL) { ++ *ps = 0; es = strchr(s, '['); if (!es) es = strchr(s, ' '); *ps = '@'; ++ update_provide_entry(s, es != NULL ? es-s : ps-s, 1, es != NULL, pkg, provides); ++ s = ps + 1; ps = strchr(s, '@'); ++ } ++ es = strchr(s, '['); if (!es) es = strchr(s, ' '); ++ update_provide_entry(s, es != NULL ? es-s : 0, 1, es != NULL, pkg, provides); ++ } ++ } ++} ++ ++static void ++update_obsoletes(URPM__Package pkg, HV *obsoletes) { ++ if (pkg->h) { ++ struct rpmtd_s td; ++ ++ /* update all provides */ ++ if (headerGet(pkg->h, RPMTAG_OBSOLETENAME, &td, HEADERGET_DEFAULT)) { ++ char **list = td.data; ++ unsigned int i; ++ for (i = 0; i < rpmtdCount(&td); ++i) ++ update_hash_entry(obsoletes, list[i], 0, 1, 0, pkg); ++ } ++ } else { ++ char *ps, *s; ++ ++ if ((s = pkg->obsoletes) != NULL && *s != 0) { ++ char *es; ++ ++ ps = strchr(s, '@'); ++ while(ps != NULL) { ++ *ps = 0; es = strchr(s, '['); if (!es) es = strchr(s, ' '); *ps = '@'; ++ update_hash_entry(obsoletes, s, es != NULL ? es-s : ps-s, 1, 0, pkg); ++ s = ps + 1; ps = strchr(s, '@'); ++ } ++ es = strchr(s, '['); if (!es) es = strchr(s, ' '); ++ update_hash_entry(obsoletes, s, es != NULL ? es-s : 0, 1, 0, pkg); ++ } ++ } ++} ++ ++static void ++update_provides_files(URPM__Package pkg, HV *provides) { ++ if (pkg->h) { ++ STRLEN len; ++ char **list = NULL; ++ unsigned int i; ++ ++ struct rpmtd_s td_baseNames, td_dirIndexes, td_dirNames; ++ if (headerGet(pkg->h, RPMTAG_BASENAMES, &td_baseNames, HEADERGET_DEFAULT) && ++ headerGet(pkg->h, RPMTAG_DIRINDEXES, &td_dirIndexes, HEADERGET_DEFAULT) && ++ headerGet(pkg->h, RPMTAG_DIRNAMES, &td_dirNames, HEADERGET_DEFAULT)) { ++ ++ char **baseNames = td_baseNames.data; ++ char **dirNames = td_dirNames.data; ++ int32_t *dirIndexes = td_dirIndexes.data; ++ ++ char buff[4096]; ++ char *p; ++ ++ for(i = 0; i < rpmtdCount(&td_baseNames); i++) { ++ len = strlen(dirNames[dirIndexes[i]]); ++ if (len >= sizeof(buff)) continue; ++ memcpy(p = buff, dirNames[dirIndexes[i]], len + 1); p += len; ++ len = strlen(baseNames[i]); ++ if (p - buff + len >= sizeof(buff)) continue; ++ memcpy(p, baseNames[i], len + 1); p += len; ++ ++ update_provide_entry(buff, p-buff, 0, 0, pkg, provides); ++ } ++ ++ free(baseNames); ++ free(dirNames); ++ } else { ++ struct rpmtd_s td; ++ headerGet(pkg->h, RPMTAG_OLDFILENAMES, &td, HEADERGET_DEFAULT); ++ if (list) { ++ for (i = 0; i < rpmtdCount(&td); i++) { ++ len = strlen(list[i]); ++ ++ update_provide_entry(list[i], len, 0, 0, pkg, provides); ++ } ++ ++ free(list); ++ } ++ } ++ } ++} ++ ++int ++open_archive(char *filename, pid_t *pid, int *empty_archive) { ++ int fd; ++ struct { ++ char header[4]; ++ char toc_d_count[4]; ++ char toc_l_count[4]; ++ char toc_f_count[4]; ++ char toc_str_size[4]; ++ char uncompress[40]; ++ char trailer[4]; ++ } buf; ++ ++ fd = open(filename, O_RDONLY); ++ if (fd >= 0) { ++ int pos = lseek(fd, -(int)sizeof(buf), SEEK_END); ++ if (read(fd, &buf, sizeof(buf)) != sizeof(buf) || strncmp(buf.header, "cz[0", 4) || strncmp(buf.trailer, "0]cz", 4)) { ++ /* this is not an archive, open it without magic, but first rewind at begin of file */ ++ lseek(fd, 0, SEEK_SET); ++ } else if (pos == 0) { ++ *empty_archive = 1; ++ fd = -1; ++ } else { ++ /* this is an archive, create a pipe and fork for reading with uncompress defined inside */ ++ int fdno[2]; ++ ++ if (!pipe(fdno)) { ++ if ((*pid = fork()) != 0) { ++ fd_set readfds; ++ struct timeval timeout; ++ ++ FD_ZERO(&readfds); ++ FD_SET(fdno[0], &readfds); ++ timeout.tv_sec = 1; ++ timeout.tv_usec = 0; ++ select(fdno[0]+1, &readfds, NULL, NULL, &timeout); ++ ++ close(fd); ++ fd = fdno[0]; ++ close(fdno[1]); ++ } else { ++ char *unpacker[22]; /* enough for 40 bytes in uncompress to never overbuf */ ++ char *p = buf.uncompress; ++ int ip = 0; ++ char *ld_loader = getenv("LD_LOADER"); ++ ++ if (ld_loader && *ld_loader) { ++ unpacker[ip++] = ld_loader; ++ } ++ ++ buf.trailer[0] = 0; /* make sure end-of-string is right */ ++ while (*p) { ++ if (*p == ' ' || *p == '\t') *p++ = 0; ++ else { ++ unpacker[ip++] = p; ++ while (*p && *p != ' ' && *p != '\t') ++p; ++ } ++ } ++ unpacker[ip] = NULL; /* needed for execlp */ ++ ++ lseek(fd, 0, SEEK_SET); ++ dup2(fd, STDIN_FILENO); close(fd); ++ dup2(fdno[1], STDOUT_FILENO); close(fdno[1]); ++ ++ /* get rid of "decompression OK, trailing garbage ignored" */ ++ fd = open("/dev/null", O_WRONLY); ++ dup2(fd, STDERR_FILENO); close(fd); ++ ++ execvp(unpacker[0], unpacker); ++ exit(1); ++ } ++ } else { ++ close(fd); ++ fd = -1; ++ } ++ } ++ } ++ return fd; ++} ++ ++static int ++call_package_callback(SV *urpm, SV *sv_pkg, SV *callback) { ++ if (sv_pkg != NULL && callback != NULL) { ++ int count; ++ ++ /* now, a callback will be called for sure */ ++ dSP; ++ PUSHMARK(SP); ++ XPUSHs(urpm); ++ XPUSHs(sv_pkg); ++ PUTBACK; ++ count = call_sv(callback, G_SCALAR); ++ SPAGAIN; ++ if (count == 1 && !POPi) { ++ /* package should not be added in depslist, so we free it */ ++ SvREFCNT_dec(sv_pkg); ++ sv_pkg = NULL; ++ } ++ PUTBACK; ++ } ++ ++ return sv_pkg != NULL; ++} ++ ++static int ++parse_line(AV *depslist, HV *provides, HV *obsoletes, URPM__Package pkg, char *buff, SV *urpm, SV *callback) { ++ SV *sv_pkg; ++ URPM__Package _pkg; ++ char *tag, *data; ++ int data_len; ++ ++ if (buff[0] == 0) { ++ return 1; ++ } else if ((tag = buff)[0] == '@' && (data = strchr(tag+1, '@')) != NULL) { ++ *tag++ = *data++ = 0; ++ data_len = 1+strlen(data); ++ if (!strcmp(tag, "info")) { ++ pkg->info = memcpy(malloc(data_len), data, data_len); ++ pkg->flag &= ~FLAG_ID; ++ pkg->flag |= 1 + av_len(depslist); ++ sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package", ++ _pkg = memcpy(malloc(sizeof(struct s_Package)), pkg, sizeof(struct s_Package))); ++ if (call_package_callback(urpm, sv_pkg, callback)) { ++ if (provides) update_provides(_pkg, provides); ++ if (obsoletes) update_obsoletes(_pkg, obsoletes); ++ av_push(depslist, sv_pkg); ++ } ++ memset(pkg, 0, sizeof(struct s_Package)); ++ } else if (!strcmp(tag, "filesize")) { ++ pkg->filesize = atoi(data); ++ } else if (!strcmp(tag, "requires")) { ++ free(pkg->requires); pkg->requires = memcpy(malloc(data_len), data, data_len); ++ } else if (!strcmp(tag, "suggests")) { ++ free(pkg->suggests); pkg->suggests = memcpy(malloc(data_len), data, data_len); ++ } else if (!strcmp(tag, "obsoletes")) { ++ free(pkg->obsoletes); pkg->obsoletes = memcpy(malloc(data_len), data, data_len); ++ } else if (!strcmp(tag, "conflicts")) { ++ free(pkg->conflicts); pkg->conflicts = memcpy(malloc(data_len), data, data_len); ++ } else if (!strcmp(tag, "provides")) { ++ free(pkg->provides); pkg->provides = memcpy(malloc(data_len), data, data_len); ++ } else if (!strcmp(tag, "summary")) { ++ free(pkg->summary); pkg->summary = memcpy(malloc(data_len), data, data_len); ++ } ++ return 1; ++ } else { ++ fprintf(stderr, "bad line <%s>\n", buff); ++ return 0; ++ } ++} ++ ++#if 0 ++static void pack_rpm_header(Header *h) { ++ Header packed = headerNew(); ++ ++ HeaderIterator hi = headerInitIterator(*h); ++ struct rpmtd_s td; ++ while (headerNext(hi, &td)) { ++ // fprintf(stderr, "adding %s %d\n", tagname(tag), c); ++ headerPut(packed, &td, HEADERPUT_DEFAULT); ++ rpmtdFreeData(&td); ++ } ++ ++ headerFreeIterator(hi); ++ *h = headerFree(*h); ++ ++ *h = packed; ++} ++ ++static void drop_tags(Header *h) { ++ headerDel(*h, RPMTAG_FILEUSERNAME); /* user ownership is correct */ ++ headerDel(*h, RPMTAG_FILEGROUPNAME); /* group ownership is correct */ ++ headerDel(*h, RPMTAG_FILEMTIMES); /* correct time without it */ ++ headerDel(*h, RPMTAG_FILEINODES); /* hardlinks work without it */ ++ headerDel(*h, RPMTAG_FILEDEVICES); /* it is the same number for every file */ ++ headerDel(*h, RPMTAG_FILESIZES); /* ? */ ++ headerDel(*h, RPMTAG_FILERDEVS); /* it seems unused. always empty */ ++ headerDel(*h, RPMTAG_FILEVERIFYFLAGS); /* only used for -V */ ++#ifndef RPM_ORG ++ headerDel(*h, RPMTAG_FILEDIGESTALGOS); /* only used for -V */ ++ headerDel(*h, RPMTAG_FILEDIGESTS); /* only used for -V */ /* alias: RPMTAG_FILEMD5S */ ++#endif ++ /* keep RPMTAG_FILEFLAGS for %config (rpmnew) to work */ ++ /* keep RPMTAG_FILELANGS for %lang (_install_langs) to work */ ++ /* keep RPMTAG_FILELINKTOS for checking conflicts between symlinks */ ++ /* keep RPMTAG_FILEMODES otherwise it segfaults with excludepath */ ++ ++ /* keep RPMTAG_POSTIN RPMTAG_POSTUN RPMTAG_PREIN RPMTAG_PREUN */ ++ /* keep RPMTAG_TRIGGERSCRIPTS RPMTAG_TRIGGERVERSION RPMTAG_TRIGGERFLAGS RPMTAG_TRIGGERNAME */ ++ /* small enough, and only in some packages. not needed per se */ ++ ++ headerDel(*h, RPMTAG_ICON); ++ headerDel(*h, RPMTAG_GIF); ++ headerDel(*h, RPMTAG_EXCLUDE); ++ headerDel(*h, RPMTAG_EXCLUSIVE); ++ headerDel(*h, RPMTAG_COOKIE); ++ headerDel(*h, RPMTAG_VERIFYSCRIPT); ++ ++ /* always the same for our packages */ ++ headerDel(*h, RPMTAG_VENDOR); ++ headerDel(*h, RPMTAG_DISTRIBUTION); ++ ++ /* keep RPMTAG_SIGSIZE, useful to tell the size of the rpm file (+440) */ ++ ++ headerDel(*h, RPMTAG_DSAHEADER); ++ headerDel(*h, RPMTAG_SHA1HEADER); ++ headerDel(*h, RPMTAG_SIGMD5); ++ headerDel(*h, RPMTAG_SIGGPG); ++ ++ pack_rpm_header(h); ++} ++#endif ++ ++static int ++update_header(char *filename, URPM__Package pkg, __attribute__((unused)) int keep_all_tags, int vsflags) { ++ int d = open(filename, O_RDONLY); ++ ++ if (d >= 0) { ++ unsigned char sig[4]; ++ ++ if (read(d, &sig, sizeof(sig)) == sizeof(sig)) { ++ lseek(d, 0, SEEK_SET); ++ if (sig[0] == 0xed && sig[1] == 0xab && sig[2] == 0xee && sig[3] == 0xdb) { ++ FD_t fd = fdDup(d); ++ Header header; ++ rpmts ts; ++ ++ close(d); ++ ts = rpmtsCreate(); ++ rpmtsSetVSFlags(ts, _RPMVSF_NOSIGNATURES | vsflags); ++ if (fd != NULL && rpmReadPackageFile(ts, fd, filename, &header) == 0 && header) { ++ char *basename; ++#ifndef RPM_ORG ++ struct stat sb; ++#else ++ int32_t size; ++#endif ++ ++ basename = strrchr(filename, '/'); ++#ifndef RPM_ORG ++ Fstat(fd, &sb); ++#else ++ size = fdSize(fd); ++#endif ++ Fclose(fd); ++ ++ /* this is only kept for compatibility with older distros ++ (where ->filename on "unpacked" URPM::Package rely on FILENAME_TAG) */ ++ headerPutString(header, FILENAME_TAG, basename != NULL ? basename + 1 : filename); ++ ++ if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); ++ pkg->h = header; ++ pkg->flag &= ~FLAG_NO_HEADER_FREE; ++ ++ /*if (!keep_all_tags) drop_tags(&pkg->h);*/ ++ (void)rpmtsFree(ts); ++ return 1; ++ } ++ (void)rpmtsFree(ts); ++ } else if (sig[0] == 0x8e && sig[1] == 0xad && sig[2] == 0xe8 && sig[3] == 0x01) { ++ FD_t fd = fdDup(d); ++ ++ close(d); ++ if (fd != NULL) { ++ if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); ++ pkg->h = headerRead(fd, HEADER_MAGIC_YES); ++ pkg->flag &= ~FLAG_NO_HEADER_FREE; ++ Fclose(fd); ++ return 1; ++ } ++ } ++ } ++ } ++ return 0; ++} ++ ++static int ++read_config_files(int force) { ++ static int already = 0; ++ int rc = 0; ++ ++ if (!already || force) { ++ rc = rpmReadConfigFiles(NULL, NULL); ++ already = (rc == 0); /* set config as load only if it succeed */ ++ } ++ return rc; ++} ++ ++static void ++ts_nosignature(rpmts ts) { ++ rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES); ++} ++ ++static void *rpmRunTransactions_callback(__attribute__((unused)) const void *h, ++ const rpmCallbackType what, ++ const rpm_loff_t amount, ++ const rpm_loff_t total, ++ fnpyKey pkgKey, ++ rpmCallbackData data) { ++ static struct timeval tprev; ++ static struct timeval tcurr; ++ static FD_t fd = NULL; ++ long delta; ++ int i; ++ struct s_TransactionData *td = data; ++ SV *callback = NULL; ++ char *callback_type = NULL; ++ char *callback_subtype = NULL; ++ ++ if (!td) ++ return NULL; ++ ++ switch (what) { ++ case RPMCALLBACK_INST_OPEN_FILE: ++ callback = td->callback_open; ++ callback_type = "open"; ++ break; ++ case RPMCALLBACK_INST_CLOSE_FILE: ++ callback = td->callback_close; ++ callback_type = "close"; ++ break; ++ case RPMCALLBACK_TRANS_START: ++ case RPMCALLBACK_TRANS_PROGRESS: ++ case RPMCALLBACK_TRANS_STOP: ++ callback = td->callback_trans; ++ callback_type = "trans"; ++ break; ++ case RPMCALLBACK_UNINST_START: ++ case RPMCALLBACK_UNINST_PROGRESS: ++ case RPMCALLBACK_UNINST_STOP: ++ callback = td->callback_uninst; ++ callback_type = "uninst"; ++ break; ++ case RPMCALLBACK_INST_START: ++ case RPMCALLBACK_INST_PROGRESS: ++ callback = td->callback_inst; ++ callback_type = "inst"; ++ break; ++ default: ++ break; ++ } ++ ++ if (callback != NULL) { ++ switch (what) { ++ case RPMCALLBACK_TRANS_START: ++ case RPMCALLBACK_UNINST_START: ++ case RPMCALLBACK_INST_START: ++ callback_subtype = "start"; ++ gettimeofday(&tprev, NULL); ++ break; ++ case RPMCALLBACK_TRANS_PROGRESS: ++ case RPMCALLBACK_UNINST_PROGRESS: ++ case RPMCALLBACK_INST_PROGRESS: ++ callback_subtype = "progress"; ++ gettimeofday(&tcurr, NULL); ++ delta = 1000000 * (tcurr.tv_sec - tprev.tv_sec) + (tcurr.tv_usec - tprev.tv_usec); ++ if (delta < td->min_delta && amount < total - 1) ++ callback = NULL; /* avoid calling too often a given callback */ ++ else ++ tprev = tcurr; ++ break; ++ case RPMCALLBACK_TRANS_STOP: ++ case RPMCALLBACK_UNINST_STOP: ++ callback_subtype = "stop"; ++ break; ++ default: ++ break; ++ } ++ ++ if (callback != NULL) { ++ /* now, a callback will be called for sure */ ++ dSP; ++ ENTER; ++ SAVETMPS; ++ PUSHMARK(SP); ++ XPUSHs(td->data); ++ XPUSHs(sv_2mortal(newSVpv(callback_type, 0))); ++ XPUSHs(pkgKey != NULL ? sv_2mortal(newSViv((long)pkgKey - 1)) : &PL_sv_undef); ++ if (callback_subtype != NULL) { ++ XPUSHs(sv_2mortal(newSVpv(callback_subtype, 0))); ++ XPUSHs(sv_2mortal(newSViv(amount))); ++ XPUSHs(sv_2mortal(newSViv(total))); ++ } ++ PUTBACK; ++ i = call_sv(callback, callback == td->callback_open ? G_SCALAR : G_DISCARD); ++ SPAGAIN; ++ if (callback == td->callback_open) { ++ if (i != 1) croak("callback_open should return a file handle"); ++ i = POPi; ++ fd = fdDup(i); ++ if (fd) { ++ fd = fdLink(fd, "persist perl-URPM"); ++ Fcntl(fd, F_SETFD, (void *)1); /* necessary to avoid forked/execed process to lock removable */ ++ } ++ PUTBACK; ++ } else if (callback == td->callback_close) { ++ fd = fdFree(fd, "persist perl-URPM"); ++ if (fd) { ++ Fclose(fd); ++ fd = NULL; ++ } ++ } ++ FREETMPS; ++ LEAVE; ++ } ++ } ++ return callback == td->callback_open ? fd : NULL; ++} ++ ++int rpmtag_from_string(char *tag) ++{ ++ if (!strcmp(tag, "name")) ++ return RPMTAG_NAME; ++ else if (!strcmp(tag, "whatprovides")) ++ return RPMTAG_PROVIDENAME; ++ else if (!strcmp(tag, "whatrequires")) ++ return RPMTAG_REQUIRENAME; ++ else if (!strcmp(tag, "whatconflicts")) ++ return RPMTAG_CONFLICTNAME; ++ else if (!strcmp(tag, "group")) ++ return RPMTAG_GROUP; ++ else if (!strcmp(tag, "triggeredby")) ++ return RPMTAG_TRIGGERNAME; ++ else if (!strcmp(tag, "path")) ++ return RPMTAG_BASENAMES; ++ else croak("unknown tag [%s]", tag); ++} ++ ++MODULE = URPM PACKAGE = URPM::Package PREFIX = Pkg_ ++ ++void ++Pkg_DESTROY(pkg) ++ URPM::Package pkg ++ CODE: ++ free(pkg->info); ++ free(pkg->requires); ++ free(pkg->suggests); ++ free(pkg->obsoletes); ++ free(pkg->conflicts); ++ free(pkg->provides); ++ free(pkg->rflags); ++ free(pkg->summary); ++ if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); ++ free(pkg); ++ ++void ++Pkg_name(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->info) { ++ char *name; ++ char *version; ++ ++ get_fullname_parts(pkg, &name, &version, NULL, NULL, NULL); ++ if (version - name < 1) croak("invalid fullname"); ++ XPUSHs(sv_2mortal(newSVpv(name, version-name-1))); ++ } else if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_NAME), 0))); ++ } ++ ++void ++Pkg_version(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->info) { ++ char *version; ++ char *release; ++ ++ get_fullname_parts(pkg, NULL, &version, &release, NULL, NULL); ++ if (release - version < 1) croak("invalid fullname"); ++ XPUSHs(sv_2mortal(newSVpv(version, release-version-1))); ++ } else if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_VERSION), 0))); ++ } ++ ++void ++Pkg_release(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->info) { ++ char *release; ++ char *arch; ++ ++ get_fullname_parts(pkg, NULL, NULL, &release, &arch, NULL); ++ if (arch - release < 1) croak("invalid fullname"); ++ XPUSHs(sv_2mortal(newSVpv(release, arch-release-1))); ++ } else if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_RELEASE), 0))); ++ } ++ ++void ++Pkg_arch(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->info) { ++ char *arch; ++ char *eos; ++ ++ get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos); ++ XPUSHs(sv_2mortal(newSVpv(arch, eos-arch))); ++ } else if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src", 0))); ++ } ++ ++int ++Pkg_is_arch_compat__XS(pkg) ++ URPM::Package pkg ++ INIT: ++#ifndef RPM_ORG ++ char * platform; ++#endif ++ CODE: ++ read_config_files(0); ++ if (pkg->info) { ++ char *arch; ++ char *eos; ++ ++ get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos); ++ *eos = 0; ++#ifndef RPM_ORG ++ platform = rpmExpand(arch, "-%{_target_vendor}-%{_target_os}%{?_gnu}", NULL); ++ RETVAL = rpmPlatformScore(platform, NULL, 0); ++ _free(platform); ++#else ++ RETVAL = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch); ++#endif ++ *eos = '@'; ++ } else if (pkg->h && headerIsEntry(pkg->h, RPMTAG_SOURCERPM)) { ++ char *arch = get_name(pkg->h, RPMTAG_ARCH); ++#ifndef RPM_ORG ++ platform = rpmExpand(arch, "-%{_target_vendor}-%{_target_os}%{?_gnu}", NULL); ++ RETVAL = rpmPlatformScore(platform, NULL, 0); ++ _free(platform); ++#else ++ RETVAL = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch); ++#endif ++ } else { ++ RETVAL = 0; ++ } ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_is_platform_compat(pkg) ++ URPM::Package pkg ++ INIT: ++#ifndef RPM_ORG ++ char * platform = NULL; ++ struct rpmtd_s val; ++#endif ++ CODE: ++#ifndef RPM_ORG ++ read_config_files(0); ++ if (pkg->h && headerIsEntry(pkg->h, RPMTAG_PLATFORM)) { ++ (void) headerGet(pkg->h, RPMTAG_PLATFORM, &val, HEADERGET_DEFAULT); ++ platform = (char *) rpmtdGetString(&val); ++ RETVAL = rpmPlatformScore(platform, NULL, 0); ++ platform = headerFreeData(platform, val.type); ++ } else if (pkg->info) { ++ char *arch; ++ char *eos; ++ ++ get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos); ++ *eos = 0; ++ platform = rpmExpand(arch, "-%{_target_vendor}-", eos, "%{?_gnu}", NULL); ++ RETVAL = rpmPlatformScore(platform, NULL, 0); ++ *eos = '@'; ++ _free(platform); ++ } else { ++#else ++ croak("is_platform_compat() is available only since rpm 4.4.8"); ++ { /* to match last } and avoid another #ifdef for it */ ++#endif ++ RETVAL = 0; ++ } ++ ++ OUTPUT: ++ RETVAL ++ ++void ++Pkg_summary(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->summary) { ++ XPUSHs(sv_2mortal(newSVpv_utf8(pkg->summary, 0))); ++ } else if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv_utf8(get_name(pkg->h, RPMTAG_SUMMARY), 0))); ++ } ++ ++void ++Pkg_description(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv_utf8(get_name(pkg->h, RPMTAG_DESCRIPTION), 0))); ++ } ++ ++void ++Pkg_sourcerpm(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_SOURCERPM), 0))); ++ } ++ ++void ++Pkg_packager(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv_utf8(get_name(pkg->h, RPMTAG_PACKAGER), 0))); ++ } ++ ++void ++Pkg_buildhost(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_BUILDHOST), 0))); ++ } ++ ++int ++Pkg_buildtime(pkg) ++ URPM::Package pkg ++ CODE: ++ if (pkg->h) { ++ RETVAL = get_int(pkg->h, RPMTAG_BUILDTIME); ++ } else { ++ RETVAL = 0; ++ } ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_installtid(pkg) ++ URPM::Package pkg ++ CODE: ++ if (pkg->h) { ++ RETVAL = get_int(pkg->h, RPMTAG_INSTALLTID); ++ } else { ++ RETVAL = 0; ++ } ++ OUTPUT: ++ RETVAL ++ ++void ++Pkg_url(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_URL), 0))); ++ } ++ ++void ++Pkg_license(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_LICENSE), 0))); ++ } ++ ++void ++Pkg_distribution(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_DISTRIBUTION), 0))); ++ } ++ ++void ++Pkg_vendor(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_VENDOR), 0))); ++ } ++ ++void ++Pkg_os(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_OS), 0))); ++ } ++ ++void ++Pkg_payload_format(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_PAYLOADFORMAT), 0))); ++ } ++ ++void ++Pkg_fullname(pkg) ++ URPM::Package pkg ++ PREINIT: ++ I32 gimme = GIMME_V; ++ PPCODE: ++ if (pkg->info) { ++ if (gimme == G_SCALAR) { ++ char *eos; ++ if ((eos = strchr(pkg->info, '@')) != NULL) { ++ XPUSHs(sv_2mortal(newSVpv(pkg->info, eos-pkg->info))); ++ } ++ } else if (gimme == G_ARRAY) { ++ char *name, *version, *release, *arch, *eos; ++ get_fullname_parts(pkg, &name, &version, &release, &arch, &eos); ++ if (version - name < 1 || release - version < 1 || arch - release < 1) ++ croak("invalid fullname"); ++ EXTEND(SP, 4); ++ PUSHs(sv_2mortal(newSVpv(name, version-name-1))); ++ PUSHs(sv_2mortal(newSVpv(version, release-version-1))); ++ PUSHs(sv_2mortal(newSVpv(release, arch-release-1))); ++ PUSHs(sv_2mortal(newSVpv(arch, eos-arch))); ++ } ++ } else if (pkg->h) { ++ char *name = get_name(pkg->h, RPMTAG_NAME); ++ char *version = get_name(pkg->h, RPMTAG_VERSION); ++ char *release = get_name(pkg->h, RPMTAG_RELEASE); ++ char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src"; ++ ++ if (gimme == G_SCALAR) { ++ XPUSHs(sv_2mortal(newSVpvf("%s-%s-%s.%s", name, version, release, arch))); ++ } else if (gimme == G_ARRAY) { ++ EXTEND(SP, 4); ++ PUSHs(sv_2mortal(newSVpv(name, 0))); ++ PUSHs(sv_2mortal(newSVpv(version, 0))); ++ PUSHs(sv_2mortal(newSVpv(release, 0))); ++ PUSHs(sv_2mortal(newSVpv(arch, 0))); ++ } ++ } ++ ++int ++Pkg_epoch(pkg) ++ URPM::Package pkg ++ CODE: ++ if (pkg->info) { ++ char *s, *eos; ++ ++ if ((s = strchr(pkg->info, '@')) != NULL) { ++ if ((eos = strchr(s+1, '@')) != NULL) *eos = 0; /* mark end of string to enable searching backwards */ ++ RETVAL = atoi(s+1); ++ if (eos != NULL) *eos = '@'; ++ } else { ++ RETVAL = 0; ++ } ++ } else if (pkg->h) { ++ RETVAL = get_int(pkg->h, RPMTAG_EPOCH); ++ } else RETVAL = 0; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_compare_pkg(lpkg, rpkg) ++ URPM::Package lpkg ++ URPM::Package rpkg ++ PREINIT: ++ int compare = 0; ++ int lepoch; ++ char *lversion; ++ char *lrelease; ++ char *larch; ++ char *leos; ++ int repoch; ++ char *rversion; ++ char *rrelease; ++ char *rarch; ++ char *reos; ++ CODE: ++ if (lpkg == rpkg) RETVAL = 0; ++ else { ++ if (lpkg->info) { ++ char *s; ++ ++ if ((s = strchr(lpkg->info, '@')) != NULL) { ++ if ((leos = strchr(s+1, '@')) != NULL) *leos = 0; /* mark end of string to enable searching backwards */ ++ lepoch = atoi(s+1); ++ if (leos != NULL) *leos = '@'; ++ } else { ++ lepoch = 0; ++ } ++ get_fullname_parts(lpkg, NULL, &lversion, &lrelease, &larch, &leos); ++ /* temporarily mark end of each substring */ ++ lrelease[-1] = 0; ++ larch[-1] = 0; ++ } else if (lpkg->h) { ++ lepoch = get_int(lpkg->h, RPMTAG_EPOCH); ++ lversion = get_name(lpkg->h, RPMTAG_VERSION); ++ lrelease = get_name(lpkg->h, RPMTAG_RELEASE); ++ larch = headerIsEntry(lpkg->h, RPMTAG_SOURCERPM) ? get_name(lpkg->h, RPMTAG_ARCH) : "src"; ++ } else croak("undefined package"); ++ if (rpkg->info) { ++ char *s; ++ ++ if ((s = strchr(rpkg->info, '@')) != NULL) { ++ if ((reos = strchr(s+1, '@')) != NULL) *reos = 0; /* mark end of string to enable searching backwards */ ++ repoch = atoi(s+1); ++ if (reos != NULL) *reos = '@'; ++ } else { ++ repoch = 0; ++ } ++ get_fullname_parts(rpkg, NULL, &rversion, &rrelease, &rarch, &reos); ++ /* temporarily mark end of each substring */ ++ rrelease[-1] = 0; ++ rarch[-1] = 0; ++ } else if (rpkg->h) { ++ repoch = get_int(rpkg->h, RPMTAG_EPOCH); ++ rversion = get_name(rpkg->h, RPMTAG_VERSION); ++ rrelease = get_name(rpkg->h, RPMTAG_RELEASE); ++ rarch = headerIsEntry(rpkg->h, RPMTAG_SOURCERPM) ? get_name(rpkg->h, RPMTAG_ARCH) : "src"; ++ } else { ++ /* restore info string modified */ ++ if (lpkg->info) { ++ lrelease[-1] = '-'; ++ larch[-1] = '.'; ++ } ++ croak("undefined package"); ++ } ++ compare = lepoch - repoch; ++ if (!compare) { ++ compare = rpmvercmp(lversion, rversion); ++ if (!compare) { ++ compare = rpmvercmp(lrelease, rrelease); ++ if (!compare) { ++ int lscore, rscore; ++ char *eolarch = strchr(larch, '@'); ++ char *eorarch = strchr(rarch, '@'); ++ ++ read_config_files(0); ++ if (eolarch) *eolarch = 0; lscore = rpmMachineScore(RPM_MACHTABLE_INSTARCH, larch); ++ if (eorarch) *eorarch = 0; rscore = rpmMachineScore(RPM_MACHTABLE_INSTARCH, rarch); ++ if (lscore == 0) { ++ if (rscore == 0) ++#if 0 ++ /* Nanar: TODO check this ++ * hu ?? what is the goal of strcmp, some of arch are equivalent */ ++ compare = 0 ++#endif ++ compare = strcmp(larch, rarch); ++ else ++ compare = -1; ++ } else { ++ if (rscore == 0) ++ compare = 1; ++ else ++ compare = rscore - lscore; /* score are lower for better */ ++ } ++ if (eolarch) *eolarch = '@'; ++ if (eorarch) *eorarch = '@'; ++ } ++ } ++ } ++ /* restore info string modified */ ++ if (lpkg->info) { ++ lrelease[-1] = '-'; ++ larch[-1] = '.'; ++ } ++ if (rpkg->info) { ++ rrelease[-1] = '-'; ++ rarch[-1] = '.'; ++ } ++ RETVAL = compare; ++ } ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_compare(pkg, evr) ++ URPM::Package pkg ++ char *evr ++ PREINIT: ++ int compare = 0; ++ int _epoch; ++ char *_version; ++ char *_release; ++ char *_eos; ++ CODE: ++ if (pkg->info) { ++ char *s; ++ ++ if ((s = strchr(pkg->info, '@')) != NULL) { ++ if ((_eos = strchr(s+1, '@')) != NULL) *_eos = 0; /* mark end of string to enable searching backwards */ ++ _epoch = atoi(s+1); ++ if (_eos != NULL) *_eos = '@'; ++ } else { ++ _epoch = 0; ++ } ++ get_fullname_parts(pkg, NULL, &_version, &_release, &_eos, NULL); ++ /* temporarily mark end of each substring */ ++ _release[-1] = 0; ++ _eos[-1] = 0; ++ } else if (pkg->h) { ++ _epoch = get_int(pkg->h, RPMTAG_EPOCH); ++ } else croak("undefined package"); ++ if (!compare) { ++ char *epoch, *version, *release; ++ ++ /* extract epoch and version from evr */ ++ version = evr; ++ while (*version && isdigit(*version)) version++; ++ if (*version == ':') { ++ epoch = evr; ++ *version++ = 0; ++ if (!*epoch) epoch = "0"; ++ compare = _epoch - (*epoch ? atoi(epoch) : 0); ++ version[-1] = ':'; /* restore in memory modification */ ++ } else { ++ /* there is no epoch defined, so assume epoch = 0 */ ++ version = evr; ++ compare = _epoch; ++ } ++ if (!compare) { ++ if (!pkg->info) ++ _version = get_name(pkg->h, RPMTAG_VERSION); ++ /* continue extracting release if any */ ++ if ((release = strrchr(version, '-')) != NULL) { ++ *release++ = 0; ++ compare = rpmvercmp(_version, version); ++ if (!compare) { ++ /* need to compare with release here */ ++ if (!pkg->info) ++ _release = get_name(pkg->h, RPMTAG_RELEASE); ++ compare = rpmvercmp(_release, release); ++ } ++ release[-1] = '-'; /* restore in memory modification */ ++ } else { ++ compare = rpmvercmp(_version, version); ++ } ++ } ++ } ++ /* restore info string modified */ ++ if (pkg->info) { ++ _release[-1] = '-'; ++ _eos[-1] = '.'; ++ } ++ RETVAL = compare; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_size(pkg) ++ URPM::Package pkg ++ CODE: ++ if (pkg->info) { ++ char *s, *eos; ++ ++ if ((s = strchr(pkg->info, '@')) != NULL && (s = strchr(s+1, '@')) != NULL) { ++ if ((eos = strchr(s+1, '@')) != NULL) *eos = 0; /* mark end of string to enable searching backwards */ ++ RETVAL = atoi(s+1); ++ if (eos != NULL) *eos = '@'; ++ } else { ++ RETVAL = 0; ++ } ++ } else if (pkg->h) { ++ RETVAL = get_int(pkg->h, RPMTAG_SIZE); ++ } else RETVAL = 0; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_filesize(pkg) ++ URPM::Package pkg ++ CODE: ++ if (pkg->filesize) { ++ RETVAL = pkg->filesize; ++ } else if (pkg->h) { ++ RETVAL = sigsize_to_filesize(get_int(pkg->h, RPMTAG_SIGSIZE)); ++ } else RETVAL = 0; ++ OUTPUT: ++ RETVAL ++ ++void ++Pkg_group(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->info) { ++ char *s; ++ ++ if ((s = strchr(pkg->info, '@')) != NULL && (s = strchr(s+1, '@')) != NULL && (s = strchr(s+1, '@')) != NULL) { ++ char *eos = strchr(s+1, '@'); ++ XPUSHs(sv_2mortal(newSVpv_utf8(s+1, eos != NULL ? eos-s-1 : 0))); ++ } ++ } else if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv_utf8(get_name(pkg->h, RPMTAG_GROUP), 0))); ++ } ++ ++void ++Pkg_filename(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->info) { ++ char *eon; ++ ++ if ((eon = strchr(pkg->info, '@')) != NULL) { ++ char savbuf[4]; ++ memcpy(savbuf, eon, 4); /* there should be at least epoch and size described so (@<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">0 at 0</A> minimum) */ ++ memcpy(eon, ".rpm", 4); ++ XPUSHs(sv_2mortal(newSVpv(pkg->info, eon-pkg->info+4))); ++ memcpy(eon, savbuf, 4); ++ } ++ } else if (pkg->h) { ++ char *name = get_name(pkg->h, RPMTAG_NAME); ++ char *version = get_name(pkg->h, RPMTAG_VERSION); ++ char *release = get_name(pkg->h, RPMTAG_RELEASE); ++ char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src"; ++ ++ XPUSHs(sv_2mortal(newSVpvf("%s-%s-%s.%s.rpm", name, version, release, arch))); ++ } ++ ++# deprecated ++void ++Pkg_header_filename(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->info) { ++ char *eon; ++ ++ if ((eon = strchr(pkg->info, '@')) != NULL) { ++ XPUSHs(sv_2mortal(newSVpv(pkg->info, eon-pkg->info))); ++ } ++ } else if (pkg->h) { ++ char buff[1024]; ++ char *p = buff; ++ char *name = get_name(pkg->h, RPMTAG_NAME); ++ char *version = get_name(pkg->h, RPMTAG_VERSION); ++ char *release = get_name(pkg->h, RPMTAG_RELEASE); ++ char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src"; ++ ++ p += snprintf(buff, sizeof(buff), "%s-%s-%s.%s", name, version, release, arch); ++ XPUSHs(sv_2mortal(newSVpv(buff, p-buff))); ++ } ++ ++void ++Pkg_id(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if ((pkg->flag & FLAG_ID) <= FLAG_ID_MAX) { ++ XPUSHs(sv_2mortal(newSViv(pkg->flag & FLAG_ID))); ++ } ++ ++void ++Pkg_set_id(pkg, id=-1) ++ URPM::Package pkg ++ int id ++ PPCODE: ++ if ((pkg->flag & FLAG_ID) <= FLAG_ID_MAX) { ++ XPUSHs(sv_2mortal(newSViv(pkg->flag & FLAG_ID))); ++ } ++ pkg->flag &= ~FLAG_ID; ++ pkg->flag |= id >= 0 && id <= FLAG_ID_MAX ? id : FLAG_ID_INVALID; ++ ++void ++Pkg_requires(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_str(pkg->requires, pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION, ++ callback_list_str_xpush_requires, NULL); ++ SPAGAIN; ++ ++void ++Pkg_requires_nosense(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_str(pkg->requires, pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, 0, ++ callback_list_str_xpush_requires, NULL); ++ SPAGAIN; ++ ++void ++Pkg_suggests(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ int count = return_list_str(pkg->suggests, pkg->h, RPMTAG_SUGGESTSNAME, 0, 0, callback_list_str_xpush, NULL); ++ if (count == 0) ++ return_list_str(pkg->suggests, pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, 0, ++ callback_list_str_xpush_old_suggests, NULL); ++ SPAGAIN; ++ ++void ++Pkg_obsoletes(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION, ++ callback_list_str_xpush, NULL); ++ SPAGAIN; ++ ++void ++Pkg_obsoletes_nosense(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, 0, 0, callback_list_str_xpush, NULL); ++ SPAGAIN; ++ ++int ++Pkg_obsoletes_overlap(pkg, s, b_nopromote=1, direction=-1) ++ URPM::Package pkg ++ char *s ++ int b_nopromote ++ int direction ++ PREINIT: ++ struct cb_overlap_s os; ++ char *eon = NULL; ++ char eonc = '\0'; ++ CODE: ++ os.name = s; ++ os.flags = 0; ++ while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; ++ if (*s) { ++ eon = s; ++ while (*s) { ++ if (*s == ' ' || *s == '[' || *s == '*' || *s == ']'); ++ else if (*s == '<') os.flags |= RPMSENSE_LESS; ++ else if (*s == '>') os.flags |= RPMSENSE_GREATER; ++ else if (*s == '=') os.flags |= RPMSENSE_EQUAL; ++ else break; ++ ++s; ++ } ++ os.evr = s; ++ } else ++ os.evr = ""; ++ os.direction = direction; ++ os.b_nopromote = b_nopromote; ++ /* mark end of name */ ++ if (eon) { eonc = *eon; *eon = 0; } ++ /* return_list_str returns a negative value is the callback has returned non-zero */ ++ RETVAL = return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION, ++ callback_list_str_overlap, &os) < 0; ++ /* restore end of name */ ++ if (eon) *eon = eonc; ++ OUTPUT: ++ RETVAL ++ ++void ++Pkg_conflicts(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_str(pkg->conflicts, pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION, ++ callback_list_str_xpush, NULL); ++ SPAGAIN; ++ ++void ++Pkg_conflicts_nosense(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_str(pkg->conflicts, pkg->h, RPMTAG_CONFLICTNAME, 0, 0, callback_list_str_xpush, NULL); ++ SPAGAIN; ++ ++void ++Pkg_provides(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION, ++ callback_list_str_xpush, NULL); ++ SPAGAIN; ++ ++void ++Pkg_provides_nosense(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, 0, 0, callback_list_str_xpush, NULL); ++ SPAGAIN; ++ ++int ++Pkg_provides_overlap(pkg, s, b_nopromote=1, direction=1) ++ URPM::Package pkg ++ char *s ++ int b_nopromote ++ int direction ++ PREINIT: ++ struct cb_overlap_s os; ++ char *eon = NULL; ++ char eonc = '\0'; ++ CODE: ++ os.name = s; ++ os.flags = 0; ++ while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; ++ if (*s) { ++ eon = s; ++ while (*s) { ++ if (*s == ' ' || *s == '[' || *s == '*' || *s == ']'); ++ else if (*s == '<') os.flags |= RPMSENSE_LESS; ++ else if (*s == '>') os.flags |= RPMSENSE_GREATER; ++ else if (*s == '=') os.flags |= RPMSENSE_EQUAL; ++ else break; ++ ++s; ++ } ++ os.evr = s; ++ } else ++ os.evr = ""; ++ os.direction = direction; ++ os.b_nopromote = b_nopromote; ++ /* mark end of name */ ++ if (eon) { eonc = *eon; *eon = 0; } ++ /* return_list_str returns a negative value is the callback has returned non-zero */ ++ RETVAL = return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION, ++ callback_list_str_overlap, &os) < 0; ++ /* restore end of name */ ++ if (eon) *eon = eonc; ++ OUTPUT: ++ RETVAL ++ ++void ++Pkg_buildarchs(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_BUILDARCHS); ++ SPAGAIN; ++ ++void ++Pkg_excludearchs(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_EXCLUDEARCH); ++ SPAGAIN; ++ ++void ++Pkg_exclusivearchs(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_EXCLUSIVEARCH); ++ SPAGAIN; ++ ++void ++Pkg_dirnames(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_DIRNAMES); ++ SPAGAIN; ++ ++void Pkg_distepoch(pkg) ++ URPM::Package pkg ++ PPCODE: ++#ifdef RPMTAG_DISTEPOCH ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_DISTEPOCH), 0))); ++ } ++#else ++ croak("distepoch isn't available with this rpm version"); ++#endif ++ ++void Pkg_disttag(pkg) ++ URPM::Package pkg ++ PPCODE: ++ if (pkg->h) { ++ XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_DISTTAG), 0))); ++ } ++ ++void ++Pkg_filelinktos(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_FILELINKTOS); ++ SPAGAIN; ++ ++void ++Pkg_files(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_files(pkg->h, 0); ++ SPAGAIN; ++ ++void ++Pkg_files_md5sum(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_FILEMD5S); ++ SPAGAIN; ++ ++void ++Pkg_files_owner(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_FILEUSERNAME); ++ SPAGAIN; ++ ++void ++Pkg_files_group(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_FILEGROUPNAME); ++ SPAGAIN; ++ ++void ++Pkg_files_mtime(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_int32_t(pkg->h, RPMTAG_FILEMTIMES); ++ SPAGAIN; ++ ++void ++Pkg_files_size(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_int32_t(pkg->h, RPMTAG_FILESIZES); ++ SPAGAIN; ++ ++void ++Pkg_files_uid(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_int32_t(pkg->h, RPMTAG_FILEUIDS); ++ SPAGAIN; ++ ++void ++Pkg_files_gid(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_int32_t(pkg->h, RPMTAG_FILEGIDS); ++ SPAGAIN; ++ ++void ++Pkg_files_mode(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_uint_16(pkg->h, RPMTAG_FILEMODES); ++ SPAGAIN; ++ ++void ++Pkg_files_flags(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_int32_t(pkg->h, RPMTAG_FILEFLAGS); ++ SPAGAIN; ++ ++void ++Pkg_conf_files(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_files(pkg->h, FILTER_MODE_CONF_FILES); ++ SPAGAIN; ++ ++void ++Pkg_changelog_time(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ return_list_int32_t(pkg->h, RPMTAG_CHANGELOGTIME); ++ SPAGAIN; ++ ++void ++Pkg_changelog_name(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_CHANGELOGNAME); ++ SPAGAIN; ++ ++void ++Pkg_changelog_text(pkg) ++ URPM::Package pkg ++ PPCODE: ++ PUTBACK; ++ xpush_simple_list_str(pkg->h, RPMTAG_CHANGELOGTEXT); ++ SPAGAIN; ++ ++void ++Pkg_queryformat(pkg, fmt) ++ URPM::Package pkg ++ char *fmt ++ PREINIT: ++ char *s; ++ PPCODE: ++ if (pkg->h) { ++ s = headerFormat(pkg->h, fmt, NULL); ++ if (s) { ++ XPUSHs(sv_2mortal(newSVpv_utf8(s,0))); ++ } ++ } ++ ++void ++Pkg_get_tag(pkg, tagname) ++ URPM::Package pkg ++ int tagname; ++ PPCODE: ++ PUTBACK; ++ return_list_tag(pkg, tagname); ++ SPAGAIN; ++ ++void ++Pkg_get_tag_modifiers(pkg, tagname) ++ URPM::Package pkg ++ int tagname; ++ PPCODE: ++ PUTBACK; ++ return_list_tag_modifier(pkg->h, tagname); ++ SPAGAIN; ++ ++void ++Pkg_pack_header(pkg) ++ URPM::Package pkg ++ CODE: ++ pack_header(pkg); ++ ++int ++Pkg_update_header(pkg, filename, ...) ++ URPM::Package pkg ++ char *filename ++ PREINIT: ++ int packing = 0; ++ int keep_all_tags = 0; ++ CODE: ++ /* compability mode with older interface of parse_hdlist */ ++ if (items == 3) { ++ packing = SvIV(ST(2)); ++ } else if (items > 3) { ++ int i; ++ for (i = 2; i < items-1; i+=2) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ ++ if (len == 7 && !memcmp(s, "packing", 7)) { ++ packing = SvTRUE(ST(i + 1)); ++ } else if (len == 13 && !memcmp(s, "keep_all_tags", 13)) { ++ keep_all_tags = SvTRUE(ST(i+1)); ++ } ++ } ++ } ++ RETVAL = update_header(filename, pkg, !packing && keep_all_tags, RPMVSF_DEFAULT); ++ if (RETVAL && packing) pack_header(pkg); ++ OUTPUT: ++ RETVAL ++ ++void ++Pkg_free_header(pkg) ++ URPM::Package pkg ++ CODE: ++ if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); ++ pkg->h = NULL; ++ ++void ++Pkg_build_info(pkg, fileno, provides_files=NULL) ++ URPM::Package pkg ++ int fileno ++ char *provides_files ++ CODE: ++ if (pkg->info) { ++ char buff[65536]; ++ size_t size; ++ ++ /* info line should be the last to be written */ ++ if (pkg->provides && *pkg->provides) { ++ size = snprintf(buff, sizeof(buff), "@provides@%s\n", pkg->provides); ++ if (size < sizeof(buff)) { ++ if (provides_files && *provides_files) { ++ --size; ++ size += snprintf(buff+size, sizeof(buff)-size, "@%s\n", provides_files); ++ } ++ write_nocheck(fileno, buff, size); ++ } ++ } ++ if (pkg->conflicts && *pkg->conflicts) { ++ size = snprintf(buff, sizeof(buff), "@conflicts@%s\n", pkg->conflicts); ++ if (size < sizeof(buff)) write_nocheck(fileno, buff, size); ++ } ++ if (pkg->obsoletes && *pkg->obsoletes) { ++ size = snprintf(buff, sizeof(buff), "@obsoletes@%s\n", pkg->obsoletes); ++ if (size < sizeof(buff)) write_nocheck(fileno, buff, size); ++ } ++ if (pkg->requires && *pkg->requires) { ++ size = snprintf(buff, sizeof(buff), "@requires@%s\n", pkg->requires); ++ if (size < sizeof(buff)) write_nocheck(fileno, buff, size); ++ } ++ if (pkg->suggests && *pkg->suggests) { ++ size = snprintf(buff, sizeof(buff), "@suggests@%s\n", pkg->suggests); ++ if (size < sizeof(buff)) write_nocheck(fileno, buff, size); ++ } ++ if (pkg->summary && *pkg->summary) { ++ size = snprintf(buff, sizeof(buff), "@summary@%s\n", pkg->summary); ++ if (size < sizeof(buff)) write_nocheck(fileno, buff, size); ++ } ++ if (pkg->filesize) { ++ size = snprintf(buff, sizeof(buff), "@filesize@%d\n", pkg->filesize); ++ if (size < sizeof(buff)) write_nocheck(fileno, buff, size); ++ } ++ size = snprintf(buff, sizeof(buff), "@info@%s\n", pkg->info); ++ write_nocheck(fileno, buff, size); ++ } else croak("no info available for package %s", ++ pkg->h ? get_name(pkg->h, RPMTAG_NAME) : "-"); ++ ++void ++Pkg_build_header(pkg, fileno) ++ URPM::Package pkg ++ int fileno ++ CODE: ++ if (pkg->h) { ++ FD_t fd; ++ ++ if ((fd = fdDup(fileno)) != NULL) { ++ headerWrite(fd, pkg->h, HEADER_MAGIC_YES); ++ Fclose(fd); ++ } else croak("unable to get rpmio handle on fileno %d", fileno); ++ } else croak("no header available for package"); ++ ++int ++Pkg_flag(pkg, name) ++ URPM::Package pkg ++ char *name ++ PREINIT: ++ unsigned mask; ++ CODE: ++ if (!strcmp(name, "skip")) mask = FLAG_SKIP; ++ else if (!strcmp(name, "disable_obsolete")) mask = FLAG_DISABLE_OBSOLETE; ++ else if (!strcmp(name, "installed")) mask = FLAG_INSTALLED; ++ else if (!strcmp(name, "requested")) mask = FLAG_REQUESTED; ++ else if (!strcmp(name, "required")) mask = FLAG_REQUIRED; ++ else if (!strcmp(name, "upgrade")) mask = FLAG_UPGRADE; ++ else croak("unknown flag: %s", name); ++ RETVAL = pkg->flag & mask; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_flag(pkg, name, value=1) ++ URPM::Package pkg ++ char *name ++ int value ++ PREINIT: ++ unsigned mask; ++ CODE: ++ if (!strcmp(name, "skip")) mask = FLAG_SKIP; ++ else if (!strcmp(name, "disable_obsolete")) mask = FLAG_DISABLE_OBSOLETE; ++ else if (!strcmp(name, "installed")) mask = FLAG_INSTALLED; ++ else if (!strcmp(name, "requested")) mask = FLAG_REQUESTED; ++ else if (!strcmp(name, "required")) mask = FLAG_REQUIRED; ++ else if (!strcmp(name, "upgrade")) mask = FLAG_UPGRADE; ++ else croak("unknown flag: %s", name); ++ RETVAL = pkg->flag & mask; ++ if (value) pkg->flag |= mask; ++ else pkg->flag &= ~mask; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_skip(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = pkg->flag & FLAG_SKIP; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_flag_skip(pkg, value=1) ++ URPM::Package pkg ++ int value ++ CODE: ++ RETVAL = pkg->flag & FLAG_SKIP; ++ if (value) pkg->flag |= FLAG_SKIP; ++ else pkg->flag &= ~FLAG_SKIP; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_base(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = pkg->flag & FLAG_BASE; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_flag_base(pkg, value=1) ++ URPM::Package pkg ++ int value ++ CODE: ++ RETVAL = pkg->flag & FLAG_BASE; ++ if (value) pkg->flag |= FLAG_BASE; ++ else pkg->flag &= ~FLAG_BASE; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_disable_obsolete(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = pkg->flag & FLAG_DISABLE_OBSOLETE; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_flag_disable_obsolete(pkg, value=1) ++ URPM::Package pkg ++ int value ++ CODE: ++ RETVAL = pkg->flag & FLAG_DISABLE_OBSOLETE; ++ if (value) pkg->flag |= FLAG_DISABLE_OBSOLETE; ++ else pkg->flag &= ~FLAG_DISABLE_OBSOLETE; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_installed(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = pkg->flag & FLAG_INSTALLED; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_flag_installed(pkg, value=1) ++ URPM::Package pkg ++ int value ++ CODE: ++ RETVAL = pkg->flag & FLAG_INSTALLED; ++ if (value) pkg->flag |= FLAG_INSTALLED; ++ else pkg->flag &= ~FLAG_INSTALLED; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_requested(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = pkg->flag & FLAG_REQUESTED; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_flag_requested(pkg, value=1) ++ URPM::Package pkg ++ int value ++ CODE: ++ RETVAL = pkg->flag & FLAG_REQUESTED; ++ if (value) pkg->flag |= FLAG_REQUESTED; ++ else pkg->flag &= ~FLAG_REQUESTED; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_required(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = pkg->flag & FLAG_REQUIRED; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_flag_required(pkg, value=1) ++ URPM::Package pkg ++ int value ++ CODE: ++ RETVAL = pkg->flag & FLAG_REQUIRED; ++ if (value) pkg->flag |= FLAG_REQUIRED; ++ else pkg->flag &= ~FLAG_REQUIRED; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_upgrade(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = pkg->flag & FLAG_UPGRADE; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_flag_upgrade(pkg, value=1) ++ URPM::Package pkg ++ int value ++ CODE: ++ RETVAL = pkg->flag & FLAG_UPGRADE; ++ if (value) pkg->flag |= FLAG_UPGRADE; ++ else pkg->flag &= ~FLAG_UPGRADE; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_selected(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = pkg->flag & FLAG_UPGRADE ? pkg->flag & (FLAG_BASE | FLAG_REQUIRED) : 0; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_flag_available(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = (pkg->flag & FLAG_INSTALLED && !(pkg->flag & FLAG_UPGRADE)) || ++ (pkg->flag & FLAG_UPGRADE ? pkg->flag & (FLAG_BASE | FLAG_REQUIRED) : 0); ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_rate(pkg) ++ URPM::Package pkg ++ CODE: ++ RETVAL = (pkg->flag & FLAG_RATE) >> FLAG_RATE_POS; ++ OUTPUT: ++ RETVAL ++ ++int ++Pkg_set_rate(pkg, rate) ++ URPM::Package pkg ++ int rate ++ CODE: ++ RETVAL = (pkg->flag & FLAG_RATE) >> FLAG_RATE_POS; ++ pkg->flag &= ~FLAG_RATE; ++ pkg->flag |= (rate >= 0 && rate <= FLAG_RATE_MAX ? rate : FLAG_RATE_INVALID) << FLAG_RATE_POS; ++ OUTPUT: ++ RETVAL ++ ++void ++Pkg_rflags(pkg) ++ URPM::Package pkg ++ PREINIT: ++ I32 gimme = GIMME_V; ++ PPCODE: ++ if (gimme == G_ARRAY && pkg->rflags != NULL) { ++ char *s = pkg->rflags; ++ char *eos; ++ while ((eos = strchr(s, '\t')) != NULL) { ++ XPUSHs(sv_2mortal(newSVpv(s, eos-s))); ++ s = eos + 1; ++ } ++ XPUSHs(sv_2mortal(newSVpv(s, 0))); ++ } ++ ++void ++Pkg_set_rflags(pkg, ...) ++ URPM::Package pkg ++ PREINIT: ++ I32 gimme = GIMME_V; ++ char *new_rflags; ++ STRLEN total_len; ++ int i; ++ PPCODE: ++ total_len = 0; ++ for (i = 1; i < items; ++i) ++ total_len += SvCUR(ST(i)) + 1; ++ ++ new_rflags = malloc(total_len); ++ total_len = 0; ++ for (i = 1; i < items; ++i) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ memcpy(new_rflags + total_len, s, len); ++ new_rflags[total_len + len] = '\t'; ++ total_len += len + 1; ++ } ++ new_rflags[total_len - 1] = 0; /* but mark end-of-string correctly */ ++ ++ if (gimme == G_ARRAY && pkg->rflags != NULL) { ++ char *s = pkg->rflags; ++ char *eos; ++ while ((eos = strchr(s, '\t')) != NULL) { ++ XPUSHs(sv_2mortal(newSVpv(s, eos-s))); ++ s = eos + 1; ++ } ++ XPUSHs(sv_2mortal(newSVpv(s, 0))); ++ } ++ ++ free(pkg->rflags); ++ pkg->rflags = new_rflags; ++ ++ ++MODULE = URPM PACKAGE = URPM::DB PREFIX = Db_ ++ ++URPM::DB ++Db_open(prefix=NULL, write_perm=0) ++ char *prefix ++ int write_perm ++ PREINIT: ++ URPM__DB db; ++ CODE: ++ read_config_files(0); ++ db = malloc(sizeof(struct s_Transaction)); ++ db->count = 1; ++ db->ts = rpmtsCreate(); ++ rpmtsSetRootDir(db->ts, prefix && prefix[0] ? prefix : NULL); ++ if (rpmtsOpenDB(db->ts, write_perm ? O_RDWR | O_CREAT : O_RDONLY) == 0) { ++ RETVAL = db; ++ } else { ++ RETVAL = NULL; ++ (void)rpmtsFree(db->ts); ++ free(db); ++ } ++ OUTPUT: ++ RETVAL ++ ++int ++Db_rebuild(prefix="") ++ char *prefix ++ PREINIT: ++ rpmts ts; ++ CODE: ++ read_config_files(0); ++ ts = rpmtsCreate(); ++ rpmtsSetRootDir(ts, prefix); ++ RETVAL = rpmtsRebuildDB(ts) == 0; ++ (void)rpmtsFree(ts); ++ OUTPUT: ++ RETVAL ++ ++int ++Db_verify(prefix="") ++ char *prefix ++ PREINIT: ++ rpmts ts; ++ CODE: ++ ts = rpmtsCreate(); ++ rpmtsSetRootDir(ts, prefix); ++ RETVAL = rpmtsVerifyDB(ts) == 0; ++ ts = rpmtsFree(ts); ++ OUTPUT: ++ RETVAL ++ ++void ++Db_DESTROY(db) ++ URPM::DB db ++ CODE: ++ (void)rpmtsFree(db->ts); ++ if (!--db->count) free(db); ++ ++int ++Db_traverse(db,callback) ++ URPM::DB db ++ SV *callback ++ PREINIT: ++ Header header; ++ rpmdbMatchIterator mi; ++ int count = 0; ++ CODE: ++ db->ts = rpmtsLink(db->ts, "URPM::DB::traverse"); ++ ts_nosignature(db->ts); ++ mi = rpmtsInitIterator(db->ts, RPMDBI_PACKAGES, NULL, 0); ++ while ((header = rpmdbNextIterator(mi))) { ++ if (SvROK(callback)) { ++ dSP; ++ URPM__Package pkg = calloc(1, sizeof(struct s_Package)); ++ ++ pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; ++ pkg->h = header; ++ ++ PUSHMARK(SP); ++ XPUSHs(sv_2mortal(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg))); ++ PUTBACK; ++ ++ call_sv(callback, G_DISCARD | G_SCALAR); ++ ++ SPAGAIN; ++ pkg->h = 0; /* avoid using it anymore, in case it has been copied inside callback */ ++ } ++ ++count; ++ } ++ rpmdbFreeIterator(mi); ++ (void)rpmtsFree(db->ts); ++ RETVAL = count; ++ OUTPUT: ++ RETVAL ++ ++int ++Db_traverse_tag(db,tag,names,callback) ++ URPM::DB db ++ char *tag ++ SV *names ++ SV *callback ++ PREINIT: ++ Header header; ++ rpmdbMatchIterator mi; ++ int count = 0; ++ CODE: ++ if (SvROK(names) && SvTYPE(SvRV(names)) == SVt_PVAV) { ++ AV* names_av = (AV*)SvRV(names); ++ int len = av_len(names_av); ++ int i, rpmtag; ++ ++ rpmtag = rpmtag_from_string(tag); ++ ++ for (i = 0; i <= len; ++i) { ++ STRLEN str_len; ++ SV **isv = av_fetch(names_av, i, 0); ++ char *name = SvPV(*isv, str_len); ++ db->ts = rpmtsLink(db->ts, "URPM::DB::traverse_tag"); ++ ts_nosignature(db->ts); ++ mi = rpmtsInitIterator(db->ts, rpmtag, name, str_len); ++ while ((header = rpmdbNextIterator(mi))) { ++ if (SvROK(callback)) { ++ dSP; ++ URPM__Package pkg = calloc(1, sizeof(struct s_Package)); ++ ++ pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; ++ pkg->h = header; ++ ++ PUSHMARK(SP); ++ XPUSHs(sv_2mortal(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg))); ++ PUTBACK; ++ ++ call_sv(callback, G_DISCARD | G_SCALAR); ++ ++ SPAGAIN; ++ pkg->h = 0; /* avoid using it anymore, in case it has been copied inside callback */ ++ } ++ ++count; ++ } ++ (void)rpmdbFreeIterator(mi); ++ (void)rpmtsFree(db->ts); ++ } ++ } else croak("bad arguments list"); ++ RETVAL = count; ++ OUTPUT: ++ RETVAL ++ ++int ++Db_traverse_tag_find(db,tag,name,callback) ++ URPM::DB db ++ char *tag ++ char *name ++ SV *callback ++ PREINIT: ++ Header header; ++ rpmdbMatchIterator mi; ++ CODE: ++ int rpmtag = rpmtag_from_string(tag); ++ int found = 0; ++ ++ db->ts = rpmtsLink(db->ts, "URPM::DB::traverse_tag"); ++ ts_nosignature(db->ts); ++ mi = rpmtsInitIterator(db->ts, rpmtag, name, 0); ++ while ((header = rpmdbNextIterator(mi))) { ++ dSP; ++ URPM__Package pkg = calloc(1, sizeof(struct s_Package)); ++ ++ pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; ++ pkg->h = header; ++ ++ PUSHMARK(SP); ++ XPUSHs(sv_2mortal(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg))); ++ PUTBACK; ++ ++ int count = call_sv(callback, G_SCALAR); ++ ++ SPAGAIN; ++ pkg->h = 0; /* avoid using it anymore, in case it has been copied inside callback */ ++ ++ if (count == 1 && POPi) { ++ found = 1; ++ break; ++ } ++ } ++ (void)rpmdbFreeIterator(mi); ++ (void)rpmtsFree(db->ts); ++ RETVAL = found; ++ OUTPUT: ++ RETVAL ++ ++URPM::Transaction ++Db_create_transaction(db, prefix="/") ++ URPM::DB db ++ char *prefix ++ CODE: ++ /* this is *REALLY* dangerous to create a new transaction while another is open, ++ so use the db transaction instead. */ ++ db->ts = rpmtsLink(db->ts, "URPM::DB::create_transaction"); ++ ++db->count; ++ RETVAL = db; ++ OUTPUT: ++ RETVAL ++ ++ ++MODULE = URPM PACKAGE = URPM::Transaction PREFIX = Trans_ ++ ++void ++Trans_DESTROY(trans) ++ URPM::Transaction trans ++ CODE: ++ (void)rpmtsFree(trans->ts); ++ if (!--trans->count) free(trans); ++ ++void ++Trans_set_script_fd(trans, fdno) ++ URPM::Transaction trans ++ int fdno ++ CODE: ++ rpmtsSetScriptFd(trans->ts, fdDup(fdno)); ++ ++int ++Trans_add(trans, pkg, ...) ++ URPM::Transaction trans ++ URPM::Package pkg ++ CODE: ++ if ((pkg->flag & FLAG_ID) <= FLAG_ID_MAX && pkg->h != NULL) { ++ int update = 0; ++#ifndef RPM_ORG ++ rpmRelocation relocations = NULL; ++#else ++ rpmRelocation *relocations = NULL; ++#endif ++ /* compability mode with older interface of add */ ++ if (items == 3) { ++ update = SvIV(ST(2)); ++ } else if (items > 3) { ++ int i; ++ for (i = 2; i < items-1; i+=2) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ ++ if (len == 6 && !memcmp(s, "update", 6)) { ++ update = SvIV(ST(i+1)); ++ } else if (len == 11 && !memcmp(s, "excludepath", 11)) { ++ if (SvROK(ST(i+1)) && SvTYPE(SvRV(ST(i+1))) == SVt_PVAV) { ++ AV *excludepath = (AV*)SvRV(ST(i+1)); ++ I32 j = 1 + av_len(excludepath); ++#ifndef RPM_ORG ++ int relno = 0; ++ relocations = malloc(sizeof(rpmRelocation)); ++#else ++ relocations = calloc(j + 1, sizeof(rpmRelocation)); ++#endif ++ while (--j >= 0) { ++ SV **e = av_fetch(excludepath, j, 0); ++ if (e != NULL && *e != NULL) { ++#ifndef RPM_ORG ++ rpmfiAddRelocation(&relocations, &relno, SvPV_nolen(*e), NULL); ++#else ++ relocations[j].oldPath = SvPV_nolen(*e); ++#endif ++ } ++ } ++ } ++ } ++ } ++ } ++ RETVAL = rpmtsAddInstallElement(trans->ts, pkg->h, (fnpyKey)(1+(long)(pkg->flag & FLAG_ID)), update, relocations) == 0; ++ /* free allocated memory, check rpm is copying it just above, at least in 4.0.4 */ ++#ifndef RPM_ORG ++ rpmfiFreeRelocations(relocations); ++#else ++ free(relocations); ++#endif ++ } else RETVAL = 0; ++ OUTPUT: ++ RETVAL ++ ++int ++Trans_remove(trans, name) ++ URPM::Transaction trans ++ char *name ++ PREINIT: ++ Header h; ++ rpmdbMatchIterator mi; ++ int count = 0; ++ char *boa = NULL, *bor = NULL; ++ CODE: ++ /* hide arch in name if present */ ++ if ((boa = strrchr(name, '.'))) { ++ *boa = 0; ++ if ((bor = strrchr(name, '-'))) { ++ *bor = 0; ++ if (!strrchr(name, '-')) { ++ *boa = '.'; boa = NULL; ++ } ++ *bor = '-'; bor = NULL; ++ } else { ++ *boa = '.'; boa = NULL; ++ } ++ } ++ mi = rpmtsInitIterator(trans->ts, RPMDBI_LABEL, name, 0); ++ while ((h = rpmdbNextIterator(mi))) { ++ unsigned int recOffset = rpmdbGetIteratorOffset(mi); ++ if (recOffset != 0) { ++ rpmtsAddEraseElement(trans->ts, h, recOffset); ++ ++count; ++ } ++ } ++ rpmdbFreeIterator(mi); ++ if (boa) *boa = '.'; ++ RETVAL=count; ++ OUTPUT: ++ RETVAL ++ ++int ++Trans_traverse(trans, callback) ++ URPM::Transaction trans ++ SV *callback ++ PREINIT: ++ rpmdbMatchIterator mi; ++ Header h; ++ int c = 0; ++ CODE: ++ mi = rpmtsInitIterator(trans->ts, RPMDBI_PACKAGES, NULL, 0); ++ while ((h = rpmdbNextIterator(mi))) { ++ if (SvROK(callback)) { ++ dSP; ++ URPM__Package pkg = calloc(1, sizeof(struct s_Package)); ++ pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; ++ pkg->h = h; ++ PUSHMARK(SP); ++ XPUSHs(sv_2mortal(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg))); ++ PUTBACK; ++ call_sv(callback, G_DISCARD | G_SCALAR); ++ SPAGAIN; ++ pkg->h = 0; /* avoid using it anymore, in case it has been copied inside callback */ ++ } ++ ++c; ++ } ++ rpmdbFreeIterator(mi); ++ RETVAL = c; ++ OUTPUT: ++ RETVAL ++ ++void ++Trans_check(trans, ...) ++ URPM::Transaction trans ++ PREINIT: ++ I32 gimme = GIMME_V; ++ int translate_message = 0; ++ int i; ++ PPCODE: ++ for (i = 1; i < items-1; i+=2) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ ++ if (len == 17 && !memcmp(s, "translate_message", 17)) { ++ translate_message = SvIV(ST(i+1)); ++ } ++ } ++ if (rpmtsCheck(trans->ts)) { ++ if (gimme == G_SCALAR) { ++ XPUSHs(sv_2mortal(newSViv(0))); ++ } else if (gimme == G_ARRAY) { ++ XPUSHs(sv_2mortal(newSVpv("error while checking dependencies", 0))); ++ } ++ } else { ++ rpmps ps = rpmtsProblems(trans->ts); ++ if (rpmpsNumProblems(ps) > 0) { ++ if (gimme == G_SCALAR) { ++ XPUSHs(sv_2mortal(newSViv(0))); ++ } else if (gimme == G_ARRAY) { ++ /* now translation is handled by rpmlib, but only for version 4.2 and above */ ++ PUTBACK; ++ return_problems(ps, 1, 0); ++ SPAGAIN; ++ } ++ } else if (gimme == G_SCALAR) { ++ XPUSHs(sv_2mortal(newSViv(1))); ++ } ++ ps = rpmpsFree(ps); ++ } ++ ++void ++Trans_order(trans) ++ URPM::Transaction trans ++ PREINIT: ++ I32 gimme = GIMME_V; ++ PPCODE: ++ if (rpmtsOrder(trans->ts) == 0) { ++ if (gimme == G_SCALAR) { ++ XPUSHs(sv_2mortal(newSViv(1))); ++ } ++ } else { ++ if (gimme == G_SCALAR) { ++ XPUSHs(sv_2mortal(newSViv(0))); ++ } else if (gimme == G_ARRAY) { ++ XPUSHs(sv_2mortal(newSVpv("error while ordering dependencies", 0))); ++ } ++ } ++ ++int ++Trans_NElements(trans) ++ URPM::Transaction trans ++ CODE: ++ RETVAL = rpmtsNElements(trans->ts); ++ OUTPUT: ++ RETVAL ++ ++char * ++Trans_Element_name(trans, index) ++ URPM::Transaction trans ++ int index ++ CODE: ++ rpmte te = rpmtsElement(trans->ts, index); ++ RETVAL = te ? (char *) rpmteN(te) : NULL; ++ OUTPUT: ++ RETVAL ++ ++char * ++Trans_Element_version(trans, index) ++ URPM::Transaction trans ++ int index ++ CODE: ++ rpmte te = rpmtsElement(trans->ts, index); ++ RETVAL = te ? (char *) rpmteV(te) : NULL; ++ OUTPUT: ++ RETVAL ++ ++char * ++Trans_Element_release(trans, index) ++ URPM::Transaction trans ++ int index ++ CODE: ++ rpmte te = rpmtsElement(trans->ts, index); ++ RETVAL = te ? (char *) rpmteR(te) : NULL; ++ OUTPUT: ++ RETVAL ++ ++char * ++Trans_Element_fullname(trans, index) ++ URPM::Transaction trans ++ int index ++ CODE: ++ rpmte te = rpmtsElement(trans->ts, index); ++ RETVAL = te ? (char *) rpmteNEVRA(te) : NULL; ++ OUTPUT: ++ RETVAL ++ ++void ++Trans_run(trans, data, ...) ++ URPM::Transaction trans ++ SV *data ++ PREINIT: ++ struct s_TransactionData td = { NULL, NULL, NULL, NULL, NULL, 100000, data }; ++ rpmtransFlags transFlags = RPMTRANS_FLAG_NONE; ++ int probFilter = 0; ++ int translate_message = 0, raw_message = 0; ++ int i; ++ PPCODE: ++ for (i = 2 ; i < items - 1 ; i += 2) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ ++ if (len == 4 && !memcmp(s, "test", 4)) { ++ if (SvIV(ST(i+1))) transFlags |= RPMTRANS_FLAG_TEST; ++ } else if (len == 11 && !memcmp(s, "excludedocs", 11)) { ++ if (SvIV(ST(i+1))) transFlags |= RPMTRANS_FLAG_NODOCS; ++ } else if (len == 5) { ++ if (!memcmp(s, "force", 5)) { ++ if (SvIV(ST(i+1))) probFilter |= (RPMPROB_FILTER_REPLACEPKG | ++ RPMPROB_FILTER_REPLACEOLDFILES | ++ RPMPROB_FILTER_REPLACENEWFILES | ++ RPMPROB_FILTER_OLDPACKAGE); ++ } else if (!memcmp(s, "delta", 5)) ++ td.min_delta = SvIV(ST(i+1)); ++ } else if (len == 6 && !memcmp(s, "nosize", 6)) { ++ if (SvIV(ST(i+1))) probFilter |= (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES); ++ } else if (len == 9 && !memcmp(s, "noscripts", 9)) { ++ if (SvIV(ST(i+1))) transFlags |= (RPMTRANS_FLAG_NOSCRIPTS | ++ RPMTRANS_FLAG_NOPRE | ++ RPMTRANS_FLAG_NOPREUN | ++ RPMTRANS_FLAG_NOPOST | ++ RPMTRANS_FLAG_NOPOSTUN ); ++ } else if (len == 10 && !memcmp(s, "oldpackage", 10)) { ++ if (SvIV(ST(i+1))) probFilter |= RPMPROB_FILTER_OLDPACKAGE; ++ } else if (len == 11 && !memcmp(s, "replacepkgs", 11)) { ++ if (SvIV(ST(i+1))) probFilter |= RPMPROB_FILTER_REPLACEPKG; ++ } else if (len == 11 && !memcmp(s, "raw_message", 11)) { ++ raw_message = 1; ++ } else if (len == 12 && !memcmp(s, "replacefiles", 12)) { ++ if (SvIV(ST(i+1))) probFilter |= RPMPROB_FILTER_REPLACEOLDFILES | RPMPROB_FILTER_REPLACENEWFILES; ++ } else if (len == 9 && !memcmp(s, "repackage", 9)) { ++ if (SvIV(ST(i+1))) transFlags |= RPMTRANS_FLAG_REPACKAGE; ++ } else if (len == 6 && !memcmp(s, "justdb", 6)) { ++ if (SvIV(ST(i+1))) transFlags |= RPMTRANS_FLAG_JUSTDB; ++ } else if (len == 10 && !memcmp(s, "ignorearch", 10)) { ++ if (SvIV(ST(i+1))) probFilter |= RPMPROB_FILTER_IGNOREARCH; ++ } else if (len == 17 && !memcmp(s, "translate_message", 17)) ++ translate_message = 1; ++ else if (len >= 9 && !memcmp(s, "callback_", 9)) { ++ if (len == 9+4 && !memcmp(s+9, "open", 4)) { ++ if (SvROK(ST(i+1))) td.callback_open = ST(i+1); ++ } else if (len == 9+5 && !memcmp(s+9, "close", 5)) { ++ if (SvROK(ST(i+1))) td.callback_close = ST(i+1); ++ } else if (len == 9+5 && !memcmp(s+9, "trans", 5)) { ++ if (SvROK(ST(i+1))) td.callback_trans = ST(i+1); ++ } else if (len == 9+6 && !memcmp(s+9, "uninst", 6)) { ++ if (SvROK(ST(i+1))) td.callback_uninst = ST(i+1); ++ } else if (len == 9+4 && !memcmp(s+9, "inst", 4)) { ++ if (SvROK(ST(i+1))) td.callback_inst = ST(i+1); ++ } ++ } ++ } ++ /* check macros */ ++ { ++ char *repa = rpmExpand("%_repackage_all_erasures", NULL); ++ if (repa && *repa && *repa != '0') ++ transFlags |= RPMTRANS_FLAG_REPACKAGE; ++ if (repa) free(repa); ++ } ++ rpmtsSetFlags(trans->ts, transFlags); ++ trans->ts = rpmtsLink(trans->ts, "URPM::Transaction::run"); ++ rpmtsSetNotifyCallback(trans->ts, rpmRunTransactions_callback, &td); ++ if (rpmtsRun(trans->ts, NULL, probFilter) > 0) { ++ rpmps ps = rpmtsProblems(trans->ts); ++ PUTBACK; ++ return_problems(ps, translate_message, raw_message || !translate_message); ++ SPAGAIN; ++ ps = rpmpsFree(ps); ++ } ++ rpmtsEmpty(trans->ts); ++ (void)rpmtsFree(trans->ts); ++ ++MODULE = URPM PACKAGE = URPM PREFIX = Urpm_ ++ ++BOOT: ++(void) read_config_files(0); ++ ++void ++Urpm_bind_rpm_textdomain_codeset() ++ CODE: ++ rpm_codeset_is_utf8 = 1; ++ bind_textdomain_codeset("rpm", "UTF-8"); ++ ++int ++Urpm_read_config_files() ++ CODE: ++ RETVAL = (read_config_files(1) == 0); /* force re-read of configuration files */ ++ OUTPUT: ++ RETVAL ++ ++void ++Urpm_list_rpm_tag(urpm=Nullsv) ++ SV *urpm ++ CODE: ++ croak("list_rpm_tag() has been removed from perl-URPM. please report if you need it back"); ++ ++int ++rpmvercmp(one, two) ++ char *one ++ char *two ++ ++int ++Urpm_ranges_overlap(a, b, b_nopromote=1) ++ char *a ++ char *b ++ int b_nopromote ++ PREINIT: ++ char *sa = a, *sb = b; ++ int aflags = 0, bflags = 0; ++ CODE: ++ while (*sa && *sa != ' ' && *sa != '[' && *sa != '<' && *sa != '>' && *sa != '=' && *sa == *sb) { ++ ++sa; ++ ++sb; ++ } ++ if ((*sa && *sa != ' ' && *sa != '[' && *sa != '<' && *sa != '>' && *sa != '=') || ++ (*sb && *sb != ' ' && *sb != '[' && *sb != '<' && *sb != '>' && *sb != '=')) { ++ /* the strings are sure to be different */ ++ RETVAL = 0; ++ } else { ++ while (*sa) { ++ if (*sa == ' ' || *sa == '[' || *sa == '*' || *sa == ']'); ++ else if (*sa == '<') aflags |= RPMSENSE_LESS; ++ else if (*sa == '>') aflags |= RPMSENSE_GREATER; ++ else if (*sa == '=') aflags |= RPMSENSE_EQUAL; ++ else break; ++ ++sa; ++ } ++ while (*sb) { ++ if (*sb == ' ' || *sb == '[' || *sb == '*' || *sb == ']'); ++ else if (*sb == '<') bflags |= RPMSENSE_LESS; ++ else if (*sb == '>') bflags |= RPMSENSE_GREATER; ++ else if (*sb == '=') bflags |= RPMSENSE_EQUAL; ++ else break; ++ ++sb; ++ } ++ RETVAL = ranges_overlap(aflags, sa, bflags, sb, b_nopromote); ++ } ++ OUTPUT: ++ RETVAL ++ ++void ++Urpm_parse_synthesis__XS(urpm, filename, ...) ++ SV *urpm ++ char *filename ++ PPCODE: ++ if (SvROK(urpm) && SvTYPE(SvRV(urpm)) == SVt_PVHV) { ++ SV **fdepslist = hv_fetch((HV*)SvRV(urpm), "depslist", 8, 0); ++ AV *depslist = fdepslist && SvROK(*fdepslist) && SvTYPE(SvRV(*fdepslist)) == SVt_PVAV ? (AV*)SvRV(*fdepslist) : NULL; ++ SV **fprovides = hv_fetch((HV*)SvRV(urpm), "provides", 8, 0); ++ HV *provides = fprovides && SvROK(*fprovides) && SvTYPE(SvRV(*fprovides)) == SVt_PVHV ? (HV*)SvRV(*fprovides) : NULL; ++ SV **fobsoletes = hv_fetch((HV*)SvRV(urpm), "obsoletes", 9, 0); ++ HV *obsoletes = fobsoletes && SvROK(*fobsoletes) && SvTYPE(SvRV(*fobsoletes)) == SVt_PVHV ? (HV*)SvRV(*fobsoletes) : NULL; ++ ++ if (depslist != NULL) { ++ char buff[65536]; ++ char *p, *eol; ++ int buff_len; ++ struct s_Package pkg; ++ gzFile f; ++ int start_id = 1 + av_len(depslist); ++ SV *callback = NULL; ++ ++ if (items > 2) { ++ int i; ++ for (i = 2; i < items-1; i+=2) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ ++ if (len == 8 && !memcmp(s, "callback", 8)) { ++ if (SvROK(ST(i+1))) callback = ST(i+1); ++ } ++ } ++ } ++ ++ PUTBACK; ++ if ((f = gzopen(filename, "rb")) != NULL) { ++ memset(&pkg, 0, sizeof(struct s_Package)); ++ buff[sizeof(buff)-1] = 0; ++ p = buff; ++ int ok = 1; ++ while ((buff_len = gzread(f, p, sizeof(buff)-1-(p-buff))) >= 0 && ++ (buff_len += p-buff)) { ++ buff[buff_len] = 0; ++ p = buff; ++ if ((eol = strchr(p, '\n')) != NULL) { ++ do { ++ *eol++ = 0; ++ if (!parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) { ok = 0; break; } ++ p = eol; ++ } while ((eol = strchr(p, '\n')) != NULL); ++ } else { ++ /* a line larger than sizeof(buff) has been encountered, bad file problably */ ++ fprintf(stderr, "invalid line <%s>\n", p); ++ ok = 0; ++ break; ++ } ++ if (gzeof(f)) { ++ if (!parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) ok = 0; ++ break; ++ } else { ++ /* move the remaining non-complete-line at beginning */ ++ memmove(buff, p, buff_len-(p-buff)); ++ /* point to the end of the non-complete-line */ ++ p = &buff[buff_len-(p-buff)]; ++ } ++ } ++ if (gzclose(f) != 0) ok = 0; ++ SPAGAIN; ++ if (ok) { ++ XPUSHs(sv_2mortal(newSViv(start_id))); ++ XPUSHs(sv_2mortal(newSViv(av_len(depslist)))); ++ } ++ } else { ++ SV **nofatal = hv_fetch((HV*)SvRV(urpm), "nofatal", 7, 0); ++ if (!errno) errno = EINVAL; /* zlib error */ ++ if (!nofatal || !SvIV(*nofatal)) ++ croak(errno == ENOENT ++ ? "unable to read synthesis file %s" ++ : "unable to uncompress synthesis file %s", filename); ++ } ++ } else croak("first argument should contain a depslist ARRAY reference"); ++ } else croak("first argument should be a reference to a HASH"); ++ ++void ++Urpm_parse_hdlist__XS(urpm, filename, ...) ++ SV *urpm ++ char *filename ++ PPCODE: ++ if (SvROK(urpm) && SvTYPE(SvRV(urpm)) == SVt_PVHV) { ++ SV **fdepslist = hv_fetch((HV*)SvRV(urpm), "depslist", 8, 0); ++ AV *depslist = fdepslist && SvROK(*fdepslist) && SvTYPE(SvRV(*fdepslist)) == SVt_PVAV ? (AV*)SvRV(*fdepslist) : NULL; ++ SV **fprovides = hv_fetch((HV*)SvRV(urpm), "provides", 8, 0); ++ HV *provides = fprovides && SvROK(*fprovides) && SvTYPE(SvRV(*fprovides)) == SVt_PVHV ? (HV*)SvRV(*fprovides) : NULL; ++ SV **fobsoletes = hv_fetch((HV*)SvRV(urpm), "obsoletes", 9, 0); ++ HV *obsoletes = fobsoletes && SvROK(*fobsoletes) && SvTYPE(SvRV(*fobsoletes)) == SVt_PVHV ? (HV*)SvRV(*fobsoletes) : NULL; ++ ++ if (depslist != NULL) { ++ pid_t pid = 0; ++ int d; ++ int empty_archive = 0; ++ FD_t fd; ++ ++ d = open_archive(filename, &pid, &empty_archive); ++ fd = fdDup(d); ++ close(d); ++ ++ if (empty_archive) { ++ XPUSHs(sv_2mortal(newSViv(1 + av_len(depslist)))); ++ XPUSHs(sv_2mortal(newSViv(av_len(depslist)))); ++ } else if (d >= 0 && fd) { ++ Header header; ++ int start_id = 1 + av_len(depslist); ++ int packing = 0; ++ SV *callback = NULL; ++ ++ /* compability mode with older interface of parse_hdlist */ ++ if (items == 3) { ++ packing = SvTRUE(ST(2)); ++ } else if (items > 3) { ++ int i; ++ for (i = 2; i < items-1; i+=2) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ ++ if (len == 7 && !memcmp(s, "packing", 7)) { ++ packing = SvTRUE(ST(i+1)); ++ } else if (len == 8 && !memcmp(s, "callback", 8)) { ++ if (SvROK(ST(i+1))) callback = ST(i+1); ++ } ++ } ++ } ++ ++ PUTBACK; ++ do { ++ header=headerRead(fd, HEADER_MAGIC_YES); ++ if (header != NULL) { ++ struct s_Package pkg, *_pkg; ++ SV *sv_pkg; ++ ++ memset(&pkg, 0, sizeof(struct s_Package)); ++ pkg.flag = 1 + av_len(depslist); ++ pkg.h = header; ++ sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package", ++ _pkg = memcpy(malloc(sizeof(struct s_Package)), &pkg, sizeof(struct s_Package))); ++ if (call_package_callback(urpm, sv_pkg, callback)) { ++ if (provides) { ++ update_provides(_pkg, provides); ++ update_provides_files(_pkg, provides); ++ } ++ if (obsoletes) update_obsoletes(_pkg, obsoletes); ++ if (packing) pack_header(_pkg); ++ av_push(depslist, sv_pkg); ++ } ++ } ++ } while (header != NULL); ++ ++ int ok = Fclose(fd) == 0; ++ ++ if (pid) { ++ kill(pid, SIGTERM); ++ int status; ++ int rc = waitpid(pid, &status, 0); ++ ok = rc != -1 && WEXITSTATUS(status) != 1; /* in our standard case, gzip will exit with status code 2, meaning "decompression OK, trailing garbage ignored" */ ++ pid = 0; ++ } else if (!empty_archive) { ++ ok = av_len(depslist) >= start_id; ++ } ++ SPAGAIN; ++ if (ok) { ++ XPUSHs(sv_2mortal(newSViv(start_id))); ++ XPUSHs(sv_2mortal(newSViv(av_len(depslist)))); ++ } ++ } else { ++ SV **nofatal = hv_fetch((HV*)SvRV(urpm), "nofatal", 7, 0); ++ if (!nofatal || !SvIV(*nofatal)) ++ croak("cannot open hdlist file %s", filename); ++ } ++ } else croak("first argument should contain a depslist ARRAY reference"); ++ } else croak("first argument should be a reference to a HASH"); ++ ++void ++Urpm_parse_rpm(urpm, filename, ...) ++ SV *urpm ++ char *filename ++ PPCODE: ++ if (SvROK(urpm) && SvTYPE(SvRV(urpm)) == SVt_PVHV) { ++ SV **fdepslist = hv_fetch((HV*)SvRV(urpm), "depslist", 8, 0); ++ AV *depslist = fdepslist && SvROK(*fdepslist) && SvTYPE(SvRV(*fdepslist)) == SVt_PVAV ? (AV*)SvRV(*fdepslist) : NULL; ++ SV **fprovides = hv_fetch((HV*)SvRV(urpm), "provides", 8, 0); ++ HV *provides = fprovides && SvROK(*fprovides) && SvTYPE(SvRV(*fprovides)) == SVt_PVHV ? (HV*)SvRV(*fprovides) : NULL; ++ SV **fobsoletes = hv_fetch((HV*)SvRV(urpm), "obsoletes", 8, 0); ++ HV *obsoletes = fobsoletes && SvROK(*fobsoletes) && SvTYPE(SvRV(*fobsoletes)) == SVt_PVHV ? (HV*)SvRV(*fobsoletes) : NULL; ++ ++ if (depslist != NULL) { ++ struct s_Package pkg, *_pkg; ++ SV *sv_pkg; ++ int packing = 0; ++ int keep_all_tags = 0; ++ SV *callback = NULL; ++ rpmVSFlags vsflags = RPMVSF_DEFAULT; ++ ++ /* compability mode with older interface of parse_hdlist */ ++ if (items == 3) { ++ packing = SvTRUE(ST(2)); ++ } else if (items > 3) { ++ int i; ++ for (i = 2; i < items-1; i+=2) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ ++ if (len == 7 && !memcmp(s, "packing", 7)) { ++ packing = SvTRUE(ST(i + 1)); ++ } else if (len == 13 && !memcmp(s, "keep_all_tags", 13)) { ++ keep_all_tags = SvTRUE(ST(i+1)); ++ } else if (len == 8 && !memcmp(s, "callback", 8)) { ++ if (SvROK(ST(i+1))) callback = ST(i+1); ++ } else if (len == 5) { ++ if (!memcmp(s, "nopgp", 5)) { ++ if (SvIV(ST(i+1))) vsflags |= (RPMVSF_NOSHA1 | RPMVSF_NOSHA1HEADER); ++ } ++ else if (!memcmp(s, "nogpg", 5)) { ++ if (SvIV(ST(i+1))) vsflags |= (RPMVSF_NOSHA1 | RPMVSF_NOSHA1HEADER); ++ } ++ else if (!memcmp(s, "nomd5", 5)) { ++ if (SvIV(ST(i+1))) vsflags |= (RPMVSF_NOMD5 | RPMVSF_NOMD5HEADER); ++ } ++ else if (!memcmp(s, "norsa", 5)) { ++ if (SvIV(ST(i+1))) vsflags |= (RPMVSF_NORSA | RPMVSF_NORSAHEADER); ++ } ++ else if (!memcmp(s, "nodsa", 5)) { ++ if (SvIV(ST(i+1))) vsflags |= (RPMVSF_NODSA | RPMVSF_NODSAHEADER); ++ } ++ } else if (len == 9) { ++ if (!memcmp(s, "nodigests", 9)) { ++ if (SvIV(ST(i+1))) vsflags |= _RPMVSF_NODIGESTS; ++ } else ++ if (!memcmp(s, "nopayload", 9)) { ++ if (SvIV(ST(i+1))) vsflags |= _RPMVSF_NOPAYLOAD; ++ } ++ } ++ } ++ } ++ PUTBACK; ++ memset(&pkg, 0, sizeof(struct s_Package)); ++ pkg.flag = 1 + av_len(depslist); ++ _pkg = memcpy(malloc(sizeof(struct s_Package)), &pkg, sizeof(struct s_Package)); ++ ++ if (update_header(filename, _pkg, keep_all_tags, vsflags)) { ++ sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package", _pkg); ++ if (call_package_callback(urpm, sv_pkg, callback)) { ++ if (provides) { ++ update_provides(_pkg, provides); ++ update_provides_files(_pkg, provides); ++ } ++ if (obsoletes) update_obsoletes(_pkg, obsoletes); ++ if (packing) pack_header(_pkg); ++ av_push(depslist, sv_pkg); ++ } ++ SPAGAIN; ++ /* only one element read */ ++ XPUSHs(sv_2mortal(newSViv(av_len(depslist)))); ++ XPUSHs(sv_2mortal(newSViv(av_len(depslist)))); ++ } else free(_pkg); ++ } else croak("first argument should contain a depslist ARRAY reference"); ++ } else croak("first argument should be a reference to a HASH"); ++ ++int ++Urpm_verify_rpm(filename, ...) ++ char *filename ++ PREINIT: ++ FD_t fd; ++ int i, oldlogmask; ++ rpmts ts = NULL; ++ struct rpmQVKArguments_s qva; ++ CODE: ++ /* Don't display error messages */ ++ oldlogmask = rpmlogSetMask(RPMLOG_UPTO(RPMLOG_PRI(4))); ++ memset(&qva, 0, sizeof(struct rpmQVKArguments_s)); ++ qva.qva_source = RPMQV_RPM; ++ qva.qva_flags = VERIFY_ALL; ++ for (i = 1 ; i < items - 1 ; i += 2) { ++ STRLEN len; ++ char *s = SvPV(ST(i), len); ++ if (len == 9 && !strncmp(s, "nodigests", 9)) { ++ if (SvIV(ST(i+1))) qva.qva_flags &= ~VERIFY_DIGEST; ++ } else if (len == 12 && !strncmp(s, "nosignatures", 12)) { ++ if (SvIV(ST(i+1))) qva.qva_flags &= ~VERIFY_SIGNATURE; ++ } ++ } ++ fd = Fopen(filename, "r"); ++ if (fd == NULL) { ++ RETVAL = 0; ++ } else { ++ read_config_files(0); ++ ts = rpmtsCreate(); ++ rpmtsSetRootDir(ts, "/"); ++ rpmtsOpenDB(ts, O_RDONLY); ++ if (rpmVerifySignatures(&qva, ts, fd, filename)) { ++ RETVAL = 0; ++ } else { ++ RETVAL = 1; ++ } ++ Fclose(fd); ++ (void)rpmtsFree(ts); ++ } ++ rpmlogSetMask(oldlogmask); ++ ++ OUTPUT: ++ RETVAL ++ ++ ++char * ++Urpm_get_gpg_fingerprint(filename) ++ char * filename ++ PREINIT: ++ uint8_t fingerprint[sizeof(pgpKeyID_t)]; ++ char fingerprint_str[sizeof(pgpKeyID_t) * 2 + 1]; ++ const uint8_t *pkt = NULL; ++ size_t pktlen = 0; ++ int rc; ++ ++ CODE: ++ memset (fingerprint, 0, sizeof (fingerprint)); ++ if ((rc = pgpReadPkts(filename, (uint8_t ** ) &pkt, &pktlen)) <= 0) { ++ pktlen = 0; ++ } else if (rc != PGPARMOR_PUBKEY) { ++ pktlen = 0; ++ } else { ++ unsigned int i; ++ pgpPubkeyFingerprint (pkt, pktlen, fingerprint); ++ for (i = 0; i < sizeof (pgpKeyID_t); i++) { ++ sprintf(&fingerprint_str[i*2], "%02x", fingerprint[i]); ++ } ++ } ++ _free(pkt); ++ RETVAL = fingerprint_str; ++ OUTPUT: ++ RETVAL ++ ++ ++char * ++Urpm_verify_signature(filename, prefix="/") ++ char *filename ++ char *prefix ++ PREINIT: ++ rpmts ts = NULL; ++ char result[1024]; ++ rpmRC rc; ++ FD_t fd; ++ Header h; ++ CODE: ++ fd = Fopen(filename, "r"); ++ if (fd == NULL) { ++ RETVAL = "NOT OK (could not read file)"; ++ } else { ++ read_config_files(0); ++ ts = rpmtsCreate(); ++ rpmtsSetRootDir(ts, prefix); ++ rpmtsOpenDB(ts, O_RDONLY); ++ rpmtsSetVSFlags(ts, RPMVSF_DEFAULT); ++ rc = rpmReadPackageFile(ts, fd, filename, &h); ++ Fclose(fd); ++ *result = '\0'; ++ switch(rc) { ++ case RPMRC_OK: ++ if (h) { ++ char *fmtsig = headerFormat( ++ h, ++ "%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:" ++ "{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|", ++ NULL); ++ snprintf(result, sizeof(result), "OK (%s)", fmtsig); ++ free(fmtsig); ++ } else snprintf(result, sizeof(result), "NOT OK (bad rpm): %s", rpmlogMessage()); ++ break; ++ case RPMRC_NOTFOUND: ++ snprintf(result, sizeof(result), "NOT OK (signature not found): %s", rpmlogMessage()); ++ break; ++ case RPMRC_FAIL: ++ snprintf(result, sizeof(result), "NOT OK (fail): %s", rpmlogMessage()); ++ break; ++ case RPMRC_NOTTRUSTED: ++ snprintf(result, sizeof(result), "NOT OK (key not trusted): %s", rpmlogMessage()); ++ break; ++ case RPMRC_NOKEY: ++ snprintf(result, sizeof(result), "NOT OK (no key): %s", rpmlogMessage()); ++ break; ++ } ++ RETVAL = result; ++ if (h) h = headerFree(h); ++ (void)rpmtsFree(ts); ++ } ++ ++ OUTPUT: ++ RETVAL ++ ++ ++int ++Urpm_import_pubkey_file(db, filename) ++ URPM::DB db ++ char * filename ++ PREINIT: ++ const uint8_t *pkt = NULL; ++ size_t pktlen = 0; ++ int rc; ++ CODE: ++ ++ rpmts ts = rpmtsLink(db->ts, "URPM::import_pubkey_file"); ++ rpmtsClean(ts); ++ ++ if ((rc = pgpReadPkts(filename, (uint8_t ** ) &pkt, &pktlen)) <= 0) { ++ RETVAL = 0; ++ } else if (rc != PGPARMOR_PUBKEY) { ++ RETVAL = 0; ++ } else if (rpmtsImportPubkey(ts, pkt, pktlen) != RPMRC_OK) { ++ RETVAL = 0; ++ } else { ++ RETVAL = 1; ++ } ++ pkt = _free(pkt); ++ (void)rpmtsFree(ts); ++ OUTPUT: ++ RETVAL ++ ++int ++Urpm_import_pubkey(...) ++ CODE: ++ unused_variable(&items); ++ croak("import_pubkey() is dead. use import_pubkey_file() instead"); ++ RETVAL = 1; ++ OUTPUT: ++ RETVAL ++ ++int ++Urpm_archscore(arch) ++ const char * arch ++ PREINIT: ++#ifndef RPM_ORG ++ char * platform = NULL; ++#endif ++ CODE: ++ read_config_files(0); ++#ifndef RPM_ORG ++ platform = rpmExpand(arch, "-%{_target_vendor}-%{_target_os}%{?_gnu}", NULL); ++ RETVAL=rpmPlatformScore(platform, NULL, 0); ++ _free(platform); ++#else ++ RETVAL=rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch); ++#endif ++ OUTPUT: ++ RETVAL ++ ++int ++Urpm_osscore(os) ++ const char * os ++ PREINIT: ++#ifndef RPM_ORG ++ char * platform = NULL; ++#endif ++ CODE: ++ read_config_files(0); ++#ifndef RPM_ORG ++ platform = rpmExpand("%{_target_cpu}-%{_target_vendor}-", os, "%{?_gnu}", NULL); ++ RETVAL=rpmPlatformScore(platform, NULL, 0); ++ _free(platform); ++#else ++ RETVAL=rpmMachineScore(RPM_MACHTABLE_INSTOS, os); ++#endif ++ OUTPUT: ++ RETVAL ++ ++int ++Urpm_platformscore(platform) ++ const char * platform ++ CODE: ++ read_config_files(0); ++#ifndef RPM_ORG ++ RETVAL=rpmPlatformScore(platform, NULL, 0); ++#else ++ unused_variable(platform); ++ croak("platformscore() is available only since rpm 4.4.8"); ++ RETVAL=0; ++#endif ++ OUTPUT: ++ RETVAL ++ ++void ++Urpm_stream2header(fp) ++ FILE *fp ++ PREINIT: ++ FD_t fd; ++ URPM__Package pkg; ++ PPCODE: ++ if ((fd = fdDup(fileno(fp)))) { ++ pkg = (URPM__Package)malloc(sizeof(struct s_Package)); ++ memset(pkg, 0, sizeof(struct s_Package)); ++ pkg->h = headerRead(fd, HEADER_MAGIC_YES); ++ if (pkg->h) { ++ SV *sv_pkg; ++ EXTEND(SP, 1); ++ sv_pkg = sv_newmortal(); ++ sv_setref_pv(sv_pkg, "URPM::Package", (void*)pkg); ++ PUSHs(sv_pkg); ++ } ++ Fclose(fd); ++ } ++ ++void ++Urpm_spec2srcheader(specfile) ++ char *specfile ++ PREINIT: ++ rpmts ts = rpmtsCreate(); ++ URPM__Package pkg; ++ Spec spec = NULL; ++ PPCODE: ++/* ensure the config is in memory with all macro */ ++ read_config_files(0); ++/* Do not verify architecture */ ++#define SPEC_ANYARCH 1 ++/* Do not verify whether sources exist */ ++#define SPEC_FORCE 1 ++ if (!parseSpec(ts, specfile, "/", NULL, 0, NULL, NULL, SPEC_ANYARCH, SPEC_FORCE)) { ++ SV *sv_pkg; ++ spec = rpmtsSetSpec(ts, NULL); ++#ifdef RPM_ORG ++ if (! spec->sourceHeader) ++#endif ++ initSourceHeader(spec); ++ pkg = (URPM__Package)malloc(sizeof(struct s_Package)); ++ memset(pkg, 0, sizeof(struct s_Package)); ++ headerPutString(spec->sourceHeader, RPMTAG_SOURCERPM, ""); ++ ++ { ++ struct rpmtd_s td = { ++ .tag = RPMTAG_ARCH, ++ .type = RPM_STRING_TYPE, ++ .data = (void *) "src", ++ .count = 1, ++ }; ++ /* parseSpec() sets RPMTAG_ARCH to %{_target_cpu} whereas we really a header similar to .src.rpm header */ ++ headerMod(spec->sourceHeader, &td); ++ } ++ ++ pkg->h = headerLink(spec->sourceHeader); ++ sv_pkg = sv_newmortal(); ++ sv_setref_pv(sv_pkg, "URPM::Package", (void*)pkg); ++ XPUSHs(sv_pkg); ++ spec = freeSpec(spec); ++ } else { ++ XPUSHs(&PL_sv_undef); ++ /* apparently rpmlib sets errno this when given a bad spec. */ ++ if (errno == EBADF) ++ errno = 0; ++ } ++ ts = rpmtsFree(ts); ++ ++void ++expand(name) ++ char * name ++ PPCODE: ++ const char * value = rpmExpand(name, NULL); ++ XPUSHs(sv_2mortal(newSVpv(value, 0))); ++ ++void ++add_macro_noexpand(macro) ++ char * macro ++ CODE: ++ rpmDefineMacro(NULL, macro, RMIL_DEFAULT); ++ ++void ++del_macro(name) ++ char * name ++ CODE: ++ delMacro(NULL, name); ++ ++void ++loadmacrosfile(filename) ++ char * filename ++ PPCODE: ++ rpmInitMacros(NULL, filename); ++ ++void ++resetmacros() ++ PPCODE: ++ rpmFreeMacros(NULL); ++ ++void ++setVerbosity(level) ++ int level ++ PPCODE: ++ rpmSetVerbosity(level); ++ ++const char * ++rpmErrorString() ++ CODE: ++ RETVAL = rpmlogMessage(); ++ OUTPUT: ++ RETVAL ++ ++void ++rpmErrorWriteTo(fd) ++ int fd ++ CODE: ++ rpmError_callback_data = fd; ++ rpmlogSetCallback(rpmError_callback, NULL); ++ ++ /* vim:set ts=8 sts=2 sw=2: */ + +Added: rpm/perl-URPM/trunk/t/00prepare.t +=================================================================== +--- rpm/perl-URPM/trunk/t/00prepare.t (rev 0) ++++ rpm/perl-URPM/trunk/t/00prepare.t 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,16 @@ ++#!/usr/bin/perl ++ ++use strict; ++use warnings; ++use Test::More tests => 1; ++use Cwd; ++ ++chdir 't' if -d 't'; ++mkdir "tmp"; ++for (qw(BUILD SOURCES RPMS RPMS/noarch)) { ++ mkdir "tmp/".$_; ++} ++# locally build a test rpm ++system(rpmbuild => '--define', '_topdir '. Cwd::cwd() . "/tmp/", '-bb', 'test-rpm.spec'); ++ok( -f 'tmp/RPMS/noarch/test-rpm-1.0-1mdk.noarch.rpm', 'rpm created' ); ++ + +Added: rpm/perl-URPM/trunk/t/buggy_synthesis.cz +=================================================================== +(Binary files differ) + + +Property changes on: rpm/perl-URPM/trunk/t/buggy_synthesis.cz +___________________________________________________________________ +Added: svn:mime-type + + application/octet-stream + +Added: rpm/perl-URPM/trunk/t/empty_synthesis.cz +=================================================================== +(Binary files differ) + + +Property changes on: rpm/perl-URPM/trunk/t/empty_synthesis.cz +___________________________________________________________________ +Added: svn:mime-type + + application/octet-stream + +Added: rpm/perl-URPM/trunk/t/fatal.t +=================================================================== +--- rpm/perl-URPM/trunk/t/fatal.t (rev 0) ++++ rpm/perl-URPM/trunk/t/fatal.t 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,23 @@ ++#!/usr/bin/perl ++ ++use strict; ++use Test::More tests => 8; ++use URPM; ++ ++my $u = new URPM; ++ ++eval { $u->parse_hdlist('non-existent'); }; ++like( $@, qr/^cannot open hdlist file non-existent/, 'fatal error on hdlist not found' ); ++is( $! + 0, $!{EBADF}, '$! is EBADF' ); ++eval { $u->parse_synthesis('non-existent'); }; ++like( $@, qr/^unable to read synthesis file non-existent/, 'fatal error on synthesis not found' ); ++is( $! + 0, $!{ENOENT}, '$! is ENOENT' ); ++ ++my $v = new URPM( nofatal => 1 ); ++ ++eval { $v->parse_hdlist('non-existent'); }; ++is( $@, '', 'no error on hdlist not found' ); ++is( $! + 0, $!{EBADF}, '$! is EBADF' ); ++eval { $v->parse_synthesis('non-existent'); }; ++is( $@, '', 'no error on synthesis not found' ); ++is( $! + 0, $!{ENOENT}, '$! is ENOENT' ); + +Added: rpm/perl-URPM/trunk/t/parse.t +=================================================================== +--- rpm/perl-URPM/trunk/t/parse.t (rev 0) ++++ rpm/perl-URPM/trunk/t/parse.t 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,119 @@ ++#!/usr/bin/perl ++ ++# $Id: parse.t 258553 2009-07-22 18:21:30Z peroyvind $ ++ ++use strict; ++use warnings; ++use Test::More tests => 39; ++use MDV::Packdrakeng; ++use URPM; ++use URPM::Build; ++use URPM::Query; ++ ++chdir 't' if -d 't'; ++ ++# shut up ++URPM::setVerbosity(2); ++ ++my $a = new URPM; ++ok($a); ++ ++END { system('rm -rf hdlist.cz empty_hdlist.cz headers tmp') } ++ ++my ($start, $end) = $a->parse_rpms_build_headers(rpms => [ "tmp/RPMS/noarch/test-rpm-1.0-1mdk.noarch.rpm" ], keep_all_tags => 1); ++ok(@{$a->{depslist}} == 1); ++my $pkg = $a->{depslist}[0]; ++ok($pkg); ++is($pkg->get_tag(1000), 'test-rpm', 'name'); ++is($pkg->get_tag(1001), '1.0', 'version'); ++is($pkg->get_tag(1002), '1mdk', 'release'); ++ ++mkdir 'headers'; ++system('touch headers/empty'); ++is(URPM->new->parse_hdlist('headers/empty'), undef, 'empty header'); ++system('echo FOO > headers/bad'); ++is(URPM->new->parse_hdlist('headers/bad'), undef, 'bad rpm header'); ++ ++$a->build_hdlist( ++ start => 0, ++ end => -1, ++ hdlist => 'empty_hdlist.cz', ++); ++ok(-f 'empty_hdlist.cz'); ++ ++($start, $end) = URPM->new->parse_hdlist('empty_hdlist.cz'); ++is("$start $end", "0 -1", 'empty hdlist'); ++ ++ ++$a->build_hdlist( ++ start => 0, ++ end => $#{$a->{depslist}}, ++ hdlist => 'hdlist.cz', ++ ratio => 9, ++); ++ ++ok(-f 'hdlist.cz'); ++ ++my $b = new URPM; ++($start, $end) = $b->parse_hdlist('hdlist.cz', keep_all_tags => 1); ++is("$start $end", "0 0", 'parse_hdlist'); ++ok(@{$b->{depslist}} == 1); ++$pkg = $b->{depslist}[0]; ++ok($pkg); ++is($pkg->get_tag(1000), 'test-rpm', 'name'); ++is($pkg->get_tag(1001), '1.0', 'version'); ++is($pkg->get_tag(1002), '1mdk', 'release'); ++is($pkg->queryformat("%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}"), "test-rpm-1.0-1mdk.noarch", ++ q/get headers from hdlist/); ++rpm_is_jbj_version() ? ++ ok($pkg->is_platform_compat() > 0, "can evaluate platform score") : ++ pass('no platform compat'); ++ ++my $headers = eval { [ $b->parse_rpms_build_headers(rpms => [ "tmp/RPMS/noarch/test-rpm-1.0-1mdk.noarch.rpm" ], ++ dir => 'headers') ] }; ++is($@, '', 'parse_rpms_build_headers'); ++is(int @$headers, 1, 'parse_rpms_build_headers'); ++ok(@{$b->{depslist}} == 2); ++($start, $end) = eval { $b->parse_headers(dir => "headers", headers => $headers) }; ++is($@, '', 'parse_headers'); ++is("$start $end", "2 2", 'parse_headers'); ++ ++ ++ ++# Version comparison ++ok(URPM::rpmvercmp("1-1mdk", "1-1mdk") == 0, "Same value = 0"); ++ok(URPM::rpmvercmp("0:1-1mdk", "1-1mdk") == -1, "Same value, epoch 0 on left = 1"); ++ok(URPM::rpmvercmp("1-1mdk", "1-2mdk") == -1, "Right value win = -1"); ++ok(URPM::rpmvercmp("1-2mdk", "1-1mdk") == 1, "Left value win = 1"); ++ok(URPM::rpmvercmp("1:1-1mdk", "2:1-1mdk") == -1, "epoch 1 vs 2 = -1"); ++ ++{ ++ open(my $hdfh, "zcat hdlist.cz 2>/dev/null |") or die $!; ++ my $pkg = URPM::stream2header($hdfh); ++ ok(defined $pkg, "Reading a header works"); ++ is($pkg->get_tag(1000), 'test-rpm'); ++ is($pkg->get_tag(1001), '1.0'); ++ is($pkg->get_tag(1002), '1mdk'); ++ is($pkg->queryformat("%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}"), "test-rpm-1.0-1mdk.noarch"); ++ ok($pkg->is_arch_compat(), "Arch compat works"); ++ close $hdfh; ++} ++ ++{ ++ my $pkg = URPM::spec2srcheader("test-rpm.spec"); ++ ok(defined $pkg, "Parsing a spec works"); ++ is($pkg->get_tag(1000), 'test-rpm', 'parsed correctly'); ++ $pkg = URPM::spec2srcheader("doesnotexist.spec"); ++ ok(!defined $pkg, "non-existent spec"); ++ open my $f, '>', 'bad.spec' or die "Can't write bad.spec: $!\n"; ++ print $f "Name: foo\nVerssion: 2\n"; ++ close $f; ++ $pkg = URPM::spec2srcheader("bad.spec"); ++ ok(!defined $pkg, "bad spec"); ++ END { unlink "bad.spec" } ++} ++ ++sub rpm_is_jbj_version { ++ # checking for --yaml support ++ `rpm --help` =~ /yaml/; ++} + +Added: rpm/perl-URPM/trunk/t/pod.t +=================================================================== +--- rpm/perl-URPM/trunk/t/pod.t (rev 0) ++++ rpm/perl-URPM/trunk/t/pod.t 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,5 @@ ++#!perl ++use Test::More; ++eval "use Test::Pod 1.14"; ++plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; ++all_pod_files_ok(); + +Added: rpm/perl-URPM/trunk/t/rpmdb.t +=================================================================== +--- rpm/perl-URPM/trunk/t/rpmdb.t (rev 0) ++++ rpm/perl-URPM/trunk/t/rpmdb.t 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,46 @@ ++#!/usr/bin/perl ++ ++use strict ; ++use warnings ; ++use Test::More tests => 7; ++use URPM; ++ ++my ($count, @all_pkgs_extern, @all_pkgs); ++my ($pkg_perl, $count_perl, $pkg_perl_extern); ++{ ++ my $db; ++ ok($db = URPM::DB::open, 'DB opened'); ++ ++ @all_pkgs_extern = sort { $a cmp $b } split /\n/ => qx(rpm -qa --nosignature --qf '%{name}-%{version}-%{release}\n'); ++ ok(@all_pkgs_extern > 0, 'There are RPMs'); ++ ++ $count = $db->traverse(sub { ++ my ($pkg) = @_; ++ my ($name, $version, $release, $arch) = $pkg->fullname; ++ #- arch is void for -pubkey- package. ++ my $fullname = "$name-$version-$release"; ++ push @all_pkgs, $fullname; ++ if ($name eq 'perl') { $pkg_perl_extern = $fullname } ++ }); ++ ++ $count_perl = $db->traverse_tag('name', ['perl'], sub { ++ my ($pkg) = @_; ++ my ($name, $version, $release) = $pkg->fullname; ++ $pkg_perl = "$name-$version-$release"; ++ }); ++} ++is($count, @all_pkgs_extern, ++ 'traversed same num of packages than given by rpm -qa'); ++is($count, @all_pkgs, ++ 'traversed each package once'); ++is($count_perl, 1, q(there's exactly 1 "perl" package)); ++is($pkg_perl, $pkg_perl_extern, '... with the correct fullname'); ++ ++my @all_pkgs_sorted = sort { $a cmp $b } @all_pkgs; ++my $bad_pkgs = 0; ++foreach (0..$#all_pkgs_sorted) { ++ $all_pkgs_sorted[$_] eq $all_pkgs_extern[$_] and next; ++ diag($all_pkgs_extern[$_] . " vs " . $all_pkgs_sorted[$_]); ++ ++$bad_pkgs; ++} ++is($bad_pkgs, 0, 'no mismatch between package lists'); + +Added: rpm/perl-URPM/trunk/t/sort_graph.t +=================================================================== +--- rpm/perl-URPM/trunk/t/sort_graph.t (rev 0) ++++ rpm/perl-URPM/trunk/t/sort_graph.t 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,76 @@ ++#!/usr/bin/perl ++ ++use strict; ++use Test::More 'no_plan'; ++use URPM; ++ ++ ++my ($list_unsorted, $requires); ++ ++$list_unsorted = [ 0, 1, 2 ]; ++$requires = { 2 => [ 1 ], 1 => [ 0 ], 0 => [ 1, 2 ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 0, 1, 2, 3, 4 ]; ++$requires = { '0' => [], '1' => [ 2, 3 ], '2' => [ 4 ], '3' => [ 4 ], '4' => [ 1, 0 ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 0, 3, 4, 5, 6, 10 ]; ++$requires = { '0' => [ 4 ], '3' => [ 5 ], '4' => [ 6, 5 ], '5' => [ 10 ], '6' => [ 10, 3 ], '10' => [ 6 ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 0, 1, 2, 3, 4 ]; ++$requires = { '0' => [ 0 ], '1' => [ 4 ], '2' => [], '3' => [ 3 ], '4' => [ 0, 2 ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 0, 1, 2, 3, 4 ]; ++$requires = { '0' => [], '1' => [ 3, 1 ], '2' => [ 2 ], '3' => [ 3 ], '4' => [ 1, 2 ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 0, 1, 2, 3, 4 ]; ++$requires = { '0' => [ 3, 4 ], '1' => [ 0, 3 ], '2' => [], '3' => [ 4 ], '4' => [ 0, 3 ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 92, 94, 133, 137, 5826, 5828, 5830, 5831, 5836, 5839, 5842, 5844, 5845, 5848, 5849, 5851, 5856, 5859, 5864, 5873, 5882, 5883, 5890, 5892, 5894, 5895, 5897, 5900, 5913, 5915, 5916, 5917, 5924, 5925, 5926, 5928, 5929, 5932, 5936, 5937, 5938, 5943, 5948, 5953, 5955, 5956, 5959, 5960, 5961, 5962, 5964, 5968, 5969, 5970, 5974, 6008, 6009, 6010, 6012, 6110, 6115, 6119, 6120, 6127, 6129, 6132, 6135, 6164, 6165, 6166, 16841, 16842, 16844, 16845, 16890, 17009, 17011, 17013, 17156, 17157, 17169 ]; ++$requires = { '17011' => [], '5883' => [], '5956' => [ 5955, 5839, 5959, 5964 ], '5897' => [], '5953' => [ 5936, 5943 ], '5894' => [ 5839 ], '17013' => [ 6135 ], '5936' => [ 5943 ], '5826' => [], '6135' => [ 5839 ], '16845' => [ 5839 ], '5974' => [ 5974, 5839, 5964 ], '5851' => [ 5856, 5849 ], '6115' => [], '92' => [ 5839, 5925, 94 ], '6010' => [ 6008, 6009, 6010 ], '5882' => [], '5970' => [ 5955, 5839, 5969 ], '16841' => [], '5926' => [ 5953, 5936, 5926, 6009, 5943, 5928 ], '17156' => [ 17157, 17156 ], '5848' => [ 5856 ], '6008' => [ 6009, 5839, 6008, 6010 ], '5842' => [ 5839, 5844 ], '16844' => [ 16845, 16841, 16842, 5839 ], '16842' => [], '5955' => [ 5970 ], '6119' => [ 6119 ], '133' => [ 5839 ], '6009' => [ 6008, 6009, 6010 ], '5831' => [], '5839' => [ 5839 ], '6165' => [ 5839 ], '5830' => [], '5960' => [ 5839, 5962 ], '5932' => [ 5953, 5936, 6009, 5932, 5938, 5943, 5928 ], '5924' => [ 5839 ], '5828' => [], '5959' => [ 5969 ], '5890' => [ 5897 ], '17169' => [ 17157 ], '5 + 937' => [ 5936, 5943 ], '137' => [ 133, 5839, 5925 ], '5895' => [], '5892' => [], '6110' => [ 5839 ], '6127' => [], '5900' => [], '5948' => [ 5953, 5936, 6009, 5932, 5937, 5948, 5929, 5938, 5943, 5928 ], '6120' => [], '5929' => [ 5936, 5943 ], '5961' => [ 5839 ], '5964' => [ 5956, 5970, 5839 ], '6164' => [ 6119, 6120, 6164 ], '5925' => [ 5924 ], '5844' => [ 5842, 5844 ], '5864' => [], '17157' => [ 5839, 17156, 17157 ], '5969' => [], '5962' => [ 6009, 5839, 5962 ], '5913' => [ 6115, 5839, 5917 ], '5968' => [ 5970, 5839, 5959 ], '5915' => [], '6166' => [ 5839, 6165 ], '6132' => [ 5839, 6129 ], '6129' => [ 5839, 6127, 6132 ], '5938' => [ 5936, 5943 ], '5836' => [], '5943' => [ 5953, 5936, 6009, 5937, 5948, 5929, 5928 ], '5856' => [ 5897 ], '5873' => [], '5917' => [ 5839, 5856, 5917, 5849 ], '17009' => [], '94' => [ 5839 ], '5859' => [ 5856 ], '16890' => [], '5845' => [ 5851, 5848, 5856, 5849 ], '5928' => [ 5953, 5936, 5926, 6009, 5943, 5928 ], '5916' => [ 5915 ], '5849' => [ 58 + 56 ], '6012' => [ 6012 ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 53, 56, 118, 189, 223, 284, 286, 304, 396, 397, 403, 442, 480, 544, 556, 596, 607, 692, 729, 758, 764, 772, 778, 798, 829, 838, 840, 865, 917, 1019, 1112, 1149, 1191, 1192, 1232, 1275, 1292, 1316, 1319, 1364, 1411, 1415, 1422, 1487, 1508, 1583, 1719, 1769, 1787, 1827, 1855, 1884, 1894, 2001, 2136, 2139, 2243, 2244, 2355, 2387, 2516, 2597, 2603, 2669, 2694, 2727, 2746, 2818, 2820, 2826, 2845, 2861, 2869, 2932, 2992, 3002, 3016, 3037, 3069, 3079, 3151, 3173, 3272, 3273, 3275, 3280, 3289, 3293, 3314, 3327, 3568, 3569, 3602, 3659, 3662, 3665, 3667, 3669, 3672, 3675, 3682, 3934, 3935, 3936, 3971, 3973, 3980, 4053, 4060, 4150, 4161, 4350, 4400, 4402, 4426, 4428, 4430, 4438, 4439, 4444, 4446, 4635, 4636, 4637, 4638, 4639, 4640, 4656, 4657, 4673, 4681, 4685, 4686, 4687, 4691, 4715, 4793, 5060, 5070, 5079, 5198, 5199, 5250, 5327, 5329, 5330, 5331, 5333, 5334, 5342, 5401, 5404, 5407, 5409, 5423, 5442, 5486, 5487, 5494, 5499, 5501, 5616, 5618, 5664, 5685, 5688, 5775, + 5777, 5778, 6166, 6178, 6305, 8295, 9859, 10199, 10649, 10651, 10659, 11879, 22012 ]; ++$requires = { '5423' => [ 5442 ], '118' => [ 5060 ], '3934' => [ 764 ], '5250' => [], '2818' => [], '2746' => [ 1019, 764 ], '2992' => [ 5327, 1884, 4636, 917, 2603, 56, 5334 ], '3002' => [ 3069 ], '5327' => [ 3934, 2746, 5327, 1884, 4636, 1019, 397, 764, 758, 829, 2603, 4681, 5331, 1232, 5777, 5334, 1719 ], '798' => [ 3273, 2861 ], '3037' => [ 3037, 2820, 838 ], '5688' => [ 5327, 1884, 4636, 2603, 5334 ], '1884' => [ 3934, 764, 4402, 5777, 2861 ], '2516' => [ 917, 596, 2826, 56, 607, 1112, 4444 ], '2001' => [ 4060, 442, 284, 5333, 1894, 396, 5329, 4640 ], '5664' => [], '1364' => [ 5250, 1364, 4060, 917, 5401, 2243, 5407, 1411 ], '5494' => [ 480, 5501 ], '4715' => [ 3151 ], '5499' => [ 764, 865, 2387, 1232, 3973 ], '3273' => [], '4636' => [ 3934, 1884, 4636, 764, 5198, 4638, 4639, 5777, 2861, 5775 ], '1019' => [ 764 ], '4060' => [ 4060, 4053 ], '4439' => [ 1364, 4060, 3682, 2932, 729, 3665, 403, 2845, 3672, 3327, 3569, 4444 ], '397' => [ 764, 1232 ], '764' => [ 5501, 5486 ], + '865' => [ 764, 2387, 3973 ], '5342' => [ 4715, 11879, 4635, 4673, 53 ], '5060' => [], '3936' => [], '3314' => [], '8295' => [], '3682' => [ 3665, 3662, 3569 ], '5198' => [ 3934, 764, 5777, 2861 ], '10649' => [ 5331, 6166 ], '4685' => [ 4687, 4686 ], '3272' => [], '11879' => [], '442' => [ 798, 1884, 3273, 442, 5778, 3935, 396, 4400 ], '4638' => [], '5778' => [ 798, 3273, 5777, 3327, 5775 ], '2932' => [ 2932 ], '1855' => [ 607, 1112 ], '2387' => [ 3973 ], '1191' => [ 5494, 1019, 5487, 480, 396 ], '3016' => [ 2746, 1191, 480, 396 ], '5404' => [ 5409 ], '284' => [ 4060, 2603 ], '5442' => [], '2136' => [ 5327, 1884, 2516, 4636, 764, 2387, 917, 596, 2603, 5409, 3293, 3973, 56, 5334, 1415, 4444 ], '2869' => [ 5494, 1232, 5487, 480, 396 ], '5070' => [ 5060 ], '4402' => [], '729' => [ 1364, 4060, 56 ], '917' => [ 917, 5401, 1411 ], '3568' => [ 764, 2387, 3973, 5501, 5486 ], '3980' => [ 5327, 1884, 4636, 4635, 2603, 5334 ], '4635' => [], '3675' => [], '758' => [ 3934, 764, 1232 ], + '829' => [ 764, 1232 ], '4687' => [ 1192, 6305 ], '596' => [ 917, 596, 544 ], '5330' => [ 5423, 3934, 2746, 5327, 1884, 4636, 1019, 397, 764, 5442, 4402, 758, 829, 2603, 4681, 1232, 1319, 5777, 5334, 5501, 5486, 4161, 2861, 1719 ], '223' => [ 1855, 223, 2727, 1112 ], '772' => [], '5401' => [], '4657' => [ 4657 ], '3289' => [ 2001, 4060, 442, 5404, 284, 3293, 5333, 5329, 4640 ], '4350' => [], '5685' => [ 5688, 10649 ], '3151' => [ 5499, 764 ], '3069' => [], '3667' => [ 3675, 3659, 3662 ], '1149' => [ 2869, 829, 480, 396 ], '3935' => [ 3934, 480, 396 ], '4673' => [ 10659, 4150, 10651 ], '2603' => [ 772 ], '2243' => [], '4053' => [], '1487' => [ 5327, 1884, 2516, 4636, 764, 5060, 2387, 2136, 917, 596, 2603, 2355, 5409, 3293, 3973, 56, 4426, 5334, 4444 ], '3659' => [ 3675 ], '2694' => [ 764, 2387, 3973 ], '4681' => [ 3934, 1019, 764 ], '1769' => [ 118, 764, 865, 5060, 2387, 4402, 1769, 1232, 3602, 5777, 3973, 3173, 5079, 2861 ], '2826' => [ 2516, 5342, 917, 596, 56, 607, 1112, 4 + 444 ], '778' => [ 397, 2869, 480, 396 ], '4639' => [ 3934, 5664, 4636, 764, 5198, 5777, 4656, 5501, 5486, 2861 ], '4430' => [ 5423, 5327, 1884, 4636, 5442, 2603, 5334, 5618 ], '5407' => [ 4060, 5401 ], '2355' => [ 5327, 1884, 2516, 4636, 10649, 2136, 917, 596, 2603, 1487, 5409, 3293, 56, 4426, 5334, 3280, 4444 ], '5409' => [], '5331' => [ 5330, 5334 ], '10199' => [], '3293' => [ 5327, 1884, 4636, 3314, 5330, 2603, 5409, 3293, 1894, 5334, 3280 ], '4446' => [], '1232' => [ 764, 5501 ], '2820' => [ 2820 ], '4637' => [], '3602' => [ 5060 ], '1192' => [ 5775 ], '1275' => [ 2820 ], '4438' => [ 2992, 5342, 917, 3568, 3675, 4446, 3669, 56, 1827, 3662, 4444 ], '556' => [ 5060, 3173 ], '22012' => [ 8295, 442, 5407, 1275, 1787, 189, 1292, 5333, 1422, 1508, 4400, 1316, 4640, 840, 4793 ], '1787' => [ 3037, 1275, 1292 ], '1319' => [ 5423, 5442, 1319, 286, 3275 ], '189' => [ 5494, 865, 5487, 480, 692, 396, 3971 ], '2597' => [ 5250, 1364, 4060, 4439, 442, 5404, 284, 2136, 729, 3289, 5333, 6 + 92, 396, 3971, 1415, 2845, 5329, 1316, 3327, 4640 ], '1292' => [ 3037, 1275 ], '5487' => [ 480, 5486 ], '5333' => [ 3934, 2746, 5327, 1884, 4636, 4060, 1019, 397, 764, 442, 5778, 1191, 3016, 284, 2869, 4402, 758, 829, 5330, 1149, 3935, 2603, 4681, 778, 1232, 5333, 5777, 4691, 3079, 396, 5334, 5501, 5486, 5329, 2861, 4640, 1719, 2669 ], '5777' => [ 2861, 5775 ], '480' => [ 5494, 189 ], '1894' => [ 5327, 1884, 4636, 764, 2603, 1894, 1583, 5334 ], '4691' => [ 1191, 3935, 4681, 480, 396 ], '3079' => [ 2869, 758, 3935, 480, 396 ], '692' => [ 2387, 480, 3971 ], '3973' => [], '5199' => [ 798, 3273, 5198, 5778, 3935, 480, 396 ], '3669' => [ 3675 ], '304' => [ 4636, 2603, 304, 5334, 2861 ], '1583' => [], '396' => [ 5494, 764, 5487, 480 ], '3173' => [], '1422' => [ 2694, 692, 396, 3971 ], '3665' => [ 3675 ], '56' => [ 2992, 917 ], '2139' => [ 2139 ], '9859' => [ 9859 ], '5616' => [ 2818, 3936, 3272, 10199, 2139, 5618 ], '4426' => [ 4430 ], '5334' => [ 764, 5060, 4402, 5334, 5079 ], '6 + 178' => [], '10659' => [], '4656' => [ 5664, 4657 ], '1508' => [ 5250, 1364, 4060, 4439, 442, 5404, 284, 5070, 729, 3289, 1487, 2355, 2597, 5333, 692, 396, 3971, 2845, 4428, 5329, 1316, 3327, 4640 ], '4400' => [ 3273, 4402 ], '1827' => [], '6305' => [ 5775 ], '5501' => [], '838' => [ 3037, 2820 ], '5486' => [], '403' => [ 4060, 3569 ], '3971' => [ 480, 3973 ], '3662' => [ 3675, 3667 ], '286' => [ 5423, 5442 ], '2845' => [ 1364, 4060, 596, 2845, 544, 3327 ], '1415' => [ 5327, 1884, 2516, 4636, 2136, 917, 596, 2603, 5409, 5331, 3293, 56, 5334, 3280, 4444 ], '5618' => [ 5616, 5618 ], '2727' => [ 607 ], '3672' => [ 4060, 3669, 3665 ], '544' => [ 917, 596 ], '4150' => [ 4350, 556, 304, 9859, 2861, 2244 ], '4161' => [ 5423, 5060, 5442, 4402, 1319, 4161, 5079 ], '10651' => [], '5079' => [ 5060, 5079 ], '3280' => [ 5327, 1884, 4636, 2603, 5334 ], '53' => [], '6166' => [], '4428' => [ 4060, 4426, 3569 ], '607' => [], '5329' => [ 4060, 396, 5334, 5329 ], '1112' => [ 1855, 607, 1112 ], + '3275' => [], '1316' => [ 5250, 2516, 1364, 4060, 4439, 729, 223, 2826, 2845, 2727 ], '2861' => [], '3327' => [ 3273 ], '4640' => [ 3934, 798, 1884, 3273, 4636, 4060, 764, 5198, 442, 4638, 5778, 4402, 3935, 4637, 5777, 5199, 396, 5501, 5486, 2861, 3327, 4640 ], '4686' => [ 5423, 5060, 5442, 4402, 1319, 5777, 4161, 5079 ], '840' => [ 118, 764, 865, 5060, 4685, 2387, 4402, 1769, 1232, 3602, 5777, 3973, 3173, 5501, 5486, 5079, 2861 ], '3569' => [], '4444' => [ 3002, 917, 3675, 4446, 4438, 3669, 56, 6178, 3662, 5618, 4444 ], '1719' => [ 1019, 764, 1232 ], '1411' => [ 917, 5401 ], '5775' => [ 5777, 2861 ], '2244' => [ 4402 ], '4793' => [], '2669' => [ 1191, 2869, 480, 396, 1719 ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 5625, 6155, 6156, 6157, 6158, 6172, 6180, 6186, 6190, 6192, 6199, 6201, 6202, 6204, 6206, 6210, 6215, 6221, 6222, 6223, 6224, 6226, 6229, 6233, 6234, 6236, 6238, 6239, 6243, 6244, 6250, 6254, 6255, 6256, 6257, 6258, 6259, 6261, 6263, 6265, 6266, 6267, 6269, 6270, 6271, 6272, 6273, 6274, 6275, 6278, 6279, 6284, 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, 6296, 6298, 6299, 6300, 6301, 6302, 6303, 6304, 6305, 6306, 6307, 6309, 6310, 6311, 6312, 6314, 6315, 6316, 6317, 6318, 6319, 6320, 6321, 6322, 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, 6333, 6334, 6335, 6336, 6337, 6338, 6339, 6341, 6342, 6343, 6344, 6346, 6347, 6348, 6349, 6350, 6376, 6377, 6379, 6380, 6385, 6387, 6388, 6390, 6394, 6400, 6402, 6403, 6404, 6405, 6412, 6414, 6416, 6417, 6418, 6419, 6420, 6426, 6427, 6429, 6430, 6436, 6439, 6444, 6451, 6454, 6459, 6462, 6464, 6466, 6469, 6472, 6477, 6478, 6479, 6480, 6481, 6483, 6484, 6485, 6489, 6491, 6493, 6495, 6497, 6500, 6501 + , 6502, 6518, 6519, 6521, 6522, 6523, 6524, 6527, 6528, 6530, 6531, 6533, 6534, 6535, 6536, 6537, 6538, 6540, 6541, 6542, 6546, 6547, 6548, 16770, 16772, 16774, 16775, 16779, 16780, 16783, 16786, 16788, 16789, 16790, 16793, 16794, 16795, 16799, 16802, 16803, 16804, 16805, 16864, 16869, 16871, 16873, 16874, 16875, 16878, 16879, 16913, 16927, 16928, 16957, 16958, 16959, 16960, 16961, 16962, 16963, 16964, 16965, 16966, 16967, 16968, 16969, 16970, 16971, 16972, 16974, 16975, 16976, 16977, 16978, 16979, 16980, 16981, 16982, 16983, 16984, 16985, 16986, 16987, 16988, 16989, 16990, 16992 ]; ++$requires = { '16977' => [ '16972', '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '6261' => [ '6500', '6481' ], '16775' => [ '16774', '16979', '16970', '16969', '16976', '16803', '6500', '16981', '16986', '6481' ], '6347' => [ '6342', '6343', 6335, 6348, 6330, 6333, 6337, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6256' => [ '6287', '6284', '6274', '6273', '6257', '6278', '6271', '6269', '6288', '6286', '6275', '6289', '6272', '6254' ], '16873' => [ '16873' ], '16965' => [ '16969' ], '6535' => [ '6377', '6500', '6524', '6481' ], '6270' => [ '6279', '6548', '6519' ], '6497' => [ '6481' ], '16967' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '16774' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '16799' => [ '16783', '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '6501' => [ '6484' ], '16793' => [ '16969', '16981', '16790' ], '16783' => [ '16969' ], '6518' => [ '6489', '6481' ], '6293' = + > [ '6293', '6300' ], '6333' => [ '6342', '6346', 6335, 6348, 6330, 6333, 6337, 6343, 6329, 6339, 6349, 6347, 6344, 6334, 6328, 6332 ], '16794' => [ '16979', '16989', '16970', '16969', '6500', '16981', '16986', '6481' ], '6222' => [ '6292', '6223', '6377', '6300' ], '16984' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '16927' => [ '16928', '6377', '6500', '6481' ], '6531' => [ '6535', '6306', '6480', '6527', '6158', '6377', '6500', '6521', '6524', '6481' ], '6405' => [ '6416' ], '16786' => [ '16979', '16795', '16970', '16969', '16976', '6500', '16981', '16986', '6481' ], '6541' => [ '6541', '6390', '6426' ], '6263' => [ '6292', '6267', '6342', '6266', '6300' ], '6341' => [ '6347', '6333', '6341', '6334', '6332', '6342', '6329', '6344', '6337', '6348', '6328', '6339', '6346', '6343', '6330', '6335', '6349' ], '16802' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '6334' => [ '6334', 6335, 6348, 6330, 6333, 6337, 6343, 6329, 6339, 63 + 46, 6349, 6347, 6344, 6342, 6328, 6332 ], '6290' => [ '6292', '6390', '6426', '6500', '6300', '6481' ], '6522' => [ '6531', '6527', '6537', '6536', '6523', '6534' ], '6527' => [ '6377', '6500', '6524', '6481' ], '16789' => [ '16969' ], '16982' => [ '16979', '16989', '16970', '16969', '6500', '16981', '16986', '6481' ], '6495' => [ '6489' ], '16804' => [ '16969', '6500', '6481' ], '16980' => [ '16979', '16989', '16970', '16969', '16976', '6500', '16981', '16986', '6481', '16961' ], '16928' => [ '16927' ], '16989' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '6332' => [ '6342', 6335, 6348, 6330, 6333, 6337, 6343, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6190' => [ '6192' ], '6292' => [ '6292', '6298', '6300' ], '6298' => [ '6290', '6300' ], '6239' => [ '6484', '6501', '6483', '6480', '6489', '6158', '6416', '6462', '6500', '6155', '6481', '6417' ], '6267' => [ '6292', '6267', '6342', '6266', '6300' ], '6186' => [ '6376', '6292', '6298', ' + 6186', '6300' ], '16958' => [ '16979', '16969', '6500', '16986', '6481' ], '6419' => [ '6342', '6339' ], '6394' => [ '6306', '6292', '6298', '6394', '6300', '6387' ], '6412' => [ '6430', '6390' ], '6204' => [ '6306', '6292', '6377', '6500', '6300', '6202', '6481' ], '6229' => [ '6233' ], '6342' => [ '6261', '6334', 6335, 6348, 6330, 6333, 6337, 6343, 6329, 6339, 6346, 6349, 6347, 6344, 6342, 6328, 6332 ], '6430' => [ '6426' ], '16795' => [ '16979', '16970', '16969', '16976', '6500', '16981', '16986', '6481' ], '6390' => [ '6426' ], '16779' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '6533' => [ '6377', '6500', '6481' ], '6478' => [ '6500' ], '16970' => [ '16979', '16969', '6500', '16981', '16986', '6481' ], '16987' => [ '16969' ], '6329' => [ '6342', '6346', '6343', 6335, 6348, 6330, 6333, 6337, 6329, 6339, 6349, 6347, 6344, 6334, 6328, 6332 ], '6530' => [ '6377', '6500', '6481' ], '16869' => [ '16869' ], '16974' => [ '16979', '16989', '16970', '16969 + ', '16976', '6500', '16981', '16986', '6481' ], '6226' => [ '5625' ], '6528' => [ '6377', '6500', '6481' ], '6344' => [ '6333', '6342', 6335, 6348, 6330, 6337, 6343, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6444' => [ '6292', '6300' ], '6156' => [ '6155' ], '6491' => [ '6484' ], '6337' => [ '6342', 6335, 6348, 6330, 6333, 6337, 6343, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6477' => [ '6485' ], '16957' => [ '16969' ], '6519' => [ '6489' ], '6348' => [ '6342', '6343', 6335, 6348, 6330, 6333, 6337, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6328' => [ '6342', '6343', 6335, 6348, 6330, 6333, 6337, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6266' => [ '6342' ], '16976' => [ '16979', '16989', '16970', '16969', '6500', '16981', '16986', '6481' ], '16990' => [ '16969' ], '6547' => [ '6489', '6481' ], '6537' => [ '6535', '6531', '6528', '6377', '6500', '6481' ], '6404' => [ '6403' ], '6388' => [ '6377' ], '6310' => [ '6320' + ], '6466' => [ '6462' ], '16803' => [ '16774', '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '16983' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '6454' => [ '6439', '6292', '6377', '6300' ], '16874' => [ '6206' ], '6540' => [ '6541' ], '6244' => [ '6270', '6311', '5625', '6310', '6259', '6255' ], '16879' => [ '16869', '16879', '16864' ], '6299' => [ '6293', '6290', '6292', '6299', '6500', '6300', '6481' ], '16805' => [ '16965', '16972', '16979', '16989', '16970', '16969', '16976', '6500', '16981', '16986', '6481' ], '6339' => [ '6342', '6346', '6343', 6335, 6348, 6330, 6333, 6337, 6329, 6339, 6349, 6347, 6344, 6334, 6328, 6332 ], '6400' => [ '6394' ], '6221' => [ '6292', '6300', '6224' ], '16966' => [ '16979', '16969', '6500', '16986', '6481' ], '16964' => [ '16972' ], '16971' => [ '16979', '16969', '16990', '6500', '16986', '6481' ], '6300' => [ '6300' ], '6346' => [ '6342', '6339', '6343', 6335, 6348, 6330, 6333, 6337, 6329, 6346, + 6349, 6347, 6344, 6334, 6328, 6332 ], '6202' => [ '6292', '6377', '6300', '6481' ], '6536' => [ '6535', '6531', '6377', '6500', '6521', '6481' ], '16975' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481' ], '16986' => [ '16979', '16969', '6500', '6481' ], '6385' => [ '6376' ], '16992' => [ '16972', '16979', '16982', '16989', '16970', '16969', '16976', '16985', '6500', '16981', '16986', '6481', '16961' ], '6538' => [ '6535', '6530', '6377', '6500', '6481' ], '6479' => [ '6483' ], '6343' => [ '6342', 6335, 6348, 6330, 6333, 6337, 6343, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6414' => [ '6417' ], '6523' => [ '6533', '6377', '6500', '6481' ], '6534' => [ '6535', '6531', '6377', '6500', '6481' ], '6234' => [ '6236' ], '6330' => [ '6342', '6343', 6335, 6348, 6330, 6333, 6337, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6493' => [ '6480' ], '6521' => [ '6377', '6500', '6521', '6481' ], '6335' => [ '6342', '6343', 6335, 6348, 6330, 6333, + 6337, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '6524' => [ '6480', '6530', '6377', '6500', '6521', '6524', '6199', '6481' ], '16772' => [ '16775', '16774', '16979', '16970', '16969', '16976', '16803', '16983', '6500', '16981', '16986', '6481' ], '6349' => [ '6342', '6343', 6335, 6348, 6330, 6333, 6337, 6329, 6339, 6346, 6349, 6347, 6344, 6334, 6328, 6332 ], '16864' => [ '16871' ], '6258' => [ '6258' ], '16968' => [ '16977', '16960', '16972', '16979', '16982', '16980', '16989', '16958', '16970', '16987', '16974', '16969', '16957', '16976', '16983', '16985', '6500', '16964', '16981', '16986', '16992', '16968', '6481', '16961', '16988', '16963', '16959' ], '16878' => [ '16878' ], '16978' => [ '16979', '16989', '16970', '16969', '6500', '16981', '16986', '6481' ], '6502' => [ '6501', '6491' ], '6157' => [ '6158' ], '16788' => [ '16979', '16969', '6500', '16986', '6481' ], '16790' => [ '16969' ], '16770' => [ '16965', '16979', '16989', '16970', '16974', '16969', '1 + 6990', '16976', '16805', '6500', '16971', '16981', '16986', '6481' ], '6210' => [ '6306', '6210' ], '6379' => [ '6387' ], '6469' => [ '6427' ], '6259' => [ '6518', '6547' ], '6206' => [ '6206' ], '16961' => [ '16979', '16989', '16970', '16969', '6500', '16981', '16986', '6481' ], '16963' => [ '16979', '16969', '6500', '16986', '6481' ], '6250' => [ '6256', '6244' ], '16988' => [ '16969', '16985' ], '16959' => [ '16979', '16970', '16969', '6500', '16981', '16986', '6481', '16963' ] }; ++check_it($list_unsorted, $requires, 0); ++ ++$list_unsorted = [ 0 .. 10 ]; ++check_it($list_unsorted, create_random($list_unsorted), 1) foreach 1 .. 10000; ++ ++ ++sub check_it { ++ my ($list_unsorted, $requires, $dump_it) = @_; ++ ++ my @sorted = eval { URPM::sort_graph($list_unsorted, $requires) }; ++ ok(@sorted > 0); ++ ++ if (!@sorted && $dump_it) { ++ require Data::Dumper; ++ $Data::Dumper::Sortkeys = 1; ++ warn Data::Dumper::Dumper($list_unsorted, $requires); ++ warn "$@\n"; ++ exit 1; ++ } ++} ++ ++ ++sub create_random { ++ my ($list_unsorted) = @_; ++ my %requires; ++ ++ foreach my $i (@$list_unsorted) { ++ my $nb = int(rand(1) * 2.8); ++ push @{$requires{$i}}, grep { $_ != $i } uniq(map { int(rand @$list_unsorted) } 1 .. $nb); ++ } ++ \%requires; ++} ++sub uniq { my %l; $l{$_} = 1 foreach @_; grep { delete $l{$_} } @_ } + +Added: rpm/perl-URPM/trunk/t/synthesis.t +=================================================================== +--- rpm/perl-URPM/trunk/t/synthesis.t (rev 0) ++++ rpm/perl-URPM/trunk/t/synthesis.t 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,151 @@ ++#!/usr/bin/perl ++ ++use strict ; ++use warnings ; ++use Test::More tests => 94; ++use URPM; ++ ++chdir 't' if -d 't'; ++my $file1 = 'synthesis.sample.cz'; ++ ++open my $f, "| gzip -9 >$file1"; ++print $f <<'EOF'; +<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">+ at provides</A>@glibc-devel == 6:2.2.4-25mdk +<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">+ at requires</A>@/sbin/<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">install-info at glibc</A> == <A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">2.2.4 at kernel-headers</A>@kernel-headers >= 2.2.1@/bin/sh@/bin/sh@/bin/<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">sh at rpmlib</A>(PayloadFilesHavePrefix) <= <A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">4.0-1 at rpmlib</A>(CompressedFileNames) <= 3.0.4-1 +<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">+ at conflicts</A>@texinfo < <A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">3.11 at gcc</A> < 2.96-0.50mdk +<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">+ at obsoletes</A>@<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">libc-debug at libc-headers</A>@<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">libc-devel at linuxthreads-devel</A>@glibc-debug +<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">+ at info</A>@<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">glibc-devel-2.2.4-25mdk.i586 at 6</A>@<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">45692097 at Development</A>/C ++EOF ++close $f; ++ ++END { unlink $file1 } ++ ++my $a = new URPM; ++ok($a); ++ ++my ($first, $end); ++ ++($first, $end) = URPM->new->parse_synthesis('empty_synthesis.cz'); ++is("$first $end", "0 -1", 'parse empty synthesis'); ++ ++is(URPM->new->parse_synthesis('buggy_synthesis.cz'), undef, 'parse buggy synthesis'); ++ ++($first, $end) = $a->parse_synthesis($file1); ++ok($first == 0 && $end == 0); ++is(int @{$a->{depslist}}, 1); ++ok(keys(%{$a->{provides}}) == 3); ++ok(defined $a->{provides}{'glibc-devel'}); ++ok(exists $a->{provides}{'/bin/sh'}); ++ok(! defined $a->{provides}{'/bin/sh'}); ++ok(exists $a->{provides}{'/sbin/install-info'}); ++ok(! defined $a->{provides}{'/sbin/install-info'}); ++ ++my $pkg = $a->{depslist}[0]; ++ok($pkg); ++ok($pkg->name eq 'glibc-devel'); ++ok($pkg->version eq '2.2.4'); ++ok($pkg->release eq '25mdk'); ++ok($pkg->arch eq 'i586'); ++ok($pkg->fullname eq 'glibc-devel-2.2.4-25mdk.i586'); ++ok(!defined $pkg->buildarchs); ++ok(!defined $pkg->buildhost); ++is($pkg->buildtime,0); ++ok(!defined $pkg->changelog_name); ++ok(!defined $pkg->changelog_text); ++ok(!defined $pkg->changelog_time); ++ ++my ($name, $version, $release, $arch, @l) = $pkg->fullname; ++ok(@l == 0); ++ok($name eq 'glibc-devel'); ++ok($version eq '2.2.4'); ++ok($release eq '25mdk'); ++ok($arch eq 'i586'); ++ ++ok($pkg->epoch == 6); ++ok($pkg->size == 45692097); ++ok($pkg->group eq 'Development/C'); ++ok($pkg->filename eq 'glibc-devel-2.2.4-25mdk.i586.rpm'); ++ok(defined $pkg->id); ++ok($pkg->id == 0); ++ok($pkg->set_id(6) == 0); ++ok($pkg->id == 6); ++ok($pkg->set_id == 6); ++ok(! defined $pkg->id); ++ok(! defined $pkg->set_id(0)); ++ok(defined $pkg->id); ++ok($pkg->id == 0); ++ ++my @obsoletes = $pkg->obsoletes; ++ok(@obsoletes == 5); ++ok($obsoletes[0] eq 'libc-debug'); ++ok($obsoletes[4] eq 'glibc-debug'); ++ ++my @conflicts = $pkg->conflicts; ++ok(@conflicts == 2); ++ok($conflicts[0] eq 'texinfo < 3.11'); ++ok($conflicts[1] eq 'gcc < 2.96-0.50mdk'); ++ ++my @requires = $pkg->requires; ++ok(@requires == 9); ++ok($requires[0] eq '/sbin/install-info'); ++ok($requires[8] eq 'rpmlib(CompressedFileNames) <= 3.0.4-1'); ++ ++my @provides = $pkg->provides; ++ok(@provides == 1); ++ok($provides[0] eq 'glibc-devel == 6:2.2.4-25mdk'); ++ ++my @files = $pkg->files; ++ok(@files == 0); ++ ++ok($pkg->compare("6:2.2.4-25mdk") == 0); ++ok($pkg->compare("2.2.4-25mdk") > 0); ++ok($pkg->compare("6:2.2.4") == 0); ++ok($pkg->compare("2.2.3") > 0); ++ok($pkg->compare("2.2") > 0); ++ok($pkg->compare("2") > 0); ++ok($pkg->compare("2.2.4.0") > 0); ++ok($pkg->compare("2.2.5") > 0); ++ok($pkg->compare("2.1.7") > 0); ++ok($pkg->compare("2.3.1") > 0); ++ok($pkg->compare("2.2.31") > 0); ++ok($pkg->compare("2.2.4-25") > 0); ++ok($pkg->compare("2.2.4-25.1mdk") > 0); ++ok($pkg->compare("2.2.4-24mdk") > 0); ++ok($pkg->compare("2.2.4-26mdk") > 0); ++ok($pkg->compare("6:2.2.4-25.1mdk") < 0); ++ok($pkg->compare("6:2.2.4.0") < 0); ++ok($pkg->compare("6:2.2.5") < 0); ++ok($pkg->compare("6:2.2.31") < 0); ++ok($pkg->compare("6:2.3.1") < 0); ++ok($pkg->compare("6:2.2.4-24mdk") > 0); ++ok($pkg->compare("6:2.2.4-26mdk") < 0); ++ok($pkg->compare("7:2.2.4-26mdk") < 0); ++ok($pkg->compare("7:2.2.4-24mdk") < 0); ++ ++ok($a->traverse() == 1); ++ ++my $test = 0; ++ok($a->traverse(sub { my ($pkg) = @_; $test = $pkg->name eq 'glibc-devel' }) == 1); ++ok($test); ++ok($a->traverse_tag('name', [ 'glibc-devel' ]) == 1); ++ok($a->traverse_tag('name', [ 'glibc' ]) == 0); ++ ++$test = 0; ++ok($a->traverse_tag('name', [ 'glibc-devel' ], sub { my ($pkg) = @_; $test = $pkg->name eq 'glibc-devel' }) == 1); ++ok($test); ++ +<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">+ at conflicts</A> = $pkg->conflicts_nosense; ++ok(@conflicts == 2); ++ok($conflicts[0] eq 'texinfo'); ++ok($conflicts[1] eq 'gcc'); ++ +<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">+ at requires</A> = $pkg->requires_nosense; ++ok(@requires == 9); ++ok($requires[0] eq '/sbin/install-info'); ++ok($requires[1] eq 'glibc'); ++ok($requires[3] eq 'kernel-headers'); ++ok($requires[8] eq 'rpmlib(CompressedFileNames)'); ++ +<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">+ at provides</A> = $pkg->provides_nosense; ++ok(@provides == 1); ++ok($provides[0] eq 'glibc-devel'); + +Added: rpm/perl-URPM/trunk/t/test-rpm.spec +=================================================================== +--- rpm/perl-URPM/trunk/t/test-rpm.spec (rev 0) ++++ rpm/perl-URPM/trunk/t/test-rpm.spec 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,40 @@ ++# $Id: test-rpm.spec 258552 2009-07-22 18:19:56Z peroyvind $ ++ ++# prevent distepoch & disttag to be added and appended to package filename ++%undefine distepoch ++%undefine disttag ++ ++Summary: test rpm for perl-URPM test suite ++BuildArch: noarch ++Name: test-rpm ++Version: 1.0 ++Release: 1mdk ++License: GPL ++Group: Application/Development ++BuildRoot: %{_tmppath}/%{name}-root ++ ++%description ++test rpm ++ ++%prep ++ ++%build ++ ++%install ++rm -rf $RPM_BUILD_ROOT ++mkdir -p $RPM_BUILD_ROOT%_sysconfdir ++ ++date >> $RPM_BUILD_ROOT%_sysconfdir/%name ++ ++%clean ++rm -rf $RPM_BUILD_ROOT ++ ++%files ++%defattr(-,root,root) ++%config(noreplace) %_sysconfdir/%name ++ ++%changelog ++* Thu Apr 22 2004 Olivier Thauvin <<A HREF="https://www.mageia.org/mailman/listinfo/mageia-sysadm">thauvin at aerov.jussieu.fr</A>> 1-1mdk ++- initial build ++ ++ + +Added: rpm/perl-URPM/trunk/typemap +=================================================================== +--- rpm/perl-URPM/trunk/typemap (rev 0) ++++ rpm/perl-URPM/trunk/typemap 2011-02-04 13:41:50 UTC (rev 419) +@@ -0,0 +1,3 @@ ++URPM::DB T_PTROBJ ++URPM::Transaction T_PTROBJ ++URPM::Package T_PTROBJ +-------------- next part -------------- +An HTML attachment was scrubbed... +URL: </pipermail/mageia-sysadm/attachments/20110204/fb8a6b76/attachment-0001.html> +</PRE> + +<!--endarticle--> + <HR> + <P><UL> + <!--threads--> + <LI>Previous message: <A HREF="002554.html">[Mageia-sysadm] [418] add README file +</A></li> + <LI>Next message: <A HREF="002555.html">[Mageia-sysadm] [420] - import cleaned mageia-lxde-config +</A></li> + <LI> <B>Messages sorted by:</B> + <a href="date.html#2825">[ date ]</a> + <a href="thread.html#2825">[ thread ]</a> + <a href="subject.html#2825">[ subject ]</a> + <a href="author.html#2825">[ author ]</a> + </LI> + </UL> + +<hr> +<a href="https://www.mageia.org/mailman/listinfo/mageia-sysadm">More information about the Mageia-sysadm +mailing list</a><br> +</body></html> |