[yum-utils] Update to latest HEAD.

James Antill james at fedoraproject.org
Thu Jan 26 20:21:23 UTC 2012


commit 5c0b80180ccf911f2b7f60065fab445804987ad3
Author: James Antill <james at and.org>
Date:   Thu Jan 26 15:21:17 2012 -0500

    Update to latest HEAD.

 yum-utils-HEAD.patch | 2280 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 2280 insertions(+), 0 deletions(-)
---
diff --git a/yum-utils-HEAD.patch b/yum-utils-HEAD.patch
new file mode 100644
index 0000000..a1d0e9e
--- /dev/null
+++ b/yum-utils-HEAD.patch
@@ -0,0 +1,2280 @@
+diff --git a/COPYING b/COPYING
+index e77696a..d159169 100644
+--- a/COPYING
++++ b/COPYING
+@@ -1,12 +1,12 @@
+-		    GNU GENERAL PUBLIC LICENSE
+-		       Version 2, June 1991
++                    GNU GENERAL PUBLIC LICENSE
++                       Version 2, June 1991
+ 
+- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+-                          675 Mass Ave, Cambridge, MA 02139, USA
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  Everyone is permitted to copy and distribute verbatim copies
+  of this license document, but changing it is not allowed.
+ 
+-			    Preamble
++                            Preamble
+ 
+   The licenses for most software are designed to take away your
+ freedom to share and change it.  By contrast, the GNU General Public
+@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users.  This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it.  (Some other Free Software Foundation software is covered by
+-the GNU Library General Public License instead.)  You can apply it to
++the GNU Lesser General Public License instead.)  You can apply it to
+ your programs, too.
+ 
+   When we speak of free software, we are referring to freedom, not
+@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
+ 
+   The precise terms and conditions for copying, distribution and
+ modification follow.
+-
+-		    GNU GENERAL PUBLIC LICENSE
++
++                    GNU GENERAL PUBLIC LICENSE
+    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ 
+   0. This License applies to any program or other work which contains
+@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
+     License.  (Exception: if the Program itself is interactive but
+     does not normally print such an announcement, your work based on
+     the Program is not required to print an announcement.)
+-
++
+ These requirements apply to the modified work as a whole.  If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+-
++
+   4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License.  Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+@@ -225,7 +225,7 @@ impose that choice.
+ 
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+-
++
+   8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License
+@@ -255,7 +255,7 @@ make exceptions for this.  Our decision will be guided by the two goals
+ of preserving the free status of all derivatives of our free software and
+ of promoting the sharing and reuse of software generally.
+ 
+-			    NO WARRANTY
++                            NO WARRANTY
+ 
+   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+ 
+-		     END OF TERMS AND CONDITIONS
+-
+-	    How to Apply These Terms to Your New Programs
++                     END OF TERMS AND CONDITIONS
++
++            How to Apply These Terms to Your New Programs
+ 
+   If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+ 
+     <one line to give the program's name and a brief idea of what it does.>
+-    Copyright (C) 19yy  <name of author>
++    Copyright (C) <year>  <name of author>
+ 
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+ 
+-    You should have received a copy of the GNU General Public License
+-    along with this program; if not, write to the Free Software
+-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++    You should have received a copy of the GNU General Public License along
++    with this program; if not, write to the Free Software Foundation, Inc.,
++    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ Also add information on how to contact you by electronic and paper mail.
+ 
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+ 
+-    Gnomovision version 69, Copyright (C) 19yy name of author
++    Gnomovision version 69, Copyright (C) year name of author
+     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+     This is free software, and you are welcome to redistribute it
+     under certain conditions; type `show c' for details.
+@@ -335,5 +335,5 @@ necessary.  Here is a sample; alter the names:
+ This General Public License does not permit incorporating your program into
+ proprietary programs.  If your program is a subroutine library, you may
+ consider it more useful to permit linking proprietary applications with the
+-library.  If this is what you want to do, use the GNU Library General
++library.  If this is what you want to do, use the GNU Lesser General
+ Public License instead of this License.
+diff --git a/debuginfo-install.py b/debuginfo-install.py
+index 177c6c3..27d19ac 100755
+--- a/debuginfo-install.py
++++ b/debuginfo-install.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # Copyright 2007 Seth Vidal
+ 
+ import sys
+diff --git a/docs/Makefile b/docs/Makefile
+index d01c1e4..13ea4e7 100644
+--- a/docs/Makefile
++++ b/docs/Makefile
+@@ -1,7 +1,7 @@
+ DOCS = repoquery package-cleanup repo-rss yumdownloader yum-builddep yum-changelog reposync \
+        yum-list-data yum-filter-data yum-verify yum-utils yum-aliases yum-debug-dump yum-versionlock \
+        yum-groups-manager debuginfo-install repodiff yum-fs-snapshot \
+-       show-installed show-changed-rco
++       show-installed show-changed-rco yum-debug-restore
+ DOCS5 = yum-changelog.conf yum-versionlock.conf yum-fs-snapshot.conf
+ DOCS8 = yum-security yum-complete-transaction yumdb
+ 
+diff --git a/docs/package-cleanup.1 b/docs/package-cleanup.1
+index 867cf4d..15f94ce 100644
+--- a/docs/package-cleanup.1
++++ b/docs/package-cleanup.1
+@@ -14,7 +14,7 @@ Use alternative config file (default is /etc/yum.conf).
+ .IP "\fB\-h, \-\-help\fP"
+ Help; display a help message and then quit\&.
+ .IP "\fB\-q, \-\-quiet\fP" 
+-Print out nothing unecessary.
++Print out nothing unnecessary.
+ .IP "\fB\-v, \-\-version\fP" 
+ Report program version and exit.
+ .IP "\fB\-y\fP" 
+diff --git a/docs/repodiff.1 b/docs/repodiff.1
+index c421c5d..ef2a373 100644
+--- a/docs/repodiff.1
++++ b/docs/repodiff.1
+@@ -11,9 +11,11 @@ repositories.  \fBNote\fP that by default only source packages are compared.
+ .PP 
+ .SH "GENERAL OPTIONS"
+ .IP "\fB\-\-old, -o\fP"
+-Add a repo. as an old repo.
++Add a repo. as an old repo. Note that if you prefix the url with "mirror:" then
++the following url is treated as a mirror and not a baseurl.
+ .IP "\fB\-\-new, -n\fP"
+-Add a repo. as an new repo.
++Add a repo. as an new repo. Note that if you prefix the url with "mirror:" then
++the following url is treated as a mirror and not a baseurl.
+ .IP "\fB\-\-archlist, -a\fP"
+ Add architectures to change the default from just comparing source packages.
+ Note that if you want the same as a native
+@@ -21,10 +23,14 @@ Note that if you want the same as a native
+ from earlier versions where you needed to specify
+ "x86_64,athlon,i686,i586,i486,i386,noarch" and you still got "src").
+ .IP "\fB\-\-size, -s\fP"
+-Ouput additional data about the size of the changes.
++Output additional data about the size of the changes.
+ .IP "\fB\-\-compare-arch\fP"
+ Normally packages are just compared based on their name, this flag makes the
+ comparison also use the arch. So foo.i386 and foo.x86_64 are different.
++.IP "\fB\-\-simple\fP"
++Output a simple one line message for modified packages.
++.IP "\fB\-\-downgrade\fP"
++Split the data for modified packages between upgraded and downgraded packages.
+ .SH "EXAMPLES"
+ .IP "Compare source pkgs in two local repos:"
+ \fBrepodiff --old=/tmp/repo-old --new=/tmp/repo-new\fP
+@@ -32,6 +38,8 @@ comparison also use the arch. So foo.i386 and foo.x86_64 are different.
+ \fBrepodiff -a x86_64 --old=http://example.com/repo1-old --old=/tmp/repo-old --new=http://example.com/repo1-new --new=/tmp/repo-new\fP
+ .IP "Compare x86_64 compat. binary pkgs, but also compare arch:"
+ \fBrepodiff -a x86_64 --compare-arch --old=http://example.com/repo1-old --old=/tmp/repo-old --new=http://example.com/repo1-new --new=/tmp/repo-new\fP
++.IP "Compare two releases of Fedora (15 => 16):"
++\fBrepodiff --old='mirror:https://mirrors.fedoraproject.org/metalink?repo=fedora-source-15&arch=i386' --new='mirror:https://mirrors.fedoraproject.org/metalink?repo=fedora-source-16&arch=i386' --size --simple --downgrade\fP
+ .PP 
+ 
+ .SH "SEE ALSO"
+diff --git a/docs/repoquery.1 b/docs/repoquery.1
+index f5a8c5d..fe842f5 100644
+--- a/docs/repoquery.1
++++ b/docs/repoquery.1
+@@ -130,7 +130,8 @@ package names).  This is the default.
+ When used with --whatrequires, search for dependencies only exactly as given.
+ This is effectively the opposite of --alldeps.
+ .IP "\fB\-\-recursive\fP"
+-When used with --whatrequires, query packages recursively.
++When used with --whatrequires, and --requires --resolve, query packages
++recursively.
+ .IP "\fB\-\-archlist=ARCH1[,ARCH2...]\fP"
+ Limit the query to packages of given architecture(s). Valid values are all
+ architectures known to rpm/yum such as 'i386' and 'src' for
+@@ -166,7 +167,7 @@ Query groups instead of packages.
+ 
+ .SH "EXAMPLES"
+ .IP "List all packages whose name contains 'perl':"
+-\fBrepoquery '*perl*'\fP
++\fBrepoquery \(aq*perl*\(aq\fP
+ .IP "List all packages depending on openssl:"
+ \fBrepoquery --whatrequires openssl\fP 
+ .IP "List all package names and the repository they come from, nicely formatted:"
+diff --git a/docs/reposync.1 b/docs/reposync.1
+index c1bc818..edc05cc 100644
+--- a/docs/reposync.1
++++ b/docs/reposync.1
+@@ -14,7 +14,7 @@ Display a help message, and then quit.
+ Config file to use (defaults to /etc/yum.conf).
+ .IP "\fB\-a ARCH, \-\-arch=ARCH\fP"
+ Act as if running the specified arch (default: current arch, note: does
+-not override $releasever).
++not override $releasever. x86_64 is a superset for i*86.).
+ .IP "\fB\-\-source\fP"
+ Also download .src.rpm files.
+ .IP "\fB\-r REPOID, \-\-repoid=REPOID\fP"
+@@ -28,6 +28,8 @@ Path to download packages to: defaults to current directory.
+ Remove packages that fail GPG signature checking after downloading.
+ .IP "\fB\-u, \-\-urls\fP"
+ Just list urls of what would be downloaded, don't download.
++.IP "\fB\-l, \-\-plugins\fP"
++Enable yum plugin support.
+ .IP "\fB\-n, \-\-newest-only\fP"
+ Download only newest packages per-repo.
+ .IP "\fB\-q, \-\-quiet\fP"
+@@ -41,6 +43,8 @@ Output as little information as possible.
+ \fB reposync --repoid=updates --repoid=extras\fP
+ .IP "Sync all packages from the 'updates' repo to the \fBrepos\fP directory:"
+ \fB reposync -p repos --repoid=updates\fP
++.IP "Sync all packages from the 'updates' repo to the \fBrepos\fP directory excluding x86_64 arch. Edit \fI/etc/yum.conf\fR adding option \fBexclude=*.x86_64\fR. Then: 
++\fBreposync -p repos --repoid=updates\fP
+ .SH "FILES"
+ \fBreposync\fP uses the yum libraries for retrieving information and
+ packages. If no configuration file is specified, the default yum
+diff --git a/docs/show-changed-rco.1 b/docs/show-changed-rco.1
+index 3e3b62c..1b0ea65 100644
+--- a/docs/show-changed-rco.1
++++ b/docs/show-changed-rco.1
+@@ -11,7 +11,7 @@ packages Requires, Conflicts and Obsoletes data from the installed (or old) to
+ a specified rpm file.
+ .SH OPTIONS
+ .TP
+-.IP \-h, \-\-help
++.IP "\fB\-h, \-\-help\fP"
+ show this help message and exit
+ .IP "\fB\-C, \-\-cache\fP" 
+ Tells repoquery to run entirely from YUM cache - does not download any metadata
+diff --git a/docs/show-installed.1 b/docs/show-installed.1
+index 7072b63..18c4af8 100644
+--- a/docs/show-installed.1
++++ b/docs/show-installed.1
+@@ -16,10 +16,10 @@ show this help message and exit
+ yum, kickstart or human; yum gives the result as a yum command line; kickstart the content of a %packages section; "human" readable is default.
+ .TP
+ .B \-i INPUT, \-\-input=INPUT
+-File to read the package list from instead of using the rpmdb. \- for stdin. The file must contain package names only separated by white space (including newlines). rpm \-qa \-\-qf='%{name}\\n' produces proper output.
++File to read the package list from instead of using the rpmdb. \- for stdin. The file must contain package names only separated by white space (including newlines). rpm \-qa \-\-qf=\(aq%{name}\\n\(aq produces proper output.
+ .TP
+ .B \-o OUTPUT, \-\-output=OUTPUT
+-File to write the result to. Stdout is used if option is omited.
++File to write the result to. Stdout is used if option is omitted.
+ .TP
+ .B \-q, \-\-quiet
+ Do not show warnings.
+diff --git a/docs/yum-aliases.1 b/docs/yum-aliases.1
+index c0f148d..8b943d4 100644
+--- a/docs/yum-aliases.1
++++ b/docs/yum-aliases.1
+@@ -28,7 +28,7 @@ last form creates a new alias.
+ .PP 
+ When you type an aliased command, like "yum --disableexcludes UPT lsu" using
+ the default aliases, the yum-aliases plugin first takes the first "command", by
+-skiping over any options, and then looks up the result (in this case "UPT" is converted to "--enablerepo=updates-tesintg"). If there is a match, then it will
++skipping over any options, and then looks up the result (in this case "UPT" is converted to "--enablerepo=updates-testing"). If there is a match, then it will
+ replace the aliased "command" in the argument list and try again (again
+ skipping over any options). By convention, in the default aliases list, alias
+ "commands" that are in all CAPS only add options so you can join together a
+diff --git a/docs/yum-debug-dump.1 b/docs/yum-debug-dump.1
+index 0e65a07..71e5f3f 100644
+--- a/docs/yum-debug-dump.1
++++ b/docs/yum-debug-dump.1
+@@ -10,11 +10,15 @@ yum-debug-dump
+ lot of information useful to developers trying to debug a problem.
+ .PP
+ By default it will output a file to the current working directory named
+-yum_debug_dump.txt.gz. This file contains no private information but does
++yum_debug_dump-<hostname>-<time>.txt.gz. This file contains no private
++information but does
+ contain a complete list of all packages you have installed, all packages
+ available in any repository, important configuration and system information.
+ You can view this file using the 'zless' command.
+ .PP 
++You can use the coresponding program \fByum-debug-restore\fP to act on this file
++and restore a set of packages (much like dump/restore).
++.PP 
+ .SH "FILES"
+ As yum-debug-dump uses YUM libraries for retrieving all the information, it
+ relies on YUM configuration for its default values like which repositories
+@@ -29,6 +33,7 @@ to use. Consult YUM documentation for details:
+ .PP 
+ .SH "SEE ALSO"
+ .nf
++.I yum-debug-restore (1)
+ .I yum.conf (5)
+ http://yum.baseurl.org/
+ .fi 
+diff --git a/docs/yum-debug-restore.1 b/docs/yum-debug-restore.1
+new file mode 100644
+index 0000000..ba96a05
+--- /dev/null
++++ b/docs/yum-debug-restore.1
+@@ -0,0 +1,62 @@
++.\" yum-debug-dump
++.TH "yum-debug-restore" "1" "15 December 2011" "James Antill" ""
++.SH "NAME"
++yum-debug-restore
++.SH "SYNOPSIS"
++\fByum-debug-restore\fP
++.SH "DESCRIPTION"
++.PP 
++\fByum-debug-restore\fP is a program which takes a gzipped file created by
++\fByum-debug-dump\fP and acts on the information about installed packages
++contained within.
++.PP
++
++.SH "GENERAL OPTIONS"
++.IP "\fB\-\-output\fP"
++Output the commands that would be run to stdout.
++.IP "\fB\-\-shell=<file>\fP"
++Output the commands that would be run to a file.
++.IP "\fB\-\-install-latest\fP"
++Ask yum to install the latest version of the given packages, instead of the
++version that was installed in the debug-dump file.
++.IP "\fB\-\-ignore-arch\fP"
++Ignore the architecture of the packages, so you can "restore" an i386 debug-dump
++on an x86_64 machine.
++.IP "\fB\-\-filter-types=[install,remove,update,downgrade]\fP"
++Only perform the given types of commands, so you can filter to just upgrades
++and installs.
++
++.SH "FILES"
++As yum-debug-restore uses YUM libraries for retrieving all the information, it
++relies on YUM configuration for its default values like which repositories
++to use. Consult YUM documentation for details:
++.PP
++.nf 
++/etc/yum.conf
++/etc/yum/repos.d/
++/var/cache/yum/
++.fi 
++
++.PP 
++.SH "SEE ALSO"
++.nf
++.I yum-debug-dump (1)
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi 
++
++.PP 
++.SH "AUTHORS"
++.nf 
++See the Authors file included with this program.
++.fi 
++
++.PP 
++.SH "BUGS"
++There are of course no bugs, but should you find any, you should first
++consult the FAQ section on http://yum.baseurl.org/wiki/Faq and if unsuccessful
++in finding a resolution contact the mailing list: yum-devel at lists.baseurl.org.
++To file a bug use http://bugzilla.redhat.com for Fedora/RHEL/Centos
++related bugs and http://yum.baseurl.org/report for all other bugs.
++
++.fi
+diff --git a/docs/yum-filter-data.1 b/docs/yum-filter-data.1
+index 6d7f1e4..b26f1fd 100644
+--- a/docs/yum-filter-data.1
++++ b/docs/yum-filter-data.1
+@@ -44,7 +44,7 @@ This option includes packages which have a committer which matches one of the
+ passed committer wildcard strings, or is unknown. Note that committers can have
+ spaces in their value, so "," is the only way to specify multiple committers as
+ one option argument. Also, committer values are so loosely formed that they 
+-could contain commas too, it is recommeneded to not do that but you can work
++could contain commas too, it is recommended to not do that but you can work
+ around it by using "?".
+ .IP "\fB\--filter-buildhosts\fP"
+ This option includes packages which have a buildhost which matches one of the
+@@ -77,23 +77,23 @@ yum --filter-package-sizes=-1m check-update
+ .PP
+ To apply updates that Dan Walsh has committed use:
+ .IP
+-yum --filter-committers='Dan Walsh *' update
++yum --filter-committers=\(aqDan Walsh *\(aq update
+ .PP
+ To list updates for a specific group use:
+ .IP
+-yum --filter-rpm-groups='App*/Sys*' list updates
++yum --filter-rpm-groups=\(aqApp*/Sys*\(aq list updates
+ .PP
+ To apply updates to a specific set of groups use:
+ .IP
+-yum --filter-rpm-groups='App*/System,Devel*/Lib*,System Environment/Base' update
++yum --filter-rpm-groups=\(aqApp*/System,Devel*/Lib*,System Environment/Base\(aq update
+ .PP
+ To list updates for a set of yum groups use:
+ .IP
+-yum --filter-groups='PostgreSQL Database,Web Server' list updates
++yum --filter-groups=\(aqPostgreSQL Database,Web Server\(aq list updates
+ .PP
+ To apply updates to a specific set of yum groups use:
+ .IP
+-yum --filter-groups='KDE,Core,Printing Support' update
++yum --filter-groups=\(aqKDE,Core,Printing Support\(aq update
+ 
+ .SH "SEE ALSO"
+ .nf
+@@ -109,7 +109,7 @@ James Antill <james.antill at redhat.com>.
+ 
+ .SH "BUGS"
+ Currently yum can't filter packages in all of the commands, so for instance
+-"yum list 'yum*'" doesn't get the results filtered.
++"yum list \(aqyum*\(aq" doesn't get the results filtered.
+ 
+ Apart from that there are no bugs, but should you find any, you should first
+ consult the FAQ section on http://yum.baseurl.org/wiki/Faq and if unsuccessful
+diff --git a/docs/yum-groups-manager.1 b/docs/yum-groups-manager.1
+index f49bde9..c256c45 100644
+--- a/docs/yum-groups-manager.1
++++ b/docs/yum-groups-manager.1
+@@ -6,7 +6,7 @@ yum-groups-manager - create and edit yum's group metadata
+ \fByum-groups-manager\fP [options] [packages]
+ .SH "DESCRIPTION"
+ \fByum-groups-manager\fP is used to create or edit a group metadata file for a
+-yum repository. This is often much easier than writting/editing the XML by hand.
++yum repository. This is often much easier than writing/editing the XML by hand.
+ The \fByum-groups-manager\fP can load an entire file of groups metadata and
+ either create a new group or edit an existing group and then write all of the
+ groups metadata back out.
+@@ -43,7 +43,7 @@ Change the integer which controls the order groups are presented in, for example
+ in yum grouplist.
+ .IP "\fB\-\-load\fP"
+ Load the groups metadata information from the specified file, before
+-performing any operataions. This option can be specified multiple times.
++performing any operations. This option can be specified multiple times.
+ .IP "\fB\-\-save\fP"
+ Save the result to this file, you can specify the name of a file you are
+ loading from as the data will only be saved when all the operations have been
+@@ -77,11 +77,11 @@ in yum.
+ 
+ .SH "EXAMPLES"
+ .IP "Create a new group metadata file, with a group called yum containing all the packages that start with yum:"
+-\fB yum-groups-manager --name YUM --save groups.xml 'yum*'\fP
++\fB yum-groups-manager --name YUM --save groups.xml \(aqyum*\(aq\fP
+ .IP "After the above command, load the groups.xml data, work with the yum group, make the group not user visible, and remove the yum-skip-broken and yum-priorities packages from it:"
+ \fB yum-groups-manager -n YUM --merge groups.xml --remove yum-skip-broken yum-priorities --not-user-visible\fP
+ .IP "After the above commands, add a description and a translated name to the yum group:"
+-\fB yum-groups-manager -n YUM --merge groups.xml --description 'This is a group with most of the yum packages in it' --translated-name 'en:yum packages'\fP
++\fB yum-groups-manager -n YUM --merge groups.xml --description \(aqThis is a group with most of the yum packages in it\(aq --translated-name \(aqen:yum packages\(aq\fP
+ .SH "FILES"
+ \fByum-groups-manager\fP uses the yum libraries for retrieving information and
+ packages. If no configuration file is specified, the default yum
+@@ -103,7 +103,7 @@ See the Authors file included with this program.
+ .fi
+ .SH "BUGS"
+ .nf
+-There are a couple of options you can't set, yet. Most notabley you cannot put
++There are a couple of options you can't set, yet. Most notably you cannot put
+ package names into the conditional section (where they are installed with
+ groupinstall only if another package is installed).
+ 
+diff --git a/docs/yum-list-data.1 b/docs/yum-list-data.1
+index d855104..a5477d6 100644
+--- a/docs/yum-list-data.1
++++ b/docs/yum-list-data.1
+@@ -61,7 +61,7 @@ added yum \fIcommand\fPs are:
+ .PP 
+ all of which take the same arguments as the list and info yum commands. The
+ difference between the list and info varieties is that the info versions lists
+-all the packages under each agregation.
++all the packages under each aggregation.
+ .PP
+ .br 
+ .br 
+@@ -118,7 +118,7 @@ more than one group at a time.
+ .IP
+ .PP 
+ It is worth noting that some of the above data can be "unknown", to yum, at
+-which point a seperate aggregation called "-- Unknown --" is listed.
++which point a separate aggregation called "-- Unknown --" is listed.
+ .SH "EXAMPLES"
+ .PP
+ To list all the groups that have an update, along with the number of packages in each group, use:
+@@ -127,7 +127,7 @@ yum list-rpm-groups updates
+ .PP
+ To list all the committers to packages that have yum in their name, use:
+ .IP
+-yum list-committers 'yum*'
++yum list-committers \(aqyum*\(aq
+ .PP
+ To list ranges of the sizes of packages installed or available, use:
+ .IP
+diff --git a/docs/yum-security.8 b/docs/yum-security.8
+index 7e260b0..9c8dbf3 100644
+--- a/docs/yum-security.8
++++ b/docs/yum-security.8
+@@ -6,13 +6,13 @@ yum security plugin
+ \fByum\fP [options] [command] [package ...]
+ .SH "DESCRIPTION"
+ .PP 
+-This plugin extends \fByum\fP to allow lists and updates to be limited using security relevant criteria
++This plugin extends \fByum\fP to allow lists and updates to be limited using security relevant criteria.
+ .PP 
+-added yum \fIcommand\fPs are:
++Added yum \fIcommand\fPs are:
+ .br 
+ .I \fR yum update-minimal
+ .PP 
+-This works like the update command, but if you have the the package foo-1
++This works like the update command, but if you have the package foo-1
+ installed and have foo-2 and foo-3 available with updateinfo.xml then
+ update-minimal will update you to foo-3.
+ .br 
+@@ -22,7 +22,7 @@ update-minimal will update you to foo-3.
+ .br 
+ .I \fR yum updateinfo summary
+ .PP 
+-all of the last three take these \fIsub-command\fPs:
++All of the last three take these \fIsub-command\fPs:
+ .br 
+ .I \fR yum updateinfo * all
+ .br 
+@@ -109,7 +109,7 @@ distribution.
+ There are four options added to yum that are available in the "list updates", "info updates", "check-update" and "update" commands. They are:
+ .PP 
+ .IP "\fB\--advisory\fP"
+-This option includes packages coresponding to the advisory ID, Eg. FEDORA-2201-123.
++This option includes packages corresponding to the advisory ID, Eg. FEDORA-2201-123.
+ .IP "\fB\--bz\fP"
+ This option includes packages that say they fix a Bugzilla ID, Eg. 123.
+ .IP "\fB\--cve\fP"
+@@ -123,7 +123,7 @@ This option includes packages that say they fix a security issue.
+ 
+ .SH "EXAMPLES"
+ .PP
+-To list all updates that are security relevant, and get a reutrn code on whether there are security updates use:
++To list all updates that are security relevant, and get a return code on whether there are security updates use:
+ .IP
+ yum --security check-update
+ .PP
+@@ -141,7 +141,7 @@ To get a list of all BZs that are fixed for packages you have installed use:
+ .IP
+ yum updateinfo list bugzillas
+ .PP
+-To get a list of all security advisoryies, including the ones you have already
++To get a list of all security advisories, including the ones you have already
+ installed use:
+ .IP
+ yum updateinfo list all security
+@@ -185,6 +185,6 @@ James Antill <james.antill at redhat.com>.
+ .SH "BUGS"
+ The update-minimal command ignores the --obsoletes flag.
+ 
+-The update-minimal command can only directly affect things atm., so if you update pkgA minimally but that requires an update to pkgB then pkgB will be updated to the newest version by the depsolver. Also the above will happen even if you've also minimally updated pkgB, if either the direct (minimal) update for pkgB happens after or if the minimal update for pkgB doesn't satisy the requirements of pkgA.
++The update-minimal command can only directly affect things atm., so if you update pkgA minimally but that requires an update to pkgB then pkgB will be updated to the newest version by the depsolver. Also the above will happen even if you've also minimally updated pkgB, if either the direct (minimal) update for pkgB happens after or if the minimal update for pkgB doesn't satisfy the requirements of pkgA.
+ 
+ The main "problem" is that if the data is not correct the plugin cannot work correctly. For instance "--bz 123" will not fix BZ 123 if a package is updated to fix that BZ without referencing that it does so in the updateinfo.xml.
+diff --git a/docs/yum-verify.1 b/docs/yum-verify.1
+index 706c38e..50ede75 100644
+--- a/docs/yum-verify.1
++++ b/docs/yum-verify.1
+@@ -24,7 +24,7 @@ only verify packages that are installed on the system.
+ .br 
+ .PP 
+ .IP "\fBverify\fP"
+-Is the generic verification command, and is intented to give the most useful
++Is the generic verification command, and is intended to give the most useful
+ output. It removes all false matches due to multilib and ignores changes to
+ configuration files by default.
+ .IP
+@@ -53,15 +53,15 @@ yum verify-rpm
+ .PP
+ To verify the packages starting with the name yum, use:
+ .IP
+-yum verify 'yum*'
++yum verify \(aqyum*\(aq
+ .PP
+ To verify the binaries that are in a bin directory, use:
+ .IP
+-yum verify --verify-filenames='*bin/*'
++yum verify --verify-filenames=\(aq*bin/*\(aq
+ .PP
+ To verify all include files, Eg. for multilib problems, use:
+ .IP
+-yum verify-all --verify-filenames='/usr/include/*'
++yum verify-all --verify-filenames=\(aq/usr/include/*\(aq
+ 
+ .SH "SEE ALSO"
+ .nf
+@@ -77,7 +77,7 @@ James Antill <james.antill at redhat.com>.
+ 
+ .SH "BUGS"
+ .nf
+-Currently yum-verify does not do verify-script checking or dependancy checking,
++Currently yum-verify does not do verify-script checking or dependency checking,
+ only file checking.
+ 
+ Should you find any other bugs, you should first
+diff --git a/docs/yum-versionlock.1 b/docs/yum-versionlock.1
+index f68665e..ee5f053 100644
+--- a/docs/yum-versionlock.1
++++ b/docs/yum-versionlock.1
+@@ -67,7 +67,7 @@ Panu Matilainen <pmatilai at laiskiainen.org>
+ .br
+ James Antill <james at and.org>
+ .br
+-Documetation modified by:
++Documentation modified by:
+ .br
+ Gerhardus Geldenhuis <gerhardus.geldenhuis at gmail.com>
+ .SH "SEE ALSO"
+diff --git a/find-repos-of-install.py b/find-repos-of-install.py
+index 0578295..aac29ea 100644
+--- a/find-repos-of-install.py
++++ b/find-repos-of-install.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # copyright 2008 red hat, inc
+ 
+ import sys
+diff --git a/needs-restarting.py b/needs-restarting.py
+index 6bc883f..0b54e63 100755
+--- a/needs-restarting.py
++++ b/needs-restarting.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # Copyright 2009 Red Hat Inc
+ # written by Seth Vidal
+ 
+@@ -40,6 +40,7 @@
+ import sys
+ import os
+ import yum
++import yum.misc
+ import glob
+ import stat
+ from optparse import OptionParser
+@@ -82,12 +83,12 @@ def get_open_files(pid):
+         return files
+ 
+     for line in maps.readlines():
+-        if line.find('fd:') == -1:
++        slash = line.find('/')
++        if slash == -1 or line.find('00:') != -1: # if we don't have a '/' or if we fine 00: in the file then it's not _REALLY_ a file
+             continue
+         line = line.replace('\n', '')
+-        slash = line.find('/')
+         filename = line[slash:]
+-        filename = filename.replace('(deleted)', '') #only mildly retarded
++        #filename = filename.replace('(deleted)', '') #only mildly retarded
+         filename = filename.strip()
+         if filename not in files:
+             files.append(filename)
+@@ -106,7 +107,7 @@ def main(args):
+     if opts.useronly:
+         myuid = os.getuid()
+     
+-    needing_restart = []
++    needing_restart = set()
+ 
+     for pid in return_running_pids(uid=myuid):
+         try:
+@@ -117,12 +118,43 @@ def main(args):
+         for fn in get_open_files(pid):
+             if found_match:
+                 break
+-            
+-            for pkg in my.rpmdb.searchFiles(fn):
++            just_fn = fn.replace('(deleted)', '')
++            just_fn = just_fn.strip()            
++            bogon = False
++            # if the file is in a pkg which has been updated since we started the pid - then it needs to be restarted            
++            for pkg in my.rpmdb.searchFiles(just_fn):
+                 if float(pkg.installtime) > float(pid_start):
+-                    needing_restart.append(pid)
++                    needing_restart.add(pid)
+                     found_match = True
++                    continue
++                if just_fn in pkg.ghostlist:
++                    bogon = True
++                    break
++            
++            if bogon:
++                continue
+ 
++            # if the file is deleted 
++            if fn.find('(deleted)') != -1: 
++                # and it is from /*bin/* then it needs to be restarted 
++                if yum.misc.re_primary_filename(just_fn):
++                    needing_restart.add(pid)
++                    found_match = True
++                    continue
++
++                # if the file is from an old ver of an installed pkg - then assume it was just updated but the 
++                # new pkg doesn't have the same file names. Fabulous huh?!
++                my.conf.cache = False
++                for oldpkg in my.pkgSack.searchFiles(just_fn): # ghostfiles are always bogons
++                    if just_fn in oldpkg.ghostlist:
++                        continue
++                    if my.rpmdb.installed(oldpkg.name):
++                        needing_restart.add(pid)
++                        found_match = True
++                        break
++
++           
++            
+     for pid in needing_restart:
+         try:
+             cmdline = open('/proc/' +pid+ '/cmdline', 'r').read()
+diff --git a/package-cleanup.py b/package-cleanup.py
+index 4794369..aebae67 100755
+--- a/package-cleanup.py
++++ b/package-cleanup.py
+@@ -12,11 +12,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ #
+ #
+ 
+@@ -119,34 +119,6 @@ class PackageCleanup(YumUtilBase):
+                                  'removing kernels')
+         self.optparser.add_option_group(kernelgrp)
+     
+-    def _find_missing_deps(self, pkgs):
+-        """find any missing dependencies for any installed package in pkgs"""
+-        # XXX - move into rpmsack/rpmdb
+-        
+-        providers = {} # To speed depsolving, don't recheck deps that have 
+-                       # already been checked
+-        problems = []
+-        for po in pkgs:
+-            for (req,flags,ver)  in po.requires:
+-                    
+-                if req.startswith('rpmlib'): continue # ignore rpmlib deps
+-                if (req,flags,ver) not in providers:
+-                    resolve_sack = self.rpmdb.whatProvides(req,flags,ver)
+-                else:
+-                    resolve_sack = providers[(req,flags,ver)]
+-                    
+-                if len(resolve_sack) < 1:
+-                    flags = yum.depsolve.flags.get(flags, flags)
+-                    missing = miscutils.formatRequire(req,ver,flags)
+-                    problems.append((po, "requires %s" % missing))
+-                                    
+-                else:
+-                    # Store the resolve_sack so that we can re-use it if another
+-                    # package has the same requirement
+-                    providers[(req,flags,ver)] = resolve_sack
+-        
+-        return problems
+-
+     def _find_installed_duplicates(self, ignore_kernel=True):
+         """find installed duplicate packages returns a dict of 
+            pkgname = [[dupe1, dupe2], [dupe3, dupe4]] """
+@@ -282,12 +254,23 @@ class PackageCleanup(YumUtilBase):
+         else:
+             kver = runningkernel
+             krel = ""
+-        remove = kernels[count:]
++
++        #  This is roughly what we want, but when there are multiple packages
++        # we want to keep N of each.
++        # remove = kernels[count:]
++        kern_name_map = {}
++        for kern in kernels:
++            if kern.name not in kern_name_map:
++                kern_name_map[kern.name] = []
++            kern_name_map[kern.name].append(kern)
++        remove = []
++        for kern in kern_name_map.values():
++            remove.extend(kern[count:])
+         
+         toremove = []
+         # Remove running kernel from remove list
+         for kernel in remove:
+-            if kernel.version == kver and krel.startswith(kernel.release):
++            if kernel.version == kver and kernel.release == krel:
+                 print "Not removing kernel %s-%s because it is the running kernel" % (kver,krel)
+             else:
+                 toremove.append(kernel)
+@@ -314,9 +297,9 @@ class PackageCleanup(YumUtilBase):
+             self.setCacheDir()
+         
+         if opts.problems:
+-            issues = self._find_missing_deps(self.rpmdb.returnPackages())
+-            for (pkg, prob) in issues:
+-                print 'Package %s %s' % (pkg.hdr.sprintf(opts.qf), prob)
++            issues = self.rpmdb.check_dependencies()
++            for prob in issues:
++                print 'Package %s' % prob
+ 
+             if issues:
+                 sys.exit(1)
+diff --git a/plugins/auto-update-debuginfo/auto-update-debuginfo.py b/plugins/auto-update-debuginfo/auto-update-debuginfo.py
+index 39993ad..9ff927c 100644
+--- a/plugins/auto-update-debuginfo/auto-update-debuginfo.py
++++ b/plugins/auto-update-debuginfo/auto-update-debuginfo.py
+@@ -38,7 +38,7 @@ def _check_man_disable(mdrs, di):
+ def enable_debuginfo_repos(yb, conduit):
+     mdrs = set()
+     opts, args = conduit.getCmdLine()
+-    if opts is not None and hasattr(opts.repos) :
++    if hasattr(opts, 'repos'):
+         for opt, repoexp in opts.repos:
+             if opt == '--disablerepo':
+                 mdrs.add(repoexp)
+diff --git a/plugins/keys/keys.py b/plugins/keys/keys.py
+index 3342576..4d2ca96 100644
+--- a/plugins/keys/keys.py
++++ b/plugins/keys/keys.py
+@@ -31,6 +31,15 @@ except:
+ requires_api_version = '2.1'
+ plugin_type = (TYPE_INTERACTIVE,)
+ 
++def gpgkey_fingerprint_ascii(gpg_cert, chop=4):
++    ''' Given a key_info data from getgpgkeyinfo(), return an ascii
++    fingerprint. Chop every 4 ascii values, as that is what GPG does. '''
++    fp = yum.pgpmsg.str_to_hex(gpg_cert.public_key.fingerprint())
++    if chop:
++        fp = [fp[i:i+chop] for i in range(0, len(fp), chop)]
++        fp = " ".join(fp)
++    return fp
++
+ def match_keys(patterns, key, globs=True):
+     for pat in patterns:
+         if pat == key.keyid:
+@@ -250,7 +259,7 @@ Key ID     : %s
+        time.ctime(key.createts),
+        gpg_cert.version, gpg_cert.user_id,
+        yum.pgpmsg.algo_pk_to_str[gpg_cert.public_key.pk_algo],
+-       yum.pgpmsg.str_to_hex(gpg_cert.public_key.fingerprint()),
++       gpgkey_fingerprint_ascii(gpg_cert),
+        yum.pgpmsg.str_to_hex(gpg_cert.public_key.key_id()))
+ 
+ 
+diff --git a/plugins/priorities/priorities.py b/plugins/priorities/priorities.py
+index 202c203..0cdfae2 100644
+--- a/plugins/priorities/priorities.py
++++ b/plugins/priorities/priorities.py
+@@ -164,6 +164,10 @@ def exclude_hook(conduit):
+                                 break
+     if cnt:
+         conduit.info(2, '%d packages excluded due to repository priority protections' % cnt)
++    if check_obsoletes:
++        #  Atm. the update object doesn't get updated when we manually exclude
++        # things ... so delete it. This needs to be re-written.
++        conduit._base.up = None
+ 
+ def _pkglist_to_dict(pl, priority, addArch = False):
+     out = dict()
+diff --git a/repo-check.py b/repo-check.py
+index 7c4ae77..2aa8bde 100755
+--- a/repo-check.py
++++ b/repo-check.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import sys
+ sys.path.insert(0,'/usr/share/yum-cli')
+@@ -239,4 +239,4 @@ class RepoCheck(YumUtilBase):
+ if __name__ == '__main__':
+     setup_locale()
+     util = RepoCheck()
+-    
+\ No newline at end of file
++    
+diff --git a/repo-graph.py b/repo-graph.py
+index bb901a8..bca41d0 100755
+--- a/repo-graph.py
++++ b/repo-graph.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # (c) 2005 Panu Matilainen <pmatilai at laiskiainen.org>
+ 
+ # generates graphviz .dot's from repomd data
+diff --git a/repo-rss.py b/repo-rss.py
+index 4a2917c..f14ff2a 100755
+--- a/repo-rss.py
++++ b/repo-rss.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # seth vidal 2005 (c) etc etc
+ 
+ import yum
+diff --git a/repoclosure.py b/repoclosure.py
+index e710d8c..22efadc 100755
+--- a/repoclosure.py
++++ b/repoclosure.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # seth vidal 2005 (c) etc etc
+ 
+ 
+diff --git a/repodiff.py b/repodiff.py
+index 67c162e..e504e0f 100755
+--- a/repodiff.py
++++ b/repodiff.py
+@@ -10,8 +10,8 @@
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # (c) 2007 Red Hat. Written by skvidal at fedoraproject.org
+ 
+ import yum
+@@ -22,8 +22,16 @@ import locale
+ import rpmUtils.arch
+ from yum.i18n import to_unicode
+ 
++from urlgrabber.progress import format_number
++
+ from optparse import OptionParser
+ 
++def bkMG(num):
++    ''' Call format_number() but deals with negative numbers. '''
++    if num >= 0:
++        return format_number(num)
++    return '-' + format_number(-num)
++
+ class DiffYum(yum.YumBase):
+     def __init__(self):
+         yum.YumBase.__init__(self)
+@@ -43,7 +51,10 @@ class DiffYum(yum.YumBase):
+         # make our new repo obj
+         newrepo = yum.yumRepo.YumRepository(repoid)
+         newrepo.name = repoid
+-        newrepo.baseurl = [baseurl]
++        if baseurl.startswith("mirror:"):
++            newrepo.mirrorlist = baseurl[len("mirror:"):]
++        else:
++            newrepo.baseurl = [baseurl]
+         newrepo.basecachedir = self.dy_basecachedir
+         newrepo.metadata_expire = 0
+         newrepo.timestamp_check = False
+@@ -157,6 +168,8 @@ def parseArgs(args):
+                       help="When comparing binary repos. also compare the arch of packages, to see if they are different")
+     parser.add_option("-s", "--size", default=False, action='store_true',
+                       help="Output size changes for any new->old packages")
++    parser.add_option("--downgrade", default=False, action='store_true',
++                      help="Output upgrade/downgrade separately")
+     parser.add_option("--simple",  default=False, action='store_true',
+                       help="output simple format")
+     (opts, argsleft) = parser.parse_args()
+@@ -177,6 +190,47 @@ def parseArgs(args):
+     
+     return opts
+ 
++def _out_mod(opts, oldpkg, pkg, sizechange):
++    if opts.simple:
++        if opts.compare_arch:
++            msg = "%s: %s ->  %s" % (pkg.name, oldpkg, pkg)
++        else:
++            msg = "%s: %s-%s-%s ->  %s-%s-%s" % (pkg.name, oldpkg.name, 
++                                                 oldpkg.ver, oldpkg.rel,
++                                                 pkg.name, pkg.ver,
++                                                 pkg.rel)
++    else:
++        if opts.compare_arch:
++            msg = "%s" % pkg
++        else:
++            msg = "%s-%s-%s" % (pkg.name, pkg.ver, pkg.rel)
++        dashes = "-" * len(msg) 
++        msg += "\n%s\n" % dashes
++        # get newest clog time from the oldpkg
++        # for any newer clog in pkg
++        # print it
++        oldlogs = oldpkg.changelog
++        if len(oldlogs):
++            #  Don't sort as that can screw the order up when time is the
++            # same.
++            oldtime    = oldlogs[0][0]
++            oldauth    = oldlogs[0][1]
++            oldcontent = oldlogs[0][2]
++            for (t, author, content) in  pkg.changelog:
++                if t < oldtime:
++                    break
++                if ((t == oldtime) and (author == oldauth) and
++                    (content == oldcontent)):
++                    break
++                tm = datetime.date.fromtimestamp(int(t))
++                tm = tm.strftime("%a %b %d %Y")
++                msg += "* %s %s\n%s\n\n" % (tm, to_unicode(author),
++                                            to_unicode(content))
++            if opts.size:
++                msg += "\nSize change: %s bytes\n" % sizechange
++
++    print msg
++
+ def main(args):
+     opts = parseArgs(args)
+ 
+@@ -221,6 +275,11 @@ def main(args):
+     total_sizechange = 0
+     add_sizechange = 0
+     remove_sizechange = 0
++    mod_sizechange = 0
++    up_sizechange = 0
++    down_sizechange = 0
++    upgraded_pkgs = 0
++    downgraded_pkgs = 0
+     if ygh.add:
+         for pkg in sorted(ygh.add):
+             if opts.compare_arch:
+@@ -243,49 +302,32 @@ def main(args):
+     if ygh.modified:
+         print '\nUpdated Packages:\n'
+         for (pkg, oldpkg) in sorted(ygh.modified):
++            if opts.downgrade and pkg.verLT(oldpkg):
++                continue
++
++            upgraded_pkgs += 1
++            sizechange = None
+             if opts.size:
+                 sizechange = int(pkg.size) - int(oldpkg.size)
+-                total_sizechange += sizechange
+-            
+-            if opts.simple:
+-                if opts.compare_arch:
+-                    msg = "%s: %s ->  %s" % (pkg.name, oldpkg, pkg)
+-                else:
+-                    msg = "%s: %s-%s-%s ->  %s-%s-%s" % (pkg.name, oldpkg.name, 
+-                                                         oldpkg.ver, oldpkg.rel,
+-                                                         pkg.name, pkg.ver,
+-                                                         pkg.rel)
+-            else:
+-                if opts.compare_arch:
+-                    msg = "%s" % pkg
++                if opts.downgrade:
++                    up_sizechange += sizechange
+                 else:
+-                    msg = "%s-%s-%s" % (pkg.name, pkg.ver, pkg.rel)
+-                dashes = "-" * len(msg) 
+-                msg += "\n%s\n" % dashes
+-                # get newest clog time from the oldpkg
+-                # for any newer clog in pkg
+-                # print it
+-                oldlogs = oldpkg.changelog
+-                if len(oldlogs):
+-                    #  Don't sort as that can screw the order up when time is the
+-                    # same.
+-                    oldtime    = oldlogs[0][0]
+-                    oldauth    = oldlogs[0][1]
+-                    oldcontent = oldlogs[0][2]
+-                    for (t, author, content) in  pkg.changelog:
+-                        if t < oldtime:
+-                            break
+-                        if ((t == oldtime) and (author == oldauth) and
+-                            (content == oldcontent)):
+-                            break
+-                        tm = datetime.date.fromtimestamp(int(t))
+-                        tm = tm.strftime("%a %b %d %Y")
+-                        msg += "* %s %s\n%s\n\n" % (tm, to_unicode(author),
+-                                                    to_unicode(content))
+-                    if opts.size:
+-                        msg += "\nSize Change: %s bytes\n" % sizechange
+-
+-            print msg
++                    mod_sizechange += sizechange
++            _out_mod(opts, oldpkg, pkg, sizechange)
++
++        if opts.downgrade:
++            print '\nDowngraded Packages:\n'
++            for (pkg, oldpkg) in sorted(ygh.modified):
++                if pkg.verGT(oldpkg):
++                    continue
++
++                downgraded_pkgs += 1
++                sizechange = None
++                if opts.size:
++                    sizechange = int(pkg.size) - int(oldpkg.size)
++                    down_sizechange += sizechange
++                _out_mod(opts, oldpkg, pkg, sizechange)
++
+ 
+     if (not ygh.add and not ygh.remove and not ygh.modified and
+         not my.pkgSack.searchNevra(arch='src')):
+@@ -294,11 +336,33 @@ def main(args):
+     print '\nSummary:'
+     print 'Added Packages: %s' % len(ygh.add)
+     print 'Removed Packages: %s' % len(ygh.remove)
+-    print 'Modified Packages: %s' % len(ygh.modified)
++    if not opts.downgrade:
++        print 'Upgraded Packages: %s' % upgraded_pkgs
++    else:
++        print 'Downgraded Packages: %s' % downgraded_pkgs
+     if opts.size:
+-        print 'Size of added packages: %s' % add_sizechange
+-        print 'Size change of modified packages: %s' % total_sizechange
+-        print 'Size of removed packages: %s' % remove_sizechange
++        print 'Size of added packages: %s (%s)' % (add_sizechange,
++                                                   bkMG(add_sizechange))
++
++        if not opts.downgrade:
++            msg = 'Size change of modified packages: %s (%s)'
++            print msg % (mod_sizechange, bkMG(mod_sizechange))
++
++            total_sizechange = add_sizechange +mod_sizechange -remove_sizechange
++        else:
++            msg = 'Size change of upgraded packages: %s (%s)'
++            print msg % (up_sizechange, bkMG(up_sizechange))
++            msg = 'Size change of downgraded packages: %s (%s)'
++            print msg % (down_sizechange, bkMG(down_sizechange))
++
++            total_sizechange = (add_sizechange +
++                                up_sizechange + down_sizechange -
++                                remove_sizechange)
++
++        msg = 'Size of removed packages: %s (%s)'
++        print msg % (remove_sizechange, bkMG(remove_sizechange))
++        msg = 'Size change: %s (%s)'
++        print msg % (total_sizechange, bkMG(total_sizechange))
+     
+       
+ if __name__ == "__main__":
+diff --git a/repomanage.py b/repomanage.py
+index ff77e0d..bef3b03 100755
+--- a/repomanage.py
++++ b/repomanage.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ # (c) Copyright Seth Vidal 2004
+ 
+diff --git a/repoquery.py b/repoquery.py
+index a3bb111..7660789 100755
+--- a/repoquery.py
++++ b/repoquery.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # (c) pmatilai at laiskiainen.org
+ 
+ 
+@@ -74,6 +74,15 @@ querytags = [ 'name', 'version', 'release', 'epoch', 'arch', 'summary',
+               'installedsize', 'archivesize', 'packagesize', 'repoid', 
+               'requires', 'provides', 'conflicts', 'obsoletes',
+               'relativepath', 'hdrstart', 'hdrend', 'id',
++              'checksum', 'pkgid', 'committer', 'committime',
++              'ui_evr', 'evr', 'ui_nevra', 'ui_envra',
++              'ui_from_repo', 'base_package_name', 'size', 'xattr_origin_url',
++              'ui_evra', 'ui_nevr', 'na', 'vr', 'vra', 'evr', 'evra',
++              'nvr', 'nvra', 'nevr', 'nevra', 'envr', 'envra',
++
++              'repo.<attr of the repo object>',
++              'yumdb.<attr of the yumdb object>',
++              '<attr of the yum object>'
+             ]
+ 
+ def sec2isodate(timestr):
+@@ -316,12 +325,13 @@ class pkgQuery:
+         print "%s%s [%s]" % (indent, str(req), str(val))
+ 
+     # These are common helpers for the --tree-* options...
+-    @staticmethod
+-    def _tree_print_req(req, val, level):
++    def _tree_print_req(self, req, val, level):
+         indent = ''
+         if level:
+             indent = ' |  ' * (level - 1) + ' \_  '
+-        print "%s%s [%s]" % (indent, str(req), str(val))
++        self.pkg = req
++        self.name = req.name
++        print "%s%s [%s]" % (indent, self.fmt_queryformat(), str(val))
+     def _tree_pkg2uniq(self, pkg):
+         """ Turn a pkg into a "unique" req."""
+         if self.yb and self.yb.conf.showdupesfromrepos:
+@@ -365,6 +375,7 @@ class pkgQuery:
+                 kw['dot'] = DotPlot()
+         elif 'dot' not in kw.keys() or kw['dot'] is None:
+             kw['dot'] = None
++        dot      = kw['dot']
+         
+         if str(kw['tree_level']).lower() != 'all':
+             try: 
+@@ -375,6 +386,15 @@ class pkgQuery:
+         if not 'output' in kw.keys():
+             kw['output'] = 'ascii-tree'
+ 
++        #  Level means something a bit different for dot, because we have to
++        # lookup it's packages ... but we don't for ascii. *sigh*
++        if dot is None:
++            self._tree_print_req(pkg, req, level)
++            lim = level + 1
++            if str(kw['tree_level']).lower() != 'all' and \
++                int(kw['tree_level']) < int(lim):
++                return
++
+         __req2pkgs = {}
+         def req2pkgs(ignore, req):
+             req = str(req)
+@@ -413,14 +433,9 @@ class pkgQuery:
+             __req2pkgs[req] = providers
+             return providers 
+         
+-        dot = kw['dot']
+-        
+         tups = getattr(pkg, prco_type)
+         rpkgs, loc_reqs = self._tree_maybe_add_pkgs(all_reqs, tups, req2pkgs)
+-        if dot is None:
+-            self._tree_print_req(pkg, req, level)
+-            lim = level + 1
+-        else:
++        if dot is not None:
+             dot.addPackage(pkg, rpkgs)
+             lim = level + 2
+         nlevel = level + 1
+@@ -449,6 +464,7 @@ class pkgQuery:
+ 
+     def fmt_tree_obsoletes(self, **kw):
+         pkg      = kw.get('pkg', self.pkg)
++        req      = kw.get('req', 'cmd line')
+         level    = kw.get('level', 0)
+         all_reqs = kw.get('all_reqs', {})
+         
+@@ -457,6 +473,7 @@ class pkgQuery:
+                 kw['dot'] = DotPlot()
+         elif 'dot' not in kw.keys() or kw['dot'] is None:
+             kw['dot'] = None
++        dot      = kw['dot']
+         
+         if str(kw['tree_level']).lower() != 'all':
+             try: 
+@@ -467,6 +484,15 @@ class pkgQuery:
+         if not 'output' in kw.keys():
+             kw['output'] = 'ascii-tree'
+         
++        #  Level means something a bit different for dot, because we have to
++        # lookup it's packages ... but we don't for ascii. *sigh*
++        if dot is None:
++            self._tree_print_req(pkg, req, level)
++            lim = level + 1
++            if str(kw['tree_level']).lower() != 'all' and \
++                int(kw['tree_level']) < int(lim):
++                return
++
+         def obs2pkgs():
+             if self.yb is None:
+                 return []
+@@ -496,10 +522,7 @@ class pkgQuery:
+         else:
+             reason = 'cmd line'
+         rpkgs = obs2pkgs()
+-        if dot is None:
+-            self._tree_print_req(pkg, reason, level)
+-            lim = level + 1
+-        else:
++        if dot is not None:
+             dot.addPackage(pkg, rpkgs)
+             lim = level + 2
+         all_reqs[pkg] = None
+@@ -514,6 +537,7 @@ class pkgQuery:
+                 self._tree_print_req(rpkg, '', nlevel)
+                 continue
+             self.fmt_tree_obsoletes(pkg=rpkg, level=nlevel, all_reqs=all_reqs,
++                                    req = pkg.name,
+                                     tree_level = kw['tree_level'],
+                                     output = kw['output'],
+                                     dot = dot)
+@@ -527,6 +551,7 @@ class pkgQuery:
+         if kw['output'].lower() == 'dot-tree':
+             if 'dot' not in kw.keys() or kw['dot'] is None:
+                 kw['dot'] = DotPlot()
++        dot      = kw['dot']
+ 
+         if str(kw['tree_level']).lower() != 'all':
+             try: 
+@@ -537,6 +562,15 @@ class pkgQuery:
+         if not 'output' in kw.keys():
+             kw['output'] = 'ascii-tree'
+ 
++        #  Level means something a bit different for dot, because we have to
++        # lookup it's packages ... but we don't for ascii. *sigh*
++        if dot is None:
++            self._tree_print_req(pkg, req, level)
++            lim = level + 1
++            if str(kw['tree_level']).lower() != 'all' and \
++                int(kw['tree_level']) < int(lim):
++                return
++
+         __prov2pkgs = {}
+         def prov2pkgs(prov, ignore):
+             if str(prov) in __prov2pkgs:
+@@ -575,12 +609,8 @@ class pkgQuery:
+         
+         tups = pkg.provides + filetupes
+         rpkgs, loc_reqs = self._tree_maybe_add_pkgs(all_reqs, tups, prov2pkgs)
+-        dot = kw['dot']
+         
+-        if dot is None:
+-            self._tree_print_req(pkg, req, level)
+-            lim = level + 1
+-        else:
++        if dot is not None:
+             dot.addPackage(pkg, rpkgs)
+             lim = level + 2
+         nlevel = level + 1
+@@ -719,13 +749,13 @@ class groupQuery:
+             raise queryError("Invalid group query: %s" % method)
+ 
+     # XXX temporary hack to make --group -a query work
+-    def fmt_queryformat(self):
++    def fmt_queryformat(self, **kw):
+         return self.fmt_nevra()
+ 
+-    def fmt_nevra(self):
++    def fmt_nevra(self, **kw):
+         return ["%s - %s" % (self.id, self.name)]
+ 
+-    def fmt_list(self):
++    def fmt_list(self, **kw):
+         pkgs = []
+         for t in self.grouppkgs.split(','):
+             if t == "mandatory":
+@@ -741,10 +771,10 @@ class groupQuery:
+             
+         return pkgs
+         
+-    def fmt_requires(self):
++    def fmt_requires(self, **kw):
+         return self.group.mandatory_packages
+ 
+-    def fmt_info(self):
++    def fmt_info(self, **kw):
+         return ["%s:\n\n%s\n" % (self.name, self.group.description)]
+ 
+ 
+@@ -1008,12 +1038,12 @@ class YumBaseQuery(yum.YumBase):
+ 
+     def fmt_whatrequires(self, name, **kw):
+         pkgs = {}
+-        done = [] # keep track of names we have already visited
++        done = set() # keep track of names we have already visited
+ 
+         def require_recursive(name):
+             if name in done:
+                 return
+-            done.append(name)
++            done.add(name)
+ 
+             provs = [name]
+                     
+@@ -1054,10 +1084,21 @@ class YumBaseQuery(yum.YumBase):
+ 
+     def fmt_requires(self, name, **kw):
+         pkgs = {}
+-        for pkg in self.returnByName(name):
++        done = set()
++        def require_recursive(pkg):
++            if pkg.name in done:
++                return
++            done.add(pkg.name)
++
+             for req in pkg.prco("requires"):
+                 for res in self.fmt_whatprovides(req):
+                     pkgs[(res.name, res.pkg.arch)] = res
++                    if self.options.recursive:
++                        require_recursive(res)
++
++        for pkg in self.returnByName(name):
++            require_recursive(pkg)
++
+         return pkgs.values()
+ 
+     def fmt_location(self, name):
+@@ -1070,6 +1111,44 @@ class YumBaseQuery(yum.YumBase):
+                 loc.append("%s/%s" % (repo.urls[0], pkg['relativepath']))
+         return loc
+ 
++    def _parseSetOpts(self, setopts):
++        """parse the setopts list handed to us and saves the results as
++           repo_setopts and main_setopts in the yumbase object"""
++
++        repoopts = {}
++        mainopts = yum.misc.GenericHolder()
++        mainopts.items = []
++
++        bad_setopt_tm = []
++        bad_setopt_ne = []
++
++        for item in setopts:
++            vals = item.split('=')
++            if len(vals) > 2:
++                bad_setopt_tm.append(item)
++                continue
++            if len(vals) < 2:
++                bad_setopt_ne.append(item)
++                continue
++            k,v = vals
++            period = k.find('.')
++            if period != -1:
++                repo = k[:period]
++                k = k[period+1:]
++                if repo not in repoopts:
++                    repoopts[repo] = yum.misc.GenericHolder()
++                    repoopts[repo].items = []
++                setattr(repoopts[repo], k, v)
++                repoopts[repo].items.append(k)
++            else:
++                setattr(mainopts, k, v)
++                mainopts.items.append(k)
++
++        self.main_setopts = mainopts
++        self.repo_setopts = repoopts
++
++        return bad_setopt_tm, bad_setopt_ne
++
+ 
+ def main(args):
+ 
+@@ -1198,6 +1277,9 @@ def main(args):
+     parser.add_option("--search-fields", action="append", dest="searchfields",
+                       default=[],
+                       help="search fields to search using --search")
++    parser.add_option("", "--setopt", dest="setopts", default=[],
++                     action="append",
++                     help="set arbitrary config and repo options")
+                       
+ 
+     (opts, regexs) = parser.parse_args()
+@@ -1261,9 +1343,10 @@ def main(args):
+     if opts.srpm:
+         needsource = 1
+     if opts.whatrequires:
+-        sackops.append("whatrequires")
+         if opts.output != 'text':
+             pkgops.append("tree_what_requires")
++        else:
++            sackops.append("whatrequires")
+     if opts.whatprovides:
+         sackops.append("whatprovides")
+     if opts.whatobsoletes:
+@@ -1303,6 +1386,13 @@ def main(args):
+         
+     repoq = YumBaseQuery(pkgops, sackops, opts)
+ 
++    # go through all the setopts and set the global ones
++    bad_setopt_tm, bad_setopt_ne = repoq._parseSetOpts(opts.setopts)
++
++    if repoq.main_setopts:
++        for opt in repoq.main_setopts.items:
++            setattr(opts, opt, getattr(repoq.main_setopts, opt))
++
+     # silence initialisation junk from modules etc unless verbose mode
+     initnoise = (not opts.quiet) * 2
+     repoq.preconf.releasever = opts.releasever
+@@ -1314,6 +1404,20 @@ def main(args):
+     repoq.preconf.init_plugins = opts.plugins
+     repoq.conf
+ 
++    for item in  bad_setopt_tm:
++        msg = "Setopt argument has multiple values: %s"
++        repoq.logger.warning(msg % item)
++    for item in  bad_setopt_ne:
++        msg = "Setopt argument has no value: %s"
++        repoq.logger.warning(msg % item)
++    # now set  all the non-first-start opts from main from our setopts
++    if repoq.main_setopts:
++        for opt in repoq.main_setopts.items:
++            if not hasattr(repoq.conf, opt):
++                msg ="Main config did not have a %s attr. before setopt"
++                repoq.logger.warning(msg % opt)
++            setattr(repoq.conf, opt, getattr(repoq.main_setopts, opt))
++
+     if opts.repofrompath:
+         # setup the fake repos
+         for repo in opts.repofrompath:
+diff --git a/reposync.py b/reposync.py
+index 7950854..fb2c592 100755
+--- a/reposync.py
++++ b/reposync.py
+@@ -11,8 +11,8 @@
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # copyright 2006 Duke University
+ # author seth vidal
+ 
+@@ -96,7 +96,7 @@ def parseArgs():
+     parser.add_option("-c", "--config", default='/etc/yum.conf',
+         help='config file to use (defaults to /etc/yum.conf)')
+     parser.add_option("-a", "--arch", default=None,
+-        help='act as if running the specified arch (default: current arch, note: does not override $releasever)')
++        help='act as if running the specified arch (default: current arch, note: does not override $releasever. x86_64 is a superset for i*86.)')
+     parser.add_option("--source", default=False, dest="source", action="store_true",
+                       help='operate on source packages')
+     parser.add_option("-r", "--repoid", default=[], action='append',
+@@ -162,6 +162,12 @@ def main():
+     elif opts.cachedir:
+         my.repos.setCacheDir(opts.cachedir)
+ 
++    #  Use progress bar display when downloading repo metadata
++    # and package files ... needs to be setup before .repos (ie. RHN/etc.).
++    if not opts.quiet:
++        my.repos.setProgressBar(TextMeter(fo=sys.stdout))
++    my.doRepoSetup()
++
+     if len(opts.repoid) > 0:
+         myrepos = []
+         
+@@ -182,13 +188,6 @@ def main():
+         print >> sys.stderr, "Error: Can't use --norepopath with multiple repositories"
+         sys.exit(1)
+ 
+-    # Use progress bar display when downloading repo metadata
+-    # and package files
+-    if not opts.quiet:
+-        my.repos.setProgressBar(TextMeter(fo=sys.stdout))
+-
+-    my.doRpmDBSetup()
+-    my.doRepoSetup()
+     try:
+         arches = rpmUtils.arch.getArchList(opts.arch)
+         if opts.source:
+@@ -278,6 +277,7 @@ def main():
+ 
+         download_list.sort(sortPkgObj)
+         n = 0
++        exit_code = 0
+         for pkg in download_list:
+             n = n + 1
+             repo = my.repos.getRepo(pkg.repoid)
+@@ -323,6 +323,7 @@ def main():
+             except yum.Errors.RepoError, e:
+                 my.logger.error("Could not retrieve package %s. Error was %s" % (pkg, str(e)))
+                 local_size += sz
++                exit_code = 1
+                 continue
+ 
+             local_size += sz
+@@ -338,12 +339,14 @@ def main():
+                     else:
+                         my.logger.warning('Removing %s due to failed signature check: %s' % (os.path.basename(remote), error))
+                     os.unlink(path)
++                    exit_code = 1
+                     continue
+ 
+             if not os.path.exists(local) or not os.path.samefile(path, local):
+                 shutil.copy2(path, local)
+ 
+     my.closeRpmDB()
++    sys.exit(exit_code)
+ 
+ if __name__ == "__main__":
+     main()
+diff --git a/repotrack.py b/repotrack.py
+index ed26b9f..6c6a18c 100755
+--- a/repotrack.py
++++ b/repotrack.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # (c) 2005 seth vidal skvidal at phy.duke.edu
+ 
+ 
+diff --git a/show-changed-rco.py b/show-changed-rco.py
+index 3489247..fca53cc 100755
+--- a/show-changed-rco.py
++++ b/show-changed-rco.py
+@@ -10,11 +10,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import yum
+ 
+diff --git a/verifytree.py b/verifytree.py
+index d1fe5e2..cb89285 100755
+--- a/verifytree.py
++++ b/verifytree.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # copyright (c) 2008 Red Hat, Inc - written by Seth Vidal and Will Woods
+ 
+ import yum
+diff --git a/yum-builddep.py b/yum-builddep.py
+index d7a37c3..f67c810 100755
+--- a/yum-builddep.py
++++ b/yum-builddep.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import sys
+ sys.path.insert(0,'/usr/share/yum-cli')
+@@ -26,6 +26,8 @@ import logging
+ import rpmUtils
+ import rpm
+ 
++rhn_source_repos = False
++
+ # Copied from yumdownloader (need a yum-utils python module ;)
+ # This is to fix Bug 469
+ # To convert from a pkg to a source pkg, we have a problem in that all we have
+@@ -61,6 +63,9 @@ class YumBuildDep(YumUtilBase):
+         self.logger = logging.getLogger("yum.verbose.cli.yumbuildep")                             
+         # Add util commandline options to the yum-cli ones
+         self.optparser = self.getOptionParser() 
++        if hasattr(rpm, 'reloadConfig'):
++            self.optparser.add_option("--target",
++                              help="set target architecture for spec parsing")
+         self.main()
+ 
+     def main(self):
+@@ -118,9 +123,16 @@ class YumBuildDep(YumUtilBase):
+         # enable the -source repos for enabled primary repos
+         archlist = rpmUtils.arch.getArchList() + ['src']    
+         for repo in self.repos.listEnabled():
+-            if not repo.id.endswith('-source'):
++            issource_repo = repo.id.endswith('-source')
++            if rhn_source_repos and repo.id.endswith('-source-rpms'):
++                issource_repo = True
++            if rhn_source_repos and (not repo.id.endswith('-source-rpms') and
++                                     repo.id.endswith('-rpms')):
++                srcrepo = '%s-source,%s-source-rpms' % (repo.id, repo.id[:-5])
++            elif not issource_repo:
+                 srcrepo = '%s-source' % repo.id
+             else:
++                # Need to change the arch.
+                 repo.close()
+                 self.repos.disableRepo(repo.id)
+                 srcrepo = repo.id
+@@ -170,10 +182,14 @@ class YumBuildDep(YumUtilBase):
+         specnames = []
+         srpms = []
+         specworks = False
++        reloadworks = False
+ 
+         # See if we can use spec files for buildrequires
+         if hasattr(rpm, 'spec') and hasattr(rpm.spec, 'sourceHeader'):
+             specworks = True
++        # See if we can reload rpm configuration
++        if hasattr(rpm, 'reloadConfig'):
++            reloadworks = True
+ 
+         for arg in self.cmds:
+             if arg.endswith('.src.rpm'):
+@@ -216,12 +232,20 @@ class YumBuildDep(YumUtilBase):
+             self.install_deps(srpm.requiresList())
+     
+         for name in specnames:
++            # (re)load rpm config for target if set
++            if reloadworks and opts.target:
++                rpm.reloadConfig(opts.target)
++
+             try:
+                 spec = rpm.spec(name)
+             except ValueError:
+                 self.logger.error("Bad spec: %s" % name)
+                 continue
+ 
++            # reset default rpm config after each parse to avoid side-effects
++            if reloadworks:
++                rpm.reloadConfig()
++
+             buildreqs = []
+             for d in rpm.ds(spec.sourceHeader, 'requires'):
+                 buildreqs.append(d.DNEVR()[2:])
+diff --git a/yum-complete-transaction.py b/yum-complete-transaction.py
+index c5074ab..66c4504 100755
+--- a/yum-complete-transaction.py
++++ b/yum-complete-transaction.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import sys
+ sys.path.insert(0,'/usr/share/yum-cli')
+diff --git a/yum-debug-dump.py b/yum-debug-dump.py
+index 4653f3c..67d943f 100755
+--- a/yum-debug-dump.py
++++ b/yum-debug-dump.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ ## (c) 2008 Red Hat. Written by skvidal at fedoraproject.org
+ 
+ import os
+diff --git a/yum-debug-restore.py b/yum-debug-restore.py
+index fd95741..1e2a659 100755
+--- a/yum-debug-restore.py
++++ b/yum-debug-restore.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ ## (c) 2008 Red Hat. Written by skvidal at fedoraproject.org
+ ##                                james at fedoraproject.org
+ 
+@@ -107,11 +107,15 @@ def pkg_data2list(yb, opkgtups, opkgmaps, install_latest, ignore_arch):
+     ret = []
+     npkgtups = set()
+     npkgmaps = {}
++    installonly = set(yb.conf.installonlypkgs)
+     for po in sorted(yb.rpmdb.returnPackages()):
+         arch = po.arch
+         if ignore_arch:
+             arch = None
+         if False: pass
++        elif po.name in installonly:
++            if not po.pkgtup in opkgtups:
++                ret.append(("remove", pkgtup2str(po.pkgtup)))
+         elif (po.name, arch) not in opkgmaps:
+             ret.append(("remove", str(po)))
+         elif po.pkgtup not in opkgtups:
+@@ -129,6 +133,8 @@ def pkg_data2list(yb, opkgtups, opkgmaps, install_latest, ignore_arch):
+             npkgmaps[(po.name, None)] = po
+ 
+     for name, arch in sorted(opkgmaps):
++        if name in installonly:
++            continue # done separately
+         if ignore_arch and arch is not None:
+             continue
+         if (name, arch) in npkgmaps:
+@@ -139,6 +145,9 @@ def pkg_data2list(yb, opkgtups, opkgmaps, install_latest, ignore_arch):
+             ret.append(("install", "%s.%s" % (name, arch)))
+         else:
+             ret.append(("install", pkgtup2str(opkgmaps[(name, arch)])))
++    for pkgtup in opkgtups:
++        if pkgtup[0] in installonly and not pkgtup in npkgtups:
++            ret.append(("install", pkgtup2str(pkgtup)))
+     return ret
+ 
+ def main():
+diff --git a/yum-util-cli-template b/yum-util-cli-template
+index 8bfdbcd..250ebc9 100644
+--- a/yum-util-cli-template
++++ b/yum-util-cli-template
+@@ -7,7 +7,7 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+diff --git a/yum-utils.bash b/yum-utils.bash
+index 1d37231..20e8e5c 100644
+--- a/yum-utils.bash
++++ b/yum-utils.bash
+@@ -100,7 +100,7 @@ _yu_repo_graph()
+             return 0
+             ;;
+         --repoid)
+-            _yum_repolist all "$cur" 2>/dev/null
++            _yum_helper repolist all "$cur" 2>/dev/null
+             return 0
+             ;;
+         -c)
+@@ -136,7 +136,7 @@ _yu_repo_rss()
+ 
+     COMPREPLY=( $( compgen -W '--help -f -l -t -d -r --tempcache -g -a -c' \
+         -- "$2" ) )
+-    [[ $2 == -* ]] || _yum_repolist all "$2" 2>/dev/null || return 0
++    [[ $2 == -* ]] || _yum_helper repolist all "$2" 2>/dev/null || return 0
+ } &&
+ complete -F _yu_repo_rss -o filenames repo-rss repo-rss.py
+ 
+@@ -155,7 +155,7 @@ _yu_repoclosure()
+             return 0
+             ;;
+         -l|--lookaside|-r|--repoid)
+-            _yum_repolist all "$cur" 2>/dev/null
++            _yum_helper repolist all "$cur" 2>/dev/null
+             return 0
+             ;;
+         -p|--pkg)
+@@ -163,7 +163,7 @@ _yu_repoclosure()
+             return 0
+             ;;
+         -g|--group)
+-            _yum_grouplist "" "$cur" 2>/dev/null
++            _yum_helper groups list all "$cur" 2>/dev/null
+             return 0
+             ;;
+     esac
+@@ -188,26 +188,23 @@ _yu_repoquery()
+     done
+ 
+     case $prev in
+-        -h|--help|--version|-f|--file|--qf|--queryformat|--resolve|--archlist|\
+-        --whatprovides|--whatrequires|--whatobsoletes|--whatconflicts|\
+-        --repofrompath|--level|--search-fields)
++        -h|--help|--version|--qf|--queryformat|--archlist|--repofrompath|\
++        --setopt)
++            return 0
++            ;;
++        -f|--file)
++            COMPREPLY=( $( compgen -f -o plusdirs -- "$cur" ) )
+             return 0
+             ;;
+         -l|--list|-i|--info|-R|--requires)
+             if $groupmode ; then
+-                _yum_grouplist "" "$cur" 2>/dev/null
++                _yum_helper groups list all "$cur" 2>/dev/null
+             else
+                 declare -F _yum_atgroups &>/dev/null && \
+                     _yum_atgroups "$cur" || _yum_list all "$cur" 2>/dev/null
+             fi
+             return 0
+             ;;
+-        --provides|--obsoletes|--conflicts|--groupmember|--changelog|\
+-        --location|--nevra|--envra|--nvr|-s|--source)
+-            declare -F _yum_atgroups &>/dev/null && \
+-                _yum_atgroups "$cur" || _yum_list all "$cur" 2>/dev/null
+-            return 0
+-            ;;
+         --grouppkgs)
+             COMPREPLY=( $( compgen -W 'all default optional mandatory' \
+                 -- "$cur" ) )
+@@ -219,38 +216,52 @@ _yu_repoquery()
+             return 0
+             ;;
+         --repoid)
+-            _yum_repolist all "$cur" 2>/dev/null
++            _yum_helper repolist all "$cur" 2>/dev/null
+             return 0
+             ;;
+         --enablerepo)
+-            _yum_repolist disabled "$cur" 2>/dev/null
++            _yum_helper repolist disabled "$cur" 2>/dev/null
+             return 0
+             ;;
+         --disablerepo)
+-            _yum_repolist enabled "$cur" 2>/dev/null
++            _yum_helper repolist enabled "$cur" 2>/dev/null
+             return 0
+             ;;
+         -c|--config)
+             COMPREPLY=( $( compgen -f -o plusdirs -X '!*.conf' -- "$cur" ) )
+             return 0
+             ;;
++        --level)
++            COMPREPLY=( $( compgen -W '{1..9} all' -- "$cur" ) )
++            return 0
++            ;;
+         --output)
+             COMPREPLY=( $( compgen -W 'text ascii-tree dot-tree' -- "$cur" ) )
+             return 0
+             ;;
++        --search-fields)
++            COMPREPLY=( $( compgen -W 'name summary description' -- "$cur" ) )
++            return 0
++            ;;
+     esac
+ 
+     $split && return 0
+ 
+-    COMPREPLY=( $( compgen -W '--version --help --list --info --file
+-        --queryformat --groupmember --all --requires --provides --obsoletes
+-        --conflicts --changelog --location --nevra --envra --nvr --source
+-        --srpm --resolve --exactdeps --recursive --whatprovides --whatrequires
+-        --whatobsoletes --whatconflicts --group --grouppkgs --archlist
+-        --pkgnarrow --installed --show-duplicates --repoid --enablerepo
+-        --disablerepo --repofrompath --plugins --quiet --verbose --cache
+-        --tempcache --querytags --config --level --output --search
+-        --search-fields' -- "$cur" ) )
++    if [[ $cur == -* ]] ; then
++        COMPREPLY=( $( compgen -W '--version --help --list --info --file
++            --queryformat --groupmember --all --requires --provides --obsoletes
++            --conflicts --changelog --location --nevra --envra --nvr --source
++            --srpm --resolve --exactdeps --recursive --whatprovides
++            --whatrequires --whatobsoletes --whatconflicts --group --grouppkgs
++            --archlist --pkgnarrow --installed --show-duplicates --repoid
++            --enablerepo --disablerepo --repofrompath --plugins --quiet
++            --verbose --cache --tempcache --querytags --config --level --output
++            --search --search-fields --setopt' -- "$cur" ) )
++        return 0
++    fi
++
++    declare -F _yum_atgroups &>/dev/null && \
++        _yum_atgroups "$cur" || _yum_list all "$cur" 2>/dev/null
+ } &&
+ complete -F _yu_repoquery -o filenames repoquery repoquery.py
+ 
+@@ -278,8 +289,8 @@ _yu_yumdb()
+ 
+     if [ $COMP_CWORD -le 1 ] ; then
+         COMPREPLY=( $( compgen -W 'get set del rename rename-force copy search
+-            exist unset info shell --version --help --noplugins --config' \
+-                -- "$cur" ) )
++            exist unset info sync undeleted shell --version --help --noplugins
++            --config' -- "$cur" ) )
+     fi
+ } &&
+ complete -F _yu_yumdb -o filenames yumdb yumdb.py
+@@ -299,7 +310,7 @@ _yu_repodiff()
+     $split && return 0
+ 
+     COMPREPLY=( $( compgen -W '--version --help --new --old --quiet --archlist
+-        --size --simple' -- "$cur" ) )
++        --compare-arch --size --downgrade --simple' -- "$cur" ) )
+ } &&
+ complete -F _yu_repodiff repodiff repodiff.py
+ 
+@@ -311,6 +322,13 @@ _yu_builddep()
+ 
+     _yum_complete_baseopts "$cur" "$prev" && return 0
+ 
++    case $prev in
++        --target)
++            declare -F _rpm_buildarchs &>/dev/null && _rpm_buildarchs
++            return 0
++            ;;
++    esac
++
+     $split && return 0
+ 
+     if [[ $cur == -* ]] ; then
+@@ -363,6 +381,36 @@ _yu_debug_dump()
+ } &&
+ complete -F _yu_debug_dump -o filenames yum-debug-dump yum-debug-dump.py
+ 
++# yumdownloader
++_yu_yumdownloader()
++{
++    local cur prev words=() split=false
++    _yu_init_completion "$2" "$3"
++
++    _yum_complete_baseopts "$cur" "$prev" 2>/dev/null && return 0
++
++    case $prev in
++        --destdir)
++            COMPREPLY=( $( compgen -d -- "$cur" ) )
++            return 0
++            ;;
++        --archlist)
++            return 0
++            ;;
++    esac
++
++    $split && return 0
++
++    if [[ $cur == -* ]] ; then
++        COMPREPLY=( $( compgen -W '$( _yum_baseopts 2>/dev/null ) --destdir
++            --urls --resolve --source --archlist' -- "$cur" ) )
++        return 0
++    fi
++
++    _yum_list all "$cur"
++} &&
++complete -F _yu_yumdownloader -o filenames yumdownloader yumdownloader.py
++
+ # Local variables:
+ # mode: shell-script
+ # sh-basic-offset: 4
+diff --git a/yum-utils.spec b/yum-utils.spec
+index ce7fb64..7516287 100644
+--- a/yum-utils.spec
++++ b/yum-utils.spec
+@@ -469,8 +469,8 @@ fi
+ %{_bindir}/yum-builddep
+ %{_bindir}/yum-config-manager
+ %{_bindir}/yum-debug-dump
+-%{_bindir}/yum-groups-manager
+ %{_bindir}/yum-debug-restore
++%{_bindir}/yum-groups-manager
+ %{_bindir}/show-installed
+ %{_bindir}/show-changed-rco
+ %{_sbindir}/yum-complete-transaction
+@@ -487,6 +487,7 @@ fi
+ %{_mandir}/man1/show-installed.1.*
+ %{_mandir}/man1/yum-builddep.1.*
+ %{_mandir}/man1/yum-debug-dump.1.*
++%{_mandir}/man1/yum-debug-restore.1.*
+ %{_mandir}/man8/yum-complete-transaction.8.*
+ %{_mandir}/man1/yum-groups-manager.1.*
+ %{_mandir}/man8/yumdb.8.*
+diff --git a/yumdb.py b/yumdb.py
+index 8a4888e..4e549cd 100755
+--- a/yumdb.py
++++ b/yumdb.py
+@@ -7,8 +7,24 @@ import fnmatch
+ import yum
+ import shlex
+ 
++import os
++import glob
++
+ parser = None
+ 
++# FIXME: Internal knowledge
++def _load_all_package_paths(db_path):
++    # glob the path and get a dict of pkgs to their subdir
++    glb = '%s/*/*/' % db_path
++    pkgdirs = glob.glob(glb)
++    _packages = {}
++    for d in pkgdirs:
++        if d[-1] == '/':
++            d = d[:-1]
++        pkgid = os.path.basename(d).split('-')[0]
++        _packages[pkgid] = d
++    return _packages
++
+ def setup_opts():
+     version = "0.0.1"
+     vers_txt = "Manage yum groups metadata version %s" % version
+@@ -25,6 +41,7 @@ def setup_opts():
+       unset?        <key> [pkg-wildcard]...
+       info          [pkg-wildcard]...
+       sync          [pkg-wildcard]...
++      undeleted
+       shell         [filename]...
+ """
+     parser =  optparse.OptionParser(usage = usage_txt, version = vers_txt)
+@@ -183,6 +200,14 @@ def run_cmd(yb, args, inshell=False):
+                 if ykey not in ndata:
+                     continue
+                 print " " * 4, ykey, '=', getattr(pkg.yumdb_info, ykey)
++    elif args[0] == 'undeleted':
++        yumdb_packages = _load_all_package_paths(yb.rpmdb.yumdb.conf.db_path)
++        for pkg in sorted(yb.rpmdb.returnPackages()):
++            if pkg.pkgid in yumdb_packages:
++                del yumdb_packages[pkg.pkgid]
++        for pkgid in yumdb_packages:
++            print "%s: %s" % (pkgid, yumdb_packages[pkgid])
++
+     elif args[0] == 'shell' and not inshell:
+         args.pop(0)
+         if args:
+diff --git a/yumdownloader.py b/yumdownloader.py
+index e6107d4..d37f15d 100755
+--- a/yumdownloader.py
++++ b/yumdownloader.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import sys
+ import os
+@@ -31,6 +31,8 @@ import shutil
+ import rpmUtils
+ import logging
+ 
++rhn_source_repos = False
++
+ # This is to fix Bug 469
+ # To convert from a pkg to a source pkg, we have a problem in that all we have
+ # is "sourcerpm", which can be a different nevra ... but just to make it fun
+@@ -112,7 +114,10 @@ class YumDownloader(YumUtilBase):
+ 
+         # Get all src repos.
+         src_repos = {}
+-        for repo in self.repos.findRepos('*-source'):
++        repos_source = self.repos.findRepos('*-source')
++        if rhn_source_repos: # RHN
++            repos_source += self.repos.findRepos('*-source-rpms')
++        for repo in repos_source:
+             src_repos[repo.id] = False
+ 
+         #  Find the enabled bin repos, and mark their respective *-source repo.
+@@ -122,9 +127,16 @@ class YumDownloader(YumUtilBase):
+                 srcrepo = '%s-source' % repo.id
+                 if srcrepo in src_repos:
+                     src_repos[srcrepo] = True
++                if not rhn_source_repos:
++                    continue
++                if not repo.id.endswith("-rpms"):
++                    continue
++                srcrepo = repo.id[:-len('-rpms')] + '-source-rpms'
++                if srcrepo in src_repos:
++                    src_repos[srcrepo] = True
+ 
+         # Toggle src repos that are set the wrong way
+-        for repo in self.repos.findRepos('*-source'):
++        for repo in repos_source:
+             if     repo.isEnabled() and not src_repos[repo.id]:
+                 repo.close()
+                 self.repos.disableRepo(repo.id)


More information about the scm-commits mailing list