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