]>
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 /*{{{*/
18 #include <apt-pkg/algorithms.h>
19 #include <apt-pkg/cachefile.h>
20 #include <apt-pkg/cacheset.h>
21 #include <apt-pkg/cmndline.h>
22 #include <apt-pkg/error.h>
23 #include <apt-pkg/fileutl.h>
24 #include <apt-pkg/indexfile.h>
25 #include <apt-pkg/init.h>
26 #include <apt-pkg/metaindex.h>
27 #include <apt-pkg/pkgrecords.h>
28 #include <apt-pkg/pkgsystem.h>
29 #include <apt-pkg/policy.h>
30 #include <apt-pkg/progress.h>
31 #include <apt-pkg/sourcelist.h>
32 #include <apt-pkg/sptr.h>
33 #include <apt-pkg/srcrecords.h>
34 #include <apt-pkg/strutl.h>
35 #include <apt-pkg/tagfile.h>
36 #include <apt-pkg/version.h>
37 #include <apt-pkg/cacheiterators.h>
38 #include <apt-pkg/configuration.h>
39 #include <apt-pkg/depcache.h>
40 #include <apt-pkg/macros.h>
41 #include <apt-pkg/mmap.h>
42 #include <apt-pkg/pkgcache.h>
44 #include <apt-private/private-cacheset.h>
45 #include <apt-private/private-cmndline.h>
46 #include <apt-private/private-show.h>
47 #include <apt-private/private-search.h>
48 #include <apt-private/private-main.h>
70 // UnMet - Show unmet dependencies /*{{{*/
71 // ---------------------------------------------------------------------
73 static bool ShowUnMet(pkgCache::VerIterator
const &V
, bool const Important
)
76 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false;)
79 pkgCache::DepIterator Start
;
80 pkgCache::DepIterator End
;
83 // Important deps only
84 if (Important
== true)
85 if (End
->Type
!= pkgCache::Dep::PreDepends
&&
86 End
->Type
!= pkgCache::Dep::Depends
)
89 // Skip conflicts and replaces
90 if (End
.IsNegative() == true || End
->Type
== pkgCache::Dep::Replaces
)
93 // Verify the or group
95 pkgCache::DepIterator RealStart
= Start
;
98 // See if this dep is Ok
99 pkgCache::Version
**VList
= Start
.AllTargets();
120 ioprintf(cout
,_("Package %s version %s has an unmet dep:\n"),
121 V
.ParentPkg().FullName(true).c_str(),V
.VerStr());
124 // Print out the dep type
125 cout
<< " " << End
.DepType() << ": ";
131 cout
<< Start
.TargetPkg().FullName(true);
132 if (Start
.TargetVer() != 0)
133 cout
<< " (" << Start
.CompType() << " " << Start
.TargetVer() <<
146 static bool UnMet(CommandLine
&CmdL
)
148 bool const Important
= _config
->FindB("APT::Cache::Important",false);
150 pkgCacheFile CacheFile
;
151 if (unlikely(CacheFile
.GetPkgCache() == NULL
))
154 if (CmdL
.FileSize() <= 1)
156 for (pkgCache::PkgIterator P
= CacheFile
.GetPkgCache()->PkgBegin(); P
.end() == false; ++P
)
157 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; ++V
)
158 if (ShowUnMet(V
, Important
) == false)
163 CacheSetHelperVirtuals
helper(true, GlobalError::NOTICE
);
164 APT::VersionList verset
= APT::VersionList::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1,
165 APT::CacheSetHelper::CANDIDATE
, helper
);
166 for (APT::VersionList::iterator V
= verset
.begin(); V
!= verset
.end(); ++V
)
167 if (ShowUnMet(V
, Important
) == false)
173 // DumpPackage - Show a dump of a package record /*{{{*/
174 // ---------------------------------------------------------------------
176 static bool DumpPackage(CommandLine
&CmdL
)
178 pkgCacheFile CacheFile
;
179 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
180 APT::PackageList pkgset
= APT::PackageList::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, helper
);
182 for (APT::PackageList::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
184 cout
<< "Package: " << Pkg
.FullName(true) << endl
;
185 cout
<< "Versions: " << endl
;
186 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; ++Cur
)
188 cout
<< Cur
.VerStr();
189 for (pkgCache::VerFileIterator Vf
= Cur
.FileList(); Vf
.end() == false; ++Vf
)
190 cout
<< " (" << Vf
.File().FileName() << ")";
192 for (pkgCache::DescIterator D
= Cur
.DescriptionList(); D
.end() == false; ++D
)
194 cout
<< " Description Language: " << D
.LanguageCode() << endl
195 << " File: " << D
.FileList().File().FileName() << endl
196 << " MD5: " << D
.md5() << endl
;
203 cout
<< "Reverse Depends: " << endl
;
204 for (pkgCache::DepIterator D
= Pkg
.RevDependsList(); D
.end() != true; ++D
)
206 cout
<< " " << D
.ParentPkg().FullName(true) << ',' << D
.TargetPkg().FullName(true);
208 cout
<< ' ' << DeNull(D
.TargetVer()) << endl
;
213 cout
<< "Dependencies: " << endl
;
214 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; ++Cur
)
216 cout
<< Cur
.VerStr() << " - ";
217 for (pkgCache::DepIterator Dep
= Cur
.DependsList(); Dep
.end() != true; ++Dep
)
218 cout
<< Dep
.TargetPkg().FullName(true) << " (" << (int)Dep
->CompareOp
<< " " << DeNull(Dep
.TargetVer()) << ") ";
222 cout
<< "Provides: " << endl
;
223 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; ++Cur
)
225 cout
<< Cur
.VerStr() << " - ";
226 for (pkgCache::PrvIterator Prv
= Cur
.ProvidesList(); Prv
.end() != true; ++Prv
)
227 cout
<< Prv
.ParentPkg().FullName(true) << " (= " << (Prv
->ProvideVersion
== 0 ? "" : Prv
.ProvideVersion()) << ") ";
230 cout
<< "Reverse Provides: " << endl
;
231 for (pkgCache::PrvIterator Prv
= Pkg
.ProvidesList(); Prv
.end() != true; ++Prv
)
232 cout
<< Prv
.OwnerPkg().FullName(true) << " " << Prv
.OwnerVer().VerStr() << " (= " << (Prv
->ProvideVersion
== 0 ? "" : Prv
.ProvideVersion()) << ")"<< endl
;
238 // ShowHashTableStats - Show stats about a hashtable /*{{{*/
239 // ---------------------------------------------------------------------
241 static map_pointer_t
PackageNext(pkgCache::Package
const * const P
) { return P
->NextPackage
; }
242 static map_pointer_t
GroupNext(pkgCache::Group
const * const G
) { return G
->Next
; }
244 static void ShowHashTableStats(std::string Type
,
246 map_pointer_t
*Hashtable
,
248 map_pointer_t(*Next
)(T
const * const))
250 // hashtable stats for the HashTable
251 unsigned long NumBuckets
= Size
;
252 unsigned long UsedBuckets
= 0;
253 unsigned long UnusedBuckets
= 0;
254 unsigned long LongestBucket
= 0;
255 unsigned long ShortestBucket
= NumBuckets
;
256 unsigned long Entries
= 0;
257 for (unsigned int i
=0; i
< NumBuckets
; ++i
)
259 T
*P
= StartP
+ Hashtable
[i
];
260 if(P
== 0 || P
== StartP
)
266 unsigned long ThisBucketSize
= 0;
267 for (; P
!= StartP
; P
= StartP
+ Next(P
))
269 Entries
+= ThisBucketSize
;
270 LongestBucket
= std::max(ThisBucketSize
, LongestBucket
);
271 ShortestBucket
= std::min(ThisBucketSize
, ShortestBucket
);
273 cout
<< "Total buckets in " << Type
<< ": " << NumBuckets
<< std::endl
;
274 cout
<< " Unused: " << UnusedBuckets
<< std::endl
;
275 cout
<< " Used: " << UsedBuckets
<< std::endl
;
276 cout
<< " Average entries: " << Entries
/(double)NumBuckets
<< std::endl
;
277 cout
<< " Longest: " << LongestBucket
<< std::endl
;
278 cout
<< " Shortest: " << ShortestBucket
<< std::endl
;
281 // Stats - Dump some nice statistics /*{{{*/
282 // ---------------------------------------------------------------------
284 static bool Stats(CommandLine
&CmdL
)
286 if (CmdL
.FileSize() > 1) {
287 _error
->Error(_("apt-cache stats does not take any arguments"));
291 pkgCacheFile CacheFile
;
292 pkgCache
*Cache
= CacheFile
.GetPkgCache();
294 if (unlikely(Cache
== NULL
))
297 cout
<< _("Total package names: ") << Cache
->Head().GroupCount
<< " (" <<
298 SizeToStr(Cache
->Head().GroupCount
*Cache
->Head().GroupSz
) << ')' << endl
299 << _("Total package structures: ") << Cache
->Head().PackageCount
<< " (" <<
300 SizeToStr(Cache
->Head().PackageCount
*Cache
->Head().PackageSz
) << ')' << endl
;
307 pkgCache::PkgIterator I
= Cache
->PkgBegin();
308 for (;I
.end() != true; ++I
)
310 if (I
->VersionList
!= 0 && I
->ProvidesList
== 0)
316 if (I
->VersionList
!= 0 && I
->ProvidesList
!= 0)
322 if (I
->VersionList
== 0 && I
->ProvidesList
!= 0)
325 if (I
.ProvidesList()->NextProvides
== 0)
333 if (I
->VersionList
== 0 && I
->ProvidesList
== 0)
339 cout
<< _(" Normal packages: ") << Normal
<< endl
;
340 cout
<< _(" Pure virtual packages: ") << Virtual
<< endl
;
341 cout
<< _(" Single virtual packages: ") << DVirt
<< endl
;
342 cout
<< _(" Mixed virtual packages: ") << NVirt
<< endl
;
343 cout
<< _(" Missing: ") << Missing
<< endl
;
345 cout
<< _("Total distinct versions: ") << Cache
->Head().VersionCount
<< " (" <<
346 SizeToStr(Cache
->Head().VersionCount
*Cache
->Head().VersionSz
) << ')' << endl
;
347 cout
<< _("Total distinct descriptions: ") << Cache
->Head().DescriptionCount
<< " (" <<
348 SizeToStr(Cache
->Head().DescriptionCount
*Cache
->Head().DescriptionSz
) << ')' << endl
;
349 cout
<< _("Total dependencies: ") << Cache
->Head().DependsCount
<< "/" << Cache
->Head().DependsDataCount
<< " (" <<
350 SizeToStr((Cache
->Head().DependsCount
*Cache
->Head().DependencySz
) +
351 (Cache
->Head().DependsDataCount
*Cache
->Head().DependencyDataSz
)) << ')' << endl
;
352 cout
<< _("Total ver/file relations: ") << Cache
->Head().VerFileCount
<< " (" <<
353 SizeToStr(Cache
->Head().VerFileCount
*Cache
->Head().VerFileSz
) << ')' << endl
;
354 cout
<< _("Total Desc/File relations: ") << Cache
->Head().DescFileCount
<< " (" <<
355 SizeToStr(Cache
->Head().DescFileCount
*Cache
->Head().DescFileSz
) << ')' << endl
;
356 cout
<< _("Total Provides mappings: ") << Cache
->Head().ProvidesCount
<< " (" <<
357 SizeToStr(Cache
->Head().ProvidesCount
*Cache
->Head().ProvidesSz
) << ')' << endl
;
360 std::set
<map_stringitem_t
> stritems
;
361 for (pkgCache::GrpIterator G
= Cache
->GrpBegin(); G
.end() == false; ++G
)
362 stritems
.insert(G
->Name
);
363 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
365 stritems
.insert(P
->Arch
);
366 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; ++V
)
369 stritems
.insert(V
->VerStr
);
371 stritems
.insert(V
->Section
);
372 stritems
.insert(V
->SourcePkgName
);
373 stritems
.insert(V
->SourceVerStr
);
374 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; ++D
)
377 stritems
.insert(D
->Version
);
379 for (pkgCache::DescIterator D
= V
.DescriptionList(); D
.end() == false; ++D
)
381 stritems
.insert(D
->md5sum
);
382 stritems
.insert(D
->language_code
);
385 for (pkgCache::PrvIterator Prv
= P
.ProvidesList(); Prv
.end() == false; ++Prv
)
387 if (Prv
->ProvideVersion
!= 0)
388 stritems
.insert(Prv
->ProvideVersion
);
391 for (pkgCache::RlsFileIterator F
= Cache
->RlsFileBegin(); F
!= Cache
->RlsFileEnd(); ++F
)
393 stritems
.insert(F
->FileName
);
394 stritems
.insert(F
->Archive
);
395 stritems
.insert(F
->Codename
);
396 stritems
.insert(F
->Version
);
397 stritems
.insert(F
->Origin
);
398 stritems
.insert(F
->Label
);
399 stritems
.insert(F
->Site
);
401 for (pkgCache::PkgFileIterator F
= Cache
->FileBegin(); F
!= Cache
->FileEnd(); ++F
)
403 stritems
.insert(F
->FileName
);
404 stritems
.insert(F
->Architecture
);
405 stritems
.insert(F
->Component
);
406 stritems
.insert(F
->IndexType
);
409 unsigned long Size
= 0;
410 for (std::set
<map_stringitem_t
>::const_iterator i
= stritems
.begin(); i
!= stritems
.end(); ++i
)
411 Size
+= strlen(Cache
->StrP
+ *i
) + 1;
412 cout
<< _("Total globbed strings: ") << stritems
.size() << " (" << SizeToStr(Size
) << ')' << endl
;
415 unsigned long Slack
= 0;
416 for (int I
= 0; I
!= 7; I
++)
417 Slack
+= Cache
->Head().Pools
[I
].ItemSize
*Cache
->Head().Pools
[I
].Count
;
418 cout
<< _("Total slack space: ") << SizeToStr(Slack
) << endl
;
420 unsigned long Total
= 0;
421 #define APT_CACHESIZE(X,Y) (Cache->Head().X * Cache->Head().Y)
422 Total
= Slack
+ Size
+
423 APT_CACHESIZE(GroupCount
, GroupSz
) +
424 APT_CACHESIZE(PackageCount
, PackageSz
) +
425 APT_CACHESIZE(VersionCount
, VersionSz
) +
426 APT_CACHESIZE(DescriptionCount
, DescriptionSz
) +
427 APT_CACHESIZE(DependsCount
, DependencySz
) +
428 APT_CACHESIZE(DependsDataCount
, DependencyDataSz
) +
429 APT_CACHESIZE(ReleaseFileCount
, ReleaseFileSz
) +
430 APT_CACHESIZE(PackageFileCount
, PackageFileSz
) +
431 APT_CACHESIZE(VerFileCount
, VerFileSz
) +
432 APT_CACHESIZE(DescFileCount
, DescFileSz
) +
433 APT_CACHESIZE(ProvidesCount
, ProvidesSz
) +
434 (2 * Cache
->Head().GetHashTableSize() * sizeof(map_id_t
));
435 cout
<< _("Total space accounted for: ") << SizeToStr(Total
) << endl
;
439 ShowHashTableStats
<pkgCache::Package
>("PkgHashTable", Cache
->PkgP
, Cache
->Head().PkgHashTableP(), Cache
->Head().GetHashTableSize(), PackageNext
);
440 ShowHashTableStats
<pkgCache::Group
>("GrpHashTable", Cache
->GrpP
, Cache
->Head().GrpHashTableP(), Cache
->Head().GetHashTableSize(), GroupNext
);
445 // Dump - show everything /*{{{*/
446 // ---------------------------------------------------------------------
447 /* This is worthless except fer debugging things */
448 static bool Dump(CommandLine
&)
450 pkgCacheFile CacheFile
;
451 pkgCache
*Cache
= CacheFile
.GetPkgCache();
452 if (unlikely(Cache
== NULL
))
455 std::cout
<< "Using Versioning System: " << Cache
->VS
->Label
<< std::endl
;
457 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
459 std::cout
<< "Package: " << P
.FullName(true) << std::endl
;
460 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; ++V
)
462 std::cout
<< " Version: " << V
.VerStr() << std::endl
;
463 std::cout
<< " File: " << V
.FileList().File().FileName() << std::endl
;
464 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; ++D
)
465 std::cout
<< " Depends: " << D
.TargetPkg().FullName(true) << ' ' <<
466 DeNull(D
.TargetVer()) << std::endl
;
467 for (pkgCache::DescIterator D
= V
.DescriptionList(); D
.end() == false; ++D
)
469 std::cout
<< " Description Language: " << D
.LanguageCode() << std::endl
470 << " File: " << D
.FileList().File().FileName() << std::endl
471 << " MD5: " << D
.md5() << std::endl
;
476 for (pkgCache::PkgFileIterator F
= Cache
->FileBegin(); F
.end() == false; ++F
)
478 std::cout
<< "File: " << F
.FileName() << std::endl
;
479 std::cout
<< " Type: " << F
.IndexType() << std::endl
;
480 std::cout
<< " Size: " << F
->Size
<< std::endl
;
481 std::cout
<< " ID: " << F
->ID
<< std::endl
;
482 std::cout
<< " Flags: " << F
->Flags
<< std::endl
;
483 std::cout
<< " Time: " << TimeRFC1123(F
->mtime
) << std::endl
;
484 std::cout
<< " Archive: " << DeNull(F
.Archive()) << std::endl
;
485 std::cout
<< " Component: " << DeNull(F
.Component()) << std::endl
;
486 std::cout
<< " Version: " << DeNull(F
.Version()) << std::endl
;
487 std::cout
<< " Origin: " << DeNull(F
.Origin()) << std::endl
;
488 std::cout
<< " Site: " << DeNull(F
.Site()) << std::endl
;
489 std::cout
<< " Label: " << DeNull(F
.Label()) << std::endl
;
490 std::cout
<< " Architecture: " << DeNull(F
.Architecture()) << std::endl
;
496 // DumpAvail - Print out the available list /*{{{*/
497 // ---------------------------------------------------------------------
498 /* This is needed to make dpkg --merge happy.. I spent a bit of time to
499 make this run really fast, perhaps I went a little overboard.. */
500 static bool DumpAvail(CommandLine
&)
502 pkgCacheFile CacheFile
;
503 pkgCache
*Cache
= CacheFile
.GetPkgCache();
504 if (unlikely(Cache
== NULL
|| CacheFile
.BuildPolicy() == false))
507 unsigned long Count
= Cache
->HeaderP
->PackageCount
+1;
508 pkgCache::VerFile
**VFList
= new pkgCache::VerFile
*[Count
];
509 memset(VFList
,0,sizeof(*VFList
)*Count
);
511 // Map versions that we want to write out onto the VerList array.
512 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
514 if (P
->VersionList
== 0)
517 /* Find the proper version to use. If the policy says there are no
518 possible selections we return the installed version, if available..
519 This prevents dselect from making it obsolete. */
520 pkgCache::VerIterator V
= CacheFile
.GetPolicy()->GetCandidateVer(P
);
523 if (P
->CurrentVer
== 0)
528 pkgCache::VerFileIterator VF
= V
.FileList();
529 for (; VF
.end() == false ; ++VF
)
530 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
533 /* Okay, here we have a bit of a problem.. The policy has selected the
534 currently installed package - however it only exists in the
535 status file.. We need to write out something or dselect will mark
536 the package as obsolete! Thus we emit the status file entry, but
537 below we remove the status line to make it valid for the
538 available file. However! We only do this if their do exist *any*
539 non-source versions of the package - that way the dselect obsolete
540 handling works OK. */
541 if (VF
.end() == true)
543 for (pkgCache::VerIterator Cur
= P
.VersionList(); Cur
.end() != true; ++Cur
)
545 for (VF
= Cur
.FileList(); VF
.end() == false; ++VF
)
547 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
554 if (VF
.end() == false)
562 LocalitySort(VFList
,Count
,sizeof(*VFList
));
564 std::vector
<pkgTagSection::Tag
> RW
;
565 RW
.push_back(pkgTagSection::Tag::Remove("Status"));
566 RW
.push_back(pkgTagSection::Tag::Remove("Config-Version"));
568 stdoutfd
.OpenDescriptor(STDOUT_FILENO
, FileFd::WriteOnly
, false);
570 // Iterate over all the package files and write them out.
571 char *Buffer
= new char[Cache
->HeaderP
->MaxVerFileSize
+10];
572 for (pkgCache::VerFile
**J
= VFList
; *J
!= 0;)
574 pkgCache::PkgFileIterator
File(*Cache
,(*J
)->File
+ Cache
->PkgFileP
);
575 if (File
.IsOk() == false)
577 _error
->Error(_("Package file %s is out of sync."),File
.FileName());
581 FileFd
PkgF(File
.FileName(),FileFd::ReadOnly
, FileFd::Extension
);
582 if (_error
->PendingError() == true)
585 /* Write all of the records from this package file, since we
586 already did locality sorting we can now just seek through the
587 file in read order. We apply 1 more optimization here, since often
588 there will be < 1 byte gaps between records (for the \n) we read that
589 into the next buffer and offset a bit.. */
590 unsigned long Pos
= 0;
593 if ((*J
)->File
+ Cache
->PkgFileP
!= File
)
596 const pkgCache::VerFile
&VF
= **J
;
598 // Read the record and then write it out again.
599 unsigned long Jitter
= VF
.Offset
- Pos
;
602 if (PkgF
.Seek(VF
.Offset
) == false)
607 if (PkgF
.Read(Buffer
,VF
.Size
+ Jitter
) == false)
609 Buffer
[VF
.Size
+ Jitter
] = '\n';
612 if ((File
->Flags
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
)
615 if (Tags
.Scan(Buffer
+Jitter
,VF
.Size
+1) == false ||
616 Tags
.Write(stdoutfd
, NULL
, RW
) == false ||
617 stdoutfd
.Write("\n", 1) == false)
619 _error
->Error("Internal Error, Unable to parse a package record");
625 if (stdoutfd
.Write(Buffer
+ Jitter
, VF
.Size
+ 1) == false)
629 Pos
= VF
.Offset
+ VF
.Size
;
632 if (_error
->PendingError() == true)
638 return !_error
->PendingError();
641 // ShowDepends - Helper for printing out a dependency tree /*{{{*/
642 static bool ShowDepends(CommandLine
&CmdL
, bool const RevDepends
)
644 pkgCacheFile CacheFile
;
645 pkgCache
*Cache
= CacheFile
.GetPkgCache();
646 if (unlikely(Cache
== NULL
))
649 CacheSetHelperVirtuals
helper(false);
650 APT::VersionList verset
= APT::VersionList::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, APT::CacheSetHelper::CANDIDATE
, helper
);
651 if (verset
.empty() == true && helper
.virtualPkgs
.empty() == true)
652 return _error
->Error(_("No packages found"));
653 std::vector
<bool> Shown(Cache
->Head().PackageCount
);
655 bool const Recurse
= _config
->FindB("APT::Cache::RecurseDepends", false);
656 bool const Installed
= _config
->FindB("APT::Cache::Installed", false);
657 bool const Important
= _config
->FindB("APT::Cache::Important", false);
658 bool const ShowDepType
= _config
->FindB("APT::Cache::ShowDependencyType", RevDepends
== false);
659 bool const ShowVersion
= _config
->FindB("APT::Cache::ShowVersion", false);
660 bool const ShowPreDepends
= _config
->FindB("APT::Cache::ShowPre-Depends", true);
661 bool const ShowDepends
= _config
->FindB("APT::Cache::ShowDepends", true);
662 bool const ShowRecommends
= _config
->FindB("APT::Cache::ShowRecommends", Important
== false);
663 bool const ShowSuggests
= _config
->FindB("APT::Cache::ShowSuggests", Important
== false);
664 bool const ShowReplaces
= _config
->FindB("APT::Cache::ShowReplaces", Important
== false);
665 bool const ShowConflicts
= _config
->FindB("APT::Cache::ShowConflicts", Important
== false);
666 bool const ShowBreaks
= _config
->FindB("APT::Cache::ShowBreaks", Important
== false);
667 bool const ShowEnhances
= _config
->FindB("APT::Cache::ShowEnhances", Important
== false);
668 bool const ShowOnlyFirstOr
= _config
->FindB("APT::Cache::ShowOnlyFirstOr", false);
669 bool const ShowImplicit
= _config
->FindB("APT::Cache::ShowImplicit", false);
671 while (verset
.empty() != true)
673 pkgCache::VerIterator Ver
= *verset
.begin();
674 verset
.erase(verset
.begin());
675 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
676 Shown
[Pkg
->ID
] = true;
678 cout
<< Pkg
.FullName(true) << endl
;
680 if (RevDepends
== true)
681 cout
<< "Reverse Depends:" << endl
;
682 for (pkgCache::DepIterator D
= RevDepends
? Pkg
.RevDependsList() : Ver
.DependsList();
683 D
.end() == false; ++D
)
686 case pkgCache::Dep::PreDepends
: if (!ShowPreDepends
) continue; break;
687 case pkgCache::Dep::Depends
: if (!ShowDepends
) continue; break;
688 case pkgCache::Dep::Recommends
: if (!ShowRecommends
) continue; break;
689 case pkgCache::Dep::Suggests
: if (!ShowSuggests
) continue; break;
690 case pkgCache::Dep::Replaces
: if (!ShowReplaces
) continue; break;
691 case pkgCache::Dep::Conflicts
: if (!ShowConflicts
) continue; break;
692 case pkgCache::Dep::DpkgBreaks
: if (!ShowBreaks
) continue; break;
693 case pkgCache::Dep::Enhances
: if (!ShowEnhances
) continue; break;
695 if (ShowImplicit
== false && D
.IsImplicit())
698 pkgCache::PkgIterator Trg
= RevDepends
? D
.ParentPkg() : D
.TargetPkg();
700 if((Installed
&& Trg
->CurrentVer
!= 0) || !Installed
)
703 if ((D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
&& ShowOnlyFirstOr
== false)
709 if (ShowDepType
== true)
710 cout
<< D
.DepType() << ": ";
711 if (Trg
->VersionList
== 0)
712 cout
<< "<" << Trg
.FullName(true) << ">";
714 cout
<< Trg
.FullName(true);
715 if (ShowVersion
== true && D
->Version
!= 0)
716 cout
<< " (" << pkgCache::CompTypeDeb(D
->CompareOp
) << ' ' << D
.TargetVer() << ')';
719 if (Recurse
== true && Shown
[Trg
->ID
] == false)
721 Shown
[Trg
->ID
] = true;
722 verset
.insert(APT::VersionSet::FromPackage(CacheFile
, Trg
, APT::CacheSetHelper::CANDIDATE
, helper
));
727 // Display all solutions
728 std::unique_ptr
<pkgCache::Version
*[]> List(D
.AllTargets());
729 pkgPrioSortList(*Cache
,List
.get());
730 for (pkgCache::Version
**I
= List
.get(); *I
!= 0; I
++)
732 pkgCache::VerIterator
V(*Cache
,*I
);
733 if (V
!= Cache
->VerP
+ V
.ParentPkg()->VersionList
||
734 V
->ParentPkg
== D
->Package
)
736 cout
<< " " << V
.ParentPkg().FullName(true) << endl
;
738 if (Recurse
== true && Shown
[V
.ParentPkg()->ID
] == false)
740 Shown
[V
.ParentPkg()->ID
] = true;
741 verset
.insert(APT::VersionSet::FromPackage(CacheFile
, V
.ParentPkg(), APT::CacheSetHelper::CANDIDATE
, helper
));
745 if (ShowOnlyFirstOr
== true)
746 while ((D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
) ++D
;
750 for (APT::PackageSet::const_iterator Pkg
= helper
.virtualPkgs
.begin();
751 Pkg
!= helper
.virtualPkgs
.end(); ++Pkg
)
752 cout
<< '<' << Pkg
.FullName(true) << '>' << endl
;
757 // Depends - Print out a dependency tree /*{{{*/
758 // ---------------------------------------------------------------------
760 static bool Depends(CommandLine
&CmdL
)
762 return ShowDepends(CmdL
, false);
765 // RDepends - Print out a reverse dependency tree /*{{{*/
766 // ---------------------------------------------------------------------
768 static bool RDepends(CommandLine
&CmdL
)
770 return ShowDepends(CmdL
, true);
773 // xvcg - Generate a graph for xvcg /*{{{*/
774 // ---------------------------------------------------------------------
775 // Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
777 static bool XVcg(CommandLine
&CmdL
)
779 pkgCacheFile CacheFile
;
780 pkgCache
*Cache
= CacheFile
.GetPkgCache();
781 if (unlikely(Cache
== NULL
))
784 bool GivenOnly
= _config
->FindB("APT::Cache::GivenOnly",false);
786 /* Normal packages are boxes
787 Pure Provides are triangles
789 rhomb are missing packages*/
790 const char *Shapes
[] = {"ellipse","triangle","box","rhomb"};
792 /* Initialize the list of packages to show.
794 2 = To Show no recurse
795 3 = Emitted no recurse
798 enum States
{None
=0, ToShow
, ToShowNR
, DoneNR
, Done
};
799 enum TheFlags
{ForceNR
=(1<<0)};
800 unsigned char *Show
= new unsigned char[Cache
->Head().PackageCount
];
801 unsigned char *Flags
= new unsigned char[Cache
->Head().PackageCount
];
802 unsigned char *ShapeMap
= new unsigned char[Cache
->Head().PackageCount
];
804 // Show everything if no arguments given
805 if (CmdL
.FileList
[1] == 0)
806 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
809 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
811 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
814 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
816 if (Pkg
->VersionList
== 0)
819 if (Pkg
->ProvidesList
== 0)
820 ShapeMap
[Pkg
->ID
] = 0;
822 ShapeMap
[Pkg
->ID
] = 1;
827 if (Pkg
->ProvidesList
== 0)
828 ShapeMap
[Pkg
->ID
] = 2;
830 ShapeMap
[Pkg
->ID
] = 3;
834 // Load the list of packages from the command line into the show list
835 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
836 std::list
<APT::CacheSetHelper::PkgModifier
> mods
;
837 mods
.push_back(APT::CacheSetHelper::PkgModifier(0, ",", APT::PackageSet::Modifier::POSTFIX
));
838 mods
.push_back(APT::CacheSetHelper::PkgModifier(1, "^", APT::PackageSet::Modifier::POSTFIX
));
839 std::map
<unsigned short, APT::PackageSet
> pkgsets
=
840 APT::PackageSet::GroupedFromCommandLine(CacheFile
, CmdL
.FileList
+ 1, mods
, 0, helper
);
842 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[0].begin();
843 Pkg
!= pkgsets
[0].end(); ++Pkg
)
844 Show
[Pkg
->ID
] = ToShow
;
845 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[1].begin();
846 Pkg
!= pkgsets
[1].end(); ++Pkg
)
848 Show
[Pkg
->ID
] = ToShow
;
849 Flags
[Pkg
->ID
] |= ForceNR
;
853 cout
<< "graph: { title: \"packages\"" << endl
<<
854 "xmax: 700 ymax: 700 x: 30 y: 30" << endl
<<
855 "layout_downfactor: 8" << endl
;
861 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
863 // See we need to show this package
864 if (Show
[Pkg
->ID
] == None
|| Show
[Pkg
->ID
] >= DoneNR
)
867 //printf ("node: { title: \"%s\" label: \"%s\" }\n", Pkg.Name(), Pkg.Name());
870 if (Show
[Pkg
->ID
] == ToShowNR
|| (Flags
[Pkg
->ID
] & ForceNR
) == ForceNR
)
872 // Pure Provides and missing packages have no deps!
873 if (ShapeMap
[Pkg
->ID
] == 0 || ShapeMap
[Pkg
->ID
] == 1)
874 Show
[Pkg
->ID
] = Done
;
876 Show
[Pkg
->ID
] = DoneNR
;
879 Show
[Pkg
->ID
] = Done
;
882 // No deps to map out
883 if (Pkg
->VersionList
== 0 || Show
[Pkg
->ID
] == DoneNR
)
886 pkgCache::VerIterator Ver
= Pkg
.VersionList();
887 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; ++D
)
889 // See if anything can meet this dep
890 // Walk along the actual package providing versions
892 pkgCache::PkgIterator DPkg
= D
.TargetPkg();
893 for (pkgCache::VerIterator I
= DPkg
.VersionList();
894 I
.end() == false && Hit
== false; ++I
)
896 if (Cache
->VS
->CheckDep(I
.VerStr(),D
->CompareOp
,D
.TargetVer()) == true)
900 // Follow all provides
901 for (pkgCache::PrvIterator I
= DPkg
.ProvidesList();
902 I
.end() == false && Hit
== false; ++I
)
904 if (Cache
->VS
->CheckDep(I
.ProvideVersion(),D
->CompareOp
,D
.TargetVer()) == false)
909 // Only graph critical deps
910 if (D
.IsCritical() == true)
912 printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg
.FullName(true).c_str(), D
.TargetPkg().FullName(true).c_str() );
914 // Colour the node for recursion
915 if (Show
[D
.TargetPkg()->ID
] <= DoneNR
)
917 /* If a conflicts does not meet anything in the database
918 then show the relation but do not recurse */
919 if (Hit
== false && D
.IsNegative() == true)
921 if (Show
[D
.TargetPkg()->ID
] == None
&&
922 Show
[D
.TargetPkg()->ID
] != ToShow
)
923 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
927 if (GivenOnly
== true && Show
[D
.TargetPkg()->ID
] != ToShow
)
928 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
930 Show
[D
.TargetPkg()->ID
] = ToShow
;
937 case pkgCache::Dep::Conflicts
:
938 printf("label: \"conflicts\" color: lightgreen }\n");
940 case pkgCache::Dep::DpkgBreaks
:
941 printf("label: \"breaks\" color: lightgreen }\n");
943 case pkgCache::Dep::Obsoletes
:
944 printf("label: \"obsoletes\" color: lightgreen }\n");
947 case pkgCache::Dep::PreDepends
:
948 printf("label: \"predepends\" color: blue }\n");
960 /* Draw the box colours after the fact since we can not tell what colour
961 they should be until everything is finished drawing */
962 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
964 if (Show
[Pkg
->ID
] < DoneNR
)
967 if (Show
[Pkg
->ID
] == DoneNR
)
968 printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg
.FullName(true).c_str(), Pkg
.FullName(true).c_str(),
969 Shapes
[ShapeMap
[Pkg
->ID
]]);
971 printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg
.FullName(true).c_str(), Pkg
.FullName(true).c_str(),
972 Shapes
[ShapeMap
[Pkg
->ID
]]);
984 // Dotty - Generate a graph for Dotty /*{{{*/
985 // ---------------------------------------------------------------------
986 /* Dotty is the graphvis program for generating graphs. It is a fairly
987 simple queuing algorithm that just writes dependencies and nodes.
988 http://www.research.att.com/sw/tools/graphviz/ */
989 static bool Dotty(CommandLine
&CmdL
)
991 pkgCacheFile CacheFile
;
992 pkgCache
*Cache
= CacheFile
.GetPkgCache();
993 if (unlikely(Cache
== NULL
))
996 bool GivenOnly
= _config
->FindB("APT::Cache::GivenOnly",false);
998 /* Normal packages are boxes
999 Pure Provides are triangles
1001 Hexagons are missing packages*/
1002 const char *Shapes
[] = {"hexagon","triangle","box","diamond"};
1004 /* Initialize the list of packages to show.
1006 2 = To Show no recurse
1007 3 = Emitted no recurse
1010 enum States
{None
=0, ToShow
, ToShowNR
, DoneNR
, Done
};
1011 enum TheFlags
{ForceNR
=(1<<0)};
1012 unsigned char *Show
= new unsigned char[Cache
->Head().PackageCount
];
1013 unsigned char *Flags
= new unsigned char[Cache
->Head().PackageCount
];
1014 unsigned char *ShapeMap
= new unsigned char[Cache
->Head().PackageCount
];
1016 // Show everything if no arguments given
1017 if (CmdL
.FileList
[1] == 0)
1018 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
1021 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
1023 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
1026 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
1028 if (Pkg
->VersionList
== 0)
1031 if (Pkg
->ProvidesList
== 0)
1032 ShapeMap
[Pkg
->ID
] = 0;
1034 ShapeMap
[Pkg
->ID
] = 1;
1039 if (Pkg
->ProvidesList
== 0)
1040 ShapeMap
[Pkg
->ID
] = 2;
1042 ShapeMap
[Pkg
->ID
] = 3;
1046 // Load the list of packages from the command line into the show list
1047 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
1048 std::list
<APT::CacheSetHelper::PkgModifier
> mods
;
1049 mods
.push_back(APT::CacheSetHelper::PkgModifier(0, ",", APT::PackageSet::Modifier::POSTFIX
));
1050 mods
.push_back(APT::CacheSetHelper::PkgModifier(1, "^", APT::PackageSet::Modifier::POSTFIX
));
1051 std::map
<unsigned short, APT::PackageSet
> pkgsets
=
1052 APT::PackageSet::GroupedFromCommandLine(CacheFile
, CmdL
.FileList
+ 1, mods
, 0, helper
);
1054 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[0].begin();
1055 Pkg
!= pkgsets
[0].end(); ++Pkg
)
1056 Show
[Pkg
->ID
] = ToShow
;
1057 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[1].begin();
1058 Pkg
!= pkgsets
[1].end(); ++Pkg
)
1060 Show
[Pkg
->ID
] = ToShow
;
1061 Flags
[Pkg
->ID
] |= ForceNR
;
1065 printf("digraph packages {\n");
1066 printf("concentrate=true;\n");
1067 printf("size=\"30,40\";\n");
1073 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
1075 // See we need to show this package
1076 if (Show
[Pkg
->ID
] == None
|| Show
[Pkg
->ID
] >= DoneNR
)
1080 if (Show
[Pkg
->ID
] == ToShowNR
|| (Flags
[Pkg
->ID
] & ForceNR
) == ForceNR
)
1082 // Pure Provides and missing packages have no deps!
1083 if (ShapeMap
[Pkg
->ID
] == 0 || ShapeMap
[Pkg
->ID
] == 1)
1084 Show
[Pkg
->ID
] = Done
;
1086 Show
[Pkg
->ID
] = DoneNR
;
1089 Show
[Pkg
->ID
] = Done
;
1092 // No deps to map out
1093 if (Pkg
->VersionList
== 0 || Show
[Pkg
->ID
] == DoneNR
)
1096 pkgCache::VerIterator Ver
= Pkg
.VersionList();
1097 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; ++D
)
1099 // See if anything can meet this dep
1100 // Walk along the actual package providing versions
1102 pkgCache::PkgIterator DPkg
= D
.TargetPkg();
1103 for (pkgCache::VerIterator I
= DPkg
.VersionList();
1104 I
.end() == false && Hit
== false; ++I
)
1106 if (Cache
->VS
->CheckDep(I
.VerStr(),D
->CompareOp
,D
.TargetVer()) == true)
1110 // Follow all provides
1111 for (pkgCache::PrvIterator I
= DPkg
.ProvidesList();
1112 I
.end() == false && Hit
== false; ++I
)
1114 if (Cache
->VS
->CheckDep(I
.ProvideVersion(),D
->CompareOp
,D
.TargetVer()) == false)
1118 // Only graph critical deps
1119 if (D
.IsCritical() == true)
1121 printf("\"%s\" -> \"%s\"",Pkg
.FullName(true).c_str(),D
.TargetPkg().FullName(true).c_str());
1123 // Colour the node for recursion
1124 if (Show
[D
.TargetPkg()->ID
] <= DoneNR
)
1126 /* If a conflicts does not meet anything in the database
1127 then show the relation but do not recurse */
1128 if (Hit
== false && D
.IsNegative() == true)
1130 if (Show
[D
.TargetPkg()->ID
] == None
&&
1131 Show
[D
.TargetPkg()->ID
] != ToShow
)
1132 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
1136 if (GivenOnly
== true && Show
[D
.TargetPkg()->ID
] != ToShow
)
1137 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
1139 Show
[D
.TargetPkg()->ID
] = ToShow
;
1146 case pkgCache::Dep::Conflicts
:
1147 case pkgCache::Dep::Obsoletes
:
1148 case pkgCache::Dep::DpkgBreaks
:
1149 printf("[color=springgreen];\n");
1152 case pkgCache::Dep::PreDepends
:
1153 printf("[color=blue];\n");
1165 /* Draw the box colours after the fact since we can not tell what colour
1166 they should be until everything is finished drawing */
1167 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
1169 if (Show
[Pkg
->ID
] < DoneNR
)
1172 // Orange box for early recursion stoppage
1173 if (Show
[Pkg
->ID
] == DoneNR
)
1174 printf("\"%s\" [color=orange,shape=%s];\n",Pkg
.FullName(true).c_str(),
1175 Shapes
[ShapeMap
[Pkg
->ID
]]);
1177 printf("\"%s\" [shape=%s];\n",Pkg
.FullName(true).c_str(),
1178 Shapes
[ShapeMap
[Pkg
->ID
]]);
1188 /* ShowAuto - show automatically installed packages (sorted) {{{*/
1189 static bool ShowAuto(CommandLine
&)
1191 pkgCacheFile CacheFile
;
1192 pkgCache
*Cache
= CacheFile
.GetPkgCache();
1193 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
1194 if (unlikely(Cache
== NULL
|| DepCache
== NULL
))
1197 std::vector
<string
> packages
;
1198 packages
.reserve(Cache
->HeaderP
->PackageCount
/ 3);
1200 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
1201 if ((*DepCache
)[P
].Flags
& pkgCache::Flag::Auto
)
1202 packages
.push_back(P
.Name());
1204 std::sort(packages
.begin(), packages
.end());
1206 for (vector
<string
>::iterator I
= packages
.begin(); I
!= packages
.end(); ++I
)
1209 _error
->Notice(_("This command is deprecated. Please use 'apt-mark showauto' instead."));
1213 // ShowPkgNames - Show package names /*{{{*/
1214 // ---------------------------------------------------------------------
1215 /* This does a prefix match on the first argument */
1216 static bool ShowPkgNames(CommandLine
&CmdL
)
1218 pkgCacheFile CacheFile
;
1219 if (unlikely(CacheFile
.BuildCaches(NULL
, false) == false))
1221 pkgCache::GrpIterator I
= CacheFile
.GetPkgCache()->GrpBegin();
1222 bool const All
= _config
->FindB("APT::Cache::AllNames","false");
1224 if (CmdL
.FileList
[1] != 0)
1226 for (;I
.end() != true; ++I
)
1228 if (All
== false && I
->FirstPackage
== 0)
1230 if (I
.FindPkg("any")->VersionList
== 0)
1232 if (strncmp(I
.Name(),CmdL
.FileList
[1],strlen(CmdL
.FileList
[1])) == 0)
1233 cout
<< I
.Name() << endl
;
1240 for (;I
.end() != true; ++I
)
1242 if (All
== false && I
->FirstPackage
== 0)
1244 if (I
.FindPkg("any")->VersionList
== 0)
1246 cout
<< I
.Name() << endl
;
1252 // ShowSrcPackage - Show source package records /*{{{*/
1253 // ---------------------------------------------------------------------
1255 static bool ShowSrcPackage(CommandLine
&CmdL
)
1257 pkgCacheFile CacheFile
;
1258 pkgSourceList
*List
= CacheFile
.GetSourceList();
1259 if (unlikely(List
== NULL
))
1262 // Create the text record parsers
1263 pkgSrcRecords
SrcRecs(*List
);
1264 if (_error
->PendingError() == true)
1268 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1272 pkgSrcRecords::Parser
*Parse
;
1273 unsigned found_this
= 0;
1274 while ((Parse
= SrcRecs
.Find(*I
,false)) != 0) {
1275 // SrcRecs.Find() will find both binary and source names
1276 if (_config
->FindB("APT::Cache::Only-Source", false) == true)
1277 if (Parse
->Package() != *I
)
1279 cout
<< Parse
->AsStr() << endl
;;
1283 if (found_this
== 0) {
1284 _error
->Warning(_("Unable to locate package %s"),*I
);
1289 _error
->Notice(_("No packages found"));
1293 // Policy - Show the results of the preferences file /*{{{*/
1294 // ---------------------------------------------------------------------
1296 static bool Policy(CommandLine
&CmdL
)
1298 pkgCacheFile CacheFile
;
1299 pkgCache
*Cache
= CacheFile
.GetPkgCache();
1300 pkgPolicy
*Plcy
= CacheFile
.GetPolicy();
1301 pkgSourceList
*SrcList
= CacheFile
.GetSourceList();
1302 if (unlikely(Cache
== NULL
|| Plcy
== NULL
|| SrcList
== NULL
))
1305 /* Should the MultiArchKiller be run to see which pseudo packages for an
1306 arch all package are currently installed? Activating it gives a speed
1307 penality for no real gain beside enhanced debugging, so in general no. */
1308 if (_config
->FindB("APT::Cache::Policy::DepCache", false) == true)
1309 CacheFile
.GetDepCache();
1311 // Print out all of the package files
1312 if (CmdL
.FileList
[1] == 0)
1314 cout
<< _("Package files:") << endl
;
1315 for (pkgCache::PkgFileIterator F
= Cache
->FileBegin(); F
.end() == false; ++F
)
1317 if (F
.Flagged(pkgCache::Flag::NoPackages
))
1319 // Locate the associated index files so we can derive a description
1321 if (SrcList
->FindIndex(F
,Indx
) == false &&
1322 _system
->FindIndex(F
,Indx
) == false)
1323 return _error
->Error(_("Cache is out of sync, can't x-ref a package file"));
1326 Plcy
->GetPriority(F
),Indx
->Describe(true).c_str());
1328 // Print the reference information for the package
1329 string Str
= F
.RelStr();
1330 if (Str
.empty() == false)
1331 printf(" release %s\n",F
.RelStr().c_str());
1332 if (F
.Site() != 0 && F
.Site()[0] != 0)
1333 printf(" origin %s\n",F
.Site());
1336 // Show any packages have explicit pins
1337 cout
<< _("Pinned packages:") << endl
;
1338 pkgCache::PkgIterator I
= Cache
->PkgBegin();
1339 for (;I
.end() != true; ++I
)
1341 // Old code for debugging
1342 if (_config
->FindI("APT::Policy", 1) < 1) {
1343 if (Plcy
->GetPriority(I
) == 0)
1346 // Print the package name and the version we are forcing to
1347 cout
<< " " << I
.FullName(true) << " -> ";
1349 pkgCache::VerIterator V
= Plcy
->GetMatch(I
);
1350 if (V
.end() == true)
1351 cout
<< _("(not found)") << endl
;
1353 cout
<< V
.VerStr() << endl
;
1358 for (pkgCache::VerIterator V
= I
.VersionList(); !V
.end(); V
++) {
1359 auto Prio
= Plcy
->GetPriority(V
, false);
1364 // Print the package name and the version we are forcing to
1365 ioprintf(cout
, _("%s -> %s with priority %d\n"), I
.FullName(true).c_str(), V
.VerStr(), Prio
);
1371 char const * const msgInstalled
= _(" Installed: ");
1372 char const * const msgCandidate
= _(" Candidate: ");
1373 short const InstalledLessCandidate
=
1374 mbstowcs(NULL
, msgInstalled
, 0) - mbstowcs(NULL
, msgCandidate
, 0);
1375 short const deepInstalled
=
1376 (InstalledLessCandidate
< 0 ? (InstalledLessCandidate
*-1) : 0) - 1;
1377 short const deepCandidate
=
1378 (InstalledLessCandidate
> 0 ? (InstalledLessCandidate
) : 0) - 1;
1380 // Print out detailed information for each package
1381 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
1382 APT::PackageList pkgset
= APT::PackageList::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, helper
);
1383 for (APT::PackageList::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
1385 cout
<< Pkg
.FullName(true) << ":" << endl
;
1387 // Installed version
1388 cout
<< msgInstalled
<< OutputInDepth(deepInstalled
, " ");
1389 if (Pkg
->CurrentVer
== 0)
1390 cout
<< _("(none)") << endl
;
1392 cout
<< Pkg
.CurrentVer().VerStr() << endl
;
1394 // Candidate Version
1395 cout
<< msgCandidate
<< OutputInDepth(deepCandidate
, " ");
1396 pkgCache::VerIterator V
= Plcy
->GetCandidateVer(Pkg
);
1397 if (V
.end() == true)
1398 cout
<< _("(none)") << endl
;
1400 cout
<< V
.VerStr() << endl
;
1403 if (_config
->FindI("APT::Policy", 1) < 1 && Plcy
->GetPriority(Pkg
) != 0)
1405 cout
<< _(" Package pin: ");
1406 V
= Plcy
->GetMatch(Pkg
);
1407 if (V
.end() == true)
1408 cout
<< _("(not found)") << endl
;
1410 cout
<< V
.VerStr() << endl
;
1413 // Show the priority tables
1414 cout
<< _(" Version table:") << endl
;
1415 for (V
= Pkg
.VersionList(); V
.end() == false; ++V
)
1417 if (Pkg
.CurrentVer() == V
)
1418 cout
<< " *** " << V
.VerStr();
1420 cout
<< " " << V
.VerStr();
1421 if (_config
->FindI("APT::Policy", 1) < 1)
1422 cout
<< " " << Plcy
->GetPriority(Pkg
) << endl
;
1424 cout
<< " " << Plcy
->GetPriority(V
) << endl
;
1425 for (pkgCache::VerFileIterator VF
= V
.FileList(); VF
.end() == false; ++VF
)
1427 // Locate the associated index files so we can derive a description
1429 if (SrcList
->FindIndex(VF
.File(),Indx
) == false &&
1430 _system
->FindIndex(VF
.File(),Indx
) == false)
1431 return _error
->Error(_("Cache is out of sync, can't x-ref a package file"));
1432 printf(" %4i %s\n",Plcy
->GetPriority(VF
.File()),
1433 Indx
->Describe(true).c_str());
1441 // Madison - Look a bit like katie's madison /*{{{*/
1442 // ---------------------------------------------------------------------
1444 static bool Madison(CommandLine
&CmdL
)
1446 pkgCacheFile CacheFile
;
1447 pkgSourceList
*SrcList
= CacheFile
.GetSourceList();
1452 // Create the src text record parsers and ignore errors about missing
1453 // deb-src lines that are generated from pkgSrcRecords::pkgSrcRecords
1454 pkgSrcRecords
SrcRecs(*SrcList
);
1455 if (_error
->PendingError() == true)
1458 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
1459 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1461 _error
->PushToStack();
1462 APT::PackageList pkgset
= APT::PackageList::FromString(CacheFile
, *I
, helper
);
1463 for (APT::PackageList::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
1465 for (pkgCache::VerIterator V
= Pkg
.VersionList(); V
.end() == false; ++V
)
1467 for (pkgCache::VerFileIterator VF
= V
.FileList(); VF
.end() == false; ++VF
)
1469 // This might be nice, but wouldn't uniquely identify the source -mdz
1470 // if (VF.File().Archive() != 0)
1472 // cout << setw(10) << Pkg.Name() << " | " << setw(10) << V.VerStr() << " | "
1473 // << VF.File().Archive() << endl;
1476 // Locate the associated index files so we can derive a description
1477 for (pkgSourceList::const_iterator S
= SrcList
->begin(); S
!= SrcList
->end(); ++S
)
1479 vector
<pkgIndexFile
*> *Indexes
= (*S
)->GetIndexFiles();
1480 for (vector
<pkgIndexFile
*>::const_iterator IF
= Indexes
->begin();
1481 IF
!= Indexes
->end(); ++IF
)
1483 if ((*IF
)->FindInCache(*(VF
.File().Cache())) == VF
.File())
1485 cout
<< setw(10) << Pkg
.FullName(true) << " | " << setw(10) << V
.VerStr() << " | "
1486 << (*IF
)->Describe(true) << endl
;
1495 pkgSrcRecords::Parser
*SrcParser
;
1496 bool foundSomething
= false;
1497 while ((SrcParser
= SrcRecs
.Find(*I
, false)) != 0)
1499 foundSomething
= true;
1500 // Maybe support Release info here too eventually
1501 cout
<< setw(10) << SrcParser
->Package() << " | "
1502 << setw(10) << SrcParser
->Version() << " | "
1503 << SrcParser
->Index().Describe(true) << endl
;
1505 if (foundSomething
== true)
1506 _error
->RevertToStack();
1508 _error
->MergeWithStack();
1514 // GenCaches - Call the main cache generator /*{{{*/
1515 // ---------------------------------------------------------------------
1517 static bool GenCaches(CommandLine
&)
1519 OpTextProgress
Progress(*_config
);
1521 pkgCacheFile CacheFile
;
1522 return CacheFile
.BuildCaches(&Progress
, true);
1525 // ShowHelp - Show a help screen /*{{{*/
1526 static bool ShowHelp(CommandLine
&, CommandLine::DispatchWithHelp
const * Cmds
)
1528 ioprintf(cout
, "%s %s (%s)\n", PACKAGE
, PACKAGE_VERSION
, COMMON_ARCH
);
1530 if (_config
->FindB("version") == true)
1534 _("Usage: apt-cache [options] command\n"
1535 " apt-cache [options] show pkg1 [pkg2 ...]\n"
1537 "apt-cache is a low-level tool used to query information\n"
1538 "from APT's binary cache files\n")
1540 << _("Commands:") << std::endl
;
1541 for (; Cmds
->Handler
!= nullptr; ++Cmds
)
1543 if (Cmds
->Help
== nullptr)
1545 std::cout
<< " " << Cmds
->Match
<< " - " << Cmds
->Help
<< std::endl
;
1548 std::cout
<< std::endl
1550 " -h This help text.\n"
1551 " -p=? The package cache.\n"
1552 " -s=? The source cache.\n"
1553 " -q Disable progress indicator.\n"
1554 " -i Show only important deps for the unmet command.\n"
1555 " -c=? Read this configuration file\n"
1556 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
1557 "See the apt-cache(8) and apt.conf(5) manual pages for more information.\n");
1561 int main(int argc
,const char *argv
[]) /*{{{*/
1565 CommandLine::DispatchWithHelp Cmds
[] = {
1566 {"gencaches",&GenCaches
, nullptr},
1567 {"showsrc",&ShowSrcPackage
, _("Show source records")},
1568 {"showpkg",&DumpPackage
, nullptr},
1569 {"stats",&Stats
, nullptr},
1570 {"dump",&Dump
, nullptr},
1571 {"dumpavail",&DumpAvail
, nullptr},
1572 {"unmet",&UnMet
, nullptr},
1573 {"search",&DoSearch
, _("Search the package list for a regex pattern")},
1574 {"depends",&Depends
, _("Show raw dependency information for a package")},
1575 {"rdepends",&RDepends
, _("Show reverse dependency information for a package")},
1576 {"dotty",&Dotty
, nullptr},
1577 {"xvcg",&XVcg
, nullptr},
1578 {"show",&ShowPackage
, _("Show a readable record for the package")},
1579 {"pkgnames",&ShowPkgNames
, _("List the names of all packages in the system")},
1580 {"showauto",&ShowAuto
, nullptr},
1581 {"policy",&Policy
, _("Show policy settings")},
1582 {"madison",&Madison
, nullptr},
1583 {nullptr, nullptr, nullptr}
1586 // Parse the command line and initialize the package library
1588 ParseCommandLine(CmdL
, Cmds
, "apt-cache", &_config
, &_system
, argc
, argv
, ShowHelp
);
1592 if (_config
->Exists("APT::Cache::Generate") == true)
1593 _config
->Set("pkgCacheFile::Generate", _config
->FindB("APT::Cache::Generate", true));
1595 return DispatchCommandLine(CmdL
, Cmds
);