rpm_finder.cxx - systemtap
Functions defined
Macros defined
Source code
#include "config.h"
#include "session.h"
#include "rpm_finder.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <cerrno>
#include <cstdlib>
using namespace std;
#ifdef HAVE_LIBRPM
extern "C" {
#define _RPM_4_4_COMPAT
#include <string.h>
#include <rpm/rpmlib.h>
#include <rpm/rpmts.h>
#include <rpm/rpmdb.h>
#include <rpm/header.h>
#ifndef xfree
#define xfree free
#endif
}
#if ! HAVE_LIBRPMIO && HAVE_NSS
extern "C" {
#include <nss.h>
}
#include "nsscommon.h"
#endif
static int
missing_rpm_enlist (systemtap_session& sess, const char *filename, const char *rpm_type)
{
static int rpm_init_done = 0;
rpmts ts;
rpmdbMatchIterator mi;
int count = 0;
if (filename == NULL)
return 0;
if (!rpm_init_done)
{
static int init_tried;
if (init_tried)
return 0;
init_tried = 1;
if (rpmReadConfigFiles(NULL, NULL) != 0)
{
cerr << _("Error reading the rpm configuration files") << endl;
return 0;
}
rpm_init_done = 1;
}
if (!sess.rpms_checked.insert(string(filename) + rpm_type).second)
return 0;
ts = rpmtsCreate();
mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
if (mi != NULL)
{
for (;;)
{
Header h;
char *rpminfo, *s, *s2;
char header[31] = {};
const char* arch = ".%{arch}";
sprintf(header, "%%{sourcerpm}%s%s", rpm_type, arch);
errmsg_t err;
size_t rpminfolen = strlen(rpm_type);
size_t srcrpmlen = sizeof (".src.rpm") - 1;
rpmdbMatchIterator mi_rpminfo;
h = rpmdbNextIterator(mi);
if (h == NULL)
break;
rpminfo = headerSprintf(h, header,
rpmTagTable, rpmHeaderFormats, &err);
if (!rpminfo)
{
cerr << _("Error querying the rpm file `") << filename << "': "
<< err << endl;
continue;
}
s = strrchr (rpminfo, '-') - srcrpmlen;
s2 = NULL;
if (s > rpminfo && memcmp (s, ".src.rpm", srcrpmlen) == 0)
{
s2 = (char *) memrchr (rpminfo, '-', s - rpminfo);
}
if (s2)
{
s2 = (char *) memrchr (rpminfo, '-', s2 - rpminfo);
}
if (!s2)
{
cerr << _("Error querying the rpm file `") << filename
<< "': " << rpminfo << endl;
xfree (rpminfo);
continue;
}
memmove (s2 + rpminfolen, s2, s - s2);
memcpy (s2, rpm_type, rpminfolen);
memmove (s + rpminfolen, s + srcrpmlen + rpminfolen,
strlen (s + srcrpmlen + rpminfolen) + 1);
mi_rpminfo = rpmtsInitIterator(ts, (rpmTag) RPMDBI_LABEL,
rpminfo, 0);
if (mi_rpminfo)
{
rpmdbFreeIterator(mi_rpminfo);
count = 0;
break;
}
if(strcmp(rpm_type,"-debuginfo")==0){
xfree(rpminfo);
rpminfo = headerSprintf(h,
"%{name}-%{version}-%{release}.%{arch}",
rpmTagTable, rpmHeaderFormats, &err);
}
if (!rpminfo)
{
cerr << _("Error querying the rpm file `") << filename
<< "': " << err << endl;
continue;
}
sess.rpms_to_install.insert(rpminfo);
}
count++;
rpmdbFreeIterator(mi);
}
rpmtsFree(ts);
#if HAVE_NSS
#if HAVE_LIBRPMIO
rpmFreeCrypto (); #else
nssCleanup (NULL); #endif
#endif
return count;
}
#endif
void
missing_rpm_list_print (systemtap_session &sess, const char* rpm_type)
{
#ifdef HAVE_LIBRPM
if (sess.rpms_to_install.size() > 0 && ! sess.suppress_warnings) {
if(strcmp(rpm_type,"-devel")==0)
cerr << _("Incorrect version or missing kernel-devel package, use: yum install ");
else if(strcmp(rpm_type,"-debuginfo")==0)
cerr << _("Missing separate debuginfos, use: debuginfo-install ");
else{
cerr << _("Incorrect parameter passed, please report this error.") << endl;
_exit(1);
}
for (set<std::string>::iterator it=sess.rpms_to_install.begin();
it !=sess.rpms_to_install.end(); it++)
{
cerr << *it << " ";
}
cerr << endl;
}
#endif
}
int
find_debug_rpms (systemtap_session &sess, const char * filename)
{
#ifdef HAVE_LIBRPM
const char *rpm_type = "-debuginfo";
return missing_rpm_enlist(sess, filename, rpm_type);
#else
return 0;
#endif
}
int find_devel_rpms(systemtap_session &sess, const char * filename)
{
#ifdef HAVE_LIBRPM
const char *rpm_type = "-devel";
return missing_rpm_enlist(sess, filename, rpm_type);
#else
return 0;
#endif
}