One really cool feature of ubuntu is the command-not-found script. If you try to execute a program, say, nmap – and that dpkg hasn’t been installed, the command-not-found script executes to parse a locally installed database to suggest, “hey, you should try executing # apt-get install nmap” or something similar.
This really makes ubuntu more user friendly. Fedora has the ability to use " # yum whatprovides <>” but yum is going to bomb out if you don’t have a working network connection. Yum’s first steps are to connect to online repositories to download filelists.sqlite.bz2, primary.sqlite,bz2, etc.
So what are these files? They are sqlite databases that contain data about what packages are available and the information about those packages… So lets say we’re looking for some binary called kde4-config, but I don’t have an active network connection…. What package contains that binary?
First, lets find all available instances of filelist.sqlite. Each fedora RPM repository is going to contain its own copy.
[cylon:/]
<svoboda>locate filelists.sqlite
/var/cache/yum/fedora/filelists.sqlite
/var/cache/yum/livna/filelists.sqlite
/var/cache/yum/updates/filelists.sqlite
/var/cache/yum/updates-newkey/filelists.sqlite
Cool – so there are 4 network repositories here. Lets mess around with the fedora repository first…
[cylon:/var/cache/yum/fedora]
<svoboda>ls -lh
total 89M
-rw-r--r-- 1 root root 0 2008-09-30 10:11 cachecookie
-rw-r--r-- 1 root root 58M 2008-09-17 13:46 filelists.sqlite
-rw-r--r-- 1 root root 2.0K 2008-09-30 07:19 mirrorlist.txt
drwxr-xr-x 2 root root 4.0K 2008-09-30 10:12 packages
-rw-r--r-- 1 root root 32M 2008-09-17 13:35 primary.sqlite
-rw-r--r-- 1 root root 2.4K 2008-09-30 10:11 repomd.xml
[cylon:/var/cache/yum/fedora]
<svoboda>file filelists.sqlite primary.sqlite
filelists.sqlite: SQLite 3.x database
primary.sqlite: SQLite 3.x database
Sure enough, they’re sqlite databases. Lets issue a select statement on filenames within the filelists.sqlite database and look for the kde4-config binary. First, lets take a peek at what we have available….
[cylon:/var/cache/yum/fedora]
<svoboda>sqlite3 filelists.sqlite
SQLite version 3.5.9
Enter ".help" for instructions
Before we get too deep, lets turn headers on and the output to column mode so things are a bit more readable…
sqlite> .headers on
sqlite> .mode column
Next, lets see what tables we have available…
sqlite> .tables
db_info filelist packages
Filelist looks interesting. What does it contain?
sqlite> .schema filelist
CREATE TABLE filelist ( pkgKey INTEGER, dirname TEXT, filenames
TEXT, filetypes TEXT);
CREATE INDEX dirnames ON filelist (dirname);
CREATE INDEX keyfile ON filelist (pkgKey);
sqlite> pragma table_info (filelist);
0|pkgKey|INTEGER|0||0
1|dirname|TEXT|0||0
2|filenames|TEXT|0||0
3|filetypes|TEXT|0||0
sqlite>
Cool. So lets extract the pkgKey and filenames column for any entries that contain the phrase “kde4-config” anywhere in the path…
sqlite> SELECT pkgKey,filenames FROM filelist
...> WHERE filenames LIKE '%kde4-config%';
pkgKey filenames
----------
---------------------------------------------------------------------------------------------
3703
preparetips/nepomuk-rcgen/meinproc4/kwrapper4/kunittestmodrunner/kshell4/kross/kjsconsole/kjscmd/kjs/kdeinit4_wrapper/kdeinit4_shutdown/kdeinit4/kded4/kde4automoc/kde4-doxygen.sh/kde4-config/kcookiejar4/kbuildsycoca4/checkXML
3703 kde4-config.1.gz/checkXML.1.gz
10746
preparetips/nepomuk-rcgen/meinproc4/kwrapper4/kunittestmodrunner/kshell4/kross/kjsconsole/kjscmd/kjs/kdeinit4_wrapper/kdeinit4_shutdown/kdeinit4/kded4/kde4automoc/kde4-doxygen.sh/kde4-config/kcookiejar4/kbuildsycoca4/checkXML
10746 kde4-config.1.gz/checkXML.1.gz
Awesome! We found something. It looks like we matched two packages – package 3703 and package 10746. Now, we just need to figure out what those packages are… Lets go peek in the second sqlite database file, primary.sqlite.
[cylon:/var/cache/yum/fedora]
<svoboda>sqlite3 primary.sqlite
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> .header on
sqlite> .mode column
sqlite> .tables
conflicts db_info files obsoletes packages provides
requires
sqlite>
What does the packages table look like?
sqlite> pragma table_info (packages);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 pkgKey INTEGER 0 1
1 pkgId TEXT 0 0
2 name TEXT 0 0
3 arch TEXT 0 0
4 version TEXT 0 0
5 epoch TEXT 0 0
6 release TEXT 0 0
7 summary TEXT 0 0
8 descriptio TEXT 0 0
9 url TEXT 0 0
10 time_file INTEGER 0 0
11 time_build INTEGER 0 0
12 rpm_licens TEXT 0 0
13 rpm_vendor TEXT 0 0
14 rpm_group TEXT 0 0
15 rpm_buildh TEXT 0 0
16 rpm_source TEXT 0 0
17 rpm_header INTEGER 0 0
18 rpm_header INTEGER 0 0
19 rpm_packag TEXT 0 0
20 size_packa INTEGER 0 0
21 size_insta INTEGER 0 0
22 size_archi INTEGER 0 0
23 location_h TEXT 0 0
24 location_b TEXT 0 0
25 checksum_t TEXT 0 0
Cool. We want to match the name of the package that has the pkgKey
entries 3703 or 10746. Lets adjust our width so we don't get truncated
values displayed to the screen...
sqlite> .width 10 50
And query aganist that pkgKey value.
sqlite> SELECT name,location_href FROM packages
...> WHERE pkgKey = 3703;
name location_href
---------- --------------------------------------------------
kdelibs Packages/kdelibs-4.0.3-7.fc9.i386.rpm
sqlite> SELECT name,location_href FROM packages
...> WHERE pkgKey = 10746;
name location_href
---------- --------------------------------------------------
kdelibs Packages/kdelibs-4.0.3-7.fc9.x86_64.rpm