]> sourceware.org Git - systemtap.git/blame - rpm_finder.cxx
tracepoints: Work with the tracequery's .o rather than .ko
[systemtap.git] / rpm_finder.cxx
CommitLineData
2ed04863 1// systemtap debuginfo rpm finder
1e6e9ec1 2// Copyright (C) 2009-2011 Red Hat Inc.
2ed04863
WC
3//
4// This file is part of systemtap, and is free software. You can
5// redistribute it and/or modify it under the terms of the GNU General
6// Public License (GPL); either version 2, or (at your option) any
7// later version.
8
9#include "config.h"
10#include "session.h"
11#include "rpm_finder.h"
12
13#include <iostream>
14#include <fstream>
15#include <sstream>
16#include <cerrno>
17#include <cstdlib>
18
19using namespace std;
20
21#ifdef HAVE_LIBRPM
22
23extern "C" {
24
25#define _RPM_4_4_COMPAT
26#include <string.h>
27#include <rpm/rpmlib.h>
28#include <rpm/rpmts.h>
29#include <rpm/rpmdb.h>
30#include <rpm/header.h>
31
32#ifndef xfree
33#define xfree free
34#endif
35
36}
37
d389518f
DB
38#if ! HAVE_LIBRPMIO && HAVE_NSS
39extern "C" {
40#include <nss.h>
41}
9a0b2b7c 42#include "nsscommon.h"
d389518f
DB
43#endif
44
2ed04863
WC
45/* Returns the count of newly added rpms. */
46/* based on the code in F11 gdb-6.8.50.20090302 source rpm */
76c87907 47/* Added in the rpm_type parameter to specify what rpm to look for */
2ed04863
WC
48
49static int
76c87907 50missing_rpm_enlist (systemtap_session& sess, const char *filename, const char *rpm_type)
2ed04863
WC
51{
52 static int rpm_init_done = 0;
53 rpmts ts;
54 rpmdbMatchIterator mi;
55 int count = 0;
56
57 if (filename == NULL)
58 return 0;
59
60 if (!rpm_init_done)
61 {
62 static int init_tried;
63
64 /* Already failed the initialization before? */
65 if (init_tried)
66 return 0;
67 init_tried = 1;
68
69 if (rpmReadConfigFiles(NULL, NULL) != 0)
70 {
efee9a98 71 cerr << _("Error reading the rpm configuration files") << endl;
2ed04863
WC
72 return 0;
73 }
74
75 rpm_init_done = 1;
76 }
77
76c87907 78 ts = rpmtsCreate();
2ed04863
WC
79
80 mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
81 if (mi != NULL)
82 {
83 for (;;)
84 {
85 Header h;
76c87907
LB
86 char *rpminfo, *s, *s2;
87 char header[31] = {};
88 const char* arch = ".%{arch}";
89 sprintf(header, "%%{sourcerpm}%s%s", rpm_type, arch);
2ed04863 90 errmsg_t err;
76c87907 91 size_t rpminfolen = strlen(rpm_type);
2ed04863 92 size_t srcrpmlen = sizeof (".src.rpm") - 1;
76c87907 93 rpmdbMatchIterator mi_rpminfo;
2ed04863
WC
94 h = rpmdbNextIterator(mi);
95 if (h == NULL)
96 break;
76c87907 97 /* Verify the kernel file is not already installed. */
2ed04863 98
76c87907
LB
99 rpminfo = headerSprintf(h, header,
100 rpmTagTable, rpmHeaderFormats, &err);
2ed04863 101
76c87907 102 if (!rpminfo)
2ed04863 103 {
efee9a98 104 cerr << _("Error querying the rpm file `") << filename << "': "
2ed04863
WC
105 << err << endl;
106 continue;
107 }
108 /* s = `.src.rpm-debuginfo.%{arch}' */
76c87907 109 s = strrchr (rpminfo, '-') - srcrpmlen;
2ed04863 110 s2 = NULL;
76c87907 111 if (s > rpminfo && memcmp (s, ".src.rpm", srcrpmlen) == 0)
2ed04863
WC
112 {
113 /* s2 = `-%{release}.src.rpm-debuginfo.%{arch}' */
76c87907 114 s2 = (char *) memrchr (rpminfo, '-', s - rpminfo);
2ed04863
WC
115 }
116 if (s2)
117 {
118 /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
76c87907 119 s2 = (char *) memrchr (rpminfo, '-', s2 - rpminfo);
2ed04863
WC
120 }
121 if (!s2)
122 {
efee9a98 123 cerr << _("Error querying the rpm file `") << filename
76c87907
LB
124 << "': " << rpminfo << endl;
125 xfree (rpminfo);
2ed04863
WC
126 continue;
127 }
128 /* s = `.src.rpm-debuginfo.%{arch}' */
129 /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
76c87907
LB
130 memmove (s2 + rpminfolen, s2, s - s2);
131 memcpy (s2, rpm_type, rpminfolen);
2ed04863
WC
132 /* s = `XXXX.%{arch}' */
133 /* strlen ("XXXX") == srcrpmlen + debuginfolen */
134 /* s2 = `-debuginfo-%{version}-%{release}XX.%{arch}' */
135 /* strlen ("XX") == srcrpmlen */
76c87907
LB
136 memmove (s + rpminfolen, s + srcrpmlen + rpminfolen,
137 strlen (s + srcrpmlen + rpminfolen) + 1);
2ed04863
WC
138 /* s = `-debuginfo-%{version}-%{release}.%{arch}' */
139
140 /* RPMDBI_PACKAGES requires keylen == sizeof (int). */
141 /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */
76c87907
LB
142 mi_rpminfo = rpmtsInitIterator(ts, (rpmTag) RPMDBI_LABEL,
143 rpminfo, 0);
144 if (mi_rpminfo)
2ed04863 145 {
76c87907 146 rpmdbFreeIterator(mi_rpminfo);
2ed04863
WC
147 count = 0;
148 break;
149 }
2ed04863 150 /* The allocated memory gets utilized below for MISSING_RPM_HASH. */
76c87907
LB
151 if(strcmp(rpm_type,"-debuginfo")==0){
152 xfree(rpminfo);
153 rpminfo = headerSprintf(h,
154 "%{name}-%{version}-%{release}.%{arch}",
155 rpmTagTable, rpmHeaderFormats, &err);
156 }
157 if (!rpminfo)
2ed04863 158 {
efee9a98 159 cerr << _("Error querying the rpm file `") << filename
2ed04863
WC
160 << "': " << err << endl;
161 continue;
162 }
163
164 /* Base package name for `debuginfo-install'. We do not use the
76c87907
LB
165 `yum' command directly as the line
166 yum --enablerepo='*-debuginfo' install NAME-debuginfo.ARCH
167 would be more complicated than just:
168 debuginfo-install NAME-VERSION-RELEASE.ARCH
169 Do not supply the rpm base name (derived from .src.rpm name) as
170 debuginfo-install is unable to install the debuginfo package if
171 the base name PKG binary rpm is not installed while for example
172 PKG-libs would be installed (RH Bug 467901).
173 FUTURE: After multiple debuginfo versions simultaneously installed
174 get supported the support for the VERSION-RELEASE tags handling
175 may need an update. */
176 sess.rpms_to_install.insert(rpminfo);
177 }
178 count++;
2ed04863
WC
179 rpmdbFreeIterator(mi);
180 }
181
182 rpmtsFree(ts);
d389518f
DB
183
184#if HAVE_NSS
185 // librpm uses NSS cryptography but doesn't shut down NSS when it is done.
186 // If NSS is available, it will be used by the compile server client on
187 // specific certificate databases and thus, it must be shut down first.
188 // Get librpm to do it if we can. Otherwise do it ourselves.
189#if HAVE_LIBRPMIO
190 rpmFreeCrypto (); // Shuts down NSS within librpm
191#else
aeb9cc10 192 nssCleanup (NULL); // Shut down NSS ourselves
d389518f
DB
193#endif
194#endif
195
2ed04863
WC
196 return count;
197}
2ed04863
WC
198#endif /* HAVE_LIBRPM */
199
200void
76c87907 201missing_rpm_list_print (systemtap_session &sess, const char* rpm_type)
2ed04863
WC
202{
203#ifdef HAVE_LIBRPM
c05365e6 204 if (sess.rpms_to_install.size() > 0 && ! sess.suppress_warnings) {
76c87907
LB
205
206 if(strcmp(rpm_type,"-devel")==0)
efee9a98 207 cerr << _("Incorrect version or missing kernel-devel package, use: yum install ");
76c87907
LB
208
209 else if(strcmp(rpm_type,"-debuginfo")==0)
efee9a98 210 cerr << _("Missing separate debuginfos, use: debuginfo-install ");
76c87907
LB
211
212 else{
efee9a98 213 cerr << _("Incorrect parameter passed, please report this error.") << endl;
76c87907
LB
214 _exit(1);
215 }
216
2ed04863
WC
217 for (set<std::string>::iterator it=sess.rpms_to_install.begin();
218 it !=sess.rpms_to_install.end(); it++)
76c87907 219 {
2ed04863 220 cerr << *it << " ";
76c87907 221 }
2ed04863
WC
222 cerr << endl;
223 }
224#endif
225}
226
227int
228find_debug_rpms (systemtap_session &sess, const char * filename)
229{
230#ifdef HAVE_LIBRPM
76c87907
LB
231 const char *rpm_type = "-debuginfo";
232 return missing_rpm_enlist(sess, filename, rpm_type);
233#else
234 return 0;
235#endif
236}
237
238int find_devel_rpms(systemtap_session &sess, const char * filename)
239{
240#ifdef HAVE_LIBRPM
241 const char *rpm_type = "-devel";
242 return missing_rpm_enlist(sess, filename, rpm_type);
2ed04863
WC
243#else
244 return 0;
245#endif
246}
This page took 0.077518 seconds and 5 git commands to generate.