]> git.saurik.com Git - apt.git/blame - apt-private/private-output.cc
edsp: ask policy engine for the pin of the version directly
[apt.git] / apt-private / private-output.cc
CommitLineData
b9179170
MV
1// Include files /*{{{*/
2#include<config.h>
3
4#include <apt-pkg/configuration.h>
5#include <apt-pkg/strutl.h>
6#include <apt-pkg/error.h>
7#include <apt-pkg/cachefile.h>
8#include <apt-pkg/pkgrecords.h>
9#include <apt-pkg/policy.h>
453b82a3
DK
10#include <apt-pkg/depcache.h>
11#include <apt-pkg/pkgcache.h>
12#include <apt-pkg/cacheiterators.h>
b9179170 13
453b82a3
DK
14#include <apt-private/private-output.h>
15#include <apt-private/private-cachefile.h>
16
17#include <regex.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
b9179170
MV
21#include <iomanip>
22#include <iostream>
b9179170
MV
23#include <langinfo.h>
24#include <unistd.h>
3163087b 25#include <signal.h>
d287a035 26#include <sys/ioctl.h>
b9179170 27
a0c19a21
DK
28#include <sstream>
29
b9179170
MV
30#include <apti18n.h>
31 /*}}}*/
32
33using namespace std;
34
35std::ostream c0out(0);
36std::ostream c1out(0);
37std::ostream c2out(0);
38std::ofstream devnull("/dev/null");
3163087b
MV
39
40
b9179170
MV
41unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
42
3163087b
MV
43// SigWinch - Window size change signal handler /*{{{*/
44// ---------------------------------------------------------------------
45/* */
46static void SigWinch(int)
47{
48 // Riped from GNU ls
49#ifdef TIOCGWINSZ
50 struct winsize ws;
51
52 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
53 ScreenWidth = ws.ws_col - 1;
54#endif
55}
56 /*}}}*/
d9e518c6 57bool InitOutput(std::basic_streambuf<char> * const out) /*{{{*/
b9179170 58{
33b813ce
MV
59 if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
60 _config->Set("quiet","1");
61
d9e518c6
DK
62 c0out.rdbuf(out);
63 c1out.rdbuf(out);
64 c2out.rdbuf(out);
b9179170
MV
65 if (_config->FindI("quiet",0) > 0)
66 c0out.rdbuf(devnull.rdbuf());
67 if (_config->FindI("quiet",0) > 1)
68 c1out.rdbuf(devnull.rdbuf());
69
3163087b
MV
70 // deal with window size changes
71 signal(SIGWINCH,SigWinch);
72 SigWinch(0);
73
b9179170
MV
74 if(!isatty(1))
75 {
76 _config->Set("APT::Color", "false");
77 _config->Set("APT::Color::Highlight", "");
78 _config->Set("APT::Color::Neutral", "");
79 } else {
80 // Colors
81 _config->CndSet("APT::Color::Highlight", "\x1B[32m");
82 _config->CndSet("APT::Color::Neutral", "\x1B[0m");
83
84 _config->CndSet("APT::Color::Red", "\x1B[31m");
85 _config->CndSet("APT::Color::Green", "\x1B[32m");
86 _config->CndSet("APT::Color::Yellow", "\x1B[33m");
87 _config->CndSet("APT::Color::Blue", "\x1B[34m");
88 _config->CndSet("APT::Color::Magenta", "\x1B[35m");
89 _config->CndSet("APT::Color::Cyan", "\x1B[36m");
90 _config->CndSet("APT::Color::White", "\x1B[37m");
91 }
92
93 return true;
94}
ee0167c4 95 /*}}}*/
65512241 96static std::string GetArchiveSuite(pkgCacheFile &/*CacheFile*/, pkgCache::VerIterator ver) /*{{{*/
b9179170
MV
97{
98 std::string suite = "";
2847bed0 99 if (ver && ver.FileList())
b9179170
MV
100 {
101 pkgCache::VerFileIterator VF = ver.FileList();
102 for (; VF.end() == false ; ++VF)
103 {
960975a1
MV
104 if(VF.File() == NULL || VF.File().Archive() == NULL)
105 suite = suite + "," + _("unknown");
106 else
107 suite = suite + "," + VF.File().Archive();
b9179170
MV
108 //suite = VF.File().Archive();
109 }
110 suite = suite.erase(0, 1);
111 }
112 return suite;
113}
ee0167c4 114 /*}}}*/
c3ccac92 115static std::string GetFlagsStr(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)/*{{{*/
b9179170
MV
116{
117 pkgDepCache *DepCache = CacheFile.GetDepCache();
118 pkgDepCache::StateCache &state = (*DepCache)[P];
119
120 std::string flags_str;
121 if (state.NowBroken())
122 flags_str = "B";
7d1b93d9 123 if (P.CurrentVer() && state.Upgradable() && state.CandidateVer != NULL)
b9179170
MV
124 flags_str = "g";
125 else if (P.CurrentVer() != NULL)
126 flags_str = "i";
127 else
128 flags_str = "-";
129 return flags_str;
130}
ee0167c4 131 /*}}}*/
c3ccac92 132static std::string GetCandidateVersion(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)/*{{{*/
b9179170
MV
133{
134 pkgPolicy *policy = CacheFile.GetPolicy();
135 pkgCache::VerIterator cand = policy->GetCandidateVer(P);
136
137 return cand ? cand.VerStr() : "(none)";
138}
ee0167c4 139 /*}}}*/
65512241 140static std::string GetInstalledVersion(pkgCacheFile &/*CacheFile*/, pkgCache::PkgIterator P)/*{{{*/
b9179170
MV
141{
142 pkgCache::VerIterator inst = P.CurrentVer();
143
144 return inst ? inst.VerStr() : "(none)";
145}
ee0167c4 146 /*}}}*/
65512241 147static std::string GetVersion(pkgCacheFile &/*CacheFile*/, pkgCache::VerIterator V)/*{{{*/
b9179170
MV
148{
149 pkgCache::PkgIterator P = V.ParentPkg();
150 if (V == P.CurrentVer())
151 {
14109555
MV
152 std::string inst_str = DeNull(V.VerStr());
153#if 0 // FIXME: do we want this or something like this?
b9179170
MV
154 pkgDepCache *DepCache = CacheFile.GetDepCache();
155 pkgDepCache::StateCache &state = (*DepCache)[P];
b9179170
MV
156 if (state.Upgradable())
157 return "**"+inst_str;
14109555 158#endif
b9179170
MV
159 return inst_str;
160 }
161
162 if(V)
163 return DeNull(V.VerStr());
164 return "(none)";
165}
ee0167c4 166 /*}}}*/
c3ccac92 167static std::string GetArchitecture(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)/*{{{*/
b9179170 168{
2409df55
DK
169 if (P->CurrentVer == 0)
170 {
171 pkgDepCache * const DepCache = CacheFile.GetDepCache();
172 pkgDepCache::StateCache const &state = (*DepCache)[P];
173 if (state.CandidateVer != NULL)
174 {
175 pkgCache::VerIterator const CandV(CacheFile, state.CandidateVer);
176 return CandV.Arch();
177 }
178 else
179 {
180 pkgCache::VerIterator const V = P.VersionList();
181 if (V.end() == false)
182 return V.Arch();
183 else
184 return P.Arch();
185 }
186 }
187 else
188 return P.CurrentVer().Arch();
b9179170 189}
ee0167c4 190 /*}}}*/
c3ccac92 191static std::string GetShortDescription(pkgCacheFile &CacheFile, pkgRecords &records, pkgCache::PkgIterator P)/*{{{*/
b9179170
MV
192{
193 pkgPolicy *policy = CacheFile.GetPolicy();
194
195 pkgCache::VerIterator ver;
196 if (P.CurrentVer())
197 ver = P.CurrentVer();
198 else
199 ver = policy->GetCandidateVer(P);
200
201 std::string ShortDescription = "(none)";
202 if(ver)
203 {
3d8232bf
DK
204 pkgCache::DescIterator const Desc = ver.TranslatedDescription();
205 if (Desc.end() == false)
206 {
207 pkgRecords::Parser & parser = records.Lookup(Desc.FileList());
208 ShortDescription = parser.ShortDesc();
209 }
b9179170
MV
210 }
211 return ShortDescription;
212}
ee0167c4 213 /*}}}*/
1a68655d
DK
214static std::string GetLongDescription(pkgCacheFile &CacheFile, pkgRecords &records, pkgCache::PkgIterator P)/*{{{*/
215{
216 pkgPolicy *policy = CacheFile.GetPolicy();
217
218 pkgCache::VerIterator ver;
219 if (P->CurrentVer != 0)
220 ver = P.CurrentVer();
221 else
222 ver = policy->GetCandidateVer(P);
223
224 std::string const EmptyDescription = "(none)";
225 if(ver.end() == true)
226 return EmptyDescription;
227
228 pkgCache::DescIterator const Desc = ver.TranslatedDescription();
3d8232bf
DK
229 if (Desc.end() == false)
230 {
231 pkgRecords::Parser & parser = records.Lookup(Desc.FileList());
232 std::string const longdesc = parser.LongDesc();
233 if (longdesc.empty() == false)
234 return SubstVar(longdesc, "\n ", "\n ");
235 }
236 return EmptyDescription;
1a68655d
DK
237}
238 /*}}}*/
ee0167c4 239void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, /*{{{*/
1a68655d
DK
240 pkgCache::VerIterator const &V, std::ostream &out,
241 std::string const &format)
b9179170 242{
2409df55
DK
243 pkgCache::PkgIterator const P = V.ParentPkg();
244 pkgDepCache * const DepCache = CacheFile.GetDepCache();
245 pkgDepCache::StateCache const &state = (*DepCache)[P];
b9179170 246
2409df55 247 std::string output;
b9179170 248 if (_config->FindB("APT::Cmd::use-format", false))
2409df55
DK
249 output = _config->Find("APT::Cmd::format", "${db::Status-Abbrev} ${Package} ${Version} ${Origin} ${Description}");
250 else
1a68655d 251 output = format;
2409df55
DK
252
253 // FIXME: some of these names are really icky – and all is nowhere documented
254 output = SubstVar(output, "${db::Status-Abbrev}", GetFlagsStr(CacheFile, P));
255 output = SubstVar(output, "${Package}", P.Name());
256 std::string const ArchStr = GetArchitecture(CacheFile, P);
257 output = SubstVar(output, "${Architecture}", ArchStr);
258 std::string const InstalledVerStr = GetInstalledVersion(CacheFile, P);
259 output = SubstVar(output, "${installed:Version}", InstalledVerStr);
260 std::string const CandidateVerStr = GetCandidateVersion(CacheFile, P);
261 output = SubstVar(output, "${candidate:Version}", CandidateVerStr);
262 std::string const VersionStr = GetVersion(CacheFile, V);
263 output = SubstVar(output, "${Version}", VersionStr);
264 output = SubstVar(output, "${Origin}", GetArchiveSuite(CacheFile, V));
265
266 std::string StatusStr = "";
267 if (P->CurrentVer != 0)
268 {
269 if (P.CurrentVer() == V)
7d1b93d9 270 {
2409df55
DK
271 if (state.Upgradable() && state.CandidateVer != NULL)
272 strprintf(StatusStr, _("[installed,upgradable to: %s]"),
273 CandidateVerStr.c_str());
274 else if (V.Downloadable() == false)
275 StatusStr = _("[installed,local]");
276 else if(V.Automatic() == true && state.Garbage == true)
277 StatusStr = _("[installed,auto-removable]");
278 else if ((state.Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
279 StatusStr = _("[installed,automatic]");
280 else
281 StatusStr = _("[installed]");
b9179170 282 }
2409df55
DK
283 else if (state.CandidateVer == V && state.Upgradable())
284 strprintf(StatusStr, _("[upgradable from: %s]"),
285 InstalledVerStr.c_str());
286 }
287 else if (V.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles)
288 StatusStr = _("[residual-config]");
289 output = SubstVar(output, "${apt:Status}", StatusStr);
290 output = SubstVar(output, "${color:highlight}", _config->Find("APT::Color::Highlight", ""));
291 output = SubstVar(output, "${color:neutral}", _config->Find("APT::Color::Neutral", ""));
2409df55 292 output = SubstVar(output, "${Description}", GetShortDescription(CacheFile, records, P));
adb4f2c5
AW
293 if (output.find("${LongDescription}") != string::npos)
294 output = SubstVar(output, "${LongDescription}", GetLongDescription(CacheFile, records, P));
1a68655d
DK
295 output = SubstVar(output, "${ }${ }", "${ }");
296 output = SubstVar(output, "${ }\n", "\n");
297 output = SubstVar(output, "${ }", " ");
298 if (APT::String::Endswith(output, " ") == true)
299 output.erase(output.length() - 1);
2409df55
DK
300
301 out << output;
b9179170 302}
ee0167c4 303 /*}}}*/
b9179170
MV
304// ShowBroken - Debugging aide /*{{{*/
305// ---------------------------------------------------------------------
306/* This prints out the names of all the packages that are broken along
307 with the name of each each broken dependency and a quite version
308 description.
309
310 The output looks like:
311 The following packages have unmet dependencies:
312 exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
313 Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
314 Depends: libsasl7 but it is not going to be installed
315 */
d39d7f88 316static void ShowBrokenPackage(ostream &out, pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg, bool const Now)
b9179170 317{
d39d7f88
DK
318 if (Now == true)
319 {
320 if ((*Cache)[Pkg].NowBroken() == false)
321 return;
322 }
323 else
324 {
325 if ((*Cache)[Pkg].InstBroken() == false)
326 return;
327 }
328
329 // Print out each package and the failed dependencies
330 out << " " << Pkg.FullName(true) << " :";
331 unsigned const Indent = Pkg.FullName(true).size() + 3;
332 bool First = true;
333 pkgCache::VerIterator Ver;
334
335 if (Now == true)
336 Ver = Pkg.CurrentVer();
337 else
338 Ver = (*Cache)[Pkg].InstVerIter(*Cache);
339
340 if (Ver.end() == true)
341 {
342 out << endl;
b9179170 343 return;
d39d7f88 344 }
b9179170 345
d39d7f88 346 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
b9179170 347 {
d39d7f88
DK
348 // Compute a single dependency element (glob or)
349 pkgCache::DepIterator Start;
350 pkgCache::DepIterator End;
351 D.GlobOr(Start,End); // advances D
352
353 if ((*Cache)->IsImportantDep(End) == false)
354 continue;
355
b9179170
MV
356 if (Now == true)
357 {
d39d7f88 358 if (((*Cache)[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
b9179170
MV
359 continue;
360 }
361 else
362 {
d39d7f88 363 if (((*Cache)[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
b9179170
MV
364 continue;
365 }
d39d7f88
DK
366
367 bool FirstOr = true;
368 while (1)
b9179170 369 {
d39d7f88
DK
370 if (First == false)
371 for (unsigned J = 0; J != Indent; J++)
372 out << ' ';
373 First = false;
b9179170 374
d39d7f88 375 if (FirstOr == false)
b9179170 376 {
d39d7f88
DK
377 for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
378 out << ' ';
b9179170
MV
379 }
380 else
d39d7f88
DK
381 out << ' ' << End.DepType() << ": ";
382 FirstOr = false;
383
384 out << Start.TargetPkg().FullName(true);
385
386 // Show a quick summary of the version requirements
387 if (Start.TargetVer() != 0)
388 out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
389
390 /* Show a summary of the target package if possible. In the case
391 of virtual packages we show nothing */
392 pkgCache::PkgIterator Targ = Start.TargetPkg();
393 if (Targ->ProvidesList == 0)
b9179170 394 {
d39d7f88
DK
395 out << ' ';
396 pkgCache::VerIterator Ver = (*Cache)[Targ].InstVerIter(*Cache);
397 if (Now == true)
398 Ver = Targ.CurrentVer();
b9179170 399
d39d7f88 400 if (Ver.end() == false)
b9179170 401 {
d39d7f88
DK
402 if (Now == true)
403 ioprintf(out,_("but %s is installed"),Ver.VerStr());
404 else
405 ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
b9179170
MV
406 }
407 else
b9179170 408 {
d39d7f88 409 if ((*Cache)[Targ].CandidateVerIter(*Cache).end() == true)
b9179170 410 {
d39d7f88
DK
411 if (Targ->ProvidesList == 0)
412 out << _("but it is not installable");
b9179170 413 else
d39d7f88
DK
414 out << _("but it is a virtual package");
415 }
b9179170 416 else
d39d7f88 417 out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
b9179170 418 }
d39d7f88
DK
419 }
420
421 if (Start != End)
422 out << _(" or");
423 out << endl;
424
425 if (Start == End)
426 break;
427 ++Start;
428 }
429 }
430}
431void ShowBroken(ostream &out, CacheFile &Cache, bool const Now)
432{
433 if (Cache->BrokenCount() == 0)
434 return;
435
436 out << _("The following packages have unmet dependencies:") << endl;
a0c19a21
DK
437 SortedPackageUniverse Universe(Cache);
438 for (auto const &Pkg: Universe)
439 ShowBrokenPackage(out, &Cache, Pkg, Now);
d39d7f88
DK
440}
441void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now)
442{
443 if (Cache->BrokenCount() == 0)
444 return;
445
446 out << _("The following packages have unmet dependencies:") << endl;
a0c19a21
DK
447 APT::PackageUniverse Universe(Cache);
448 for (auto const &Pkg: Universe)
d39d7f88 449 ShowBrokenPackage(out, &Cache, Pkg, Now);
b9179170
MV
450}
451 /*}}}*/
452// ShowNew - Show packages to newly install /*{{{*/
b9179170
MV
453void ShowNew(ostream &out,CacheFile &Cache)
454{
a0c19a21
DK
455 SortedPackageUniverse Universe(Cache);
456 ShowList(out,_("The following NEW packages will be installed:"), Universe,
457 [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].NewInstall(); },
458 &PrettyFullName,
459 CandidateVersion(&Cache));
b9179170
MV
460}
461 /*}}}*/
462// ShowDel - Show packages to delete /*{{{*/
b9179170
MV
463void ShowDel(ostream &out,CacheFile &Cache)
464{
a0c19a21
DK
465 SortedPackageUniverse Universe(Cache);
466 ShowList(out,_("The following packages will be REMOVED:"), Universe,
467 [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].Delete(); },
468 [&Cache](pkgCache::PkgIterator const &Pkg)
469 {
470 std::string str = PrettyFullName(Pkg);
471 if (((*Cache)[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
472 str.append("*");
473 return str;
474 },
475 CandidateVersion(&Cache));
b9179170
MV
476}
477 /*}}}*/
478// ShowKept - Show kept packages /*{{{*/
b9179170
MV
479void ShowKept(ostream &out,CacheFile &Cache)
480{
a0c19a21
DK
481 SortedPackageUniverse Universe(Cache);
482 ShowList(out,_("The following packages have been kept back:"), Universe,
483 [&Cache](pkgCache::PkgIterator const &Pkg)
484 {
485 return Cache[Pkg].Upgrade() == false &&
486 Cache[Pkg].Upgradable() == true &&
487 Pkg->CurrentVer != 0 &&
488 Cache[Pkg].Delete() == false;
489 },
490 &PrettyFullName,
491 CurrentToCandidateVersion(&Cache));
b9179170
MV
492}
493 /*}}}*/
494// ShowUpgraded - Show upgraded packages /*{{{*/
b9179170
MV
495void ShowUpgraded(ostream &out,CacheFile &Cache)
496{
a0c19a21
DK
497 SortedPackageUniverse Universe(Cache);
498 ShowList(out,_("The following packages will be upgraded:"), Universe,
499 [&Cache](pkgCache::PkgIterator const &Pkg)
500 {
501 return Cache[Pkg].Upgrade() == true && Cache[Pkg].NewInstall() == false;
502 },
503 &PrettyFullName,
504 CurrentToCandidateVersion(&Cache));
b9179170
MV
505}
506 /*}}}*/
507// ShowDowngraded - Show downgraded packages /*{{{*/
508// ---------------------------------------------------------------------
509/* */
510bool ShowDowngraded(ostream &out,CacheFile &Cache)
511{
a0c19a21
DK
512 SortedPackageUniverse Universe(Cache);
513 return ShowList(out,_("The following packages will be DOWNGRADED:"), Universe,
514 [&Cache](pkgCache::PkgIterator const &Pkg)
515 {
516 return Cache[Pkg].Downgrade() == true && Cache[Pkg].NewInstall() == false;
517 },
518 &PrettyFullName,
519 CurrentToCandidateVersion(&Cache));
b9179170
MV
520}
521 /*}}}*/
522// ShowHold - Show held but changed packages /*{{{*/
b9179170
MV
523bool ShowHold(ostream &out,CacheFile &Cache)
524{
a0c19a21
DK
525 SortedPackageUniverse Universe(Cache);
526 return ShowList(out,_("The following held packages will be changed:"), Universe,
527 [&Cache](pkgCache::PkgIterator const &Pkg)
528 {
529 return Pkg->SelectedState == pkgCache::State::Hold &&
530 Cache[Pkg].InstallVer != (pkgCache::Version *)Pkg.CurrentVer();
531 },
532 &PrettyFullName,
533 CurrentToCandidateVersion(&Cache));
b9179170
MV
534}
535 /*}}}*/
536// ShowEssential - Show an essential package warning /*{{{*/
537// ---------------------------------------------------------------------
538/* This prints out a warning message that is not to be ignored. It shows
a0c19a21 539 all essential packages and their dependents that are to be removed.
b9179170 540 It is insanely risky to remove the dependents of an essential package! */
a0c19a21
DK
541struct APT_HIDDEN PrettyFullNameWithDue {
542 std::map<unsigned long long, pkgCache::PkgIterator> due;
543 PrettyFullNameWithDue() {}
544 std::string operator() (pkgCache::PkgIterator const &Pkg)
545 {
546 std::string const A = PrettyFullName(Pkg);
547 std::map<unsigned long long, pkgCache::PkgIterator>::const_iterator d = due.find(Pkg->ID);
548 if (d == due.end())
549 return A;
550
551 std::string const B = PrettyFullName(d->second);
552 std::ostringstream outstr;
553 ioprintf(outstr, _("%s (due to %s)"), A.c_str(), B.c_str());
554 return outstr.str();
555 }
556};
b9179170
MV
557bool ShowEssential(ostream &out,CacheFile &Cache)
558{
a0c19a21
DK
559 std::vector<bool> Added(Cache->Head().PackageCount, false);
560 APT::PackageDeque pkglist;
561 PrettyFullNameWithDue withdue;
562
563 SortedPackageUniverse Universe(Cache);
564 for (pkgCache::PkgIterator const &I: Universe)
b9179170 565 {
b9179170
MV
566 if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
567 (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
568 continue;
a0c19a21 569
b9179170 570 // The essential package is being removed
a0c19a21
DK
571 if (Cache[I].Delete() == false)
572 continue;
573
574 if (Added[I->ID] == false)
b9179170 575 {
a0c19a21
DK
576 Added[I->ID] = true;
577 pkglist.insert(I);
b9179170 578 }
b9179170
MV
579
580 if (I->CurrentVer == 0)
581 continue;
582
583 // Print out any essential package depenendents that are to be removed
584 for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; ++D)
585 {
586 // Skip everything but depends
587 if (D->Type != pkgCache::Dep::PreDepends &&
588 D->Type != pkgCache::Dep::Depends)
589 continue;
a0c19a21 590
b9179170
MV
591 pkgCache::PkgIterator P = D.SmartTargetPkg();
592 if (Cache[P].Delete() == true)
593 {
594 if (Added[P->ID] == true)
595 continue;
596 Added[P->ID] = true;
a0c19a21
DK
597
598 pkglist.insert(P);
599 withdue.due[P->ID] = I;
600 }
601 }
b9179170 602 }
b9179170 603 return ShowList(out,_("WARNING: The following essential packages will be removed.\n"
a0c19a21
DK
604 "This should NOT be done unless you know exactly what you are doing!"),
605 pkglist, &AlwaysTrue, withdue, &EmptyString);
b9179170 606}
b9179170
MV
607 /*}}}*/
608// Stats - Show some statistics /*{{{*/
609// ---------------------------------------------------------------------
610/* */
611void Stats(ostream &out,pkgDepCache &Dep)
612{
613 unsigned long Upgrade = 0;
614 unsigned long Downgrade = 0;
615 unsigned long Install = 0;
616 unsigned long ReInstall = 0;
617 for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; ++I)
618 {
619 if (Dep[I].NewInstall() == true)
620 Install++;
621 else
622 {
623 if (Dep[I].Upgrade() == true)
624 Upgrade++;
625 else
626 if (Dep[I].Downgrade() == true)
627 Downgrade++;
628 }
629
630 if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
631 ReInstall++;
632 }
633
634 ioprintf(out,_("%lu upgraded, %lu newly installed, "),
635 Upgrade,Install);
636
637 if (ReInstall != 0)
638 ioprintf(out,_("%lu reinstalled, "),ReInstall);
639 if (Downgrade != 0)
640 ioprintf(out,_("%lu downgraded, "),Downgrade);
641
642 ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
643 Dep.DelCount(),Dep.KeepCount());
644
645 if (Dep.BadCount() != 0)
646 ioprintf(out,_("%lu not fully installed or removed.\n"),
647 Dep.BadCount());
648}
649 /*}}}*/
650// YnPrompt - Yes No Prompt. /*{{{*/
651// ---------------------------------------------------------------------
652/* Returns true on a Yes.*/
653bool YnPrompt(bool Default)
654{
655 /* nl_langinfo does not support LANGUAGE setting, so we unset it here
656 to have the help-message (hopefully) match the expected characters */
657 char * language = getenv("LANGUAGE");
658 if (language != NULL)
659 language = strdup(language);
660 if (language != NULL)
661 unsetenv("LANGUAGE");
662
663 if (Default == true)
664 // TRANSLATOR: Yes/No question help-text: defaulting to Y[es]
665 // e.g. "Do you want to continue? [Y/n] "
666 // The user has to answer with an input matching the
667 // YESEXPR/NOEXPR defined in your l10n.
668 c2out << " " << _("[Y/n]") << " " << std::flush;
669 else
670 // TRANSLATOR: Yes/No question help-text: defaulting to N[o]
671 // e.g. "Should this file be removed? [y/N] "
672 // The user has to answer with an input matching the
673 // YESEXPR/NOEXPR defined in your l10n.
674 c2out << " " << _("[y/N]") << " " << std::flush;
675
676 if (language != NULL)
677 {
678 setenv("LANGUAGE", language, 0);
679 free(language);
680 }
681
682 if (_config->FindB("APT::Get::Assume-Yes",false) == true)
683 {
684 // TRANSLATOR: "Yes" answer printed for a yes/no question if --assume-yes is set
685 c1out << _("Y") << std::endl;
686 return true;
687 }
688 else if (_config->FindB("APT::Get::Assume-No",false) == true)
689 {
690 // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
691 c1out << _("N") << std::endl;
692 return false;
693 }
694
695 char response[1024] = "";
696 std::cin.getline(response, sizeof(response));
697
698 if (!std::cin)
699 return false;
700
701 if (strlen(response) == 0)
702 return Default;
703
704 regex_t Pattern;
705 int Res;
706
707 Res = regcomp(&Pattern, nl_langinfo(YESEXPR),
708 REG_EXTENDED|REG_ICASE|REG_NOSUB);
709
710 if (Res != 0) {
711 char Error[300];
712 regerror(Res,&Pattern,Error,sizeof(Error));
713 return _error->Error(_("Regex compilation error - %s"),Error);
714 }
715
716 Res = regexec(&Pattern, response, 0, NULL, 0);
717 if (Res == 0)
718 return true;
719 return false;
720}
721 /*}}}*/
722// AnalPrompt - Annoying Yes No Prompt. /*{{{*/
723// ---------------------------------------------------------------------
724/* Returns true on a Yes.*/
725bool AnalPrompt(const char *Text)
726{
727 char Buf[1024];
728 std::cin.getline(Buf,sizeof(Buf));
729 if (strcmp(Buf,Text) == 0)
730 return true;
731 return false;
732}
733 /*}}}*/
a0c19a21
DK
734
735std::string PrettyFullName(pkgCache::PkgIterator const &Pkg)
736{
737 return Pkg.FullName(true);
738}
739std::string CandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg)
740{
741 return (*Cache)[Pkg].CandVersion;
742}
743std::function<std::string(pkgCache::PkgIterator const &)> CandidateVersion(pkgCacheFile * const Cache)
744{
745 return std::bind(static_cast<std::string(*)(pkgCacheFile * const, pkgCache::PkgIterator const&)>(&CandidateVersion), Cache, std::placeholders::_1);
746}
747std::string CurrentToCandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg)
748{
749 return std::string((*Cache)[Pkg].CurVersion) + " => " + (*Cache)[Pkg].CandVersion;
750}
751std::function<std::string(pkgCache::PkgIterator const &)> CurrentToCandidateVersion(pkgCacheFile * const Cache)
752{
753 return std::bind(static_cast<std::string(*)(pkgCacheFile * const, pkgCache::PkgIterator const&)>(&CurrentToCandidateVersion), Cache, std::placeholders::_1);
754}
755bool AlwaysTrue(pkgCache::PkgIterator const &)
756{
757 return true;
758}
759std::string EmptyString(pkgCache::PkgIterator const &)
760{
761 return std::string();
762}
763