Chapter 05

Using the RPM Database

In This Chapter

*	Querying the RPM database

*	Getting information on RPM files

*	Finding out which packages own files on your system

*	Verifying installed packages

*	Backing up the RPM database

*	Repairing damaged RPM databases

Every package you install with RPM is recorded in the RPM database. The RPM system includes commands to query this database to find out which packages are installed and to provide quite a few details about these packages.

This chapter covers querying both the RPM database and RPM package files. Both types of query are important:

*	Query the RPM database to see what is installed, or not installed, on your system.

*	Query package files to see what the files require, as well as what the files provide.

In addition to querying the RPM database, you can use the database to verify packages. Since this database is so important to the management of your Linux system, this chapter covers how to back it up, as well as how to repair a damaged RPM database.

Querying the RPM Database

In Chapter 4, you saw that the rpm command usually takes one major command-line option to tell it the operation to perform and a myriad of command-line options to customize the operation. The rpm command may also take the name of one or more RPM package files or the name of one or more installed packages. For example, the rpm –i command performs an installation operation, and the rpm –U command performs an upgrade.

For querying the RPM database, the major command-line option is –q, short for query. This option tells the rpm command to query the RPM database. You can also use the long option --query.

In the last few chapters, you've used the –q option with the rpm command to query just for the presence or absence of installed packages. You can expand the -q option to perform a wide array of queries to find out information about the packages installed on a Linux system.

Querying packages

The basic format of the rpm –q command follows:

rpm –q package_name

You need to provide the name of a package to query. For example:

rpm -q telnet-0.17

This command returns the name of the package, if installed. For example:

telnet-0.17-20

If the package is not installed, you’ll see a message like the following:

package telnet-0.17 is not installed

You can provide the whole package name to the rpm command, which includes the name, the version, and the RPM package number, as discussed in Chapter 3. You can also just provide the name and version number, as shown previously, or just the base name of the package.

For example, the following command uses just the base name of the package:

$ rpm -q telnet

telnet-0.17-20

Note

The rpm –q command expects a package name. Although it supports some amount of customized queries, you really need to know which packages you want the rpm command to report on.

You can provide more than one package name; the rpm command reports on each package, as shown following.

$ rpm -q telnet telnet-server

telnet-0.17-20

telnet-server-0.17-20

You need to change the way you query if you want to perform searches when you do not know the full package name in advance. The following sections cover options for creating various queries.

Querying everything

Up to now, we have used the rpm command to query only for specific packages. The –a option tells the rpm command to query for all packages. You can also use the longer option, --all, in place of –a.

For example:

rpm -qa

This command returns every package installed on your system, quite a few packages. The packages are returned one per line, as shown following.

words-2-17

kudzu-0.99.23-1

openldap-2.0.11-13

rpm-4.0.3-1.03

kernel-smp-2.4.7-10

quota-3.01pre9-3

expat-1.95.1-7

groff-perl-1.17.2-3

perl-DateManip-5.39-5

perl-libnet-1.0703-6

perl-URI-1.12-5

perl-XML-Parser-2.30-7

perl-XML-Twig-2.02-2

a2ps-4.13b-15

4Suite-0.11-2

XFree86-xfs-4.1.0-3

ghostscript-6.51-12

tcl-8.3.3-65

portmap-4.0-38

bind-utils-9.1.3-4

ftp-0.17-12

micq-0.4.6.p1-2

Note

This output has been modified to meet size constraints. Try the rpm –qa command to see the full output for your system.

There may be over a thousand packages on your system. Even so, the rpm –qa command executes surprisingly fast.

Refining the query

When you query all the installed packages, you get too much output for most purposes, other than to get a general idea of the magnitude of packages installed on your system. But if you cannot remember a package name, there's no real option, other than writing your own RPM query program.

You can take advantage of the power of the Linux shells, though, and the wonderful ability to pipe the output of one command into another to work around this problem. With the large amount of output, you may want to pipe the output to the more or less programs, and display the output one page at a time.

Cross Reference

For more information on the more or less commands, view the online manuals with the man more and man less commands.

Even with more and less, the rpm –qa command outputs too much information to be really useful, unless you can somehow filter the information automatically.

Piping the Output To grep

The Linux (and Unix) grep command provides a powerful tool for filtering through lots of textual data. If you pipe the output of the rpm –qa command into the grep command, you have a powerful search engine—Linux--at your fingertips.

For example, if you know that most packages that use the Python scripting language have a py in their names, you can find all these packages by using a command like the following:

rpm -qa | grep py

This command outputs packages such as the following:

python-2.2.1-17

pygtk2-1.99.12-7

pyxf86config-0.3.1-2

rpm404-python-4.0.4-8x.27

python-devel-2.2.1-17

gnome-python2-gtkhtml2-1.99.11-8

orbit-python-1.99.0-4

gnome-python2-canvas-1.99.11-8

gnome-python2-bonobo-1.99.11-8

gnome-python2-1.99.11-8

pyOpenSSL-0.5.0.91-1

rpm-python-4.1-1.06

pygtk2-devel-1.99.12-7

kdesdk-kspy-3.0.3-2

mod_python-3.0.0-10

gnome-python2-gconf-1.99.11-8

libxslt-python-1.0.19-1

python-tools-2.2.1-17

libxml2-python-2.4.23-1

pygtk2-libglade-1.99.12-7

python-optik-1.3-2

kfloppy-3.0.3-3

You can also use the --pipe option to the rpm command, introduced in Chapter 4. With this option, your command becomes:

rpm -qa --pipe "grep py"

Cross Reference

Chapter 17 covers programming with the RPM system with the Python scripting language.

You can take advantage of some of the options that the grep command supports, including -i for ignoring the case of the string to match, --regexp to pass a regular expression to grep, and -v, to output only those entries that do not match the search string.

Cross Reference

If you are unfamiliar with grep, the online manual pages for the grep command provide a listing of the command-line options available for grep as well as a short tutorial on regular expressions supported by grep.

Table 5-1 lists some of the common package-naming conventions. Remember that these are just conventions, not hard-and-fast rules. You can use these conventions in concert with rpm queries.

Table 5-1 Common Naming Conventions on Linux

Convention	Usually indicates
Starts with g	GNOME desktop application or a GNU application, especially GNU C programming tools and libraries
Starts with j	Cross-platform Java application
Starts with k	KDE desktop application, Linux kernel package, or Kerberos security package
Starts with py	Python application
Starts with rh	Red Hat application, usually for configuring your system
Starts with tk	Graphical Tcl application
Starts with x	X Window System graphical desktop application
Ends with wm	Window manager for controlling the layout of windows on the screen

Querying with Wildcards

In addition to using other Linux commands, the rpm command supports some search options. You can pass a wildcard to rpm –qa (but not just rpm –q, you need the –a to look for all packages). For example:

$ rpm -qa "send*"

sendmail-cf-8.11.6-3

sendmail-8.11.6-3

Note

The quotation marks around "send*" are to prevent the Linux shell from expanding the wildcard character, *, to try to match a list of file names in the local directory. By passing the command-line parameter as "send*", the rpm program gets to see the * character. Otherwise, the shell expands the parameter and the program, rpm in this case, never sees the *.

This command searches for all package names starting with send. You can reverse this with an exclamation mark. For example:

$ rpm -qa '!send*'

This command works sort of like grep –v and searches for all packages that do not start with send.

There are quite a few other Linux commands you can use in pipelines with the rpm –qa command to better filter and display the data, such as wc –l to count the number of packages that you query. You can also use a number of other query options to find out more specialized information from the RPM database.

Cross Reference

If you aren’t familiar with grep or other Linux commands, pick up a Linux tutorial such as (insert shameless plug) Teach Yourself Linux by Steve Oualline and Eric Foster-Johnson, available from Wiley Publishing, Inc.

Finding which packages own files

One of the common problems with package management comes when you want to track a given file on your system back to the package that “owns” the file (that is, the package that, when installed, installed the particular file).

The -qf option tells the rpm command to query for all packages that own a particular file. You can also use the longer option, --file, in place of –f. The basic syntax follows:

rpm -qf filename

For example, the grep command used in previous examples is really a file. (Just about all Linux commands are a file of some sort, be it a shell script or an executable application.) You can use a few Linux commands to determine which package provides this handy program.

First, we need the exact path to the file. For Linux commands, you can use the which command, if the program is in your path. (The grep program must be in your path, or commands with grep will fail.)

Try the following command:

which grep

This command returns the path to grep:

/bin/grep

We can now check which package owns this file with the following command:

# rpm -qf /bin/grep

grep-2.4.2-7

You can also use the Linux back-tick operator to perform this check with one command.

# rpm -qf `which grep`

grep-2.4.2-7

Production: note use of back-quote, `, above. Don’t change to “smart quotes” please. -Eric

If you use the bash shell, you can use the $(command parameters) syntax in place of the back tick, or `, characters. For example:

# rpm -qf $(which grep)

grep-2.4.2-7

If no package owns a given file, you’ll see output like the following:

# rpm -qf mail

file mail is not owned by any package

Often, the package that owns a file does not have an intuitive name. The ssh command, for example, is owned by the openssh-clients package, as shown following:

# rpm -qf `which ssh`

openssh-clients-3.1p1-2

As you can see, the name of a command does not always correspond directly to the name of the package that provides that command. This is where the rpm –qf command proves very useful. Otherwise, you would just have to know that OpenSSH is the project responsible for this command.

Symbolic Links

The rpm -qf command follows symbolic links. This was not always true with older versions of the rpm command, but the modern rpm command can now trace package ownership to files placed in linked directories.

For example, the directory /usr/lib/X11 is a link to the real directory, /usr/X11R6/lib/X11. You can track the package ownership of a file in that directory, XKeysymDB, for example, by using the following command:

# rpm -qf /usr/lib/X11/XKeysymDB

XFree86-4.2.0-72

This file, XKeysymDB, really resides in /usr/X11R6/lib/X11.

Getting Information on Packages

The query options for the rpm command include a whole set of options that return information about the files that make up a package, the scripts, and other parts of the original package. The following sections cover these options.

Describing packages

The –i option with an rpm query command tells the rpm command to output descriptive information about the package. You can also use the longer option, --info, in place of –i. The basic syntax is:

rpm -qi package

Warning

The order of the command-line options is very important. Remember that the rpm command has the following general syntax:

rpm –MajorOperation –extra_options packages_or_files

The rpm –i command installs packages. The rpm –q command queries packages. The rpm –qi command outputs the descriptive information on packages. If you make a mistake and place the i in front of the q, you are telling the rpm command to perform a different operation.

When you run this command, being very careful with the order of the options, you’ll see output like the following, which describes the tcsh shell package.

# rpm -qi tcsh-6.10-6

Name : tcsh Relocations: (not relocateable)

Version : 6.10 Vendor: Red Hat, Inc.

Release : 6 Build Date: Sun 24 Jun 2001 10:45:29

PM CDT

Install date: Fri 14 Dec 2001 10:45:39 AM CST Build

Host: porky.devel.redhat.com

Group : System Environment/Shells Source RPM: tcsh-6.10-6.src.rpm

Size : 764000 License: distributable

Packager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>

URL : http://www.primate.wisc.edu/software/csh-tcsh-book/

Summary : An enhanced version of csh, the C shell.

Description :

Tcsh is an enhanced but completely compatible version of csh, the C

shell. Tcsh is a command language interpreter which can be used both

as an interactive login shell and as a shell script command processor.

Tcsh includes a command line editor, programmable word completion,

spelling correction, a history mechanism, job control and a C language

like syntax.

From this description, you can find out a lot about a package, such as where it comes from. Note how the description also names the source RPM used to build the package programs.

Cross Reference

The sections on custom queries following in this chapter show how you can query for any information stored in a package header, including all of the information shown with the rpm –qi command, as well as any other header tag.

Package groups

RPM packages can be placed into groups, merely arbitrary names for a set of packages. The rpm –qi command, shown previously, lists the group for a package, if there is one. For the tcsh package shown in the previous example, the package is System Environment/Shells.

The –g option to the rpm –q command tells the rpm command to list all the packages in a given group. You can also use the longer option, --group, in place of –g. The basic syntax follows:

rpm –qg group_name

For example:

# rpm -qg "System Environment/Shells"

bash-2.05b-5

sh-utils-2.0.12-3

ash-0.3.8-5

tcsh-6.12-2

Note

This group has a space in its name, so you need quotation marks to pass the group name as one parameter to the rpm command.

Listing the files in a package

The –l (ell) option queries all the files in a package. You can also use the longer option, --list, in place of –l. The basic syntax is:

rpm –ql package

For example, to query the files in the tcsh package, you’ll see the following:

# rpm -ql tcsh

/bin/csh

/bin/tcsh

/usr/share/doc/tcsh-6.10

/usr/share/doc/tcsh-6.10/FAQ

/usr/share/doc/tcsh-6.10/Fixes

/usr/share/doc/tcsh-6.10/NewThings

/usr/share/doc/tcsh-6.10/complete.tcsh

/usr/share/doc/tcsh-6.10/eight-bit.txt

/usr/share/doc/tcsh-6.10/tcsh.html

/usr/share/doc/tcsh-6.10/tcsh.html/header.html

/usr/share/doc/tcsh-6.10/tcsh.html/index.html

/usr/share/doc/tcsh-6.10/tcsh.html/lists.html

/usr/share/doc/tcsh-6.10/tcsh.html/tcsh.man

/usr/share/doc/tcsh-6.10/tcsh.html/tcsh.man2html

/usr/share/doc/tcsh-6.10/tcsh.html/top.html

/usr/share/locale/de/LC_MESSAGES/tcsh

/usr/share/locale/el/LC_MESSAGES/tcsh

/usr/share/locale/es/LC_MESSAGES/tcsh

/usr/share/locale/fr/LC_MESSAGES/tcsh

/usr/share/locale/it/LC_MESSAGES/tcsh

/usr/share/locale/ja/LC_MESSAGES/tcsh

/usr/share/man/man1/tcsh.1.gz

Note

You can pass more than one package name to this option, but it won’t tell you which package owns which file. Use the --filesbypkg option to list files by package (see the related sidebar).

Listing Files By Package

The --filesbypkg option outputs the files by package, so you can make some sense of a list of files from more than one package.

For example:

# rpm -q --filesbypkg file openssh-clients

file /usr/bin/file

file /usr/share/magic

file /usr/share/magic.mgc

file /usr/share/magic.mime

file /usr/share/man/man1/file.1.gz

file /usr/share/man/man5/magic.5.gz

openssh-clients /etc/ssh/ssh_config

openssh-clients /usr/bin/sftp

openssh-clients /usr/bin/slogin

openssh-clients /usr/bin/ssh

openssh-clients /usr/bin/ssh-add

openssh-clients /usr/bin/ssh-agent

openssh-clients /usr/bin/ssh-keyscan

openssh-clients /usr/share/man/man1/sftp.1.gz

openssh-clients /usr/share/man/man1/slogin.1.gz

openssh-clients /usr/share/man/man1/ssh-add.1.gz

openssh-clients /usr/share/man/man1/ssh-agent.1.gz

openssh-clients /usr/share/man/man1/ssh-keyscan.1.gz

openssh-clients /usr/share/man/man1/ssh.1.gz

Use this option without –l, because the –l option will also list the files alone, without any package name.

The –v (verbose) option can give you more information on the files when used with the various query options. For example:

# rpm -qlv tcsh

lrwxrwxrwx 1 root root 4 Jun 24 2001 /bin/csh -> tcsh

-rwxr-xr-x 1 root root 288604 Jun 24 2001 /bin/tcsh

drwxr-xr-x 2 root root 0 Jun 24 2001 /usr/share/doc/tcsh-6.10

-rw-r--r-- 1 root root 8306 Aug 25 2000 /usr/share/doc/tcsh-6.10/FAQ

-rw-r--r-- 1 root root 64761 Nov 19 2000 /usr/share/doc/tcsh-6.10/Fixes

-rw-r--r-- 1 root root 6518 Oct 2 1998 /usr/share/doc/tcsh-6.10/NewThings

-rw-r--r-- 1 root root 41328 Nov 19 2000 /usr/share/doc/tcsh-6.10/complete.tcsh

-rw-r--r-- 1 root root 4668 Jun 24 2001 /usr/share/doc/tcsh-6.10/eight-bit.txt

drwxr-xr-x 2 root root 0 Jun 24 2001 /usr/share/doc/tcsh-6.10/tcsh.html

-rw-r--r-- 1 root root 124 Jun 24 2001 /usr/share/doc/tcsh-6.10/tcsh.html/header.html

lrwxrwxrwx 1 root root 8 Jun 24 2001 /usr/share/doc/tcsh-6.10/tcsh.html/index.html -> top.html

-rw-r--r-- 1 root root 911 Jun 24 2001 /usr/share/doc/tcsh-6.10/tcsh.html/lists.html

-rw-r--r-- 1 root root 0 Jun 24 2001 /usr/share/doc/tcsh-6.10/tcsh.html/tcsh.man

-rw-r--r-- 1 root root 22542 Jun 24 2001 /usr/share/doc/tcsh-6.10/tcsh.html/tcsh.man2html

-rw-r--r-- 1 root root 693 Jun 24 2001 /usr/share/doc/tcsh-6.10/tcsh.html/top.html

-rw-r--r-- 1 root root 45861 Jun 24 2001 /usr/share/locale/de/LC_MESSAGES/tcsh

-rw-r--r-- 1 root root 47566 Jun 24 2001 /usr/share/locale/el/LC_MESSAGES/tcsh

-rw-r--r-- 1 root root 47413 Jun 24 2001 /usr/share/locale/es/LC_MESSAGES/tcsh

-rw-r--r-- 1 root root 47156 Jun 24 2001 /usr/share/locale/fr/LC_MESSAGES/tcsh

-rw-r--r-- 1 root root 48264 Jun 24 2001 /usr/share/locale/it/LC_MESSAGES/tcsh

-rw-r--r-- 1 root root 18682 Jun 24 2001 /usr/share/locale/ja/LC_MESSAGES/tcsh

-rw-r--r-- 1 root root 62399 Jun 24 2001 /usr/share/man/man1/tcsh.1.gz

This information is the same as a long listing on the files.

As you can see, the –l option results in quite a lot of output. In some cases, though, you aren’t interested in documentation and other miscellaneous files in the package. It’s the commands and libraries that cause the most package-related problems. To help with this, you can use a series of rpm options to list only certain types of files.

Listing the configuration files for a package

The –c option tells the rpm –q command to list the configuration files for a package. You can also use the longer option, --configfiles, in place of –c. The basic syntax is:

rpm –qc package_name

For example:

# rpm -qc bash

/etc/skel/.bash_logout

/etc/skel/.bash_profile

/etc/skel/.bashrc

This command lists the configuration files for the bash package.

Some packages don’t have configuration files, as shown following:

# rpm -qc python

#

In this case, the rpm command provides no output. Other packages have a lot of configuration files, such as the sendmail mail transfer agent, as shown following:

# rpm -qc sendmail

/etc/aliases

/etc/mail/Makefile

/etc/mail/access

/etc/mail/domaintable

/etc/mail/helpfile

/etc/mail/local-host-names

/etc/mail/mailertable

/etc/mail/sendmail.mc

/etc/mail/statistics

/etc/mail/trusted-users

/etc/mail/virtusertable

/etc/rc.d/init.d/sendmail

/etc/sendmail.cf

/etc/sysconfig/sendmail

/usr/lib/sasl/Sendmail.conf

As with the –l option, the –v option provides more information on each file, as shown following:

#rpm -qcv bash

-rw-r--r-- 1 root root 24 Jul 9 2001 /etc/skel/.bash_logout

-rw-r--r-- 1 root root 191 Jul 9 2001 /etc/skel/.bash_profile

-rw-r--r-- 1 root root 124 Jul 9 2001 /etc/skel/.bashrc

Listing the documentation files for a package

Similarly to the –c option, the –d option tells the rpm –q command to list just the documentation files for a package. The basic syntax is:

rpm –qd package_name

For example:

# rpm -qd tcsh

/usr/share/doc/tcsh-6.10/FAQ

/usr/share/doc/tcsh-6.10/Fixes

/usr/share/doc/tcsh-6.10/NewThings

/usr/share/doc/tcsh-6.10/complete.tcsh

/usr/share/doc/tcsh-6.10/eight-bit.txt

/usr/share/doc/tcsh-6.10/tcsh.html/header.html

/usr/share/doc/tcsh-6.10/tcsh.html/index.html

/usr/share/doc/tcsh-6.10/tcsh.html/lists.html

/usr/share/doc/tcsh-6.10/tcsh.html/tcsh.man

/usr/share/doc/tcsh-6.10/tcsh.html/tcsh.man2html

/usr/share/doc/tcsh-6.10/tcsh.html/top.html

/usr/share/man/man1/tcsh.1.gz

Note

You can add the –v option to all of the file-listing options to get more information.

You can also use the longer option, --docfiles, in place of –d.

Listing the state of the files in a package

The –s option to the rpm –q command lists the state of each file in a package. The basic syntax follows.

rpm –qs package_name

For example:

# rpm -qs tcsh

normal /bin/csh

normal /bin/tcsh

normal /usr/share/doc/tcsh-6.10

normal /usr/share/doc/tcsh-6.10/FAQ

normal /usr/share/doc/tcsh-6.10/Fixes

normal /usr/share/doc/tcsh-6.10/NewThings

normal /usr/share/doc/tcsh-6.10/complete.tcsh

normal /usr/share/doc/tcsh-6.10/eight-bit.txt

normal /usr/share/doc/tcsh-6.10/tcsh.html

normal /usr/share/doc/tcsh-6.10/tcsh.html/header.html

normal /usr/share/doc/tcsh-6.10/tcsh.html/index.html

normal /usr/share/doc/tcsh-6.10/tcsh.html/lists.html

normal /usr/share/doc/tcsh-6.10/tcsh.html/tcsh.man

normal /usr/share/doc/tcsh-6.10/tcsh.html/tcsh.man2html

normal /usr/share/doc/tcsh-6.10/tcsh.html/top.html

not installed /usr/share/locale/de/LC_MESSAGES/tcsh

not installed /usr/share/locale/el/LC_MESSAGES/tcsh

not installed /usr/share/locale/es/LC_MESSAGES/tcsh

not installed /usr/share/locale/fr/LC_MESSAGES/tcsh

not installed /usr/share/locale/it/LC_MESSAGES/tcsh

not installed /usr/share/locale/ja/LC_MESSAGES/tcsh

normal /usr/share/man/man1/tcsh.1.gz

You can also use the longer option, --state, in place of –s.

You can combine the –s option with other file filters, such as –d, for listing only the documentation files for a package.

Table 5-2 lists the states that the rpm command supports.

Table 5-2 RPM File States

State	Usage
normal	The file has been installed.
not installed	The file from the package is not installed.
replaced	The file has been replaced.

Sometimes files in a package may have been skipped during installation with options such as --excludedocs. This can lead to non-normal states. You may have also modified files installed from a given package.

Cross Reference

See Chapter 4 for more on installing RPMs.

Listing the scripts in a package

RPM packages can have preinstallation, postinstallation, preuninstallation, and postuninstallation scripts. These are scripts that the rpm command will execute before and after installing a package, as well as before and after removing the package. The --scripts option to the rpm –q command lists the scripts associated with a package. The basic syntax follows:

rpm -q --scripts package_name

For example:

# rpm -q --scripts tcsh

postinstall scriptlet (through /bin/sh):

if [ ! -f /etc/shells ]; then

echo "/bin/tcsh" >> /etc/shells

echo "/bin/csh" >> /etc/shells

else

grep '^/bin/tcsh$' /etc/shells > /dev/null || echo "/bin/tcsh" >> /etc/shell

s

grep '^/bin/csh$' /etc/shells > /dev/null || echo "/bin/csh" >> /etc/shells

fi

postuninstall scriptlet (through /bin/sh):

if [ ! -x /bin/tcsh ]; then

grep -v '^/bin/tcsh$' /etc/shells | grep -v '^/bin/csh$'> /etc/shells.rpm

mv /etc/shells.rpm /etc/shells

fi

PRODUCTION: NOTE THE “fi” on a line by itself at the end of this listing. Thanks, -Eric

The simple scripts shown here add an entry to the /etc/shells file and clean up the entry when uninstalled.

Cross Reference

Cleaning up any changes your package makes on uninstallation is a very good idea. See the chapters in Part II, Creating RPMs, for details on making your own well-behaved packages.

Other packages have more complex scripts, as shown following:

# rpm -q --scripts sendmail

preinstall scriptlet (through /bin/sh):

/usr/sbin/useradd -u 47 -d /var/spool/mqueue -r -s /dev/null mailnull >/dev/null

2>&1 || :

postinstall scriptlet (through /bin/sh):

#

# Convert old format to new

#

if [ -f /etc/mail/deny ] ; then

cat /etc/mail/deny | \

awk 'BEGIN{ print "# Entries from obsoleted /etc/mail/deny"} \

{print $1" REJECT"}' >> /etc/mail/access

cp /etc/mail/deny /etc/mail/deny.rpmorig

fi

for oldfile in relay_allow ip_allow name_allow ; do

if [ -f /etc/mail/$oldfile ] ; then

cat /etc/mail/$oldfile | \

awk "BEGIN { print \"# Entries from obsoleted /etc/mail/$oldfile

\" ;} \

{ print \$1\" RELAY\" }" >> /etc/mail/access

cp /etc/mail/$oldfile /etc/mail/$oldfile.rpmorig

fi

done

#

# Oops, these files moved

#

if [ -f /etc/sendmail.cw ] ; then

cat /etc/sendmail.cw | \

awk 'BEGIN { print "# Entries from obsoleted /etc/sendmail.cw" ;} \

{ print $1 }' >> /etc/mail/local-host-names

cp /etc/sendmail.cw /etc/sendmail.cw.rpmorig

fi

#

# Rebuild maps (next reboot will rebuild also)

#

{ /usr/bin/newaliases

for map in virtusertable access domaintable mailertable

do

if [ -f /etc/mail/${map} ] ; then

/usr/bin/makemap hash /etc/mail/${map} < /etc/mail/${map}

sleep 1

fi

done

} > /dev/null 2>&1

/sbin/chkconfig --add sendmail

preuninstall scriptlet (through /bin/sh):

if [ $1 = 0 ]; then

/etc/rc.d/init.d/sendmail stop >/dev/null 2>&1

/sbin/chkconfig --del sendmail

fi

postuninstall scriptlet (through /bin/sh):

if [ "$1" -ge "1" ]; then

/etc/rc.d/init.d/sendmail condrestart >/dev/null 2>&1

fi

exit 0

In this case, the main script is the post-install script, which tries to convert old-format data into the new format, thereby helping users upgrade to the newer release.

Listing what has changed

The --changelog option lists what has changed, as described in a file that logs changes, from previous versions of a given package. The change log is just a convention, so not all packages will sport this nifty feature. In addition, the change log for many packages documents the changes in the RPM packaging, not the changes in the underlying application. If a change log is available, however, this can prove a very good way to help determine whether you want to upgrade to a new version of a package.

For example, a network server application may have been updated to fix some security problems. In that case, you likely want to upgrade. Other changes may not affect your site, leading you to decide not to upgrade.

The basic format of the command is:

rpm –q --changelog package_name

For example, the following shows the beginning of the log-change log for the bash package, with names and e-mail addresses changed to protect the innocent:

# rpm -q --changelog bash

* Fri Aug 23 2002 Bob Marley <bob@marley.com.>

- re-bzip the docs, something was corrupted

* Thu Aug 22 2002 Peter Tosh <peter@tosh.com> 2.05b-4

- Fix history substitution modifiers in UTF-8 (bug #70294, bug #71186).

- Fix ADVANCE_CHAR at end of string (bug #70819).

- docs: CWRU/POSIX.NOTES no longer exists, but ship POSIX.

* Wed Aug 07 2002 Jimmy Cliff <jimmy@cliff.com> 2.05b-3

- Fixed out of memory problem with readline.

* Tue Jul 23 2002 Jimmy Cliff <jimmy@cliff.com> 2.05b-2

- Added symlink for sh.1 in man1 section so that man sh works (#44039).

Combining queries

The rpm command is very flexible in allowing you to combine queries. Just start the command with rpm –q and add the various options either on their own, such as –q with –s and –f, or together, such as –qsf.

The following sections show a few handy combinations of the options you can use for real-world package-management tasks.

Listing Package Description and Documentation Files

To find information on a package and where it is documented, use the –qdi option to the rpm command (a combination of the –q, –d, and –i options):

# rpm -qdi grep

Name : grep Relocations: /usr

Version : 2.5.1 Vendor: Red Hat,

Inc.

Release : 4 Build Date: Sat 20 Jul

2002 01:08:48 AM CDT

Install date: Sat 05 Oct 2002 12:21:58 PM CDT Build

Host: stripples.devel.redhat.com

Group : Applications/Text Source RPM: grep-2.5.1-

4.src.rpm

Size : 475770 License: GPL

Signature : DSA/SHA1, Tue 03 Sep 2002 04:17:47 PM CDT, Key ID

219180cddb42a60ePackager : Red Hat, Inc.

<http://bugzilla.redhat.com/bugzilla>

Summary : The GNU versions of grep pattern matching utilities.

Description :

The GNU versions of commonly used grep utilities. Grep searches

through textual input for lines which contain a match to a specified

pattern and then prints the matching lines. GNU's grep utilities

include grep, egrep, and fgrep.

You should install grep on your system, because it is a very useful

utility for searching text.

/usr/share/doc/grep-2.5.1/ABOUT-NLS

/usr/share/doc/grep-2.5.1/AUTHORS

/usr/share/doc/grep-2.5.1/ChangeLog

/usr/share/doc/grep-2.5.1/NEWS

/usr/share/doc/grep-2.5.1/README

/usr/share/doc/grep-2.5.1/THANKS

/usr/share/doc/grep-2.5.1/TODO

/usr/share/info/grep.info-1.gz

/usr/share/info/grep.info-2.gz

/usr/share/info/grep.info-3.gz

/usr/share/info/grep.info.gz

/usr/share/man/man1/egrep.1.gz

/usr/share/man/man1/fgrep.1.gz

/usr/share/man/man1/grep.1.gz

It's often hard to track down the documentation for a given package. Some packages use Unix manual pages; others use info files, and still others provide HTML for other formatted manuals. Some have no real documentation at all.

Listing the State of Configuration Files

To find the state of all the configuration files for a given Linux command, use a command with the –qcsf option with the name of the file, as shown here, or the -qcs option with the name of a package.

For example:

# rpm -qcsf /bin/bash

normal /etc/skel/.bash_logout

normal /etc/skel/.bash_profile

normal /etc/skel/.bashrc

Listing the Most Recently Installed Packages

To list the most recently installed packages, use the following command with the --last option. This is very useful if you recently installed or upgraded a number of packages and something unexpected happens. If you cannot remember the package names, you can use the --last option to list out packages in reverse order of installation.

You can pipe the output of a query to the head command to show only the last ten packages that were installed or upgraded, as shown following:

# rpm -qa --last | head

comps-8.0-0.20020910 Sat 05 Oct 2002 01:17:30 PM CDT

tkinter-2.2.1-17 Sat 05 Oct 2002 01:16:58 PM CDT

tix-8.2.0b1-74 Sat 05 Oct 2002 01:16:52 PM CDT

tclx-8.3-74 Sat 05 Oct 2002 01:16:44 PM CDT

python-tools-2.2.1-17 Sat 05 Oct 2002 01:16:41 PM CDT

mx-2.0.3-6 Sat 05 Oct 2002 01:16:34 PM CDT

libxslt-python-1.0.19-1 Sat 05 Oct 2002 01:16:31 PM CDT

librpm404-devel-4.0.4-8x.27 Sat 05 Oct 2002 01:16:27 PM CDT

itcl-3.2-74 Sat 05 Oct 2002 01:16:12 PM CDT

gnumeric-1.0.9-2 Sat 05 Oct 2002 01:15:46 PM CDT

You can pass options to the head command to show more or fewer than ten lines. In general, starting with the last ten packages can help you track down something you installed the day before.

Creating custom queries

The --qf or --queryformat option allows you to create custom queries with the rpm command, although in a rather difficult manner. You need to pass a query format string, the syntax of which originates with the C printf function and requires precision.

The basic syntax of the query format is %{tag_name}. (The percent sign is about the only part that comes from the C printf function.) You can combine tag names to display more than one item per package. You can also add formatting options following C language conventions.

For example, to list all package names, use a command like the following:

# rpm -qa --qf "%{NAME}"

redhat-menusglibccracklibgdbmgmplibacllibjpeglincpcreshadow-

utilslibtermcapfreetypeinfofileutilspsmiscntpmountcracklib-dictskrb5-libscyrus-

saslusermodeXftlibpnglibxmllibbonobopythonpygtk2pyxf86configredhat-config-

usersredhat-config-keyboardrpm404-pythongnome-vfs2libgnomeuiashbind-utilscyrus-

sasl-plaindos2unixethtoolfingergroffautofskbdconfiglesslibtool-

libslockdevmailcapMAKEDEVmouseconfignetpbmntsysvORBitpartedppppsutilsrdaterhnlibrp

mrshsetuptoolstatserialtarlilopciutilstimeconfigunzipkernel-pcmcia-

csanacronXFree86

This command used the simplest format, which is just the value of the tag in the package headers, in this case the package names. Because we used no other formatting, this command outputs all the package names smashed together. To deal with this problem in the output, you can place a \n, the C language convention for a newline character, at the end of the format string. This fixes the output considerably.

For example (showing just the first few entries):

# rpm -qa --qf "%{NAME}\n"

redhat-menus

glibc

cracklib

gdbm

gmp

libacl

libjpeg

linc

pcre

shadow-utils

libtermcap

freetype

info

fileutils

psmisc

ntp

mount

cracklib-dicts

krb5-libs

cyrus-sasl

usermode

Xft

This command provides a custom query that is essentially the same as the rpm -qa command. You’ll likely not use this command in favor of the simpler rpm option, but you can use this example as a guide for creating your own custom queries.

Cross Reference

A great many of the command-line options to the rpm command are defined as popt aliases. These popt aliases define the rpm command-line options in terms of longer query format strings. See Chapter 21 for more information on popt.

You can add items to the query string and use C language conventions for formatting and controlling the amount of space provided for each item output.

For example, the following command prints the name and platform for all packages, showing the first few entries, formatted with 20 characters for each item:

rpm -qa --qf "%-20{NAME} %-20{PLATFORM}\n"

redhat-menus noarch-redhat-linux-gnu

glibc i686-redhat-linux-gnu

cracklib i386-redhat-linux

gdbm i386-redhat-linux-gnu

gmp i386-redhat-linux-gnu

libacl i386-redhat-linux-gnu

libjpeg i386-redhat-linux

linc i386-redhat-linux-gnu

pcre i386-redhat-linux

shadow-utils i386-redhat-linux-gnu

libtermcap i386-redhat-linux

freetype i386-redhat-linux-gnu

info i386-redhat-linux-gnu

fileutils i386-redhat-linux-gnu

psmisc i386-redhat-linux

ntp i386-redhat-linux-gnu

mount i386-redhat-linux-gnu

cracklib-dicts i386-redhat-linux

krb5-libs i386-redhat-linux-gnu

cyrus-sasl i386-redhat-linux-gnu

usermode i386-redhat-linux-gnu

Xft i386-redhat-linux-gnu

Working With Query Format Tags

To build queries with the --queryformat option, you need to know what tags you can use. To list the names of the available query format tags, use the --querytags option, which returns a large set of tags, truncated here for space:

# rpm --querytags

NAME

VERSION

RELEASE

SUMMARY

DESCRIPTION

BUILDTIME

Each of these tags also has a version with a RPMTAG_ prefix, such as RPMTAG_NAME. You can use this tags with or without the RPMTAG_ prefix. For example:

$ rpm -q --qf "%{RPMTAG_NAME}\n" sendmail

sendmail

Note how this command uses the –q option to query for one package, instead of –qa to query for all packages. You can use query formats with any of the rpm queries.

The next sections cover the available tags based on the type of the information stored in the tag.

Querying for Package Information

Many of the query format tags refer to package-information data stored in the RPM header, introduced in Chapter 3. Table 5-3 lists the package-information tags.

Table 5-3 Package-information query tags

Tag	Holds
NAME	Package name
VERSION	Version number
RELEASE	Release number
SUMMARY	One-line summary of the package contents
DESCRIPTION	Descriptive text about the package
BUILDTIME	Time package was built
BUILDHOST	Host package was built on
SIZE	Size of all the regular files in the payload
LICENSE	License package was released under
GROUP	Descriptive group or category name for the package
OS	Operating system package was built for
ARCH	Architecture, such as i386
SOURCERPM	The associated source RPM
CHANGELOGTIME	Array of changelog times
CHANGELOGNAME	Array of changelog names
CHANGELOGTEXT	Array of changelog text entries
PREIN	Pre-install script
POSTIN	Post-install script
PREUN	Pre-uninstall script
POSTUN	Post uninstall script
PLATFORM	Platform

All of these tags, except for the CHANGELOGTIME, CHANGELOGTEXT and CHANGELOGNAME tags, are single-value tags. You can query for these tag values using

Formatting Arrays

Many of the header entries are arrays, so the header tags can hold more than one item. For example, RPM packages can have more than one file in the payload.

To specify a format for each item in an array, use square brackets. For example:

$ rpm -q --queryformat "[%-50{FILENAMES} %{FILESIZES}\n]" sendmail

/etc/aliases 1295

/etc/aliases.db 12288

/etc/mail 4096

/etc/mail/Makefile 748

/etc/mail/access 331

/etc/mail/access.db 12288

/etc/mail/domaintable 0

/etc/mail/domaintable.db 12288

/etc/mail/helpfile 5588

/etc/mail/local-host-names 64

This example lists the files and file sizes within a package, with the listing of files truncated for size.

If you want to mix array tags with non-array tags, you can use an equals sign, =, in front of the tag name to specify that the given tag should be repeated for each item in the array. For example:

$ rpm -q --queryformat "[%-15{=NAME} %-50{FILENAMES}\n]" sendmail jikes

sendmail /usr/lib/sendmail

sendmail /usr/sbin/mailstats

sendmail /usr/sbin/makemap

sendmail /usr/sbin/praliases

sendmail /usr/sbin/sendmail.sendmail

sendmail /usr/sbin/smrsh

sendmail /usr/share/man/man1/mailq.sendmail.1.gz

sendmail /usr/share/man/man1/newaliases.sendmail.1.gz

sendmail /usr/share/man/man5/aliases.sendmail.5.gz

sendmail /usr/share/man/man8/mailstats.8.gz

sendmail /usr/share/man/man8/makemap.8.gz

sendmail /usr/share/man/man8/praliases.8.gz

sendmail /usr/share/man/man8/rmail.8.gz

sendmail /usr/share/man/man8/sendmail.8.gz

sendmail /usr/share/man/man8/smrsh.8.gz

sendmail /var/spool/clientmqueue

sendmail /var/spool/mqueue

jikes /usr/bin/jikes

jikes /usr/doc/jikes-1.18/license.htm

jikes /usr/man/man1/jikes.1.gz

This example, also truncated for size, lists the package name along with the file name for the files contained in these two packages.

Special Formatting

Some of the tags within an RPM package header contain special binary information that usually makes no sense when printed out. To help with these header tags, you can use special RPM formatting options, using a syntax like the following:

%{tag:special_format}

For example, to print the INSTALLTIME tag, use %{INSTALLTIME:date}, which specifies to print the INSTALLTIME tag in date format. For example:

$ rpm -q --qf "%{NAME}-%{VERSION}-%{RELEASE} %{INSTALLTIME:date}\n" jikes

jikes-1.18-1 Fri 06 Dec 2002 09:19:30 PM CST

This example prints the NAME-VERSION-RELEASE of the package, along with the INSTALLTIME in date format.

Most tags in a header are optional. You can print the value of these tags, but you may get nothing. To help deal with this, you can use a conditional operator based loosely on the C language ternary operator. The basic syntax is:

%|tag?{print_if_present}:{print_if_absent}|

With the normal %{tag} syntax, this conditional syntax gets complicated really fast. You need to break the elements down. For example:

$ rpm -q --qf "%{NAME} %|EPOCH?{%{EPOCH}}:{(no Epoch)}|\n" perl

perl 1

If the package has a value for the EPOCH tag, you will see output as shown in this example. Most packages do not have an EPOCH defined, in which case, you will see output like the following:

RPM files likely hold packages that are not installed. If you query one of these packages, you will get the alternative text, as shown following:

$ rpm -q --qf "%{NAME} %|EPOCH?{%{EPOCH}}:{(no Epoch)}|\n" sendmail

sendmail (no Epoch)

Cross Reference

See the "Getting Information on Package Files" section in this chapter for more on querying RPM package files.

Other special-formatting options are described in the following sections on the dependency and file information tags.

Querying for Package Dependencies

A number of tags provide package dependency information. Each of these tags comes in triples, which are formatted similarly. For example, for the capabilities a package requires, you have the REQUIRENAME, REQUIREVERSION, and REQUIREFLAGS tags.

The REQUIRENAME tag holds an array of required capability names. The REQUIREVERSION tag holds an array of the versions of the required capabilities. The REQUIREFLAGS tag ties the two together with a set of bit flags that specify whether the requirement is for a version less than the given number, equal to the given number, greater than or equal to the given number, and so on.

Table 5-4 lists the dependency tags.

Table 5-4 Dependency query tags

Tag	Holds
CONFLICTFLAGS	Array of flags for the capabilities this package conflicts
CONFLICTNAME	Array of capabilities that this package conflicts
CONFLICTVERSION	Array of version numbers that this package conflicts
REQUIREFLAGS	Array of flags for the capabilities this package requires
REQUIRENAME	Array of capabilities that this package requires
REQUIREVERSION	Array of version numbers that this package requires
OBSOLETENAME	Array of capabilities that this package obsoletes
OBSOLETEFLAGS	Array of flags for the capabilities this package obsoletes
OBSOLETEVERSION	Array of version numbers that this package obsoletes
PROVIDENAME	Array of capabilities that this package provides
PROVIDEFLAGS	Array of flags for the capabilities this package provides
PROVIDEVERSION	Array of version numbers that this package provides

Each of these tags is an array. The PROVIDENAME, PROVIDEVERSION, and PROVIDEFLAGS tags work similarly for the capabilities this package provides. The CONFLICTNAME, CONFLICTVERSION, and CONFLICTFLAGS tags specify the conflicts, and, the OBSOLETENAME, OBSOLETEVERSION, and OBSOLETEFLAGS tags specify the obsolete dependencies.

The depflags special-formatting option prints out the flag tags, such as REQUIREFLAGS, in human-readable format. For example, the following command lists the requirements for a package:

$ rpm -q --qf \

"[%{REQUIRENAME} %{REQUIREFLAGS:depflags} %{REQUIREVERSION}\n]" sendmail

rpmlib(VersionedDependencies) <= 3.0.3-1

chkconfig >= 1.3

/usr/sbin/useradd

/bin/mktemp

fileutils

gawk

sed

sh-utils

procmail

bash >= 2.0

/bin/sh

rpmlib(PayloadFilesHavePrefix) <= 4.0-1

rpmlib(CompressedFileNames) <= 3.0.4-1

For those requirements that have specific version numbers, this command prints out the version number along with the operator, such as >= for a version greater than or equal to the given number.

Note that for many of the requirements, there is no specific version information.

Note

In addition to normal capabilities, most packages will have some RPM-related requirements as well, which specify any required RPM versions, for example, rpmlib(CompressedFileNames).

Querying for File Information

The file-information tags hold data on the files within the package payload, that is, the files the rpm command installs when you install the package. These tags are arrays, with one value per file.

Table 5-5 lists the file-information tags.

Table 5-5 File-information query tags

Tag	Holds
OLDFILENAMES	Array of full file names, used in older packages
FILESIZES	Array of sizes for each file
FILEMODES	Array of permissions for each file
FILERDEVS	Array of rdev values for each file
FILEMTIMES	Array of modified times for each file
FILEMD5S	MD5 checksum for each file
FILELINKTOS	Array of link information for each file
FILEFLAGS	Array of flags for each file
FILEUSERNAME	Array of user names for the file owners
FILEGROUPNAME	Array of group names for the file owners
FILEDEVICES	Array of devices for each file
FILEINODES	Array of inodes for each file
FILELANGS	Array of language flags for each file
DIRINDEXES	Array of values that matches the DIRNAMES with the BASENBAMES
BASENAMES	Array of file base names
DIRNAMES	Array of directories that matches up with BASENAMES

The OLDFILENAMES tag is used when the files are not compressed, when the REQUIRENAME tag does not indicate rpmlib(CompressedFileNames).

The FILESIZES tag specifies the size of each file in the payload, while the FILEMODES tag specifies the file modes (permissions) and the FILEMTIMES tag holds the last modification time for each file.

The BASENAMES tag holds an array of the base file names for the files in the payload. The DIRNAMES tag holds an array of the directories for the files. The DIRINDEXES tag contains an index into the DIRNAMES for the directory. Each RPM must have either OLDFILENAMES or the triple of BASENAMES, DIRNAMES, and DIRINDEXES, but not both.

When listing file information, use the square bracket array syntax with your query formats. You can use the perms special formatting option for the file modes. For example:

$ rpm -q --qf "[%-15{=NAME} %-36{FILENAMES} %{FILEMODES:perms}\n]" jikes

jikes /usr/bin/jikes -rwxr-xr-x

jikes /usr/doc/jikes-1.18/license.htm -rw-r--r--

jikes /usr/man/man1/jikes.1.gz -rw-r--r--

Other Query Format Tags

In addition to all these tags, there are a number of other miscellaneous tags, many of which are listed in Table 5-6.

Table 5-6 Other query tags

Tag	Holds
ARCHIVESIZE	Uncompressed size of the payload section
COOKIE	Holds an opaque string
RPMVERSION	Holds the version of the RPM tool used to create the package
OPTFLAGS	Compiler optimization flags used to build the package
PAYLOADFORMAT	Must be cpio for LSB-compliant packages
PAYLOADCOMPRESSOR	Must be gzip for LSB-compliant packages
PAYLOADFLAGS	Must be 9 for LSB-compliant packages
RHNPLATFORM	Holds an opaque string
FILEVERIFYFLAGS	Bitmask that specifies which tests to perform to verify the files after an install

For example, you can list the version of RPM that created a package with a command like the following:

$ rpm -qp --qf "%{name} - rpm %{rpmversion}\n" *.rpm

acroread - rpm 2.5.5

canvas - rpm 3.0.3

jikes - rpm 4.0.2

SDL - rpm 2.5.1

ted - rpm 2.5.5

Cross Reference

See Appendix D for a listing of all the tags in an RPM file.

Other queries

If what you’ve seen so far isn’t enough, the rpm command supports a number of extra queries, mostly of use to developers at Red Hat.

Table 5-7 summarizes these extra queries.

Table 5-7 Extra Queries

Option	Meaning
--dump	Dumps out extra information on files
--fileid md5_id	Queries for the package with the given MD5 digest
--hdrid sha1_header_id	Queries for the package with the given header identifier number, in SHA1 format
--last	Reorders the output of the rpm command to show the most recently-installed packages first
--pkgid md5_id	Queries for the package with the given MD5 package ID
--querybynumber number	Queries for the given entry, by number, in the RPM database
--tid transaction_id	Queries for the package or packages with the given transaction ID

Getting Information on Package Files

In addition to querying the RPM database about installed packages, the rpm command provides the handy ability to extract information from RPM files. This is very useful for determining whether you want to install a given package or not. It also helps with the simple task of figuring out what a package’s purpose, especially if names like kudzu, anaconda, or dia don’t immediately tell you what the corresponding packages provide.

The –p option tells the rpm command to provide information on the given package file. The basic syntax is:

rpm –qp option_query_options filename.rpm

You can use the longer option, --package, in place of –p. You can also pass more than one RPM file to the command.

The query information options shown previously for installed packages also work for RPM files. For example, to list the configuration files for a package, combine the -q, -p, and -c options with the name of a package file, as shown following:

# rpm -qpc telnet-server-0.17-23.i386.rpm

/etc/xinetd.d/telnet

To list all the files in an RPM package, combine the -q, -p, and -l options:

# rpm -qpl telnet-server-0.17-23.i386.rpm

/etc/xinetd.d/telnet

/usr/sbin/in.telnetd

/usr/share/man/man5/issue.net.5.gz

/usr/share/man/man8/in.telnetd.8.gz

/usr/share/man/man8/telnetd.8.gz

Querying Package Files Remotely

As shown in Chapter 4, you can access RPM package files over a network using FTP or HTTP connections. To query remote files, use the same rules as shown in Chapter 4, with the following syntax:

rpm -qp ftp://username:password@hostname:port/path/to/rpm/file

rpm -qp ftp://username@hostname:port/path/to/rpm/file

rpm -qp ftp://hostname:port/path/to/rpm/file

rpm -qp http://hostname:port/path/to/rpm/file

If your system resides behind a firewall with a proxy server, use the options in the following table to name the proxy. Note that these proxy options only work with the TIS Firewall toolkit.

Network Proxy Option	Meaning
--ftpproxy proxy_hostname	Names the proxy system
--ftpport proxy_port_number	Network port number on the proxy system
--httpproxy proxy_hostname	Names the proxy system
--httpport proxy_port_number	Network port number on the proxy system

Verifying Installed RPM Packages

You can do a lot more than just query packages in the RPM database. You can ask the rpm command to verify packages with the -V (or --verify) option.

The basic syntax is:

rpm -V verify_options package_name

For example:

# rpm -V telnet

#

If everything checks out, you'll get no response. The rpm command reports problems only. For example, if you have an installation of the telnet-server package that is missing some files, the rpm -V command will let you know, as shown following:

# rpm -V telnet-server

missing c /etc/xinetd.d/telnet

missing /usr/sbin/in.telnetd

missing d /usr/share/man/man5/issue.net.5.gz

In this example, the c and d stand for configuration and documentation files, respectively.

Note

The rpm -V command will also report missing dependencies.

Verifying your entire system

To verify your entire system, use the -a option.

For example:

# rpm -Va

SM5....T c /usr/share/info/dir

.......T c /etc/krb5.conf

.......T /usr/share/pixmaps/gnome-default-dlg.png

.......T /usr/share/pixmaps/gnome-error.png

.......T /usr/share/pixmaps/gnome-info.png

.......T /usr/share/pixmaps/gnome-question.png

.......T /usr/share/pixmaps/gnome-warning.png

S.5....T c /etc/sysconfig/pcmcia

.....U.. /dev/winradio0

Each line that the rpm command outputs indicates a problem with the given file. The rpm command uses letter codes to show the type of the problem. Table 5-8 lists the letter codes with their meanings.

Table 5-8 RPM verify output codes

Code	Meaning
S	File size differs.
M	File mode differs.
5	The MD5 checksum differs.
D	The major and minor version numbers differ on a device file.
L	A mismatch occurs in a link.
U	The file ownership differs.
G	The file group owner differs.
T	The file time (mtime) differs.

Controlling the verification

You can use a number of options to tell the verification command specifically what to check for or not check for. Table 5-9 lists these options.

Table 5-9 Controlling the verification

Option	Usage
--nodeps	Don't verify dependencies.
--nodigest	Don't verify the package or header digests.
--nofiles	Don't verify the file attributes.
--noscripts	Don't try to verify the scripts.
--nosignature	Don't verify the package or header signatures.
--nolinkto	Don't verify the link file attribute.
--nomd5	Don't verify the MD5 digest file attribute.
--nosize	Don't verify the file size attribute.
--nouser	Don't verify the file owner attribute.
--nogroup	Don't verify the file group owner attribute.
--nomtime	Don't verify the file mtime attribute.
--nomode	Don't verify the file mode attribute.
--nordev	Don't verify the file rdev attribute.
-a	Verify all packages in a given group.
-g group	Verify all packages in a given group.
-p file	Verify the given RPM file.

Cross Reference

Chapter 12 covers another option for verifying a package file, the rpm –K command.

The --nofiles option is often used with the –Va option to verify the whole system but skip tests of file attributes. This command is used to often it has become an idiom for RPM usage, especially for debugging RPM problems. Run a command like the following:

$ rpm -Va --nofiles

Working With the RPM Database

As mentioned in Chapter 3, the RPM database is stored in /var/lib/rpm. The files in that directory are Berkeley DB files, as shown by the file command:

# file /var/lib/rpm/*

/var/lib/rpm/Basenames: Berkeley DB (Hash, version 7, native byte-order)

/var/lib/rpm/Conflictname: Berkeley DB (Hash, version 7, native byte-order)

/var/lib/rpm/__db.001: data

/var/lib/rpm/__db.002: X11 SNF font data, LSB first

/var/lib/rpm/__db.003: X11 SNF font data, LSB first

/var/lib/rpm/Dirnames: Berkeley DB (Btree, version 8, native byte-order)

/var/lib/rpm/Filemd5s: Berkeley DB (Btree, version 8, native byte-order)

/var/lib/rpm/Group: Berkeley DB (Hash, version 7, native byte-order)

/var/lib/rpm/Installtid: Berkeley DB (Btree, version 8, native byte-order)

/var/lib/rpm/Name: Berkeley DB (Hash, version 7, native byte-order)

/var/lib/rpm/Packages: Berkeley DB (Hash, version 7, native byte-order)

/var/lib/rpm/Providename: Berkeley DB (Hash, version 7, native byte-order)

/var/lib/rpm/Provideversion: Berkeley DB (Btree, version 8, native byte-order)

/var/lib/rpm/Requirename: Berkeley DB (Hash, version 7, native byte-order)

/var/lib/rpm/Requireversion: Berkeley DB (Btree, version 8, native byte-order)

/var/lib/rpm/Sha1header: Berkeley DB (Btree, version 8, native byte-order)

/var/lib/rpm/Sigmd5: Berkeley DB (Btree, version 8, native byte-order)

/var/lib/rpm/Triggername: Berkeley DB (Hash, version 7, native byte-order)

Each file is a separate database in Berkeley DB format, except for a few __db data files. (These are not really X11 font files, just plain data files. The file command is confused by the data in the files.)

The Berkeley DB Library

Available from SleepyCat Software at www.sleepycat.com/, the Berkeley DB library provides a simple database API. This is not a traditional relational database. Instead, data values are stored in what amounts to a persistent hash table of name/value pairs. This type of database is very quick to look up a named entry (such as a package name) but is not so quick for iterating over all the entries.

One of the nice things about this library is that it is available in an open-source format, and you can get programming API libraries for C, C++, Java, Python, Perl, and Tcl languages.

The RPM database is really a number of Berkeley DB databases, each designed for a different type of query.

If something goes wrong with your RPM database, you can first try to rebuild it. If that fails, you may need to initialize a new database, although that is generally not needed. First and foremost, however, you should back up this database.

Backing up the RPM database

As mentioned before, the RPM database resides in the /var/lib/rpm. You can back up the RPM database by using commands such as the following:

# cd /var/lib

# tar cvf rpmdb.tar ./rpm

# gzip rpmdb.tar

These commands create a tar archive from the contents of the rpm directory (where the RPM database is stored) and compress the file with the gzip command.

Note

Adding the z option to the tar command can create a compressed archive directly, without the need for the gzip command.

Rebuilding the RPM database

If the RPM database has been corrupted in some way, you can use the --rebuilddb option to tell the rpm command to rebuild your database.

For example:

rpm --rebuilddb

This command rebuilds the RPM database from the installed packages, the file named Packages in the /var/lib/rpm directory. Only the Packages file is required. All the other files can be recreated from the Packages file. If your database is OK, this command won't do much, other than shrink the size of your RPM database by removing unused entries. This command will take some time to execute, though.

Warning

Before running this command, back up your RPM database.

To check that the rpm --rebuilddb command has not damaged the RPM database, you can check with a file listing, query all packages, and then check the results of the rpm –rebuilddb command with another file listing when done.

Another useful technique that can help with a corrupted RPM database is to use the db_dump and db_load utilities that come with RPM (from the SleepyCat DB database library). Use db_dump to dump the Packages file. Then, use db_load to reload the Packages file. The act of dumping and restoring may fix a corrupted file. As always, back up your RPM database prior to performing these commands.

Creating a new RPM database

If all else fails, use the --initdb option to tell the rpm command to create a new empty RPM database. In almost all cases, you do not want to create a new RPM database, since this database will be empty. It will not have any knowledge about the packages you have already installed on your system. That could lead to a lot of problems, since you have the files installed, but the RPM system just doesn’t know about them.

The basic syntax follows.

rpm --initdb

Note

This command should not damage an existing database.

If the RPM system cannot be rebuilt, you may have to reinstall the operating system to recreate a clean system. In general, if things are this far gone, reinstalling may be your best answer instead of wiping the RPM database and creating an empty database.

You can also use the --dbpath option to tell the rpm command to create an RPM database in a different directory.

For example:

mkdir /tmp/rpm

rpm --initdb --dbpath /tmp/rpm

These commands create a temporary directory and an RPM database in the /tmp/rpm directory.

After running this command, you can examine the files created.

# ls -l /tmp/rpm

total 288

-rw-r--r-- 1 root root 8192 Oct 10 20:29 __db.001

-rw-r--r-- 1 root root 1310720 Oct 10 20:29 __db.002

-rw-r--r-- 1 root root 360448 Oct 10 20:29 __db.003

-rw-r--r-- 1 root root 12288 Oct 10 20:29 Packages

This shows an empty RPM database.

Summary

This chapter covers the rpm command options to query the RPM database and RPM package files. You can determine the packages installed on your system, as well as which packages are responsible for the files on your system.

The RPM database maintains a lot of information about the files and packages on your system. Thus, it is crucial for managing your Linux systems. You should back up the RPM database before and after any installation, upgrade, or removal of packages.

You can also use the --rebuilddb option to the rpm command to rebuild a damaged RPM database.

Chapter 05

Chris Ricker

2003-01-27T09:20:00

Eric Foster-Johnson