Chapter 33

RPM - The Red Hat Package Manager
 

 
 
In this chapter:
 
 
* An introduction to the Red Hat Package Manager (RPM)
* RPM's capabilities
* SuSE's integration of RPM
* RPM in action -- installation, management, verification, and removal of packages
* Potential pitfalls with RPM on the SuSE Linux platform
 
 
 
Red Hat Package Manager (RPM) is the package management tool used by the SuSE distribution. Historically, SuSE had a tight alignment with the Slackware and Jurix distributions. When SuSE began to publish a Linux distribution, it was basically a Slackware distribution with a German installation and a couple of bug fixes. As the Linux business grew, the need for a native SuSE distribution increased. That's when SuSE decided to make Jurix the basis for its own SuSE Linux distribution. SuSE chose the RPM (the Red Hat Package Manager) which was about to become teh de facto standard at that time. While RPM does contain Red Hat in the name, it is completely intended to be an open packaging system available for anyone to use. Since SuSE uses RPM, it contributed bug fixes to the code as it became involved in RPM's development.
 
NOTE Because of the different aspects of RPM, we need some convention for referring to RPM. In this chapter we will use 'RPM' when we talk about the package management tool in general and rpm to refer to the tool itself.
 
 
The regular SuSE Linux user almost never actually sees the rpm tool or has to call it manually. YaST acts as a wrapper to it and hides RPM from the user. This chapter will give an overview of RPM's main concepts. We will see practical examples on how to use the rpm-tool in the chapters 35 and 36 .
 
RPM has two major modes of operation: package management and package development. The package development aspect is discussed in chapter 35 and 36 . In this chapter we will learn how to use rpm to manage RPM packages. We won't go into too much detail here. RPM is another example of a tool which fills an entire book on its own. In this case that book is 'Maximum RPM', Red Hat Press, 1997 by Edward Bailey. The book is available online as PostScript or LaTeX source at http://www.rpm.org. You'll find a lot of useful information about RPM here. A good first point to find out more about RPM is its man page rpm(8).
 
33.1 Installing Packages
 

RPM is most commonly used for package installation. The call to install a package with rpm is:
 

 
#rpm -i install-options package-list 
 
 
As package-list, rpm takes a list of files or URLs pointing to a file on an FTP server. For example, to install the Secure Shell on your system, you could use the command:
 
 
# rpm -i ftp://ftp.gwdg.de/pub/linux/suse/6.1/i386.de/suse/sec1/ssh.rpm 
 
 
You can list as many package files as you want and mix local with FTP files. There are two sources-FTP and local hard disk. You can use local hard disk and/or FTP files. You are not obligated to use one or the other. They can be used in any combination you chose. The install-options are listed in table 34-1 . We'll discuss them a little bit later.  
Table 33-1 RPM Options for Package Installation or Upgrade
 
Option Meaning
--relocate old=new relocate files from old to new path
--badreloc relocate files even though the package doesn't allow it
--prefix dir relocate the package to dir, if relocatable
--dbpath dir use dir as the directory for the database
--excludedocs do not install documentation
--force short hand for --replacepkgs --replacefiles
-h or --hash print hash marks as package installs (good with -v)
--allfiles install all files, even configurations which might otherwise be skipped
--ignorearch don't verify package architecture
--ignoreos don't verify package operating system
--includedocs install documentation
--justdb update the database, but do not modify the filesystem
--nodeps do not verify package dependencies
--noorder do not reorder package installation to satisfy dependencies
--noscripts don't execute any installation scripts
--notriggers don't execute any scripts triggered by this package
--percent print percentages as package installs
--replacefiles install even if the package replaces installed files
--replacepkgs reinstall if the package is already present
--root dir use dir as the top level directory
--test don't install, but tell if it would work or not
--oldpackage upgrade to an old version of the package (--force on upgrades does this automatically)
-v be verbose
-vv print lots of ugly debugging information
 
 
What does RPM do when it installs a package? If the task were simply to unpack the archive, why would we need it anyway? Obviously, RPM does a lot more than just copy files. It performs a number of tasks during the package installation. Some of them take place before anything is copied to the hard disk, some of them take care of post installation issues. Let's look at those steps:
 
* Dependency checks
It's no secret that some, if not the most, packages require other packages to be installed prior to their installation so that they can operate properly. RPM checks prior to the installation if all dependencies listed in the package are resolved. It also checks if the new package will cause dependency problems for packages that already exist.
* Checking for Conflicts
The package you try to install may conflict with software already installed on your system. You may have the package installed already, and the installed version is newer then the one you are trying to install. Or a file contained in the new package will overwrite a file of another package. Things like this are checked prior to the actual
* Performing Pre-Installation Tasks
The package builder may have included commands or scripts to be executed before the package is installed. We'll see later in chapter 36 how to do this, when we actually create an RPM package. Anyway, these tasks are performed by the rpm-tool.
* Handling configuration files
RPM allows the packager to mark files as configuration files. These are handled in a special way to ensure that customizations don't get lost when a package is upgraded. We will see how this is done in the next section
* Copying the files from the archive to the hard drive
This is the actual installation. The package files are copied to the hard drive. Their owner, group, and permission attributes are set accordingly.
* Performing Post-Installation Tasks
Lots of packages require certain tasks to take place after they have been installed. This may be an additional entry in /etc/rc.config, the customization of the window manager menus, etc. Like the pre-install tasks, this actions are specified by the package builder and we will see examples how to do this in chapter 36 .
* Updating the Package Database
RPM keeps track of all of its action in this database. The database contains information about all files installed. This includes which package they are contained in, the type of file (documentation, configuration, etc.), the installation date, checksums, and so on. It uses this information to find out about conflicts and to check dependencies. We'll see in the section about package maintenance how to query this database.
 
 
As an example of how RPM works, we will use the package dosemu.rpm. This package is part of the SuSE Linux distribution, so you could use YaST to install it, but hey, we need something to play with. Assuming the RPM file is /tmp/dosemu.rpm, we can install the package simply by executing the command:
 
 
# rpm -i /tmp/dosemu.rpm 
 
 
Not very exiting. To get more out of it, we can tell rpm to be verbose by adding the -v switch:
 
 
# rpm -i -v /tmp/dosemu.rpm 
Installing dosemu.rpm 
 
 
At least we get some output now. To see exactly what's going on, use the -vv option instead of -v:
 
 
Maggie:/tmp # rpm -i -vv dosemu.rpm 
D: counting packages to install 
D: found 1 packages 
D: looking for packages to download 
D: retrieved 0 packages 
D: finding source and binary packages 
D: New Header signature 
D: Signature size: 68 
D: Signature pad : 4 
D: sigsize         : 72 
D: Header + Archive: 1397497 
D: expected size   : 1397497 
D: found 0 source and 1 binary packages 
D: opening database mode: 0102 
D: opening database in //var/lib/rpm/ 
D: dependencies: looking for mtools 
D: dependencies: looking for binutils 
D: dependencies: looking for /bin/sh 
D: dependencies: looking for /bin/bash 
D: dependencies: looking for /bin/sh 
D: installing binary packages 
Installing dosemu.rpm 
D: New Header signature 
D: Signature size: 68 
D: Signature pad : 4 
D: sigsize         : 72 
D: Header + Archive: 1397497 
D: expected size   : 1397497 
D: package: dosemu-0.98.6-3 files test = 0 
D: running preinstall script (if any) 
D: running postinstall script (if any) 
+ cd var/lib/dosemu 
+ ../../../usr/bin/mkfatimage16 -b dosC/boot.bin -p -f hdimage.test -l DOSEMU dosC/ipl.sys  
dosC/kernel.exe dosC/command.com commands/aspi.sys commands/autoexec.bat  
commands/bootoff.com commands/booton.com commands/cdrom.sys commands/cmdline.exe  
commands/config.sys commands/dosdbg.exe commands/dumpconf.sys commands/ecpuoff.com  
commands/ecpuon.com commands/eject.com commands/ems.sys commands/emufs.sys  
commands/emumouse.exe commands/exitemu.com commands/ezedit.com commands/ezedit.doc  
commands/fossil.com commands/isemu.com commands/lredir.exe commands/mgarrot.com  
commands/speed.com commands/system.com commands/uchdir.com commands/ugetcwd.com  
commands/unix.exe commands/vgaoff.com commands/vgaon.com commands/xmode.exe 
 
 
Ok, here we go. This may be more information than we really wanted to have. Another nice switch is -h. This way, you get a hash sign (#) for every two percent of the installation. Combined with -v, you get the output you ordinarily get when YaST installs packages (in fact, YaST uses these options):
 
 
# rpm -i -h -v dosemu.rpm 
dosemu                      ################################################## 
 
 
These are probably the most oft-used options for installing packages. Sometimes, you may need to use some of the more advanced options from table 33-1. We won't explain all of them here, just the ones used most frequently:
 
 
* --test: Perform tests, but don't install
As the headline says, this option assigns rpm to do all the checks and tell you the action it would perform. This option us useful if you want to see if an installation would be successful, or to check for unresolved dependencies before preceding.
* --replacepkgs: Install package even if it is installed already
If you need to fix a package that is already installed, you can use this option to install a new copy of the package without removing the old one. This way you can make sure that none of the files that belong to this package are damaged.
* --replacefiles: Install even when existing files are overwritten
While RPM usually prohibits one package from overwriting files of another package, you can bypass this restriction by specifying the option --replacefiles.
* --nodeps: Ignore dependencies
This switch disables RPM's dependency checking. With this switch packages will be installed even when RPM recognizes unresolved dependencies.
* --force: Do it anyway
With this switch enabled, the only thing that will stop RPM from installing the package are unresolved dependencies. Entering --force on the command line is like telling RPM that you're not interested in any conflict with existing packages. Combining it with --nodeps guarantees that the package will be installed. Whether it'll work or not is another matter.
 
 
NOTE Despite the fact that RPM has a dependency mechanism, SuSE doesn't make extensive use of it. YaST has its own dependency database and uses this instead of the RPM features. In fact, SuSE's dependency mechanism allows for more flexibility than RPM. The downside of this is that if you try to install a package file using RPM on the command line, you may get errors that dependencies are not resolved. YaST uses the options --nodeps --force to install packages. If you run into trouble give this a try. There is a slight chance that it will work.
 
 
So much about using RPM to install new packages. My recommendation is that you not use it for this task. YaST allows you to do almost everything you need to do with plain old rpm. Sometimes the command line is just the fastest way to get things done.
 
33.2 Upgrading Packages
 

One of the reasons SuSE decided to use RPM is because of the package database and how it enables RPM to upgrade packages. One would think upgrading a package is the same as removing the old version and installing the new one. It's not quite that simple. Most software has some kind of configuration data stored in a configuration file. If you do the upgrade as instructed, the configuration will be lost. This is in especially painful if you invested time in customizing the installation.
 
In terms of the rpm command line, upgrading follows almost the same syntax as installing a new package. The only difference is that instead of using the switch -i for installation, you use -U for upgrade. The options listed in table 33-1 are valid for both modes, installation and upgrade.
 
Back to the configuration file issue. How does RPM handle this? First of all, it knows which files are configuration files. The package builder marked these files. When the package is installed for the first time, a checksum (MD5) is generated for each file contained in the package. Using this checksum RPM can decide if any modifications have taken place.
 
In fact, there are three versions of any configuration file involved in a package upgrade. A checksum for each file is calculated and used in the upgrade procedure:

 
* The Original File
This is the file that came from the original (the very first) installation of the package.
* The Current Filee
By this I mean the file as it is just prior to the upgrade, including all changes you may have made to it.
* The New Filee
As we are performing an upgrade, the new version of the package probably includes a new version of the configuration file too (it should). This version is what we are referring to as the new file.
 
 
This leads us to several combinations of checksums for these three files and to referring actions which have to take place for each of these combinations. Let's walk through the possible scenarios.
 
We'll use the letters X, Y, Z in place of the lengthy MD5 checksums:
 
 
* Original = X, Current = X, New = X
All three files are the same. RPM takes the file from the new package and installs it over the old copy. It does this to make sure that changes in ownership or permissions which may possibly exist in the new package are taken care of.
* Original = X, Current = X, New = Y
The new file is different form the original, but the original configuration hasn't been changed. RPM does the same as in the first case. It takes the file from the new package and installs it over the original file. This makes total sense. No customization is lost since nobody changed the original. The new version may include bug fixes or other improvements, so it's a wise decision to use this one for the upgraded version of the package.
* Original = X, Current = Y, New = X
The new file is identical to the original, but the original has been changed. The existing file will stay in place. RPM makes the assumption that as the original equals the new version of the file, the modifications made to this file should be valid for the new version of the package too.
* Original = X, Current = Y, New = Y
The original file was changed, but the changes reflect the new version. These modification may have fixed a bug and the same bug fix was incorporated into the new version. RPM uses the new version in this case. The same philosophy applies as in the first scenario since permission and user flags may have changed. And as the file contents are the same (MD5 guarantees this) it doesn't really make a difference anyway.
* Original = X, Current = Y, New = Z
Here we come to the more interesting cases. The original has been modified at some point, and the new version is different from the original and the current file.
This case is difficult to handle. RPM can't analyze the file contents. So it goes the safe route. It creates a backup copy of the current version and then installs the new version of the file. The backup copy has the same name as the original (and the new) file, with the extension .rpmsave added to it.
This is a reasonable approach. RPM knows that the original and the new version are different. It's reasonable to assume that extensive changes have taken place. It also knows that the new version works with the new package. This can't be guaranteed for the original file. However, someone took the effort to change the original. Maybe those changes are still useful and can easily be applied to the new configuration, so saving those changes is a good idea.
* Original = ??, Current = X, New = y
We know nothing about the original, and the current and the new file are different. This scenario can't happen when the original was installed with RPM. If this was the case, there would be a checksum for this file in the RPM database. But as RPM is a friendly tool, it handles this case anyway.
As there is no checksum for the original, the checksum for the current version doesn't tell us a whole lot either, so we don't know if it has changed or not. RPM reacts to this scenario in a similar way as described in the last section. It uses the new file and creates a backup copy of the current version. In this case the extension .rpmorig will be added to the filename. This way you can distinguish between files RPM knew of and files RPM saw for the first time during the upgrade.
 
 
As you see, RPM is capable of taking care of your configuration. If it creates backup files it'll print out a warning to inform that there is something you should be aware of. If you do a lot of upgrades in one batch, it may be easier to search for .rpmsave and .rpmorig files after the batch is finished, rather than watching the job and look out for warning messages.
 
33.3 Querying Package Information
 

RPM's usefulness doesn't end with the package installation. We learned that rpm uses the RPM database for certain tasks, but this database is not only of interest to RPM. Since it contains complete information on what is installed on your system and where did it came from, it holds valuable information for the system administration in its human form factor as well. But that's not all. You can also use RPM to gain information about packages you have not yet installed. This may be even more interesting, as you may want to know what you put on your system prior to installing it.
 
The tables 34-2 and 34-3 list the options for rpm used for queries either on the database or on a package file. You see we divided the options in two parts. One to list option used to select the package or packages we want to get information about. And the second one with options to select the kind of information we are interested in.
 

33.3.1 Package Selection
 

First let's see how we tell rpm which package(s) we want to get information about. The first choice is do we want to know something about a package that has already been installed, or do we want to have a sneak peek into a package file? The latter case is the easiest one, so we'll discuss it first.
 

 Query a Specific RPM Package File
 

As you can see in table 34-2 , the switch -p allows you to specify a package file as the query's target. Combined with the query switch -q, it will tell you which package is contained in this file:
 

 
# rpm -qp  dosemu.rpm 
dosemu-0.98.6-3 
 
 
You see the file dosemu.rpm contains the package dosemu-0.98.6-3. The package label is not related in any way to the filename. It's contained in the package itself. This means even when you rename the file, the package name will remain the same:
 
 
# mv dosemu.rpm DosEmulation.rpm-package 
# rpm -qp  DosEmulation.rpm-package 
dosemu-0.98.6-3 
 
 
NOTE A package label is composed of three parts. The name of the packaged software (dosemu), the version of the packaged software (0.98.6), and the package's release number (3). This is important to know when we issue queries on the RPM database. To specify a package within the RPM database, we have to be aware of this labeling scheme.
 
 
 
Table 33-2 RPM Query Package Specification Options
 
Option Meaning
-a query all packages
-f files query package owning file
-p packagefiles query (uninstalled) package packagefile
--triggeredby pkg query packages triggered by pkg
--whatprovides cap query packages which provide cap capability
--whatrequires cap query packages which require cap capability
 
 Querying the RPM Database
 

Assuming that the dosemu package is installed, we can select it within the RPM database by addressing it by either by its name, the name and the version number, or by giving the full label including name, version number and release number:
 

 
# rpm -q dosemu 
dosemu-0.98.6-3 

 
# rpm -q dosemu-0.98.6 dosemu-0.98.6-3
 
# rpm -q dosemu-0.98.6-3 dosemu-0.98.6-3
 
 
The result in all cases is the full label.
 
CAUTION rpm is case sensitive and doesn't match partial names. Here are examples for queries that don't work:
 
 
# rpm -q DosEmu 
package DosEmu is not installed 

 
# rpm -q "dos*" package dos* is not installed
 
# rpm -q dos package dos is not installed
 
# rpm -q dosemu-0.98 package dosemu-0.98 is not installed
 
 
 
You see this mechanism isn't very powerful if you don't know the exact name of the package you are looking for. But there are ways to get the exact name if you have a faint idea of what it is. You can get a list of all installed packages using the -a option:
 
 
# rpm -qa 
aaa_base-99.4.19-0 
aaa_dir-99.4.19-0 
aaa_skel-99.4.9-0 
at-3.1.8-54 
base-99.4.9-1 
bash-2.02.1-38 
bash1-1.14.7-59 
bdflush-1.5-61 
compress-4.2.4-58 
[...] 
 
TIP If you only have part of the name, you can pipe this output to grep and easily find a package's full name:
 
 
# rpm -qa | grep -i "Dos" 
mkdosfs-0.4-56 
dosemu-0.98.6-3 
 
 
 
 Query Package Containing a Specific File
 

If you have a file and you want to know the package it belongs to, you can use the -f switch to find out about this:
 

 
# rpm -qf /etc/inittab 
aaa_base-99.4.19-0 
 
 
If you ask for a file that wasn't installed by RPM, it will tell you this too:
 
 
# rpm -qf /etc/lilo.conf 
file /etc/lilo.conf is not owned by any package 
 
 
CAUTION There is a tricky detail about these kinds of queries. Beware of links. Let's say you want to know the package of the file /usr/X11/bin/xterm. You'll probably get a surprising result -- it's not contained in any package:
 
 
# rpm -qf /usr/X11/bin/xterm 
file /usr/X11/bin/xterm is not owned by any package 
 
 
The puzzle is how this can be since it had to come from somewhere. The answer is that /usr/X11 is a soft-link to /usr/X11R6. When you ask for /usr/X11R6/bin/xterm you'll get the reply that it's a part of xf86-3.3.3.1-20:
 
 
# rpm -qf /usr/X11R6/bin/xterm 
xf86-3.3.3.1-20 
 
 
How to avoid those trapdoors? Unfortunately, there is no specific answer. One piece of advice is to use the utility namei, which follows a pathname until a terminal point is found. In our example you would see very quickly that there is a soft link in the path to xterm as we first indicated:
 
 
>namei  /usr/X11/bin/xterm 
f: /usr/X11/bin/xterm 
 d / 
 d usr 
 l X11 -> X11R6 
   d X11R6 
 d bin 
 - xterm 
 
 
For more information on namei refer to it's man page namei(1).
 
 
NOTE RPM supports a few more selection mechanisms. You can place queries based on requirements of packages, on what a package provides, or on the group a package belongs to. These features however are not used by SuSE, so using them doesn't make a whole lot of sense. SuSE doesn't make very much use of the provide/require mechanism RPM offers. YaST has its own database of requirements which exceeds RPM's abilities. YaST also takes care of grouping the packages into series. The RPM group SuSE choose to put packages in is the same for all package files: unsorted.
 
 
33.3.2 Information Selection
 

So far the only results we got from a query were package labels. Not very exciting. But the examples given in the last section were intended to demonstrate how to focus the query on certain packages. This section will show us which information RPM can provide about those packages. Table 34-3 gives a short overview of the options used to select the desired information.  

Table 33-3 RPM Query Information Selection Options
 
Option Meaning
-i display package information
--changelog display the package's change log
-l display package file list
-s show file states (implies -l)
-d list only documentation files (implies -l)
-c list only configuration files (implies -l)
--dump show all verifiable information for each file (must be used with -l, -c, or -d)
--provides list capabilities package provides
--requires or -R list package dependencies
--scripts print the various (un)install scripts
--triggers show the trigger scripts contained in the package
-V or -y or--pipe cmd send stdout to cmd
--verify verify a package installation using the same same package specification options as -q
--nodeps do not verify package dependencies
--nomd5 do not verify file md5 checksums
--nofiles do not verify file attributes
 
 
 General Package Information
 

Adding -i to rpm -q tells RPM to give you general package information contained in the package file. Look at the package rxvt as an example:
 

 
# rpm -qi rxvt 

 
Name : rxvt Distribution: SuSE Linux 6.1 (i386) Version : 2.4.7 Vendor: SuSE GmbH, Nuernberg, Germany Release : 28 Build Date: Thu Apr 15 00:26:33 1999 Install date: Mon Jun 14 23:08:19 1999 Build Host: Fenchel.suse.de Group : unsorted Source RPM: rxvt-2.4.7-28.src.rpm Size : 417457 License: 1999 - not specified Packager : feedback@suse.de Summary : The 'other' X-Terminal. Description : rxvt is as small as xterm. That's why many people like it. This package also includes rclock - it is now included in the rxvt source package. Authors: -------- Mark Olesen <olesen@me.QueensU.CA> Robert Nation <nation@rocket.sanders.lockheed.com>
 
 
The above information is pretty obvious, so I won't go into details here. Note that the version number and the release number are listed separately. The release number is used to distinguish between separate packages which contain the same version of the software. This may sound confusing, but it makes sense when you think about it. Assume a package has been built and released on the SuSE Linux distribution. Then a bug is found and a patch becomes available. At this point SuSE often decides to make an update available as an RPM package on its FTP server. Now what if the original author of the package didn't incorporate the fix yet and the software has still the same version number? It would be hard to distinguish between the package with the bug fix and the old one without the fix. This is often the situation when the release number gets incremented. Now you can see which package is the newer on. Usually the release number is zero (0) for the initial build of the package. It is incremented with every release of the same software version. Every time the version of the software changes, the release number is reset to zero.
 
 The Package's File List
 

Another very interesting part of the package is the list of files it contains. You get a full file list with the -l switch:
 

 
# rpm -ql rxvt 
/usr/X11R6/bin/rclock 
/usr/X11R6/bin/rxvt 
[...] 
/usr/doc/packages/rxvt/rxvtRef.txt 
/usr/doc/packages/rxvt/xterm.seq 
 
 
If you add -v to rpm -ql, than the list includes the file attributes:
 
 
# rpm -qlv rxvt 
-rwxr-xr-x  root  root   34376 Apr 15 00:26 /usr/X11R6/bin/rclock 
-rwxr-xr-x  root   tty  104572 Apr 15 00:26 /usr/X11R6/bin/rxvt 
[...] 
-rw-r--r--  root  root   26150 Aug 27 17:13 /usr/doc/packages/rxvt/rxvtRef.txt 
-rw-r--r--  root  root   16051 Apr 19  1998 /usr/doc/packages/rxvt/xterm.seq 
 
 
We saw that RPM distinguishes between regular, configuration, and documentation files. Since those files are marked as such within the RPM package file, you can get them listed separately. The option -c selects configuration files, and with -d you get documentation files:
 
 
# rpm -qc rxvt 
/usr/X11R6/lib/X11/app-defaults/Rxvt 

 
# rpm -qd rxvt /usr/X11R6/man/man1/rclock.1.gz /usr/X11R6/man/man1/rxvt.1.gz /usr/doc/packages/rxvt/BUGS /usr/doc/packages/rxvt/FAQ /usr/doc/packages/rxvt/README.SuSE /usr/doc/packages/rxvt/README.greek /usr/doc/packages/rxvt/README.menu /usr/doc/packages/rxvt/README.xvt /usr/doc/packages/rxvt/TODO /usr/doc/packages/rxvt/menu/example.menu /usr/doc/packages/rxvt/menu/jedmenu.sl /usr/doc/packages/rxvt/menu/menu /usr/doc/packages/rxvt/menu/rxvt.menu /usr/doc/packages/rxvt/menu/terminal.menu /usr/doc/packages/rxvt/rxvt.html /usr/doc/packages/rxvt/rxvtRef-frame.html /usr/doc/packages/rxvt/rxvtRef-toc.html /usr/doc/packages/rxvt/rxvtRef.html /usr/doc/packages/rxvt/rxvtRef.txt /usr/doc/packages/rxvt/xterm.seq
 
 
The configuration files are especially interesting. The combination of -a to select all packages and -c to specify the configuration files gives you an easy way to list all configuration files in the system that RPM knows about:
 
 
# rpm -qac 
/etc/DIR_COLORS 
/etc/conf.modules 
/etc/csh.cshrc 
/etc/csh.login 
/etc/inittab 
/etc/inputrc 
/etc/issue 
/etc/issue.net 
[...] 
 
 
There are many more ways to use RPM for requests on package files or the package database. But getting the file list and the general package information are by far the most used ones. Refer to the sources given at the beginning of this chapter for more query options.
 
33.4 Verification of installed packages
 

Sometimes its handy to have an easy way to verify that an installed packages is still 'OK'. RPM's verification function is a nice tool that supports you with this task. It can alert you to changes made to any of the files installed by RPM. The command rpm -V verifies an installed package. The selection of the package is made the same way as we have seen it in the last section for queries on the RPM database. The options in table 33-2 work the same way with the -V switch. Table 34-4 lists additional options for package validation.
 
 

Table 33-4 RPM Verification Options
 
Option Meaning
--nomd5 do not verify file md5 checksums
--nodeps do not verify package dependencies
--nofiles do not verify file attributes
  In the list of options, you'll see that they are meant to switch on certain checks. But which checks are performed by default? RPM verifies that package dependencies are resolved, that all the files listed for the package in the RPM database are present in the system, and it verifies the following attributes for each file of the package:
 
 
* File owner and group,
* File permissions (mode),
* MD5 checksum,
* File size,
* File major and minor number (for special device files),
* Symbolic link string (if file is a soft link), and
* File modification time.
 
 
NOTE A word on the MD5 checksums. They came up a couple of times before without a full explanation. The MD5 checksum of a file is a 128-bit number derived from the file's content. The algorithm was designed by Ron Rovest, the 'R' in the popular RSA algorithm for encryption. 'MD' stands for Message Digest, but unlike literary digests, the MD5 checksum conveys no information about the file's contents. However it guarantees that any change in the file results in a change to the MD5 checksum. So MD5 checksums are a perfect way to see if a file has changed since the checksum has been calculated the last time. RPM stores MD5 checksums for every file it installed in its database. So it's an easy task to find modified files using RPM.
 
 
So much about the theory, let's get practical again. To verify the contents of an installed package, just call rpm -V package-label. For example, to check the package rxvt do the following:
 
 
# rpm -V rxvt 
.M......   /usr/X11R6/bin/rxvt 
 
 
RPM reports only those files where it found differences in the values of the attributes stored in its database. You see the file /usr/X11R6/bin/rxvt has been changed. Each file reported is preceded by a nine digit string. This string tells you which modifications have been found:
 
 
SM5DLUGT  
|||||||| 
|||||||+- Modification Time 
||||||+-- Group 
|||||+--- Owner (User) 
||||+---- Symbolic Link String 
|||+----- Major/Minor Number 
||+------ MD5 Checksum 
|+------- Permissions (Mode) 
+-------- Size 
 
 
For our rxvt example this means that the permissions have been changed. To make the example complete, we will do an RPM query to see how the permissions should be set by referring to the RPM database and how they are for the actual file. So we can see what exactly has been modified:
 
 
# rpm -qflv /usr/X11R6/bin/rxvt | grep "/usr/X11R6/bin/rxvt" 
-rwxr-xr-x     root      tty     104572 Apr 15 00:26 /usr/X11R6/bin/rxvt 
-rwxr-xr-x     root     root     108244 Apr 15 00:26 /usr/X11R6/bin/rxvt.xpm 

 
# ls -l /usr/X11R6/bin/rxvt -rwsr-xr-x 1 root tty 104572 Apr 15 00:26 /usr/X11R6/bin/rxvt
 
 
You see the set-user-id bit has been set for this binary. If this happened in the real world, and you didn't know who changed this, it would be an alert to check the whole system for a possible intruder? (refer to part IV to see more about security issues).
 
NOTE In this case everything is OK. The permissions have been changed by SuSE, which is why we picked this example. It demonstrates that the RPM database can't be used as a reliable reference on a SuSE system. As explained in chapter 24, SuSE has its own lists of permissions in /etc/permissions*. If you look in /etc/permissions.easy, you will see that the set-user-id flag for the rxvt binary is turned on in there. That's why the flag changed and RPM reported this file. So no security alert, everything is fine. Sometimes it's good to beware of 'the SuSE way'. SuSE used RPM as package manager, but a lot of RPM features interfere with native SuSE mechanisms.
 
 
33.5 Removing Packages
 

RPM would be a poor example of package management if it wouldn't support the uninstallation of installed software. But of course it covers this aspect of package management too. With rpm -e (e like erase), you can remove installed packages. As usual there are additional flags to this command which are listed in table 34-5 .
 
 

Table 33-5 RPM Erase Options
 
Option Meaning
--allmatches remove all packages which match
--justdb update the database, but do not modify the file system
--nodeps do not verify package dependencies
--noorder do not reorder package installation to satisfy dependencies
--noscripts do not execute any package specific scripts
--notriggers don't execute any scripts triggered by this package
  There is not very much more to say about this. The steps RPM performs to remove a package are:
 
* Check if any other package relies on the package that you want to remove. If so, RPM won't remove the package and will print an error message.
* Execute pre-uninstall scripts if those exist for this package.
* Check if any configuration file of the package has been changed. If so, copies of these files will be saved.
* Delete all files of the package which are not part of any other package.
* Execute post-uninstall scripts if those exist for this package.
* Remove all traces of the package from the RPM database.
 
 
You see RPM does pretty much what you probably expect it to do. No surprises here. To see a short example, remove the package dosemu that we installed at the beginning of this chapter:
 
 
# rpm -e dosemu 
cannot remove /var/lib/dosemu - directory not empty 
 
 
You see there is a warning message that the directory /var/lib/dosemu, which is expected to be empty, can not be removed because there are still files in it. If you look into this directory you'll find the file hdimage.test, which was created by the post-install script of the dosemu package. One can argue if this file should have been removed by the pre-uninstall script or not. It certainly would make the package removal cleaner. This is an issue to discuss with package builder, and not a topic for this chapter.
 
 
Summary:
  In this chapter we learned how to use RPM, the Red Hat package manager, for daily administrative tasks. We saw how we can install and uninstall packages, how to use the RPM database to keep track of the packages installed on the system, and how to use RPM to ensure that the actually installed files are consistent with the records of the RPM database.
 
--
Back Up Contents Next
--

Copyright (c) 1999 by Terrehon Bowden and Bodo Bauer
To contact the author please sent mail to bb@bb-zone.com