1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
// cmdline_show_broken.cc
//
// Copyright 2004 Daniel Burrows
// Copyright 2015 Manuel A. Fernandez Montecelo
#include "cmdline_show_broken.h"
#include "cmdline_common.h"
#include "aptitude.h"
#include "generic/apt/apt.h"
#include <cstdio>
#include <cstring>
using namespace std;
/** Helper function for other functions in this file showing information about
* broken packages, to print an explanation about the installability of the
* package provided.
*
* For example, a broken package might be so because it conflicts with a package
* that remains installed, or depends on a version of a package not to be
* installed, or depends on a package but the user requested it to be removed,
* etc.
*
* @pkg The package to consider
*/
void print_installation_explanation(const pkgCache::PkgIterator& pkg)
{
pkgCache::VerIterator ver = (*apt_cache_file)[pkg].InstVerIter(*apt_cache_file);
if (!ver.end()) // ok, it's installable.
{
if ((*apt_cache_file)[pkg].Install())
printf(_("but %s is to be installed."),
ver.VerStr());
else if ((*apt_cache_file)[pkg].Upgradable())
printf(_("but %s is installed and it is kept back."),
pkg.CurrentVer().VerStr());
else
printf(_("but %s is installed."),
pkg.CurrentVer().VerStr());
}
else
{
pkgCache::VerIterator cand = (*apt_cache_file)[pkg].CandidateVerIter(*apt_cache_file);
if (cand.end())
printf(_("but it is not installable."));
else
printf(_("but it is not going to be installed."));
}
}
void show_broken_deps(const pkgCache::PkgIterator& pkg)
{
string pkg_name_segment = string(" ") + pkg.FullName(true) + " :";
const unsigned int indent = pkg_name_segment.length();
cout << pkg_name_segment;
pkgCache::VerIterator ver = (*apt_cache_file)[pkg].InstVerIter(*apt_cache_file);
if (ver.end() == true)
{
cout << endl;
return;
}
bool is_first_dep = true;
for (pkgCache::DepIterator dep = ver.DependsList(); !dep.end(); ++dep)
{
pkgCache::DepIterator first = dep, prev = dep;
while (dep->CompareOp & pkgCache::Dep::Or)
++dep;
// Yep, it's broken.
if (dep.IsCritical() &&
!((*apt_cache_file)[dep]&pkgDepCache::DepGInstall))
{
bool is_first_of_or = true;
// Iterate over the OR group, print out the information.
do
{
if (!is_first_dep)
for (unsigned int i = 0; i < indent; ++i)
printf(" ");
is_first_dep = false;
size_t indent_dep = strlen(dep.DepType()) + 3;
if (!is_first_of_or)
for (size_t i = 0; i < indent_dep; ++i)
printf(" ");
else
printf(" %s: ", first.DepType());
is_first_of_or = false;
cout << first.TargetPkg().FullName(true);
if (first.TargetVer())
printf(" (%s %s)", first.CompType(), first.TargetVer());
pkgCache::PkgIterator target = first.TargetPkg();
// Don't skip real packages which are provided.
if (!target.VersionList().end())
{
printf(" ");
print_installation_explanation(target);
}
else
{
if (target.ProvidesList().end())
{
printf(_(" which is a virtual package and is not provided by any available package.\n"));
}
else
{
printf(_(" which is a virtual package, provided by:\n"));
for (pkgCache::PrvIterator prv = target.ProvidesList(); !prv.end(); ++prv)
{
pkgCache::PkgIterator prv_pkg = prv.OwnerPkg();
if (!prv_pkg.end())
{
for (size_t i = 0; i < (indent + indent_dep); ++i)
printf(" ");
printf(" - %s, ", prv_pkg.FullName(true).c_str());
print_installation_explanation(prv_pkg);
}
}
}
}
if (first != dep)
printf(_(" or"));
printf("\n");
prev = first;
++first;
} while (prev != dep);
}
}
}
bool show_broken()
{
pkgvector broken;
for (pkgCache::PkgIterator i = (*apt_cache_file)->PkgBegin(); !i.end(); ++i)
{
if ((*apt_cache_file)[i].InstBroken())
broken.push_back(i);
}
if (!broken.empty())
{
printf(_("The following packages have unmet dependencies:\n"));
for (pkgvector::const_iterator pkg = broken.begin(); pkg != broken.end(); ++pkg)
show_broken_deps(*pkg);
return false;
}
return true;
}
|