How to locate a named file anywhere in the rpm database

How to list packages that contain a file name.

[For my own purposes I want to find matches whether or not they
are in the same directories. You can modify this yourself if you
only want to find exact matches including paths.]

Not just one file name at a time. You can pass this a whole list
of 'em and in fact depending on your needs, this could cut down the
amount of time it takes to collect the data.

You can load this (see code snippet below) as a text file. Name it
something like ‘rpm.src’ and type

source ‘rpm.src’

to load it.


#########################################################################
# Locates all occurrances of each filename listed and which package it is
# found in.
#########################################################################

rpm.db_locatefiles() # <list of files> prints package and full path
{
  # error check
  if  "$1" == "" ]; then echo "Need a filename(s) to locate"; return; fi
    
  # status report
  echo "Creating package list..."
  
  # init some non-global vars
  local findfiles="$@"
  local filelist=""
  local bname=""
  
  # get the package list (one of the time consuming parts)
  local pkglist=`rpm -qa`
  
  # status report again
  echo "Searching packages..."
  
  # loop by package name
  for i in $pkglist; do
    
    # simple progress inidcator so we know we haven't stalled out
    printf "." 
    
      # get the list of files (another time consuming part)
      filelist=`rpm -q --fileprovide $i`
      
      # loop by file named in the rpm database = ii
      for ii in $filelist; do
        
        # extract the base name from the full path
        bname=`basename $ii`
        
        # loop by files in the list input by the user
        for file in $findfiles; do
          # show package name, newline, indent, and full path from rpm database
          if  "$bname" == "$file" ]; then
            echo
            echo "Found in $i"
            echo "  $ii"
          fi
        done
      done
  done
}

Then let’s test it.

Let’s go to /usr/bin and look up all the files there.

Type this
list=$(cd /usr/bin && find * -maxdepth 0 -type f)

That will change to the /usr/bin folder temporarily and if the
directory exists it will also &&] execute ‘find’ in that directory
returning the string $(…)] of filenames collected.

We want to eliminate subdirectories because we don’t want slashes in the
names so we tell find the maxdepth to search is 0, which confines us to
the current directory (which is only in effect inside the parens).

Finally, we want to make sure we only get actual file names. This will
miss symlinks, but that’s ok for now, eh?

Now we test.

rpm.db_locatefiles $list

And sit back and watch. :slight_smile:

This may be useful in discovering packages that a source installation
has clobbered.

For example, I just ran it on my PREFIX/bin and PREFIX/lib and
PREFIX/share/qt folders and made a list of all the packages the qt4
source installation clobbers and/or obsoletes.

But it’s also useful for…

…well, just for fun! :slight_smile:

Give it a spin. See what you think.