]> sourceware.org Git - systemtap.git/blame - rpm_finder.cxx
Consolidate task_finder/vma tracker initialization.
[systemtap.git] / rpm_finder.cxx
CommitLineData
2ed04863
WC
1// systemtap debuginfo rpm finder
2// Copyright (C) 2009 Red Hat Inc.
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
38/* Returns the count of newly added rpms. */
39/* based on the code in F11 gdb-6.8.50.20090302 source rpm */
40
41static int
42missing_rpm_enlist (systemtap_session& sess, const char *filename)
43{
44 static int rpm_init_done = 0;
45 rpmts ts;
46 rpmdbMatchIterator mi;
47 int count = 0;
48
49 if (filename == NULL)
50 return 0;
51
52 if (!rpm_init_done)
53 {
54 static int init_tried;
55
56 /* Already failed the initialization before? */
57 if (init_tried)
58 return 0;
59 init_tried = 1;
60
61 if (rpmReadConfigFiles(NULL, NULL) != 0)
62 {
63 cerr << "Error reading the rpm configuration files" << endl;
64 return 0;
65 }
66
67 rpm_init_done = 1;
68 }
69
70 ts = rpmtsCreate();
71
72 mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
73 if (mi != NULL)
74 {
75 for (;;)
76 {
77 Header h;
78 char *debuginfo, *s, *s2;
79 errmsg_t err;
80 size_t srcrpmlen = sizeof (".src.rpm") - 1;
81 size_t debuginfolen = sizeof ("-debuginfo") - 1;
82 rpmdbMatchIterator mi_debuginfo;
83
84 h = rpmdbNextIterator(mi);
85 if (h == NULL)
86 break;
87
88 /* Verify the debuginfo file is not already installed. */
89
90 debuginfo = headerSprintf(h, "%{sourcerpm}-debuginfo.%{arch}",
91 rpmTagTable, rpmHeaderFormats, &err);
92
93 if (!debuginfo)
94 {
95 cerr << "Error querying the rpm file `" << filename << "': "
96 << err << endl;
97 continue;
98 }
99 /* s = `.src.rpm-debuginfo.%{arch}' */
100 s = strrchr (debuginfo, '-') - srcrpmlen;
101 s2 = NULL;
102 if (s > debuginfo && memcmp (s, ".src.rpm", srcrpmlen) == 0)
103 {
104 /* s2 = `-%{release}.src.rpm-debuginfo.%{arch}' */
105 s2 = (char *) memrchr (debuginfo, '-', s - debuginfo);
106 }
107 if (s2)
108 {
109 /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
110 s2 = (char *) memrchr (debuginfo, '-', s2 - debuginfo);
111 }
112 if (!s2)
113 {
114 cerr << "Error querying the rpm file `" << filename
115 << "': " << debuginfo << endl;
116 xfree (debuginfo);
117 continue;
118 }
119 /* s = `.src.rpm-debuginfo.%{arch}' */
120 /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
121 memmove (s2 + debuginfolen, s2, s - s2);
122 memcpy (s2, "-debuginfo", debuginfolen);
123 /* s = `XXXX.%{arch}' */
124 /* strlen ("XXXX") == srcrpmlen + debuginfolen */
125 /* s2 = `-debuginfo-%{version}-%{release}XX.%{arch}' */
126 /* strlen ("XX") == srcrpmlen */
127 memmove (s + debuginfolen, s + srcrpmlen + debuginfolen,
128 strlen (s + srcrpmlen + debuginfolen) + 1);
129 /* s = `-debuginfo-%{version}-%{release}.%{arch}' */
130
131 /* RPMDBI_PACKAGES requires keylen == sizeof (int). */
132 /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */
133 mi_debuginfo = rpmtsInitIterator(ts, (rpmTag) RPMDBI_LABEL,
134 debuginfo, 0);
135 xfree (debuginfo);
136 if (mi_debuginfo)
137 {
138 rpmdbFreeIterator(mi_debuginfo);
139 count = 0;
140 break;
141 }
142
143 /* The allocated memory gets utilized below for MISSING_RPM_HASH. */
144 debuginfo = headerSprintf(h,
145 "%{name}-%{version}-%{release}.%{arch}",
146 rpmTagTable, rpmHeaderFormats, &err);
147 if (!debuginfo)
148 {
149 cerr << "Error querying the rpm file `" << filename
150 << "': " << err << endl;
151 continue;
152 }
153
154 /* Base package name for `debuginfo-install'. We do not use the
155 `yum' command directly as the line
156 yum --enablerepo='*-debuginfo' install NAME-debuginfo.ARCH
157 would be more complicated than just:
158 debuginfo-install NAME-VERSION-RELEASE.ARCH
159 Do not supply the rpm base name (derived from .src.rpm name) as
160 debuginfo-install is unable to install the debuginfo package if
161 the base name PKG binary rpm is not installed while for example
162 PKG-libs would be installed (RH Bug 467901).
163 FUTURE: After multiple debuginfo versions simultaneously installed
164 get supported the support for the VERSION-RELEASE tags handling
165 may need an update. */
166
167 sess.rpms_to_install.insert(debuginfo);
168 count++;
169 }
170
171 rpmdbFreeIterator(mi);
172 }
173
174 rpmtsFree(ts);
175
176 return count;
177}
178
179#endif /* HAVE_LIBRPM */
180
181void
182missing_rpm_list_print (systemtap_session &sess)
183{
184#ifdef HAVE_LIBRPM
185 if (sess.rpms_to_install.size() > 0) {
186 cerr << "Missing separate debuginfos, use: debuginfo-install ";
187 for (set<std::string>::iterator it=sess.rpms_to_install.begin();
188 it !=sess.rpms_to_install.end(); it++)
189 cerr << *it << " ";
190 cerr << endl;
191 }
192#endif
193}
194
195int
196find_debug_rpms (systemtap_session &sess, const char * filename)
197{
198#ifdef HAVE_LIBRPM
199 return missing_rpm_enlist (sess, filename);
200#else
201 return 0;
202#endif
203}
This page took 0.052791 seconds and 5 git commands to generate.