Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

A script to locate the package that created a given file UNIX
Sometimes one needs to know what package a given file belongs to. Such information is contained in Archive.bom files that are added under the /Library/Recepits directory every time a package is installed. However, it's impractical to scan this folder for all Archive.bom files.

The findutils tool locate can be used to perform the task of mapping files to packages in a much more convenient way. It's enough to build a databse containing the required information in a format that locate is able to use, and then point locate to such database.

The database will contain a tab-separated list of file/package names; to produce such list we use find to obtain the list of all Archive.bom files, lsbom to list their contents, and a bit of bash magic to paste the file and package name. Once we have the list, we just need to sort it and to front-code it (using the frcode tool, from findutils).

The following script (that will be named updatepgkdb) performs exactly these steps:
#!/bin/bash
LANG=C
FRCODE=/sw/lib/locate/frcode
DB=~/.pkglocate.database

find /Library/Receipts -name Archive.bom | while read line; do 
  t=${line#/Library/Receipts/}
  pkgname=${t%.pkg/Contents/Archive.bom}
  lsbom -fs "$line" | perl -pe "s|$|t$pkgname|"
done | sort -f | $FRCODE > $DB
Notice that I used the Fink version of findutils, and that I store the database in a file in my home directory. It's enough to change FRCODE and DB variables to adapt the scirpt to your setup. After installing a package, you can simply run the script to update the database.

Once the databse has been created/updated, you can query it with locate, using the suitable option to specify the database location. Or you can use the following script (named locatepkg):
#!/bin/bash
LANG=C
LOCATE=/sw/bin/locate
DB=~/.pkglocate.database
$LOCATE -d $DB "$@"
That takes care of all the details. Again, you can change the LOCATE and DB variables to adapt the script to your setup. On my system, if I run...
$ updatepkgdb
$ locatepkg kcproxy
...what I got as output is:
./Applications/Utilities/Keychain Access.app/Contents/Resources/kcproxy AdditionalEssentials
./Applications/Utilities/Keychain Access.app/Contents/Resources/kcproxy MacOSXUpdateCombo10.3.9
The output first shows the full path to any matches for the kcproxy file, then there's a space, and after that, the name of the package containing the file. In this example, kcproxy is in both the AdditionalEssentials and the MacOSXUpdateCombo10.3.9 packages.
    •    
  • Currently 3.75 / 5
  You rated: 4 / 5 (4 votes cast)
 
[10,473 views]  

A script to locate the package that created a given file | 2 comments | Create New Account
Click here to return to the 'A script to locate the package that created a given file' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Darwinports alternative
Authored by: jokke on Mar 02, '06 12:13:12PM

For those who use Darwinports rather than Fink, there's a findutils as well. frcode is called gnufrcode and is placed in /opt/local/libexec/gnufrcode (at least on my machine).
Similarly, the locatepkg script needs to be updated with the new locate utility called gnulocate in /opt/local/bin/gnulocate. The Apple provided locate does not allow specification of a database file.

Apart from having to change a 't' to a space (lsbom -fs "$line" | perl -pe "s|$| $pkgname|") in the updatepkgdb script to produce readable output, this is a way cool script.

---
http://jokke.dk | Pulling the trigger at port 80



[ Reply to This | # ]
A script to locate the package that created a given file
Authored by: wgscott on Mar 02, '06 01:15:23PM
Gary Kerbaugh wrote two scripts, pkgrep and pkgdiff, to so similar sorts of things. I wrote a brief description and example and have posted it here: pkgdiff.html

[ Reply to This | # ]