]>
git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-cache.cc,v 1.72 2004/04/30 04:34:03 mdz Exp $
4 /* ######################################################################
6 apt-cache - Manages the cache files
8 apt-cache provides some functions fo manipulating the cache files.
9 It uses the command line interface common to all the APT tools.
11 Returns 100 on failure, 0 on success.
13 ##################################################################### */
15 // Include Files /*{{{*/
16 #include <apt-pkg/error.h>
18 #include <apt-pkg/pkgcachegen.h>
19 #include <apt-pkg/cachefile.h>
20 #include <apt-pkg/cacheset.h>
21 #include <apt-pkg/init.h>
22 #include <apt-pkg/progress.h>
23 #include <apt-pkg/sourcelist.h>
24 #include <apt-pkg/cmndline.h>
25 #include <apt-pkg/strutl.h>
26 #include <apt-pkg/pkgrecords.h>
27 #include <apt-pkg/srcrecords.h>
28 #include <apt-pkg/version.h>
29 #include <apt-pkg/policy.h>
30 #include <apt-pkg/tagfile.h>
31 #include <apt-pkg/algorithms.h>
32 #include <apt-pkg/sptr.h>
49 // CacheSetHelper saving virtual packages /*{{{*/
50 class CacheSetHelperVirtuals
: public APT::CacheSetHelper
{
52 APT::PackageSet virtualPkgs
;
54 virtual pkgCache::VerIterator
canNotFindCandidateVer(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
) {
55 virtualPkgs
.insert(Pkg
);
56 return CacheSetHelper::canNotFindCandidateVer(Cache
, Pkg
);
59 virtual pkgCache::VerIterator
canNotFindNewestVer(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
) {
60 virtualPkgs
.insert(Pkg
);
61 return CacheSetHelper::canNotFindNewestVer(Cache
, Pkg
);
64 virtual APT::VersionSet
canNotFindAllVer(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
) {
65 virtualPkgs
.insert(Pkg
);
66 return CacheSetHelper::canNotFindAllVer(Cache
, Pkg
);
69 CacheSetHelperVirtuals(bool const &ShowErrors
= true, GlobalError::MsgType
const &ErrorType
= GlobalError::NOTICE
) : CacheSetHelper(ShowErrors
, ErrorType
) {}
72 // LocalitySort - Sort a version list by package file locality /*{{{*/
73 // ---------------------------------------------------------------------
75 int LocalityCompare(const void *a
, const void *b
)
77 pkgCache::VerFile
*A
= *(pkgCache::VerFile
**)a
;
78 pkgCache::VerFile
*B
= *(pkgCache::VerFile
**)b
;
87 if (A
->File
== B
->File
)
88 return A
->Offset
- B
->Offset
;
89 return A
->File
- B
->File
;
92 void LocalitySort(pkgCache::VerFile
**begin
,
93 unsigned long Count
,size_t Size
)
95 qsort(begin
,Count
,Size
,LocalityCompare
);
98 void LocalitySort(pkgCache::DescFile
**begin
,
99 unsigned long Count
,size_t Size
)
101 qsort(begin
,Count
,Size
,LocalityCompare
);
104 // UnMet - Show unmet dependencies /*{{{*/
105 // ---------------------------------------------------------------------
107 bool ShowUnMet(pkgCache::VerIterator
const &V
, bool const &Important
)
110 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false;)
113 pkgCache::DepIterator Start
;
114 pkgCache::DepIterator End
;
117 // Important deps only
118 if (Important
== true)
119 if (End
->Type
!= pkgCache::Dep::PreDepends
&&
120 End
->Type
!= pkgCache::Dep::Depends
)
123 // Skip conflicts and replaces
124 if (End
.IsNegative() == true)
127 // Verify the or group
129 pkgCache::DepIterator RealStart
= Start
;
132 // See if this dep is Ok
133 pkgCache::Version
**VList
= Start
.AllTargets();
154 ioprintf(cout
,_("Package %s version %s has an unmet dep:\n"),
155 V
.ParentPkg().FullName(true).c_str(),V
.VerStr());
158 // Print out the dep type
159 cout
<< " " << End
.DepType() << ": ";
165 cout
<< Start
.TargetPkg().FullName(true);
166 if (Start
.TargetVer() != 0)
167 cout
<< " (" << Start
.CompType() << " " << Start
.TargetVer() <<
180 bool UnMet(CommandLine
&CmdL
)
182 bool const Important
= _config
->FindB("APT::Cache::Important",false);
184 pkgCacheFile CacheFile
;
185 if (unlikely(CacheFile
.GetPkgCache() == NULL
))
188 if (CmdL
.FileSize() <= 1)
190 for (pkgCache::PkgIterator P
= CacheFile
.GetPkgCache()->PkgBegin(); P
.end() == false; P
++)
191 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; ++V
)
192 if (ShowUnMet(V
, Important
) == false)
197 CacheSetHelperVirtuals
helper(true, GlobalError::NOTICE
);
198 APT::VersionSet verset
= APT::VersionSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1,
199 APT::VersionSet::CANDIDATE
, helper
);
200 for (APT::VersionSet::iterator V
= verset
.begin(); V
!= verset
.end(); ++V
)
201 if (ShowUnMet(V
, Important
) == false)
207 // DumpPackage - Show a dump of a package record /*{{{*/
208 // ---------------------------------------------------------------------
210 bool DumpPackage(CommandLine
&CmdL
)
212 pkgCacheFile CacheFile
;
213 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
214 APT::PackageSet pkgset
= APT::PackageSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, helper
);
216 for (APT::PackageSet::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
218 cout
<< "Package: " << Pkg
.FullName(true) << endl
;
219 cout
<< "Versions: " << endl
;
220 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
222 cout
<< Cur
.VerStr();
223 for (pkgCache::VerFileIterator Vf
= Cur
.FileList(); Vf
.end() == false; Vf
++)
224 cout
<< " (" << Vf
.File().FileName() << ")";
226 for (pkgCache::DescIterator D
= Cur
.DescriptionList(); D
.end() == false; D
++)
228 cout
<< " Description Language: " << D
.LanguageCode() << endl
229 << " File: " << D
.FileList().File().FileName() << endl
230 << " MD5: " << D
.md5() << endl
;
237 cout
<< "Reverse Depends: " << endl
;
238 for (pkgCache::DepIterator D
= Pkg
.RevDependsList(); D
.end() != true; D
++)
240 cout
<< " " << D
.ParentPkg().FullName(true) << ',' << D
.TargetPkg().FullName(true);
242 cout
<< ' ' << DeNull(D
.TargetVer()) << endl
;
247 cout
<< "Dependencies: " << endl
;
248 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
250 cout
<< Cur
.VerStr() << " - ";
251 for (pkgCache::DepIterator Dep
= Cur
.DependsList(); Dep
.end() != true; Dep
++)
252 cout
<< Dep
.TargetPkg().FullName(true) << " (" << (int)Dep
->CompareOp
<< " " << DeNull(Dep
.TargetVer()) << ") ";
256 cout
<< "Provides: " << endl
;
257 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
259 cout
<< Cur
.VerStr() << " - ";
260 for (pkgCache::PrvIterator Prv
= Cur
.ProvidesList(); Prv
.end() != true; Prv
++)
261 cout
<< Prv
.ParentPkg().FullName(true) << " ";
264 cout
<< "Reverse Provides: " << endl
;
265 for (pkgCache::PrvIterator Prv
= Pkg
.ProvidesList(); Prv
.end() != true; Prv
++)
266 cout
<< Prv
.OwnerPkg().FullName(true) << " " << Prv
.OwnerVer().VerStr() << endl
;
272 // Stats - Dump some nice statistics /*{{{*/
273 // ---------------------------------------------------------------------
275 bool Stats(CommandLine
&Cmd
)
277 pkgCacheFile CacheFile
;
278 pkgCache
*Cache
= CacheFile
.GetPkgCache();
279 if (unlikely(Cache
== NULL
))
282 cout
<< _("Total package names: ") << Cache
->Head().GroupCount
<< " (" <<
283 SizeToStr(Cache
->Head().GroupCount
*Cache
->Head().GroupSz
) << ')' << endl
284 << _("Total package structures: ") << Cache
->Head().PackageCount
<< " (" <<
285 SizeToStr(Cache
->Head().PackageCount
*Cache
->Head().PackageSz
) << ')' << endl
;
292 pkgCache::PkgIterator I
= Cache
->PkgBegin();
293 for (;I
.end() != true; I
++)
295 if (I
->VersionList
!= 0 && I
->ProvidesList
== 0)
301 if (I
->VersionList
!= 0 && I
->ProvidesList
!= 0)
307 if (I
->VersionList
== 0 && I
->ProvidesList
!= 0)
310 if (I
.ProvidesList()->NextProvides
== 0)
318 if (I
->VersionList
== 0 && I
->ProvidesList
== 0)
324 cout
<< _(" Normal packages: ") << Normal
<< endl
;
325 cout
<< _(" Pure virtual packages: ") << Virtual
<< endl
;
326 cout
<< _(" Single virtual packages: ") << DVirt
<< endl
;
327 cout
<< _(" Mixed virtual packages: ") << NVirt
<< endl
;
328 cout
<< _(" Missing: ") << Missing
<< endl
;
330 cout
<< _("Total distinct versions: ") << Cache
->Head().VersionCount
<< " (" <<
331 SizeToStr(Cache
->Head().VersionCount
*Cache
->Head().VersionSz
) << ')' << endl
;
332 cout
<< _("Total distinct descriptions: ") << Cache
->Head().DescriptionCount
<< " (" <<
333 SizeToStr(Cache
->Head().DescriptionCount
*Cache
->Head().DescriptionSz
) << ')' << endl
;
334 cout
<< _("Total dependencies: ") << Cache
->Head().DependsCount
<< " (" <<
335 SizeToStr(Cache
->Head().DependsCount
*Cache
->Head().DependencySz
) << ')' << endl
;
337 cout
<< _("Total ver/file relations: ") << Cache
->Head().VerFileCount
<< " (" <<
338 SizeToStr(Cache
->Head().VerFileCount
*Cache
->Head().VerFileSz
) << ')' << endl
;
339 cout
<< _("Total Desc/File relations: ") << Cache
->Head().DescFileCount
<< " (" <<
340 SizeToStr(Cache
->Head().DescFileCount
*Cache
->Head().DescFileSz
) << ')' << endl
;
341 cout
<< _("Total Provides mappings: ") << Cache
->Head().ProvidesCount
<< " (" <<
342 SizeToStr(Cache
->Head().ProvidesCount
*Cache
->Head().ProvidesSz
) << ')' << endl
;
345 unsigned long Size
= 0;
346 unsigned long Count
= 0;
347 for (pkgCache::StringItem
*I
= Cache
->StringItemP
+ Cache
->Head().StringList
;
348 I
!= Cache
->StringItemP
; I
= Cache
->StringItemP
+ I
->NextItem
)
351 Size
+= strlen(Cache
->StrP
+ I
->String
) + 1;
353 cout
<< _("Total globbed strings: ") << Count
<< " (" << SizeToStr(Size
) << ')' << endl
;
355 unsigned long DepVerSize
= 0;
356 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; P
++)
358 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
360 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; D
++)
363 DepVerSize
+= strlen(D
.TargetVer()) + 1;
367 cout
<< _("Total dependency version space: ") << SizeToStr(DepVerSize
) << endl
;
369 unsigned long Slack
= 0;
370 for (int I
= 0; I
!= 7; I
++)
371 Slack
+= Cache
->Head().Pools
[I
].ItemSize
*Cache
->Head().Pools
[I
].Count
;
372 cout
<< _("Total slack space: ") << SizeToStr(Slack
) << endl
;
374 unsigned long Total
= 0;
375 Total
= Slack
+ Size
+ Cache
->Head().DependsCount
*Cache
->Head().DependencySz
+
376 Cache
->Head().VersionCount
*Cache
->Head().VersionSz
+
377 Cache
->Head().PackageCount
*Cache
->Head().PackageSz
+
378 Cache
->Head().VerFileCount
*Cache
->Head().VerFileSz
+
379 Cache
->Head().ProvidesCount
*Cache
->Head().ProvidesSz
;
380 cout
<< _("Total space accounted for: ") << SizeToStr(Total
) << endl
;
385 // Dump - show everything /*{{{*/
386 // ---------------------------------------------------------------------
387 /* This is worthless except fer debugging things */
388 bool Dump(CommandLine
&Cmd
)
390 pkgCacheFile CacheFile
;
391 pkgCache
*Cache
= CacheFile
.GetPkgCache();
392 if (unlikely(Cache
== NULL
))
395 cout
<< "Using Versioning System: " << Cache
->VS
->Label
<< endl
;
397 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; P
++)
399 cout
<< "Package: " << P
.FullName(true) << endl
;
400 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
402 cout
<< " Version: " << V
.VerStr() << endl
;
403 cout
<< " File: " << V
.FileList().File().FileName() << endl
;
404 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; D
++)
405 cout
<< " Depends: " << D
.TargetPkg().FullName(true) << ' ' <<
406 DeNull(D
.TargetVer()) << endl
;
407 for (pkgCache::DescIterator D
= V
.DescriptionList(); D
.end() == false; D
++)
409 cout
<< " Description Language: " << D
.LanguageCode() << endl
410 << " File: " << D
.FileList().File().FileName() << endl
411 << " MD5: " << D
.md5() << endl
;
416 for (pkgCache::PkgFileIterator F
= Cache
->FileBegin(); F
.end() == false; F
++)
418 cout
<< "File: " << F
.FileName() << endl
;
419 cout
<< " Type: " << F
.IndexType() << endl
;
420 cout
<< " Size: " << F
->Size
<< endl
;
421 cout
<< " ID: " << F
->ID
<< endl
;
422 cout
<< " Flags: " << F
->Flags
<< endl
;
423 cout
<< " Time: " << TimeRFC1123(F
->mtime
) << endl
;
424 cout
<< " Archive: " << DeNull(F
.Archive()) << endl
;
425 cout
<< " Component: " << DeNull(F
.Component()) << endl
;
426 cout
<< " Version: " << DeNull(F
.Version()) << endl
;
427 cout
<< " Origin: " << DeNull(F
.Origin()) << endl
;
428 cout
<< " Site: " << DeNull(F
.Site()) << endl
;
429 cout
<< " Label: " << DeNull(F
.Label()) << endl
;
430 cout
<< " Architecture: " << DeNull(F
.Architecture()) << endl
;
436 // DumpAvail - Print out the available list /*{{{*/
437 // ---------------------------------------------------------------------
438 /* This is needed to make dpkg --merge happy.. I spent a bit of time to
439 make this run really fast, perhaps I went a little overboard.. */
440 bool DumpAvail(CommandLine
&Cmd
)
442 pkgCacheFile CacheFile
;
443 pkgCache
*Cache
= CacheFile
.GetPkgCache();
444 if (unlikely(Cache
== NULL
|| CacheFile
.BuildPolicy() == false))
447 unsigned long Count
= Cache
->HeaderP
->PackageCount
+1;
448 pkgCache::VerFile
**VFList
= new pkgCache::VerFile
*[Count
];
449 memset(VFList
,0,sizeof(*VFList
)*Count
);
451 // Map versions that we want to write out onto the VerList array.
452 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; P
++)
454 if (P
->VersionList
== 0)
457 /* Find the proper version to use. If the policy says there are no
458 possible selections we return the installed version, if available..
459 This prevents dselect from making it obsolete. */
460 pkgCache::VerIterator V
= CacheFile
.GetPolicy()->GetCandidateVer(P
);
463 if (P
->CurrentVer
== 0)
468 pkgCache::VerFileIterator VF
= V
.FileList();
469 for (; VF
.end() == false ; VF
++)
470 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
473 /* Okay, here we have a bit of a problem.. The policy has selected the
474 currently installed package - however it only exists in the
475 status file.. We need to write out something or dselect will mark
476 the package as obsolete! Thus we emit the status file entry, but
477 below we remove the status line to make it valid for the
478 available file. However! We only do this if their do exist *any*
479 non-source versions of the package - that way the dselect obsolete
480 handling works OK. */
481 if (VF
.end() == true)
483 for (pkgCache::VerIterator Cur
= P
.VersionList(); Cur
.end() != true; Cur
++)
485 for (VF
= Cur
.FileList(); VF
.end() == false; VF
++)
487 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
494 if (VF
.end() == false)
502 LocalitySort(VFList
,Count
,sizeof(*VFList
));
504 // Iterate over all the package files and write them out.
505 char *Buffer
= new char[Cache
->HeaderP
->MaxVerFileSize
+10];
506 for (pkgCache::VerFile
**J
= VFList
; *J
!= 0;)
508 pkgCache::PkgFileIterator
File(*Cache
,(*J
)->File
+ Cache
->PkgFileP
);
509 if (File
.IsOk() == false)
511 _error
->Error(_("Package file %s is out of sync."),File
.FileName());
515 FileFd
PkgF(File
.FileName(),FileFd::ReadOnly
);
516 if (_error
->PendingError() == true)
519 /* Write all of the records from this package file, since we
520 already did locality sorting we can now just seek through the
521 file in read order. We apply 1 more optimization here, since often
522 there will be < 1 byte gaps between records (for the \n) we read that
523 into the next buffer and offset a bit.. */
524 unsigned long Pos
= 0;
527 if ((*J
)->File
+ Cache
->PkgFileP
!= File
)
530 const pkgCache::VerFile
&VF
= **J
;
532 // Read the record and then write it out again.
533 unsigned long Jitter
= VF
.Offset
- Pos
;
536 if (PkgF
.Seek(VF
.Offset
) == false)
541 if (PkgF
.Read(Buffer
,VF
.Size
+ Jitter
) == false)
543 Buffer
[VF
.Size
+ Jitter
] = '\n';
546 if ((File
->Flags
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
)
549 TFRewriteData RW
[] = {{"Status",0},{"Config-Version",0},{}};
550 const char *Zero
= 0;
551 if (Tags
.Scan(Buffer
+Jitter
,VF
.Size
+1) == false ||
552 TFRewrite(stdout
,Tags
,&Zero
,RW
) == false)
554 _error
->Error("Internal Error, Unable to parse a package record");
561 if (fwrite(Buffer
+Jitter
,VF
.Size
+1,1,stdout
) != 1)
565 Pos
= VF
.Offset
+ VF
.Size
;
569 if (_error
->PendingError() == true)
575 return !_error
->PendingError();
578 // ShowDepends - Helper for printing out a dependency tree /*{{{*/
579 bool ShowDepends(CommandLine
&CmdL
, bool const RevDepends
)
581 pkgCacheFile CacheFile
;
582 pkgCache
*Cache
= CacheFile
.GetPkgCache();
583 if (unlikely(Cache
== NULL
))
586 CacheSetHelperVirtuals
helper(false);
587 APT::VersionSet verset
= APT::VersionSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, APT::VersionSet::CANDIDATE
, helper
);
588 if (verset
.empty() == true && helper
.virtualPkgs
.empty() == true)
589 return _error
->Error(_("No packages found"));
590 std::vector
<bool> Shown(Cache
->Head().PackageCount
);
592 bool const Recurse
= _config
->FindB("APT::Cache::RecurseDepends", false);
593 bool const Installed
= _config
->FindB("APT::Cache::Installed", false);
594 bool const Important
= _config
->FindB("APT::Cache::Important", false);
595 bool const ShowDepType
= _config
->FindB("APT::Cache::ShowDependencyType", RevDepends
== false);
596 bool const ShowPreDepends
= _config
->FindB("APT::Cache::ShowPre-Depends", true);
597 bool const ShowDepends
= _config
->FindB("APT::Cache::ShowDepends", true);
598 bool const ShowRecommends
= _config
->FindB("APT::Cache::ShowRecommends", Important
== false);
599 bool const ShowSuggests
= _config
->FindB("APT::Cache::ShowSuggests", Important
== false);
600 bool const ShowReplaces
= _config
->FindB("APT::Cache::ShowReplaces", Important
== false);
601 bool const ShowConflicts
= _config
->FindB("APT::Cache::ShowConflicts", Important
== false);
602 bool const ShowBreaks
= _config
->FindB("APT::Cache::ShowBreaks", Important
== false);
603 bool const ShowEnhances
= _config
->FindB("APT::Cache::ShowEnhances", Important
== false);
604 bool const ShowOnlyFirstOr
= _config
->FindB("APT::Cache::ShowOnlyFirstOr", false);
606 while (verset
.empty() != true)
608 pkgCache::VerIterator Ver
= *verset
.begin();
609 verset
.erase(verset
.begin());
610 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
611 Shown
[Pkg
->ID
] = true;
613 cout
<< Pkg
.FullName(true) << endl
;
615 if (RevDepends
== true)
616 cout
<< "Reverse Depends:" << endl
;
617 for (pkgCache::DepIterator D
= RevDepends
? Pkg
.RevDependsList() : Ver
.DependsList();
618 D
.end() == false; D
++)
621 case pkgCache::Dep::PreDepends
: if (!ShowPreDepends
) continue; break;
622 case pkgCache::Dep::Depends
: if (!ShowDepends
) continue; break;
623 case pkgCache::Dep::Recommends
: if (!ShowRecommends
) continue; break;
624 case pkgCache::Dep::Suggests
: if (!ShowSuggests
) continue; break;
625 case pkgCache::Dep::Replaces
: if (!ShowReplaces
) continue; break;
626 case pkgCache::Dep::Conflicts
: if (!ShowConflicts
) continue; break;
627 case pkgCache::Dep::DpkgBreaks
: if (!ShowBreaks
) continue; break;
628 case pkgCache::Dep::Enhances
: if (!ShowEnhances
) continue; break;
631 pkgCache::PkgIterator Trg
= RevDepends
? D
.ParentPkg() : D
.TargetPkg();
633 if((Installed
&& Trg
->CurrentVer
!= 0) || !Installed
)
636 if ((D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
&& ShowOnlyFirstOr
== false)
642 if (ShowDepType
== true)
643 cout
<< D
.DepType() << ": ";
644 if (Trg
->VersionList
== 0)
645 cout
<< "<" << Trg
.FullName(true) << ">" << endl
;
647 cout
<< Trg
.FullName(true) << endl
;
649 if (Recurse
== true && Shown
[Trg
->ID
] == false)
651 Shown
[Trg
->ID
] = true;
652 verset
.insert(APT::VersionSet::FromPackage(CacheFile
, Trg
, APT::VersionSet::CANDIDATE
, helper
));
657 // Display all solutions
658 SPtrArray
<pkgCache::Version
*> List
= D
.AllTargets();
659 pkgPrioSortList(*Cache
,List
);
660 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
662 pkgCache::VerIterator
V(*Cache
,*I
);
663 if (V
!= Cache
->VerP
+ V
.ParentPkg()->VersionList
||
664 V
->ParentPkg
== D
->Package
)
666 cout
<< " " << V
.ParentPkg().FullName(true) << endl
;
668 if (Recurse
== true && Shown
[V
.ParentPkg()->ID
] == false)
670 Shown
[V
.ParentPkg()->ID
] = true;
671 verset
.insert(APT::VersionSet::FromPackage(CacheFile
, V
.ParentPkg(), APT::VersionSet::CANDIDATE
, helper
));
675 if (ShowOnlyFirstOr
== true)
676 while ((D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
) ++D
;
680 for (APT::PackageSet::const_iterator Pkg
= helper
.virtualPkgs
.begin();
681 Pkg
!= helper
.virtualPkgs
.end(); ++Pkg
)
682 cout
<< '<' << Pkg
.FullName(true) << '>' << endl
;
687 // Depends - Print out a dependency tree /*{{{*/
688 // ---------------------------------------------------------------------
690 bool Depends(CommandLine
&CmdL
)
692 return ShowDepends(CmdL
, false);
695 // RDepends - Print out a reverse dependency tree /*{{{*/
696 // ---------------------------------------------------------------------
698 bool RDepends(CommandLine
&CmdL
)
700 return ShowDepends(CmdL
, true);
703 // xvcg - Generate a graph for xvcg /*{{{*/
704 // ---------------------------------------------------------------------
705 // Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
707 bool XVcg(CommandLine
&CmdL
)
709 pkgCacheFile CacheFile
;
710 pkgCache
*Cache
= CacheFile
.GetPkgCache();
711 if (unlikely(Cache
== NULL
))
714 bool GivenOnly
= _config
->FindB("APT::Cache::GivenOnly",false);
716 /* Normal packages are boxes
717 Pure Provides are triangles
719 rhomb are missing packages*/
720 const char *Shapes
[] = {"ellipse","triangle","box","rhomb"};
722 /* Initialize the list of packages to show.
724 2 = To Show no recurse
725 3 = Emitted no recurse
728 enum States
{None
=0, ToShow
, ToShowNR
, DoneNR
, Done
};
729 enum TheFlags
{ForceNR
=(1<<0)};
730 unsigned char *Show
= new unsigned char[Cache
->Head().PackageCount
];
731 unsigned char *Flags
= new unsigned char[Cache
->Head().PackageCount
];
732 unsigned char *ShapeMap
= new unsigned char[Cache
->Head().PackageCount
];
734 // Show everything if no arguments given
735 if (CmdL
.FileList
[1] == 0)
736 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
739 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
741 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
744 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; Pkg
++)
746 if (Pkg
->VersionList
== 0)
749 if (Pkg
->ProvidesList
== 0)
750 ShapeMap
[Pkg
->ID
] = 0;
752 ShapeMap
[Pkg
->ID
] = 1;
757 if (Pkg
->ProvidesList
== 0)
758 ShapeMap
[Pkg
->ID
] = 2;
760 ShapeMap
[Pkg
->ID
] = 3;
764 // Load the list of packages from the command line into the show list
765 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
766 std::list
<APT::PackageSet::Modifier
> mods
;
767 mods
.push_back(APT::PackageSet::Modifier(0, ",", APT::PackageSet::Modifier::POSTFIX
));
768 mods
.push_back(APT::PackageSet::Modifier(1, "^", APT::PackageSet::Modifier::POSTFIX
));
769 std::map
<unsigned short, APT::PackageSet
> pkgsets
=
770 APT::PackageSet::GroupedFromCommandLine(CacheFile
, CmdL
.FileList
+ 1, mods
, 0, helper
);
772 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[0].begin();
773 Pkg
!= pkgsets
[0].end(); ++Pkg
)
774 Show
[Pkg
->ID
] = ToShow
;
775 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[1].begin();
776 Pkg
!= pkgsets
[1].end(); ++Pkg
)
778 Show
[Pkg
->ID
] = ToShow
;
779 Flags
[Pkg
->ID
] |= ForceNR
;
783 cout
<< "graph: { title: \"packages\"" << endl
<<
784 "xmax: 700 ymax: 700 x: 30 y: 30" << endl
<<
785 "layout_downfactor: 8" << endl
;
791 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; Pkg
++)
793 // See we need to show this package
794 if (Show
[Pkg
->ID
] == None
|| Show
[Pkg
->ID
] >= DoneNR
)
797 //printf ("node: { title: \"%s\" label: \"%s\" }\n", Pkg.Name(), Pkg.Name());
800 if (Show
[Pkg
->ID
] == ToShowNR
|| (Flags
[Pkg
->ID
] & ForceNR
) == ForceNR
)
802 // Pure Provides and missing packages have no deps!
803 if (ShapeMap
[Pkg
->ID
] == 0 || ShapeMap
[Pkg
->ID
] == 1)
804 Show
[Pkg
->ID
] = Done
;
806 Show
[Pkg
->ID
] = DoneNR
;
809 Show
[Pkg
->ID
] = Done
;
812 // No deps to map out
813 if (Pkg
->VersionList
== 0 || Show
[Pkg
->ID
] == DoneNR
)
816 pkgCache::VerIterator Ver
= Pkg
.VersionList();
817 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; D
++)
819 // See if anything can meet this dep
820 // Walk along the actual package providing versions
822 pkgCache::PkgIterator DPkg
= D
.TargetPkg();
823 for (pkgCache::VerIterator I
= DPkg
.VersionList();
824 I
.end() == false && Hit
== false; I
++)
826 if (Cache
->VS
->CheckDep(I
.VerStr(),D
->CompareOp
,D
.TargetVer()) == true)
830 // Follow all provides
831 for (pkgCache::PrvIterator I
= DPkg
.ProvidesList();
832 I
.end() == false && Hit
== false; I
++)
834 if (Cache
->VS
->CheckDep(I
.ProvideVersion(),D
->CompareOp
,D
.TargetVer()) == false)
839 // Only graph critical deps
840 if (D
.IsCritical() == true)
842 printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg
.FullName(true).c_str(), D
.TargetPkg().FullName(true).c_str() );
844 // Colour the node for recursion
845 if (Show
[D
.TargetPkg()->ID
] <= DoneNR
)
847 /* If a conflicts does not meet anything in the database
848 then show the relation but do not recurse */
849 if (Hit
== false && D
.IsNegative() == true)
851 if (Show
[D
.TargetPkg()->ID
] == None
&&
852 Show
[D
.TargetPkg()->ID
] != ToShow
)
853 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
857 if (GivenOnly
== true && Show
[D
.TargetPkg()->ID
] != ToShow
)
858 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
860 Show
[D
.TargetPkg()->ID
] = ToShow
;
867 case pkgCache::Dep::Conflicts
:
868 printf("label: \"conflicts\" color: lightgreen }\n");
870 case pkgCache::Dep::DpkgBreaks
:
871 printf("label: \"breaks\" color: lightgreen }\n");
873 case pkgCache::Dep::Obsoletes
:
874 printf("label: \"obsoletes\" color: lightgreen }\n");
877 case pkgCache::Dep::PreDepends
:
878 printf("label: \"predepends\" color: blue }\n");
890 /* Draw the box colours after the fact since we can not tell what colour
891 they should be until everything is finished drawing */
892 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; Pkg
++)
894 if (Show
[Pkg
->ID
] < DoneNR
)
897 if (Show
[Pkg
->ID
] == DoneNR
)
898 printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg
.FullName(true).c_str(), Pkg
.FullName(true).c_str(),
899 Shapes
[ShapeMap
[Pkg
->ID
]]);
901 printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg
.FullName(true).c_str(), Pkg
.FullName(true).c_str(),
902 Shapes
[ShapeMap
[Pkg
->ID
]]);
914 // Dotty - Generate a graph for Dotty /*{{{*/
915 // ---------------------------------------------------------------------
916 /* Dotty is the graphvis program for generating graphs. It is a fairly
917 simple queuing algorithm that just writes dependencies and nodes.
918 http://www.research.att.com/sw/tools/graphviz/ */
919 bool Dotty(CommandLine
&CmdL
)
921 pkgCacheFile CacheFile
;
922 pkgCache
*Cache
= CacheFile
.GetPkgCache();
923 if (unlikely(Cache
== NULL
))
926 bool GivenOnly
= _config
->FindB("APT::Cache::GivenOnly",false);
928 /* Normal packages are boxes
929 Pure Provides are triangles
931 Hexagons are missing packages*/
932 const char *Shapes
[] = {"hexagon","triangle","box","diamond"};
934 /* Initialize the list of packages to show.
936 2 = To Show no recurse
937 3 = Emitted no recurse
940 enum States
{None
=0, ToShow
, ToShowNR
, DoneNR
, Done
};
941 enum TheFlags
{ForceNR
=(1<<0)};
942 unsigned char *Show
= new unsigned char[Cache
->Head().PackageCount
];
943 unsigned char *Flags
= new unsigned char[Cache
->Head().PackageCount
];
944 unsigned char *ShapeMap
= new unsigned char[Cache
->Head().PackageCount
];
946 // Show everything if no arguments given
947 if (CmdL
.FileList
[1] == 0)
948 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
951 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
953 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
956 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; Pkg
++)
958 if (Pkg
->VersionList
== 0)
961 if (Pkg
->ProvidesList
== 0)
962 ShapeMap
[Pkg
->ID
] = 0;
964 ShapeMap
[Pkg
->ID
] = 1;
969 if (Pkg
->ProvidesList
== 0)
970 ShapeMap
[Pkg
->ID
] = 2;
972 ShapeMap
[Pkg
->ID
] = 3;
976 // Load the list of packages from the command line into the show list
977 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
978 std::list
<APT::PackageSet::Modifier
> mods
;
979 mods
.push_back(APT::PackageSet::Modifier(0, ",", APT::PackageSet::Modifier::POSTFIX
));
980 mods
.push_back(APT::PackageSet::Modifier(1, "^", APT::PackageSet::Modifier::POSTFIX
));
981 std::map
<unsigned short, APT::PackageSet
> pkgsets
=
982 APT::PackageSet::GroupedFromCommandLine(CacheFile
, CmdL
.FileList
+ 1, mods
, 0, helper
);
984 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[0].begin();
985 Pkg
!= pkgsets
[0].end(); ++Pkg
)
986 Show
[Pkg
->ID
] = ToShow
;
987 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[1].begin();
988 Pkg
!= pkgsets
[1].end(); ++Pkg
)
990 Show
[Pkg
->ID
] = ToShow
;
991 Flags
[Pkg
->ID
] |= ForceNR
;
995 printf("digraph packages {\n");
996 printf("concentrate=true;\n");
997 printf("size=\"30,40\";\n");
1003 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; Pkg
++)
1005 // See we need to show this package
1006 if (Show
[Pkg
->ID
] == None
|| Show
[Pkg
->ID
] >= DoneNR
)
1010 if (Show
[Pkg
->ID
] == ToShowNR
|| (Flags
[Pkg
->ID
] & ForceNR
) == ForceNR
)
1012 // Pure Provides and missing packages have no deps!
1013 if (ShapeMap
[Pkg
->ID
] == 0 || ShapeMap
[Pkg
->ID
] == 1)
1014 Show
[Pkg
->ID
] = Done
;
1016 Show
[Pkg
->ID
] = DoneNR
;
1019 Show
[Pkg
->ID
] = Done
;
1022 // No deps to map out
1023 if (Pkg
->VersionList
== 0 || Show
[Pkg
->ID
] == DoneNR
)
1026 pkgCache::VerIterator Ver
= Pkg
.VersionList();
1027 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; D
++)
1029 // See if anything can meet this dep
1030 // Walk along the actual package providing versions
1032 pkgCache::PkgIterator DPkg
= D
.TargetPkg();
1033 for (pkgCache::VerIterator I
= DPkg
.VersionList();
1034 I
.end() == false && Hit
== false; I
++)
1036 if (Cache
->VS
->CheckDep(I
.VerStr(),D
->CompareOp
,D
.TargetVer()) == true)
1040 // Follow all provides
1041 for (pkgCache::PrvIterator I
= DPkg
.ProvidesList();
1042 I
.end() == false && Hit
== false; I
++)
1044 if (Cache
->VS
->CheckDep(I
.ProvideVersion(),D
->CompareOp
,D
.TargetVer()) == false)
1048 // Only graph critical deps
1049 if (D
.IsCritical() == true)
1051 printf("\"%s\" -> \"%s\"",Pkg
.FullName(true).c_str(),D
.TargetPkg().FullName(true).c_str());
1053 // Colour the node for recursion
1054 if (Show
[D
.TargetPkg()->ID
] <= DoneNR
)
1056 /* If a conflicts does not meet anything in the database
1057 then show the relation but do not recurse */
1058 if (Hit
== false && D
.IsNegative() == true)
1060 if (Show
[D
.TargetPkg()->ID
] == None
&&
1061 Show
[D
.TargetPkg()->ID
] != ToShow
)
1062 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
1066 if (GivenOnly
== true && Show
[D
.TargetPkg()->ID
] != ToShow
)
1067 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
1069 Show
[D
.TargetPkg()->ID
] = ToShow
;
1076 case pkgCache::Dep::Conflicts
:
1077 case pkgCache::Dep::Obsoletes
:
1078 case pkgCache::Dep::DpkgBreaks
:
1079 printf("[color=springgreen];\n");
1082 case pkgCache::Dep::PreDepends
:
1083 printf("[color=blue];\n");
1095 /* Draw the box colours after the fact since we can not tell what colour
1096 they should be until everything is finished drawing */
1097 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; Pkg
++)
1099 if (Show
[Pkg
->ID
] < DoneNR
)
1102 // Orange box for early recursion stoppage
1103 if (Show
[Pkg
->ID
] == DoneNR
)
1104 printf("\"%s\" [color=orange,shape=%s];\n",Pkg
.FullName(true).c_str(),
1105 Shapes
[ShapeMap
[Pkg
->ID
]]);
1107 printf("\"%s\" [shape=%s];\n",Pkg
.FullName(true).c_str(),
1108 Shapes
[ShapeMap
[Pkg
->ID
]]);
1118 // DisplayRecord - Displays the complete record for the package /*{{{*/
1119 // ---------------------------------------------------------------------
1120 /* This displays the package record from the proper package index file.
1121 It is not used by DumpAvail for performance reasons. */
1122 bool DisplayRecord(pkgCacheFile
&CacheFile
, pkgCache::VerIterator V
)
1124 pkgCache
*Cache
= CacheFile
.GetPkgCache();
1125 if (unlikely(Cache
== NULL
))
1128 // Find an appropriate file
1129 pkgCache::VerFileIterator Vf
= V
.FileList();
1130 for (; Vf
.end() == false; Vf
++)
1131 if ((Vf
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
1133 if (Vf
.end() == true)
1136 // Check and load the package list file
1137 pkgCache::PkgFileIterator I
= Vf
.File();
1138 if (I
.IsOk() == false)
1139 return _error
->Error(_("Package file %s is out of sync."),I
.FileName());
1142 if (PkgF
.Open(I
.FileName(), FileFd::ReadOnlyGzip
) == false)
1146 unsigned char *Buffer
= new unsigned char[Cache
->HeaderP
->MaxVerFileSize
+1];
1147 Buffer
[V
.FileList()->Size
] = '\n';
1148 if (PkgF
.Seek(V
.FileList()->Offset
) == false ||
1149 PkgF
.Read(Buffer
,V
.FileList()->Size
) == false)
1155 // Get a pointer to start of Description field
1156 const unsigned char *DescP
= (unsigned char*)strstr((char*)Buffer
, "Description:");
1158 // Write all but Description
1159 if (fwrite(Buffer
,1,DescP
- Buffer
,stdout
) < (size_t)(DescP
- Buffer
))
1165 // Show the right description
1166 pkgRecords
Recs(*Cache
);
1167 pkgCache::DescIterator Desc
= V
.TranslatedDescription();
1168 pkgRecords::Parser
&P
= Recs
.Lookup(Desc
.FileList());
1169 cout
<< "Description" << ( (strcmp(Desc
.LanguageCode(),"") != 0) ? "-" : "" ) << Desc
.LanguageCode() << ": " << P
.LongDesc();
1171 // Find the first field after the description (if there is any)
1172 for(DescP
++;DescP
!= &Buffer
[V
.FileList()->Size
];DescP
++)
1174 if(*DescP
== '\n' && *(DescP
+1) != ' ')
1176 // write the rest of the buffer
1177 const unsigned char *end
=&Buffer
[V
.FileList()->Size
];
1178 if (fwrite(DescP
,1,end
-DescP
,stdout
) < (size_t)(end
-DescP
))
1187 // write a final newline (after the description)
1197 pkgCache::DescFile
*Df
;
1201 // Search - Perform a search /*{{{*/
1202 // ---------------------------------------------------------------------
1203 /* This searches the package names and package descriptions for a pattern */
1204 bool Search(CommandLine
&CmdL
)
1206 bool const ShowFull
= _config
->FindB("APT::Cache::ShowFull",false);
1207 bool const NamesOnly
= _config
->FindB("APT::Cache::NamesOnly",false);
1208 unsigned int const NumPatterns
= CmdL
.FileSize() -1;
1210 pkgCacheFile CacheFile
;
1211 pkgCache
*Cache
= CacheFile
.GetPkgCache();
1212 pkgDepCache::Policy
*Plcy
= CacheFile
.GetPolicy();
1213 if (unlikely(Cache
== NULL
|| Plcy
== NULL
))
1216 // Make sure there is at least one argument
1217 if (NumPatterns
< 1)
1218 return _error
->Error(_("You must give at least one search pattern"));
1220 // Compile the regex pattern
1221 regex_t
*Patterns
= new regex_t
[NumPatterns
];
1222 memset(Patterns
,0,sizeof(*Patterns
)*NumPatterns
);
1223 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1225 if (regcomp(&Patterns
[I
],CmdL
.FileList
[I
+1],REG_EXTENDED
| REG_ICASE
|
1229 regfree(&Patterns
[I
]);
1230 return _error
->Error("Regex compilation error");
1234 if (_error
->PendingError() == true)
1236 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1237 regfree(&Patterns
[I
]);
1241 ExDescFile
*DFList
= new ExDescFile
[Cache
->HeaderP
->GroupCount
+1];
1242 memset(DFList
,0,sizeof(*DFList
)*Cache
->HeaderP
->GroupCount
+1);
1244 // Map versions that we want to write out onto the VerList array.
1245 for (pkgCache::GrpIterator G
= Cache
->GrpBegin(); G
.end() == false; ++G
)
1247 if (DFList
[G
->ID
].NameMatch
== true)
1250 DFList
[G
->ID
].NameMatch
= true;
1251 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1253 if (regexec(&Patterns
[I
],G
.Name(),0,0,0) == 0)
1255 DFList
[G
->ID
].NameMatch
= false;
1259 // Doing names only, drop any that dont match..
1260 if (NamesOnly
== true && DFList
[G
->ID
].NameMatch
== false)
1263 // Find the proper version to use
1264 pkgCache::PkgIterator P
= G
.FindPreferredPkg();
1265 if (P
.end() == true)
1267 pkgCache::VerIterator V
= Plcy
->GetCandidateVer(P
);
1268 if (V
.end() == false)
1269 DFList
[G
->ID
].Df
= V
.TranslatedDescription().FileList();
1271 if (DFList
[G
->ID
].NameMatch
== false)
1274 // Include all the packages that provide matching names too
1275 for (pkgCache::PrvIterator Prv
= P
.ProvidesList() ; Prv
.end() == false; Prv
++)
1277 pkgCache::VerIterator V
= Plcy
->GetCandidateVer(Prv
.OwnerPkg());
1278 if (V
.end() == true)
1281 unsigned long id
= Prv
.OwnerPkg().Group()->ID
;
1282 DFList
[id
].Df
= V
.TranslatedDescription().FileList();
1283 DFList
[id
].NameMatch
= true;
1287 LocalitySort(&DFList
->Df
,Cache
->HeaderP
->GroupCount
,sizeof(*DFList
));
1289 // Create the text record parser
1290 pkgRecords
Recs(*Cache
);
1291 // Iterate over all the version records and check them
1292 for (ExDescFile
*J
= DFList
; J
->Df
!= 0; J
++)
1294 pkgRecords::Parser
&P
= Recs
.Lookup(pkgCache::DescFileIterator(*Cache
,J
->Df
));
1296 if (J
->NameMatch
== false && NamesOnly
== false)
1298 string
const LongDesc
= P
.LongDesc();
1299 J
->NameMatch
= true;
1300 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1302 if (regexec(&Patterns
[I
],LongDesc
.c_str(),0,0,0) == 0)
1304 J
->NameMatch
= false;
1309 if (J
->NameMatch
== true)
1311 if (ShowFull
== true)
1315 P
.GetRec(Start
,End
);
1316 fwrite(Start
,End
-Start
,1,stdout
);
1320 printf("%s - %s\n",P
.Name().c_str(),P
.ShortDesc().c_str());
1325 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1326 regfree(&Patterns
[I
]);
1328 return _error
->Error("Write to stdout failed");
1332 /* ShowAuto - show automatically installed packages (sorted) {{{*/
1333 bool ShowAuto(CommandLine
&CmdL
)
1335 pkgCacheFile CacheFile
;
1336 pkgCache
*Cache
= CacheFile
.GetPkgCache();
1337 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
1338 if (unlikely(Cache
== NULL
|| DepCache
== NULL
))
1341 std::vector
<string
> packages
;
1342 packages
.reserve(Cache
->HeaderP
->PackageCount
/ 3);
1344 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; P
++)
1345 if ((*DepCache
)[P
].Flags
& pkgCache::Flag::Auto
)
1346 packages
.push_back(P
.Name());
1348 std::sort(packages
.begin(), packages
.end());
1350 for (vector
<string
>::iterator I
= packages
.begin(); I
!= packages
.end(); I
++)
1353 _error
->Notice(_("This command is deprecated. Please use 'apt-mark showauto' instead."));
1357 // ShowPackage - Dump the package record to the screen /*{{{*/
1358 // ---------------------------------------------------------------------
1360 bool ShowPackage(CommandLine
&CmdL
)
1362 pkgCacheFile CacheFile
;
1363 CacheSetHelperVirtuals
helper(true, GlobalError::NOTICE
);
1364 APT::VersionSet::Version
const select
= _config
->FindB("APT::Cache::AllVersions", true) ?
1365 APT::VersionSet::ALL
: APT::VersionSet::CANDIDATE
;
1366 APT::VersionSet
const verset
= APT::VersionSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, select
, helper
);
1367 for (APT::VersionSet::const_iterator Ver
= verset
.begin(); Ver
!= verset
.end(); ++Ver
)
1368 if (DisplayRecord(CacheFile
, Ver
) == false)
1371 if (verset
.empty() == true)
1373 if (helper
.virtualPkgs
.empty() == true)
1374 return _error
->Error(_("No packages found"));
1376 _error
->Notice(_("No packages found"));
1381 // ShowPkgNames - Show package names /*{{{*/
1382 // ---------------------------------------------------------------------
1383 /* This does a prefix match on the first argument */
1384 bool ShowPkgNames(CommandLine
&CmdL
)
1386 pkgCacheFile CacheFile
;
1387 if (unlikely(CacheFile
.BuildCaches(NULL
, false) == false))
1389 pkgCache::GrpIterator I
= CacheFile
.GetPkgCache()->GrpBegin();
1390 bool const All
= _config
->FindB("APT::Cache::AllNames","false");
1392 if (CmdL
.FileList
[1] != 0)
1394 for (;I
.end() != true; I
++)
1396 if (All
== false && I
->FirstPackage
== 0)
1398 if (I
.FindPkg("any")->VersionList
== 0)
1400 if (strncmp(I
.Name(),CmdL
.FileList
[1],strlen(CmdL
.FileList
[1])) == 0)
1401 cout
<< I
.Name() << endl
;
1408 for (;I
.end() != true; I
++)
1410 if (All
== false && I
->FirstPackage
== 0)
1412 if (I
.FindPkg("any")->VersionList
== 0)
1414 cout
<< I
.Name() << endl
;
1420 // ShowSrcPackage - Show source package records /*{{{*/
1421 // ---------------------------------------------------------------------
1423 bool ShowSrcPackage(CommandLine
&CmdL
)
1425 pkgCacheFile CacheFile
;
1426 pkgSourceList
*List
= CacheFile
.GetSourceList();
1427 if (unlikely(List
== NULL
))
1430 // Create the text record parsers
1431 pkgSrcRecords
SrcRecs(*List
);
1432 if (_error
->PendingError() == true)
1436 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1440 pkgSrcRecords::Parser
*Parse
;
1441 unsigned found_this
= 0;
1442 while ((Parse
= SrcRecs
.Find(*I
,false)) != 0) {
1443 cout
<< Parse
->AsStr() << endl
;;
1447 if (found_this
== 0) {
1448 _error
->Warning(_("Unable to locate package %s"),*I
);
1453 _error
->Notice(_("No packages found"));
1457 // Policy - Show the results of the preferences file /*{{{*/
1458 // ---------------------------------------------------------------------
1460 bool Policy(CommandLine
&CmdL
)
1462 pkgCacheFile CacheFile
;
1463 pkgCache
*Cache
= CacheFile
.GetPkgCache();
1464 pkgPolicy
*Plcy
= CacheFile
.GetPolicy();
1465 pkgSourceList
*SrcList
= CacheFile
.GetSourceList();
1466 if (unlikely(Cache
== NULL
|| Plcy
== NULL
|| SrcList
== NULL
))
1469 /* Should the MultiArchKiller be run to see which pseudo packages for an
1470 arch all package are currently installed? Activating it gives a speed
1471 penality for no real gain beside enhanced debugging, so in general no. */
1472 if (_config
->FindB("APT::Cache::Policy::DepCache", false) == true)
1473 CacheFile
.GetDepCache();
1475 // Print out all of the package files
1476 if (CmdL
.FileList
[1] == 0)
1478 cout
<< _("Package files:") << endl
;
1479 for (pkgCache::PkgFileIterator F
= Cache
->FileBegin(); F
.end() == false; F
++)
1481 // Locate the associated index files so we can derive a description
1483 if (SrcList
->FindIndex(F
,Indx
) == false &&
1484 _system
->FindIndex(F
,Indx
) == false)
1485 return _error
->Error(_("Cache is out of sync, can't x-ref a package file"));
1488 Plcy
->GetPriority(F
),Indx
->Describe(true).c_str());
1490 // Print the reference information for the package
1491 string Str
= F
.RelStr();
1492 if (Str
.empty() == false)
1493 printf(" release %s\n",F
.RelStr().c_str());
1494 if (F
.Site() != 0 && F
.Site()[0] != 0)
1495 printf(" origin %s\n",F
.Site());
1498 // Show any packages have explicit pins
1499 cout
<< _("Pinned packages:") << endl
;
1500 pkgCache::PkgIterator I
= Cache
->PkgBegin();
1501 for (;I
.end() != true; I
++)
1503 if (Plcy
->GetPriority(I
) == 0)
1506 // Print the package name and the version we are forcing to
1507 cout
<< " " << I
.FullName(true) << " -> ";
1509 pkgCache::VerIterator V
= Plcy
->GetMatch(I
);
1510 if (V
.end() == true)
1511 cout
<< _("(not found)") << endl
;
1513 cout
<< V
.VerStr() << endl
;
1519 char const * const msgInstalled
= _(" Installed: ");
1520 char const * const msgCandidate
= _(" Candidate: ");
1521 short const InstalledLessCandidate
=
1522 mbstowcs(NULL
, msgInstalled
, 0) - mbstowcs(NULL
, msgCandidate
, 0);
1523 short const deepInstalled
=
1524 (InstalledLessCandidate
< 0 ? (InstalledLessCandidate
*-1) : 0) - 1;
1525 short const deepCandidate
=
1526 (InstalledLessCandidate
> 0 ? (InstalledLessCandidate
) : 0) - 1;
1528 // Print out detailed information for each package
1529 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
1530 APT::PackageSet pkgset
= APT::PackageSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, helper
);
1531 for (APT::PackageSet::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
1533 cout
<< Pkg
.FullName(true) << ":" << endl
;
1535 // Installed version
1536 cout
<< msgInstalled
<< OutputInDepth(deepInstalled
, " ");
1537 if (Pkg
->CurrentVer
== 0)
1538 cout
<< _("(none)") << endl
;
1540 cout
<< Pkg
.CurrentVer().VerStr() << endl
;
1542 // Candidate Version
1543 cout
<< msgCandidate
<< OutputInDepth(deepCandidate
, " ");
1544 pkgCache::VerIterator V
= Plcy
->GetCandidateVer(Pkg
);
1545 if (V
.end() == true)
1546 cout
<< _("(none)") << endl
;
1548 cout
<< V
.VerStr() << endl
;
1551 if (Plcy
->GetPriority(Pkg
) != 0)
1553 cout
<< _(" Package pin: ");
1554 V
= Plcy
->GetMatch(Pkg
);
1555 if (V
.end() == true)
1556 cout
<< _("(not found)") << endl
;
1558 cout
<< V
.VerStr() << endl
;
1561 // Show the priority tables
1562 cout
<< _(" Version table:") << endl
;
1563 for (V
= Pkg
.VersionList(); V
.end() == false; V
++)
1565 if (Pkg
.CurrentVer() == V
)
1566 cout
<< " *** " << V
.VerStr();
1568 cout
<< " " << V
.VerStr();
1569 cout
<< " " << Plcy
->GetPriority(Pkg
) << endl
;
1570 for (pkgCache::VerFileIterator VF
= V
.FileList(); VF
.end() == false; VF
++)
1572 // Locate the associated index files so we can derive a description
1574 if (SrcList
->FindIndex(VF
.File(),Indx
) == false &&
1575 _system
->FindIndex(VF
.File(),Indx
) == false)
1576 return _error
->Error(_("Cache is out of sync, can't x-ref a package file"));
1577 printf(" %4i %s\n",Plcy
->GetPriority(VF
.File()),
1578 Indx
->Describe(true).c_str());
1586 // Madison - Look a bit like katie's madison /*{{{*/
1587 // ---------------------------------------------------------------------
1589 bool Madison(CommandLine
&CmdL
)
1591 pkgCacheFile CacheFile
;
1592 pkgSourceList
*SrcList
= CacheFile
.GetSourceList();
1597 // Create the src text record parsers and ignore errors about missing
1598 // deb-src lines that are generated from pkgSrcRecords::pkgSrcRecords
1599 pkgSrcRecords
SrcRecs(*SrcList
);
1600 if (_error
->PendingError() == true)
1603 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
1604 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1606 _error
->PushToStack();
1607 APT::PackageSet pkgset
= APT::PackageSet::FromString(CacheFile
, *I
, helper
);
1608 for (APT::PackageSet::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
1610 for (pkgCache::VerIterator V
= Pkg
.VersionList(); V
.end() == false; V
++)
1612 for (pkgCache::VerFileIterator VF
= V
.FileList(); VF
.end() == false; VF
++)
1614 // This might be nice, but wouldn't uniquely identify the source -mdz
1615 // if (VF.File().Archive() != 0)
1617 // cout << setw(10) << Pkg.Name() << " | " << setw(10) << V.VerStr() << " | "
1618 // << VF.File().Archive() << endl;
1621 // Locate the associated index files so we can derive a description
1622 for (pkgSourceList::const_iterator S
= SrcList
->begin(); S
!= SrcList
->end(); S
++)
1624 vector
<pkgIndexFile
*> *Indexes
= (*S
)->GetIndexFiles();
1625 for (vector
<pkgIndexFile
*>::const_iterator IF
= Indexes
->begin();
1626 IF
!= Indexes
->end(); IF
++)
1628 if ((*IF
)->FindInCache(*(VF
.File().Cache())) == VF
.File())
1630 cout
<< setw(10) << Pkg
.FullName(true) << " | " << setw(10) << V
.VerStr() << " | "
1631 << (*IF
)->Describe(true) << endl
;
1640 pkgSrcRecords::Parser
*SrcParser
;
1641 bool foundSomething
= false;
1642 while ((SrcParser
= SrcRecs
.Find(*I
, false)) != 0)
1644 foundSomething
= true;
1645 // Maybe support Release info here too eventually
1646 cout
<< setw(10) << SrcParser
->Package() << " | "
1647 << setw(10) << SrcParser
->Version() << " | "
1648 << SrcParser
->Index().Describe(true) << endl
;
1650 if (foundSomething
== true)
1651 _error
->RevertToStack();
1653 _error
->MergeWithStack();
1659 // GenCaches - Call the main cache generator /*{{{*/
1660 // ---------------------------------------------------------------------
1662 bool GenCaches(CommandLine
&Cmd
)
1664 OpTextProgress
Progress(*_config
);
1666 pkgCacheFile CacheFile
;
1667 return CacheFile
.BuildCaches(&Progress
, true);
1670 // ShowHelp - Show a help screen /*{{{*/
1671 // ---------------------------------------------------------------------
1673 bool ShowHelp(CommandLine
&Cmd
)
1675 ioprintf(cout
,_("%s %s for %s compiled on %s %s\n"),PACKAGE
,VERSION
,
1676 COMMON_ARCH
,__DATE__
,__TIME__
);
1678 if (_config
->FindB("version") == true)
1682 _("Usage: apt-cache [options] command\n"
1683 " apt-cache [options] showpkg pkg1 [pkg2 ...]\n"
1684 " apt-cache [options] showsrc pkg1 [pkg2 ...]\n"
1686 "apt-cache is a low-level tool used to query information\n"
1687 "from APT's binary cache files\n"
1690 " gencaches - Build both the package and source cache\n"
1691 " showpkg - Show some general information for a single package\n"
1692 " showsrc - Show source records\n"
1693 " stats - Show some basic statistics\n"
1694 " dump - Show the entire file in a terse form\n"
1695 " dumpavail - Print an available file to stdout\n"
1696 " unmet - Show unmet dependencies\n"
1697 " search - Search the package list for a regex pattern\n"
1698 " show - Show a readable record for the package\n"
1699 " depends - Show raw dependency information for a package\n"
1700 " rdepends - Show reverse dependency information for a package\n"
1701 " pkgnames - List the names of all packages in the system\n"
1702 " dotty - Generate package graphs for GraphViz\n"
1703 " xvcg - Generate package graphs for xvcg\n"
1704 " policy - Show policy settings\n"
1707 " -h This help text.\n"
1708 " -p=? The package cache.\n"
1709 " -s=? The source cache.\n"
1710 " -q Disable progress indicator.\n"
1711 " -i Show only important deps for the unmet command.\n"
1712 " -c=? Read this configuration file\n"
1713 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
1714 "See the apt-cache(8) and apt.conf(5) manual pages for more information.\n");
1718 int main(int argc
,const char *argv
[]) /*{{{*/
1720 CommandLine::Args Args
[] = {
1721 {'h',"help","help",0},
1722 {'v',"version","version",0},
1723 {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg
},
1724 {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg
},
1725 {'q',"quiet","quiet",CommandLine::IntLevel
},
1726 {'i',"important","APT::Cache::Important",0},
1727 {'f',"full","APT::Cache::ShowFull",0},
1728 {'g',"generate","APT::Cache::Generate",0},
1729 {'a',"all-versions","APT::Cache::AllVersions",0},
1730 {'n',"names-only","APT::Cache::NamesOnly",0},
1731 {0,"all-names","APT::Cache::AllNames",0},
1732 {0,"recurse","APT::Cache::RecurseDepends",0},
1733 {'t',"target-release","APT::Default-Release",CommandLine::HasArg
},
1734 {'t',"default-release","APT::Default-Release",CommandLine::HasArg
},
1735 {'c',"config-file",0,CommandLine::ConfigFile
},
1736 {'o',"option",0,CommandLine::ArbItem
},
1737 {0,"installed","APT::Cache::Installed",0},
1738 {0,"pre-depends","APT::Cache::ShowPreDepends",0},
1739 {0,"depends","APT::Cache::ShowDepends",0},
1740 {0,"recommends","APT::Cache::ShowRecommends",0},
1741 {0,"suggests","APT::Cache::ShowSuggests",0},
1742 {0,"replaces","APT::Cache::ShowReplaces",0},
1743 {0,"breaks","APT::Cache::ShowBreaks",0},
1744 {0,"conflicts","APT::Cache::ShowConflicts",0},
1745 {0,"enhances","APT::Cache::ShowEnhances",0},
1747 CommandLine::Dispatch CmdsA
[] = {{"help",&ShowHelp
},
1748 {"gencaches",&GenCaches
},
1749 {"showsrc",&ShowSrcPackage
},
1751 CommandLine::Dispatch CmdsB
[] = {{"showpkg",&DumpPackage
},
1754 {"dumpavail",&DumpAvail
},
1757 {"depends",&Depends
},
1758 {"rdepends",&RDepends
},
1761 {"show",&ShowPackage
},
1762 {"pkgnames",&ShowPkgNames
},
1763 {"showauto",&ShowAuto
},
1765 {"madison",&Madison
},
1768 // Set up gettext support
1769 setlocale(LC_ALL
,"");
1770 textdomain(PACKAGE
);
1772 // Parse the command line and initialize the package library
1773 CommandLine
CmdL(Args
,_config
);
1774 if (pkgInitConfig(*_config
) == false ||
1775 CmdL
.Parse(argc
,argv
) == false ||
1776 pkgInitSystem(*_config
,_system
) == false)
1778 _error
->DumpErrors();
1782 // See if the help should be shown
1783 if (_config
->FindB("help") == true ||
1784 CmdL
.FileSize() == 0)
1790 // Deal with stdout not being a tty
1791 if (!isatty(STDOUT_FILENO
) && _config
->FindI("quiet", -1) == -1)
1792 _config
->Set("quiet","1");
1794 if (_config
->Exists("APT::Cache::Generate") == true)
1795 _config
->Set("pkgCacheFile::Generate", _config
->FindB("APT::Cache::Generate", true));
1797 if (CmdL
.DispatchArg(CmdsA
,false) == false && _error
->PendingError() == false)
1798 CmdL
.DispatchArg(CmdsB
);
1800 // Print any errors or warnings found during parsing
1801 bool const Errors
= _error
->PendingError();
1802 if (_config
->FindI("quiet",0) > 0)
1803 _error
->DumpErrors();
1805 _error
->DumpErrors(GlobalError::DEBUG
);
1806 return Errors
== true ? 100 : 0;