]>
git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
4b3a74922c69422dbaed2ed68056219277c4b8fb
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>
69 // UnMet - Show unmet dependencies /*{{{*/
70 // ---------------------------------------------------------------------
72 static bool ShowUnMet(pkgCache::VerIterator
const &V
, bool const Important
)
75 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false;)
78 pkgCache::DepIterator Start
;
79 pkgCache::DepIterator End
;
82 // Important deps only
83 if (Important
== true)
84 if (End
->Type
!= pkgCache::Dep::PreDepends
&&
85 End
->Type
!= pkgCache::Dep::Depends
)
88 // Skip conflicts and replaces
89 if (End
.IsNegative() == true || End
->Type
== pkgCache::Dep::Replaces
)
92 // Verify the or group
94 pkgCache::DepIterator RealStart
= Start
;
97 // See if this dep is Ok
98 pkgCache::Version
**VList
= Start
.AllTargets();
119 ioprintf(cout
,_("Package %s version %s has an unmet dep:\n"),
120 V
.ParentPkg().FullName(true).c_str(),V
.VerStr());
123 // Print out the dep type
124 cout
<< " " << End
.DepType() << ": ";
130 cout
<< Start
.TargetPkg().FullName(true);
131 if (Start
.TargetVer() != 0)
132 cout
<< " (" << Start
.CompType() << " " << Start
.TargetVer() <<
145 static bool UnMet(CommandLine
&CmdL
)
147 bool const Important
= _config
->FindB("APT::Cache::Important",false);
149 pkgCacheFile CacheFile
;
150 if (unlikely(CacheFile
.GetPkgCache() == NULL
))
153 if (CmdL
.FileSize() <= 1)
155 for (pkgCache::PkgIterator P
= CacheFile
.GetPkgCache()->PkgBegin(); P
.end() == false; ++P
)
156 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; ++V
)
157 if (ShowUnMet(V
, Important
) == false)
162 CacheSetHelperVirtuals
helper(true, GlobalError::NOTICE
);
163 APT::VersionList verset
= APT::VersionList::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1,
164 APT::CacheSetHelper::CANDIDATE
, helper
);
165 for (APT::VersionList::iterator V
= verset
.begin(); V
!= verset
.end(); ++V
)
166 if (ShowUnMet(V
, Important
) == false)
172 // DumpPackage - Show a dump of a package record /*{{{*/
173 // ---------------------------------------------------------------------
175 static bool DumpPackage(CommandLine
&CmdL
)
177 pkgCacheFile CacheFile
;
178 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
179 APT::PackageList pkgset
= APT::PackageList::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, helper
);
181 for (APT::PackageList::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
183 cout
<< "Package: " << Pkg
.FullName(true) << endl
;
184 cout
<< "Versions: " << endl
;
185 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; ++Cur
)
187 cout
<< Cur
.VerStr();
188 for (pkgCache::VerFileIterator Vf
= Cur
.FileList(); Vf
.end() == false; ++Vf
)
189 cout
<< " (" << Vf
.File().FileName() << ")";
191 for (pkgCache::DescIterator D
= Cur
.DescriptionList(); D
.end() == false; ++D
)
193 cout
<< " Description Language: " << D
.LanguageCode() << endl
194 << " File: " << D
.FileList().File().FileName() << endl
195 << " MD5: " << D
.md5() << endl
;
202 cout
<< "Reverse Depends: " << endl
;
203 for (pkgCache::DepIterator D
= Pkg
.RevDependsList(); D
.end() != true; ++D
)
205 cout
<< " " << D
.ParentPkg().FullName(true) << ',' << D
.TargetPkg().FullName(true);
207 cout
<< ' ' << DeNull(D
.TargetVer()) << endl
;
212 cout
<< "Dependencies: " << endl
;
213 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; ++Cur
)
215 cout
<< Cur
.VerStr() << " - ";
216 for (pkgCache::DepIterator Dep
= Cur
.DependsList(); Dep
.end() != true; ++Dep
)
217 cout
<< Dep
.TargetPkg().FullName(true) << " (" << (int)Dep
->CompareOp
<< " " << DeNull(Dep
.TargetVer()) << ") ";
221 cout
<< "Provides: " << endl
;
222 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; ++Cur
)
224 cout
<< Cur
.VerStr() << " - ";
225 for (pkgCache::PrvIterator Prv
= Cur
.ProvidesList(); Prv
.end() != true; ++Prv
)
226 cout
<< Prv
.ParentPkg().FullName(true) << " (= " << (Prv
->ProvideVersion
== 0 ? "" : Prv
.ProvideVersion()) << ") ";
229 cout
<< "Reverse Provides: " << endl
;
230 for (pkgCache::PrvIterator Prv
= Pkg
.ProvidesList(); Prv
.end() != true; ++Prv
)
231 cout
<< Prv
.OwnerPkg().FullName(true) << " " << Prv
.OwnerVer().VerStr() << " (= " << (Prv
->ProvideVersion
== 0 ? "" : Prv
.ProvideVersion()) << ")"<< endl
;
237 // ShowHashTableStats - Show stats about a hashtable /*{{{*/
238 // ---------------------------------------------------------------------
240 static map_pointer_t
PackageNext(pkgCache::Package
const * const P
) { return P
->NextPackage
; }
241 static map_pointer_t
GroupNext(pkgCache::Group
const * const G
) { return G
->Next
; }
243 static void ShowHashTableStats(std::string Type
,
245 map_pointer_t
*Hashtable
,
247 map_pointer_t(*Next
)(T
const * const))
249 // hashtable stats for the HashTable
250 unsigned long NumBuckets
= Size
;
251 unsigned long UsedBuckets
= 0;
252 unsigned long UnusedBuckets
= 0;
253 unsigned long LongestBucket
= 0;
254 unsigned long ShortestBucket
= NumBuckets
;
255 unsigned long Entries
= 0;
256 for (unsigned int i
=0; i
< NumBuckets
; ++i
)
258 T
*P
= StartP
+ Hashtable
[i
];
259 if(P
== 0 || P
== StartP
)
265 unsigned long ThisBucketSize
= 0;
266 for (; P
!= StartP
; P
= StartP
+ Next(P
))
268 Entries
+= ThisBucketSize
;
269 LongestBucket
= std::max(ThisBucketSize
, LongestBucket
);
270 ShortestBucket
= std::min(ThisBucketSize
, ShortestBucket
);
272 cout
<< "Total buckets in " << Type
<< ": " << NumBuckets
<< std::endl
;
273 cout
<< " Unused: " << UnusedBuckets
<< std::endl
;
274 cout
<< " Used: " << UsedBuckets
<< std::endl
;
275 cout
<< " Average entries: " << Entries
/(double)NumBuckets
<< std::endl
;
276 cout
<< " Longest: " << LongestBucket
<< std::endl
;
277 cout
<< " Shortest: " << ShortestBucket
<< std::endl
;
280 // Stats - Dump some nice statistics /*{{{*/
281 // ---------------------------------------------------------------------
283 static bool Stats(CommandLine
&CmdL
)
285 if (CmdL
.FileSize() > 1) {
286 _error
->Error(_("apt-cache stats does not take any arguments"));
290 pkgCacheFile CacheFile
;
291 pkgCache
*Cache
= CacheFile
.GetPkgCache();
293 if (unlikely(Cache
== NULL
))
296 cout
<< _("Total package names: ") << Cache
->Head().GroupCount
<< " (" <<
297 SizeToStr(Cache
->Head().GroupCount
*Cache
->Head().GroupSz
) << ')' << endl
298 << _("Total package structures: ") << Cache
->Head().PackageCount
<< " (" <<
299 SizeToStr(Cache
->Head().PackageCount
*Cache
->Head().PackageSz
) << ')' << endl
;
306 pkgCache::PkgIterator I
= Cache
->PkgBegin();
307 for (;I
.end() != true; ++I
)
309 if (I
->VersionList
!= 0 && I
->ProvidesList
== 0)
315 if (I
->VersionList
!= 0 && I
->ProvidesList
!= 0)
321 if (I
->VersionList
== 0 && I
->ProvidesList
!= 0)
324 if (I
.ProvidesList()->NextProvides
== 0)
332 if (I
->VersionList
== 0 && I
->ProvidesList
== 0)
338 cout
<< _(" Normal packages: ") << Normal
<< endl
;
339 cout
<< _(" Pure virtual packages: ") << Virtual
<< endl
;
340 cout
<< _(" Single virtual packages: ") << DVirt
<< endl
;
341 cout
<< _(" Mixed virtual packages: ") << NVirt
<< endl
;
342 cout
<< _(" Missing: ") << Missing
<< endl
;
344 cout
<< _("Total distinct versions: ") << Cache
->Head().VersionCount
<< " (" <<
345 SizeToStr(Cache
->Head().VersionCount
*Cache
->Head().VersionSz
) << ')' << endl
;
346 cout
<< _("Total distinct descriptions: ") << Cache
->Head().DescriptionCount
<< " (" <<
347 SizeToStr(Cache
->Head().DescriptionCount
*Cache
->Head().DescriptionSz
) << ')' << endl
;
348 cout
<< _("Total dependencies: ") << Cache
->Head().DependsCount
<< "/" << Cache
->Head().DependsDataCount
<< " (" <<
349 SizeToStr((Cache
->Head().DependsCount
*Cache
->Head().DependencySz
) +
350 (Cache
->Head().DependsDataCount
*Cache
->Head().DependencyDataSz
)) << ')' << endl
;
351 cout
<< _("Total ver/file relations: ") << Cache
->Head().VerFileCount
<< " (" <<
352 SizeToStr(Cache
->Head().VerFileCount
*Cache
->Head().VerFileSz
) << ')' << endl
;
353 cout
<< _("Total Desc/File relations: ") << Cache
->Head().DescFileCount
<< " (" <<
354 SizeToStr(Cache
->Head().DescFileCount
*Cache
->Head().DescFileSz
) << ')' << endl
;
355 cout
<< _("Total Provides mappings: ") << Cache
->Head().ProvidesCount
<< " (" <<
356 SizeToStr(Cache
->Head().ProvidesCount
*Cache
->Head().ProvidesSz
) << ')' << endl
;
359 std::set
<map_stringitem_t
> stritems
;
360 for (pkgCache::GrpIterator G
= Cache
->GrpBegin(); G
.end() == false; ++G
)
361 stritems
.insert(G
->Name
);
362 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
364 stritems
.insert(P
->Arch
);
365 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; ++V
)
368 stritems
.insert(V
->VerStr
);
370 stritems
.insert(V
->Section
);
371 stritems
.insert(V
->SourcePkgName
);
372 stritems
.insert(V
->SourceVerStr
);
373 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; ++D
)
376 stritems
.insert(D
->Version
);
378 for (pkgCache::DescIterator D
= V
.DescriptionList(); D
.end() == false; ++D
)
380 stritems
.insert(D
->md5sum
);
381 stritems
.insert(D
->language_code
);
384 for (pkgCache::PrvIterator Prv
= P
.ProvidesList(); Prv
.end() == false; ++Prv
)
386 if (Prv
->ProvideVersion
!= 0)
387 stritems
.insert(Prv
->ProvideVersion
);
390 for (pkgCache::RlsFileIterator F
= Cache
->RlsFileBegin(); F
!= Cache
->RlsFileEnd(); ++F
)
392 stritems
.insert(F
->FileName
);
393 stritems
.insert(F
->Archive
);
394 stritems
.insert(F
->Codename
);
395 stritems
.insert(F
->Version
);
396 stritems
.insert(F
->Origin
);
397 stritems
.insert(F
->Label
);
398 stritems
.insert(F
->Site
);
400 for (pkgCache::PkgFileIterator F
= Cache
->FileBegin(); F
!= Cache
->FileEnd(); ++F
)
402 stritems
.insert(F
->FileName
);
403 stritems
.insert(F
->Architecture
);
404 stritems
.insert(F
->Component
);
405 stritems
.insert(F
->IndexType
);
408 unsigned long Size
= 0;
409 for (std::set
<map_stringitem_t
>::const_iterator i
= stritems
.begin(); i
!= stritems
.end(); ++i
)
410 Size
+= strlen(Cache
->StrP
+ *i
) + 1;
411 cout
<< _("Total globbed strings: ") << stritems
.size() << " (" << SizeToStr(Size
) << ')' << endl
;
414 unsigned long Slack
= 0;
415 for (int I
= 0; I
!= 7; I
++)
416 Slack
+= Cache
->Head().Pools
[I
].ItemSize
*Cache
->Head().Pools
[I
].Count
;
417 cout
<< _("Total slack space: ") << SizeToStr(Slack
) << endl
;
419 unsigned long Total
= 0;
420 #define APT_CACHESIZE(X,Y) (Cache->Head().X * Cache->Head().Y)
421 Total
= Slack
+ Size
+
422 APT_CACHESIZE(GroupCount
, GroupSz
) +
423 APT_CACHESIZE(PackageCount
, PackageSz
) +
424 APT_CACHESIZE(VersionCount
, VersionSz
) +
425 APT_CACHESIZE(DescriptionCount
, DescriptionSz
) +
426 APT_CACHESIZE(DependsCount
, DependencySz
) +
427 APT_CACHESIZE(DependsDataCount
, DependencyDataSz
) +
428 APT_CACHESIZE(ReleaseFileCount
, ReleaseFileSz
) +
429 APT_CACHESIZE(PackageFileCount
, PackageFileSz
) +
430 APT_CACHESIZE(VerFileCount
, VerFileSz
) +
431 APT_CACHESIZE(DescFileCount
, DescFileSz
) +
432 APT_CACHESIZE(ProvidesCount
, ProvidesSz
) +
433 (2 * Cache
->Head().GetHashTableSize() * sizeof(map_id_t
));
434 cout
<< _("Total space accounted for: ") << SizeToStr(Total
) << endl
;
438 ShowHashTableStats
<pkgCache::Package
>("PkgHashTable", Cache
->PkgP
, Cache
->Head().PkgHashTableP(), Cache
->Head().GetHashTableSize(), PackageNext
);
439 ShowHashTableStats
<pkgCache::Group
>("GrpHashTable", Cache
->GrpP
, Cache
->Head().GrpHashTableP(), Cache
->Head().GetHashTableSize(), GroupNext
);
444 // Dump - show everything /*{{{*/
445 // ---------------------------------------------------------------------
446 /* This is worthless except fer debugging things */
447 static bool Dump(CommandLine
&)
449 pkgCacheFile CacheFile
;
450 pkgCache
*Cache
= CacheFile
.GetPkgCache();
451 if (unlikely(Cache
== NULL
))
454 std::cout
<< "Using Versioning System: " << Cache
->VS
->Label
<< std::endl
;
456 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
458 std::cout
<< "Package: " << P
.FullName(true) << std::endl
;
459 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; ++V
)
461 std::cout
<< " Version: " << V
.VerStr() << std::endl
;
462 std::cout
<< " File: " << V
.FileList().File().FileName() << std::endl
;
463 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; ++D
)
464 std::cout
<< " Depends: " << D
.TargetPkg().FullName(true) << ' ' <<
465 DeNull(D
.TargetVer()) << std::endl
;
466 for (pkgCache::DescIterator D
= V
.DescriptionList(); D
.end() == false; ++D
)
468 std::cout
<< " Description Language: " << D
.LanguageCode() << std::endl
469 << " File: " << D
.FileList().File().FileName() << std::endl
470 << " MD5: " << D
.md5() << std::endl
;
475 for (pkgCache::PkgFileIterator F
= Cache
->FileBegin(); F
.end() == false; ++F
)
477 std::cout
<< "File: " << F
.FileName() << std::endl
;
478 std::cout
<< " Type: " << F
.IndexType() << std::endl
;
479 std::cout
<< " Size: " << F
->Size
<< std::endl
;
480 std::cout
<< " ID: " << F
->ID
<< std::endl
;
481 std::cout
<< " Flags: " << F
->Flags
<< std::endl
;
482 std::cout
<< " Time: " << TimeRFC1123(F
->mtime
) << std::endl
;
483 std::cout
<< " Archive: " << DeNull(F
.Archive()) << std::endl
;
484 std::cout
<< " Component: " << DeNull(F
.Component()) << std::endl
;
485 std::cout
<< " Version: " << DeNull(F
.Version()) << std::endl
;
486 std::cout
<< " Origin: " << DeNull(F
.Origin()) << std::endl
;
487 std::cout
<< " Site: " << DeNull(F
.Site()) << std::endl
;
488 std::cout
<< " Label: " << DeNull(F
.Label()) << std::endl
;
489 std::cout
<< " Architecture: " << DeNull(F
.Architecture()) << std::endl
;
495 // DumpAvail - Print out the available list /*{{{*/
496 // ---------------------------------------------------------------------
497 /* This is needed to make dpkg --merge happy.. I spent a bit of time to
498 make this run really fast, perhaps I went a little overboard.. */
499 static bool DumpAvail(CommandLine
&)
501 pkgCacheFile CacheFile
;
502 pkgCache
*Cache
= CacheFile
.GetPkgCache();
503 if (unlikely(Cache
== NULL
|| CacheFile
.BuildPolicy() == false))
506 unsigned long Count
= Cache
->HeaderP
->PackageCount
+1;
507 pkgCache::VerFile
**VFList
= new pkgCache::VerFile
*[Count
];
508 memset(VFList
,0,sizeof(*VFList
)*Count
);
510 // Map versions that we want to write out onto the VerList array.
511 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
513 if (P
->VersionList
== 0)
516 /* Find the proper version to use. If the policy says there are no
517 possible selections we return the installed version, if available..
518 This prevents dselect from making it obsolete. */
519 pkgCache::VerIterator V
= CacheFile
.GetPolicy()->GetCandidateVer(P
);
522 if (P
->CurrentVer
== 0)
527 pkgCache::VerFileIterator VF
= V
.FileList();
528 for (; VF
.end() == false ; ++VF
)
529 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
532 /* Okay, here we have a bit of a problem.. The policy has selected the
533 currently installed package - however it only exists in the
534 status file.. We need to write out something or dselect will mark
535 the package as obsolete! Thus we emit the status file entry, but
536 below we remove the status line to make it valid for the
537 available file. However! We only do this if their do exist *any*
538 non-source versions of the package - that way the dselect obsolete
539 handling works OK. */
540 if (VF
.end() == true)
542 for (pkgCache::VerIterator Cur
= P
.VersionList(); Cur
.end() != true; ++Cur
)
544 for (VF
= Cur
.FileList(); VF
.end() == false; ++VF
)
546 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
553 if (VF
.end() == false)
561 LocalitySort(VFList
,Count
,sizeof(*VFList
));
563 std::vector
<pkgTagSection::Tag
> RW
;
564 RW
.push_back(pkgTagSection::Tag::Remove("Status"));
565 RW
.push_back(pkgTagSection::Tag::Remove("Config-Version"));
567 stdoutfd
.OpenDescriptor(STDOUT_FILENO
, FileFd::WriteOnly
, false);
569 // Iterate over all the package files and write them out.
570 char *Buffer
= new char[Cache
->HeaderP
->MaxVerFileSize
+10];
571 for (pkgCache::VerFile
**J
= VFList
; *J
!= 0;)
573 pkgCache::PkgFileIterator
File(*Cache
,(*J
)->File
+ Cache
->PkgFileP
);
574 if (File
.IsOk() == false)
576 _error
->Error(_("Package file %s is out of sync."),File
.FileName());
580 FileFd
PkgF(File
.FileName(),FileFd::ReadOnly
, FileFd::Extension
);
581 if (_error
->PendingError() == true)
584 /* Write all of the records from this package file, since we
585 already did locality sorting we can now just seek through the
586 file in read order. We apply 1 more optimization here, since often
587 there will be < 1 byte gaps between records (for the \n) we read that
588 into the next buffer and offset a bit.. */
589 unsigned long Pos
= 0;
592 if ((*J
)->File
+ Cache
->PkgFileP
!= File
)
595 const pkgCache::VerFile
&VF
= **J
;
597 // Read the record and then write it out again.
598 unsigned long Jitter
= VF
.Offset
- Pos
;
601 if (PkgF
.Seek(VF
.Offset
) == false)
606 if (PkgF
.Read(Buffer
,VF
.Size
+ Jitter
) == false)
608 Buffer
[VF
.Size
+ Jitter
] = '\n';
611 if ((File
->Flags
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
)
614 if (Tags
.Scan(Buffer
+Jitter
,VF
.Size
+1) == false ||
615 Tags
.Write(stdoutfd
, NULL
, RW
) == false ||
616 stdoutfd
.Write("\n", 1) == false)
618 _error
->Error("Internal Error, Unable to parse a package record");
624 if (stdoutfd
.Write(Buffer
+ Jitter
, VF
.Size
+ 1) == false)
628 Pos
= VF
.Offset
+ VF
.Size
;
631 if (_error
->PendingError() == true)
637 return !_error
->PendingError();
640 // ShowDepends - Helper for printing out a dependency tree /*{{{*/
641 static bool ShowDepends(CommandLine
&CmdL
, bool const RevDepends
)
643 pkgCacheFile CacheFile
;
644 pkgCache
*Cache
= CacheFile
.GetPkgCache();
645 if (unlikely(Cache
== NULL
))
648 CacheSetHelperVirtuals
helper(false);
649 APT::VersionList verset
= APT::VersionList::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, APT::CacheSetHelper::CANDIDATE
, helper
);
650 if (verset
.empty() == true && helper
.virtualPkgs
.empty() == true)
651 return _error
->Error(_("No packages found"));
652 std::vector
<bool> Shown(Cache
->Head().PackageCount
);
654 bool const Recurse
= _config
->FindB("APT::Cache::RecurseDepends", false);
655 bool const Installed
= _config
->FindB("APT::Cache::Installed", false);
656 bool const Important
= _config
->FindB("APT::Cache::Important", false);
657 bool const ShowDepType
= _config
->FindB("APT::Cache::ShowDependencyType", RevDepends
== false);
658 bool const ShowVersion
= _config
->FindB("APT::Cache::ShowVersion", false);
659 bool const ShowPreDepends
= _config
->FindB("APT::Cache::ShowPre-Depends", true);
660 bool const ShowDepends
= _config
->FindB("APT::Cache::ShowDepends", true);
661 bool const ShowRecommends
= _config
->FindB("APT::Cache::ShowRecommends", Important
== false);
662 bool const ShowSuggests
= _config
->FindB("APT::Cache::ShowSuggests", Important
== false);
663 bool const ShowReplaces
= _config
->FindB("APT::Cache::ShowReplaces", Important
== false);
664 bool const ShowConflicts
= _config
->FindB("APT::Cache::ShowConflicts", Important
== false);
665 bool const ShowBreaks
= _config
->FindB("APT::Cache::ShowBreaks", Important
== false);
666 bool const ShowEnhances
= _config
->FindB("APT::Cache::ShowEnhances", Important
== false);
667 bool const ShowOnlyFirstOr
= _config
->FindB("APT::Cache::ShowOnlyFirstOr", false);
668 bool const ShowImplicit
= _config
->FindB("APT::Cache::ShowImplicit", false);
670 while (verset
.empty() != true)
672 pkgCache::VerIterator Ver
= *verset
.begin();
673 verset
.erase(verset
.begin());
674 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
675 Shown
[Pkg
->ID
] = true;
677 cout
<< Pkg
.FullName(true) << endl
;
679 if (RevDepends
== true)
680 cout
<< "Reverse Depends:" << endl
;
681 for (pkgCache::DepIterator D
= RevDepends
? Pkg
.RevDependsList() : Ver
.DependsList();
682 D
.end() == false; ++D
)
685 case pkgCache::Dep::PreDepends
: if (!ShowPreDepends
) continue; break;
686 case pkgCache::Dep::Depends
: if (!ShowDepends
) continue; break;
687 case pkgCache::Dep::Recommends
: if (!ShowRecommends
) continue; break;
688 case pkgCache::Dep::Suggests
: if (!ShowSuggests
) continue; break;
689 case pkgCache::Dep::Replaces
: if (!ShowReplaces
) continue; break;
690 case pkgCache::Dep::Conflicts
: if (!ShowConflicts
) continue; break;
691 case pkgCache::Dep::DpkgBreaks
: if (!ShowBreaks
) continue; break;
692 case pkgCache::Dep::Enhances
: if (!ShowEnhances
) continue; break;
694 if (ShowImplicit
== false && D
.IsImplicit())
697 pkgCache::PkgIterator Trg
= RevDepends
? D
.ParentPkg() : D
.TargetPkg();
699 if((Installed
&& Trg
->CurrentVer
!= 0) || !Installed
)
702 if ((D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
&& ShowOnlyFirstOr
== false)
708 if (ShowDepType
== true)
709 cout
<< D
.DepType() << ": ";
710 if (Trg
->VersionList
== 0)
711 cout
<< "<" << Trg
.FullName(true) << ">";
713 cout
<< Trg
.FullName(true);
714 if (ShowVersion
== true && D
->Version
!= 0)
715 cout
<< " (" << pkgCache::CompTypeDeb(D
->CompareOp
) << ' ' << D
.TargetVer() << ')';
718 if (Recurse
== true && Shown
[Trg
->ID
] == false)
720 Shown
[Trg
->ID
] = true;
721 verset
.insert(APT::VersionSet::FromPackage(CacheFile
, Trg
, APT::CacheSetHelper::CANDIDATE
, helper
));
726 // Display all solutions
727 std::unique_ptr
<pkgCache::Version
*[]> List(D
.AllTargets());
728 pkgPrioSortList(*Cache
,List
.get());
729 for (pkgCache::Version
**I
= List
.get(); *I
!= 0; I
++)
731 pkgCache::VerIterator
V(*Cache
,*I
);
732 if (V
!= Cache
->VerP
+ V
.ParentPkg()->VersionList
||
733 V
->ParentPkg
== D
->Package
)
735 cout
<< " " << V
.ParentPkg().FullName(true) << endl
;
737 if (Recurse
== true && Shown
[V
.ParentPkg()->ID
] == false)
739 Shown
[V
.ParentPkg()->ID
] = true;
740 verset
.insert(APT::VersionSet::FromPackage(CacheFile
, V
.ParentPkg(), APT::CacheSetHelper::CANDIDATE
, helper
));
744 if (ShowOnlyFirstOr
== true)
745 while ((D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
) ++D
;
749 for (APT::PackageSet::const_iterator Pkg
= helper
.virtualPkgs
.begin();
750 Pkg
!= helper
.virtualPkgs
.end(); ++Pkg
)
751 cout
<< '<' << Pkg
.FullName(true) << '>' << endl
;
756 // Depends - Print out a dependency tree /*{{{*/
757 // ---------------------------------------------------------------------
759 static bool Depends(CommandLine
&CmdL
)
761 return ShowDepends(CmdL
, false);
764 // RDepends - Print out a reverse dependency tree /*{{{*/
765 // ---------------------------------------------------------------------
767 static bool RDepends(CommandLine
&CmdL
)
769 return ShowDepends(CmdL
, true);
772 // xvcg - Generate a graph for xvcg /*{{{*/
773 // ---------------------------------------------------------------------
774 // Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
776 static bool XVcg(CommandLine
&CmdL
)
778 pkgCacheFile CacheFile
;
779 pkgCache
*Cache
= CacheFile
.GetPkgCache();
780 if (unlikely(Cache
== NULL
))
783 bool GivenOnly
= _config
->FindB("APT::Cache::GivenOnly",false);
785 /* Normal packages are boxes
786 Pure Provides are triangles
788 rhomb are missing packages*/
789 const char *Shapes
[] = {"ellipse","triangle","box","rhomb"};
791 /* Initialize the list of packages to show.
793 2 = To Show no recurse
794 3 = Emitted no recurse
797 enum States
{None
=0, ToShow
, ToShowNR
, DoneNR
, Done
};
798 enum TheFlags
{ForceNR
=(1<<0)};
799 unsigned char *Show
= new unsigned char[Cache
->Head().PackageCount
];
800 unsigned char *Flags
= new unsigned char[Cache
->Head().PackageCount
];
801 unsigned char *ShapeMap
= new unsigned char[Cache
->Head().PackageCount
];
803 // Show everything if no arguments given
804 if (CmdL
.FileList
[1] == 0)
805 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
808 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
810 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
813 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
815 if (Pkg
->VersionList
== 0)
818 if (Pkg
->ProvidesList
== 0)
819 ShapeMap
[Pkg
->ID
] = 0;
821 ShapeMap
[Pkg
->ID
] = 1;
826 if (Pkg
->ProvidesList
== 0)
827 ShapeMap
[Pkg
->ID
] = 2;
829 ShapeMap
[Pkg
->ID
] = 3;
833 // Load the list of packages from the command line into the show list
834 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
835 std::list
<APT::CacheSetHelper::PkgModifier
> mods
;
836 mods
.push_back(APT::CacheSetHelper::PkgModifier(0, ",", APT::PackageSet::Modifier::POSTFIX
));
837 mods
.push_back(APT::CacheSetHelper::PkgModifier(1, "^", APT::PackageSet::Modifier::POSTFIX
));
838 std::map
<unsigned short, APT::PackageSet
> pkgsets
=
839 APT::PackageSet::GroupedFromCommandLine(CacheFile
, CmdL
.FileList
+ 1, mods
, 0, helper
);
841 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[0].begin();
842 Pkg
!= pkgsets
[0].end(); ++Pkg
)
843 Show
[Pkg
->ID
] = ToShow
;
844 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[1].begin();
845 Pkg
!= pkgsets
[1].end(); ++Pkg
)
847 Show
[Pkg
->ID
] = ToShow
;
848 Flags
[Pkg
->ID
] |= ForceNR
;
852 cout
<< "graph: { title: \"packages\"" << endl
<<
853 "xmax: 700 ymax: 700 x: 30 y: 30" << endl
<<
854 "layout_downfactor: 8" << endl
;
860 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
862 // See we need to show this package
863 if (Show
[Pkg
->ID
] == None
|| Show
[Pkg
->ID
] >= DoneNR
)
866 //printf ("node: { title: \"%s\" label: \"%s\" }\n", Pkg.Name(), Pkg.Name());
869 if (Show
[Pkg
->ID
] == ToShowNR
|| (Flags
[Pkg
->ID
] & ForceNR
) == ForceNR
)
871 // Pure Provides and missing packages have no deps!
872 if (ShapeMap
[Pkg
->ID
] == 0 || ShapeMap
[Pkg
->ID
] == 1)
873 Show
[Pkg
->ID
] = Done
;
875 Show
[Pkg
->ID
] = DoneNR
;
878 Show
[Pkg
->ID
] = Done
;
881 // No deps to map out
882 if (Pkg
->VersionList
== 0 || Show
[Pkg
->ID
] == DoneNR
)
885 pkgCache::VerIterator Ver
= Pkg
.VersionList();
886 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; ++D
)
888 // See if anything can meet this dep
889 // Walk along the actual package providing versions
891 pkgCache::PkgIterator DPkg
= D
.TargetPkg();
892 for (pkgCache::VerIterator I
= DPkg
.VersionList();
893 I
.end() == false && Hit
== false; ++I
)
895 if (Cache
->VS
->CheckDep(I
.VerStr(),D
->CompareOp
,D
.TargetVer()) == true)
899 // Follow all provides
900 for (pkgCache::PrvIterator I
= DPkg
.ProvidesList();
901 I
.end() == false && Hit
== false; ++I
)
903 if (Cache
->VS
->CheckDep(I
.ProvideVersion(),D
->CompareOp
,D
.TargetVer()) == false)
908 // Only graph critical deps
909 if (D
.IsCritical() == true)
911 printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg
.FullName(true).c_str(), D
.TargetPkg().FullName(true).c_str() );
913 // Colour the node for recursion
914 if (Show
[D
.TargetPkg()->ID
] <= DoneNR
)
916 /* If a conflicts does not meet anything in the database
917 then show the relation but do not recurse */
918 if (Hit
== false && D
.IsNegative() == true)
920 if (Show
[D
.TargetPkg()->ID
] == None
&&
921 Show
[D
.TargetPkg()->ID
] != ToShow
)
922 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
926 if (GivenOnly
== true && Show
[D
.TargetPkg()->ID
] != ToShow
)
927 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
929 Show
[D
.TargetPkg()->ID
] = ToShow
;
936 case pkgCache::Dep::Conflicts
:
937 printf("label: \"conflicts\" color: lightgreen }\n");
939 case pkgCache::Dep::DpkgBreaks
:
940 printf("label: \"breaks\" color: lightgreen }\n");
942 case pkgCache::Dep::Obsoletes
:
943 printf("label: \"obsoletes\" color: lightgreen }\n");
946 case pkgCache::Dep::PreDepends
:
947 printf("label: \"predepends\" color: blue }\n");
959 /* Draw the box colours after the fact since we can not tell what colour
960 they should be until everything is finished drawing */
961 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
963 if (Show
[Pkg
->ID
] < DoneNR
)
966 if (Show
[Pkg
->ID
] == DoneNR
)
967 printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg
.FullName(true).c_str(), Pkg
.FullName(true).c_str(),
968 Shapes
[ShapeMap
[Pkg
->ID
]]);
970 printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg
.FullName(true).c_str(), Pkg
.FullName(true).c_str(),
971 Shapes
[ShapeMap
[Pkg
->ID
]]);
983 // Dotty - Generate a graph for Dotty /*{{{*/
984 // ---------------------------------------------------------------------
985 /* Dotty is the graphvis program for generating graphs. It is a fairly
986 simple queuing algorithm that just writes dependencies and nodes.
987 http://www.research.att.com/sw/tools/graphviz/ */
988 static bool Dotty(CommandLine
&CmdL
)
990 pkgCacheFile CacheFile
;
991 pkgCache
*Cache
= CacheFile
.GetPkgCache();
992 if (unlikely(Cache
== NULL
))
995 bool GivenOnly
= _config
->FindB("APT::Cache::GivenOnly",false);
997 /* Normal packages are boxes
998 Pure Provides are triangles
1000 Hexagons are missing packages*/
1001 const char *Shapes
[] = {"hexagon","triangle","box","diamond"};
1003 /* Initialize the list of packages to show.
1005 2 = To Show no recurse
1006 3 = Emitted no recurse
1009 enum States
{None
=0, ToShow
, ToShowNR
, DoneNR
, Done
};
1010 enum TheFlags
{ForceNR
=(1<<0)};
1011 unsigned char *Show
= new unsigned char[Cache
->Head().PackageCount
];
1012 unsigned char *Flags
= new unsigned char[Cache
->Head().PackageCount
];
1013 unsigned char *ShapeMap
= new unsigned char[Cache
->Head().PackageCount
];
1015 // Show everything if no arguments given
1016 if (CmdL
.FileList
[1] == 0)
1017 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
1020 for (unsigned long I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
1022 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
1025 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
1027 if (Pkg
->VersionList
== 0)
1030 if (Pkg
->ProvidesList
== 0)
1031 ShapeMap
[Pkg
->ID
] = 0;
1033 ShapeMap
[Pkg
->ID
] = 1;
1038 if (Pkg
->ProvidesList
== 0)
1039 ShapeMap
[Pkg
->ID
] = 2;
1041 ShapeMap
[Pkg
->ID
] = 3;
1045 // Load the list of packages from the command line into the show list
1046 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
1047 std::list
<APT::CacheSetHelper::PkgModifier
> mods
;
1048 mods
.push_back(APT::CacheSetHelper::PkgModifier(0, ",", APT::PackageSet::Modifier::POSTFIX
));
1049 mods
.push_back(APT::CacheSetHelper::PkgModifier(1, "^", APT::PackageSet::Modifier::POSTFIX
));
1050 std::map
<unsigned short, APT::PackageSet
> pkgsets
=
1051 APT::PackageSet::GroupedFromCommandLine(CacheFile
, CmdL
.FileList
+ 1, mods
, 0, helper
);
1053 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[0].begin();
1054 Pkg
!= pkgsets
[0].end(); ++Pkg
)
1055 Show
[Pkg
->ID
] = ToShow
;
1056 for (APT::PackageSet::const_iterator Pkg
= pkgsets
[1].begin();
1057 Pkg
!= pkgsets
[1].end(); ++Pkg
)
1059 Show
[Pkg
->ID
] = ToShow
;
1060 Flags
[Pkg
->ID
] |= ForceNR
;
1064 printf("digraph packages {\n");
1065 printf("concentrate=true;\n");
1066 printf("size=\"30,40\";\n");
1072 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
1074 // See we need to show this package
1075 if (Show
[Pkg
->ID
] == None
|| Show
[Pkg
->ID
] >= DoneNR
)
1079 if (Show
[Pkg
->ID
] == ToShowNR
|| (Flags
[Pkg
->ID
] & ForceNR
) == ForceNR
)
1081 // Pure Provides and missing packages have no deps!
1082 if (ShapeMap
[Pkg
->ID
] == 0 || ShapeMap
[Pkg
->ID
] == 1)
1083 Show
[Pkg
->ID
] = Done
;
1085 Show
[Pkg
->ID
] = DoneNR
;
1088 Show
[Pkg
->ID
] = Done
;
1091 // No deps to map out
1092 if (Pkg
->VersionList
== 0 || Show
[Pkg
->ID
] == DoneNR
)
1095 pkgCache::VerIterator Ver
= Pkg
.VersionList();
1096 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; ++D
)
1098 // See if anything can meet this dep
1099 // Walk along the actual package providing versions
1101 pkgCache::PkgIterator DPkg
= D
.TargetPkg();
1102 for (pkgCache::VerIterator I
= DPkg
.VersionList();
1103 I
.end() == false && Hit
== false; ++I
)
1105 if (Cache
->VS
->CheckDep(I
.VerStr(),D
->CompareOp
,D
.TargetVer()) == true)
1109 // Follow all provides
1110 for (pkgCache::PrvIterator I
= DPkg
.ProvidesList();
1111 I
.end() == false && Hit
== false; ++I
)
1113 if (Cache
->VS
->CheckDep(I
.ProvideVersion(),D
->CompareOp
,D
.TargetVer()) == false)
1117 // Only graph critical deps
1118 if (D
.IsCritical() == true)
1120 printf("\"%s\" -> \"%s\"",Pkg
.FullName(true).c_str(),D
.TargetPkg().FullName(true).c_str());
1122 // Colour the node for recursion
1123 if (Show
[D
.TargetPkg()->ID
] <= DoneNR
)
1125 /* If a conflicts does not meet anything in the database
1126 then show the relation but do not recurse */
1127 if (Hit
== false && D
.IsNegative() == true)
1129 if (Show
[D
.TargetPkg()->ID
] == None
&&
1130 Show
[D
.TargetPkg()->ID
] != ToShow
)
1131 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
1135 if (GivenOnly
== true && Show
[D
.TargetPkg()->ID
] != ToShow
)
1136 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
1138 Show
[D
.TargetPkg()->ID
] = ToShow
;
1145 case pkgCache::Dep::Conflicts
:
1146 case pkgCache::Dep::Obsoletes
:
1147 case pkgCache::Dep::DpkgBreaks
:
1148 printf("[color=springgreen];\n");
1151 case pkgCache::Dep::PreDepends
:
1152 printf("[color=blue];\n");
1164 /* Draw the box colours after the fact since we can not tell what colour
1165 they should be until everything is finished drawing */
1166 for (pkgCache::PkgIterator Pkg
= Cache
->PkgBegin(); Pkg
.end() == false; ++Pkg
)
1168 if (Show
[Pkg
->ID
] < DoneNR
)
1171 // Orange box for early recursion stoppage
1172 if (Show
[Pkg
->ID
] == DoneNR
)
1173 printf("\"%s\" [color=orange,shape=%s];\n",Pkg
.FullName(true).c_str(),
1174 Shapes
[ShapeMap
[Pkg
->ID
]]);
1176 printf("\"%s\" [shape=%s];\n",Pkg
.FullName(true).c_str(),
1177 Shapes
[ShapeMap
[Pkg
->ID
]]);
1187 /* ShowAuto - show automatically installed packages (sorted) {{{*/
1188 static bool ShowAuto(CommandLine
&)
1190 pkgCacheFile CacheFile
;
1191 pkgCache
*Cache
= CacheFile
.GetPkgCache();
1192 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
1193 if (unlikely(Cache
== NULL
|| DepCache
== NULL
))
1196 std::vector
<string
> packages
;
1197 packages
.reserve(Cache
->HeaderP
->PackageCount
/ 3);
1199 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
1200 if ((*DepCache
)[P
].Flags
& pkgCache::Flag::Auto
)
1201 packages
.push_back(P
.Name());
1203 std::sort(packages
.begin(), packages
.end());
1205 for (vector
<string
>::iterator I
= packages
.begin(); I
!= packages
.end(); ++I
)
1208 _error
->Notice(_("This command is deprecated. Please use 'apt-mark showauto' instead."));
1212 // ShowPkgNames - Show package names /*{{{*/
1213 // ---------------------------------------------------------------------
1214 /* This does a prefix match on the first argument */
1215 static bool ShowPkgNames(CommandLine
&CmdL
)
1217 pkgCacheFile CacheFile
;
1218 if (unlikely(CacheFile
.BuildCaches(NULL
, false) == false))
1220 pkgCache::GrpIterator I
= CacheFile
.GetPkgCache()->GrpBegin();
1221 bool const All
= _config
->FindB("APT::Cache::AllNames","false");
1223 if (CmdL
.FileList
[1] != 0)
1225 for (;I
.end() != true; ++I
)
1227 if (All
== false && I
->FirstPackage
== 0)
1229 if (I
.FindPkg("any")->VersionList
== 0)
1231 if (strncmp(I
.Name(),CmdL
.FileList
[1],strlen(CmdL
.FileList
[1])) == 0)
1232 cout
<< I
.Name() << endl
;
1239 for (;I
.end() != true; ++I
)
1241 if (All
== false && I
->FirstPackage
== 0)
1243 if (I
.FindPkg("any")->VersionList
== 0)
1245 cout
<< I
.Name() << endl
;
1251 // ShowSrcPackage - Show source package records /*{{{*/
1252 // ---------------------------------------------------------------------
1254 static bool ShowSrcPackage(CommandLine
&CmdL
)
1256 pkgCacheFile CacheFile
;
1257 pkgSourceList
*List
= CacheFile
.GetSourceList();
1258 if (unlikely(List
== NULL
))
1261 // Create the text record parsers
1262 pkgSrcRecords
SrcRecs(*List
);
1263 if (_error
->PendingError() == true)
1267 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1271 pkgSrcRecords::Parser
*Parse
;
1272 unsigned found_this
= 0;
1273 while ((Parse
= SrcRecs
.Find(*I
,false)) != 0) {
1274 // SrcRecs.Find() will find both binary and source names
1275 if (_config
->FindB("APT::Cache::Only-Source", false) == true)
1276 if (Parse
->Package() != *I
)
1278 cout
<< Parse
->AsStr() << endl
;;
1282 if (found_this
== 0) {
1283 _error
->Warning(_("Unable to locate package %s"),*I
);
1288 _error
->Notice(_("No packages found"));
1292 // Policy - Show the results of the preferences file /*{{{*/
1293 // ---------------------------------------------------------------------
1295 static bool Policy(CommandLine
&CmdL
)
1297 pkgCacheFile CacheFile
;
1298 pkgCache
*Cache
= CacheFile
.GetPkgCache();
1299 pkgPolicy
*Plcy
= CacheFile
.GetPolicy();
1300 pkgSourceList
*SrcList
= CacheFile
.GetSourceList();
1301 if (unlikely(Cache
== NULL
|| Plcy
== NULL
|| SrcList
== NULL
))
1304 /* Should the MultiArchKiller be run to see which pseudo packages for an
1305 arch all package are currently installed? Activating it gives a speed
1306 penality for no real gain beside enhanced debugging, so in general no. */
1307 if (_config
->FindB("APT::Cache::Policy::DepCache", false) == true)
1308 CacheFile
.GetDepCache();
1310 // Print out all of the package files
1311 if (CmdL
.FileList
[1] == 0)
1313 cout
<< _("Package files:") << endl
;
1314 for (pkgCache::PkgFileIterator F
= Cache
->FileBegin(); F
.end() == false; ++F
)
1316 if (F
.Flagged(pkgCache::Flag::NoPackages
))
1318 // Locate the associated index files so we can derive a description
1320 if (SrcList
->FindIndex(F
,Indx
) == false &&
1321 _system
->FindIndex(F
,Indx
) == false)
1322 return _error
->Error(_("Cache is out of sync, can't x-ref a package file"));
1325 Plcy
->GetPriority(F
),Indx
->Describe(true).c_str());
1327 // Print the reference information for the package
1328 string Str
= F
.RelStr();
1329 if (Str
.empty() == false)
1330 printf(" release %s\n",F
.RelStr().c_str());
1331 if (F
.Site() != 0 && F
.Site()[0] != 0)
1332 printf(" origin %s\n",F
.Site());
1335 // Show any packages have explicit pins
1336 cout
<< _("Pinned packages:") << endl
;
1337 pkgCache::PkgIterator I
= Cache
->PkgBegin();
1338 for (;I
.end() != true; ++I
)
1340 // Old code for debugging
1341 if (_config
->FindI("APT::Policy", 1) < 1) {
1342 if (Plcy
->GetPriority(I
) == 0)
1345 // Print the package name and the version we are forcing to
1346 cout
<< " " << I
.FullName(true) << " -> ";
1348 pkgCache::VerIterator V
= Plcy
->GetMatch(I
);
1349 if (V
.end() == true)
1350 cout
<< _("(not found)") << endl
;
1352 cout
<< V
.VerStr() << endl
;
1357 for (pkgCache::VerIterator V
= I
.VersionList(); !V
.end(); V
++) {
1358 auto Prio
= Plcy
->GetPriority(V
, false);
1363 // Print the package name and the version we are forcing to
1364 ioprintf(cout
, _("%s -> %s with priority %d\n"), I
.FullName(true).c_str(), V
.VerStr(), Prio
);
1370 char const * const msgInstalled
= _(" Installed: ");
1371 char const * const msgCandidate
= _(" Candidate: ");
1372 short const InstalledLessCandidate
=
1373 mbstowcs(NULL
, msgInstalled
, 0) - mbstowcs(NULL
, msgCandidate
, 0);
1374 short const deepInstalled
=
1375 (InstalledLessCandidate
< 0 ? (InstalledLessCandidate
*-1) : 0) - 1;
1376 short const deepCandidate
=
1377 (InstalledLessCandidate
> 0 ? (InstalledLessCandidate
) : 0) - 1;
1379 // Print out detailed information for each package
1380 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
1381 APT::PackageList pkgset
= APT::PackageList::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, helper
);
1382 for (APT::PackageList::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
1384 cout
<< Pkg
.FullName(true) << ":" << endl
;
1386 // Installed version
1387 cout
<< msgInstalled
<< OutputInDepth(deepInstalled
, " ");
1388 if (Pkg
->CurrentVer
== 0)
1389 cout
<< _("(none)") << endl
;
1391 cout
<< Pkg
.CurrentVer().VerStr() << endl
;
1393 // Candidate Version
1394 cout
<< msgCandidate
<< OutputInDepth(deepCandidate
, " ");
1395 pkgCache::VerIterator V
= Plcy
->GetCandidateVer(Pkg
);
1396 if (V
.end() == true)
1397 cout
<< _("(none)") << endl
;
1399 cout
<< V
.VerStr() << endl
;
1402 if (_config
->FindI("APT::Policy", 1) < 1 && Plcy
->GetPriority(Pkg
) != 0)
1404 cout
<< _(" Package pin: ");
1405 V
= Plcy
->GetMatch(Pkg
);
1406 if (V
.end() == true)
1407 cout
<< _("(not found)") << endl
;
1409 cout
<< V
.VerStr() << endl
;
1412 // Show the priority tables
1413 cout
<< _(" Version table:") << endl
;
1414 for (V
= Pkg
.VersionList(); V
.end() == false; ++V
)
1416 if (Pkg
.CurrentVer() == V
)
1417 cout
<< " *** " << V
.VerStr();
1419 cout
<< " " << V
.VerStr();
1420 if (_config
->FindI("APT::Policy", 1) < 1)
1421 cout
<< " " << Plcy
->GetPriority(Pkg
) << endl
;
1423 cout
<< " " << Plcy
->GetPriority(V
) << endl
;
1424 for (pkgCache::VerFileIterator VF
= V
.FileList(); VF
.end() == false; ++VF
)
1426 // Locate the associated index files so we can derive a description
1428 if (SrcList
->FindIndex(VF
.File(),Indx
) == false &&
1429 _system
->FindIndex(VF
.File(),Indx
) == false)
1430 return _error
->Error(_("Cache is out of sync, can't x-ref a package file"));
1431 printf(" %4i %s\n",Plcy
->GetPriority(VF
.File()),
1432 Indx
->Describe(true).c_str());
1440 // Madison - Look a bit like katie's madison /*{{{*/
1441 // ---------------------------------------------------------------------
1443 static bool Madison(CommandLine
&CmdL
)
1445 pkgCacheFile CacheFile
;
1446 pkgSourceList
*SrcList
= CacheFile
.GetSourceList();
1451 // Create the src text record parsers and ignore errors about missing
1452 // deb-src lines that are generated from pkgSrcRecords::pkgSrcRecords
1453 pkgSrcRecords
SrcRecs(*SrcList
);
1454 if (_error
->PendingError() == true)
1457 APT::CacheSetHelper
helper(true, GlobalError::NOTICE
);
1458 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1460 _error
->PushToStack();
1461 APT::PackageList pkgset
= APT::PackageList::FromString(CacheFile
, *I
, helper
);
1462 for (APT::PackageList::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
1464 for (pkgCache::VerIterator V
= Pkg
.VersionList(); V
.end() == false; ++V
)
1466 for (pkgCache::VerFileIterator VF
= V
.FileList(); VF
.end() == false; ++VF
)
1468 // This might be nice, but wouldn't uniquely identify the source -mdz
1469 // if (VF.File().Archive() != 0)
1471 // cout << setw(10) << Pkg.Name() << " | " << setw(10) << V.VerStr() << " | "
1472 // << VF.File().Archive() << endl;
1475 // Locate the associated index files so we can derive a description
1476 for (pkgSourceList::const_iterator S
= SrcList
->begin(); S
!= SrcList
->end(); ++S
)
1478 vector
<pkgIndexFile
*> *Indexes
= (*S
)->GetIndexFiles();
1479 for (vector
<pkgIndexFile
*>::const_iterator IF
= Indexes
->begin();
1480 IF
!= Indexes
->end(); ++IF
)
1482 if ((*IF
)->FindInCache(*(VF
.File().Cache())) == VF
.File())
1484 cout
<< setw(10) << Pkg
.FullName(true) << " | " << setw(10) << V
.VerStr() << " | "
1485 << (*IF
)->Describe(true) << endl
;
1494 pkgSrcRecords::Parser
*SrcParser
;
1495 bool foundSomething
= false;
1496 while ((SrcParser
= SrcRecs
.Find(*I
, false)) != 0)
1498 foundSomething
= true;
1499 // Maybe support Release info here too eventually
1500 cout
<< setw(10) << SrcParser
->Package() << " | "
1501 << setw(10) << SrcParser
->Version() << " | "
1502 << SrcParser
->Index().Describe(true) << endl
;
1504 if (foundSomething
== true)
1505 _error
->RevertToStack();
1507 _error
->MergeWithStack();
1513 // GenCaches - Call the main cache generator /*{{{*/
1514 // ---------------------------------------------------------------------
1516 static bool GenCaches(CommandLine
&)
1518 OpTextProgress
Progress(*_config
);
1520 pkgCacheFile CacheFile
;
1521 return CacheFile
.BuildCaches(&Progress
, true);
1524 // ShowHelp - Show a help screen /*{{{*/
1525 static bool ShowHelp(CommandLine
&, CommandLine::DispatchWithHelp
const * Cmds
)
1527 ioprintf(cout
, "%s %s (%s)\n", PACKAGE
, PACKAGE_VERSION
, COMMON_ARCH
);
1529 if (_config
->FindB("version") == true)
1533 _("Usage: apt-cache [options] command\n"
1534 " apt-cache [options] show pkg1 [pkg2 ...]\n"
1536 "apt-cache is a low-level tool used to query information\n"
1537 "from APT's binary cache files\n")
1539 << _("Commands:") << std::endl
;
1540 for (; Cmds
->Handler
!= nullptr; ++Cmds
)
1542 if (Cmds
->Help
== nullptr)
1544 std::cout
<< " " << Cmds
->Match
<< " - " << Cmds
->Help
<< std::endl
;
1547 std::cout
<< std::endl
1549 " -h This help text.\n"
1550 " -p=? The package cache.\n"
1551 " -s=? The source cache.\n"
1552 " -q Disable progress indicator.\n"
1553 " -i Show only important deps for the unmet command.\n"
1554 " -c=? Read this configuration file\n"
1555 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
1556 "See the apt-cache(8) and apt.conf(5) manual pages for more information.\n");
1560 int main(int argc
,const char *argv
[]) /*{{{*/
1562 CommandLine::DispatchWithHelp Cmds
[] = {
1563 {"gencaches",&GenCaches
, nullptr},
1564 {"showsrc",&ShowSrcPackage
, _("Show source records")},
1565 {"showpkg",&DumpPackage
, nullptr},
1566 {"stats",&Stats
, nullptr},
1567 {"dump",&Dump
, nullptr},
1568 {"dumpavail",&DumpAvail
, nullptr},
1569 {"unmet",&UnMet
, nullptr},
1570 {"search",&DoSearch
, _("Search the package list for a regex pattern")},
1571 {"depends",&Depends
, _("Show raw dependency information for a package")},
1572 {"rdepends",&RDepends
, _("Show reverse dependency information for a package")},
1573 {"dotty",&Dotty
, nullptr},
1574 {"xvcg",&XVcg
, nullptr},
1575 {"show",&ShowPackage
, _("Show a readable record for the package")},
1576 {"pkgnames",&ShowPkgNames
, _("List the names of all packages in the system")},
1577 {"showauto",&ShowAuto
, nullptr},
1578 {"policy",&Policy
, _("Show policy settings")},
1579 {"madison",&Madison
, nullptr},
1580 {nullptr, nullptr, nullptr}
1583 std::vector
<CommandLine::Args
> Args
= getCommandArgs("apt-cache", CommandLine::GetCommand(Cmds
, argc
, argv
));
1585 // Set up gettext support
1586 setlocale(LC_ALL
,"");
1587 textdomain(PACKAGE
);
1589 // Parse the command line and initialize the package library
1591 ParseCommandLine(CmdL
, Cmds
, Args
.data(), &_config
, &_system
, argc
, argv
, ShowHelp
);
1595 if (_config
->Exists("APT::Cache::Generate") == true)
1596 _config
->Set("pkgCacheFile::Generate", _config
->FindB("APT::Cache::Generate", true));
1598 // Match the operation
1599 CmdL
.DispatchArg(Cmds
);
1601 // Print any errors or warnings found during parsing
1602 bool const Errors
= _error
->PendingError();
1603 if (_config
->FindI("quiet",0) > 0)
1604 _error
->DumpErrors();
1606 _error
->DumpErrors(GlobalError::DEBUG
);
1607 return Errors
== true ? 100 : 0;