]> git.saurik.com Git - apt.git/blame - cmdline/apt-cache.cc
move 'search' implementations as well
[apt.git] / cmdline / apt-cache.cc
CommitLineData
1164783d
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
ea7f6363 3// $Id: apt-cache.cc,v 1.72 2004/04/30 04:34:03 mdz Exp $
1164783d
AL
4/* ######################################################################
5
e1b74f61 6 apt-cache - Manages the cache files
1164783d 7
e1b74f61 8 apt-cache provides some functions fo manipulating the cache files.
b2e465d6 9 It uses the command line interface common to all the APT tools.
1164783d
AL
10
11 Returns 100 on failure, 0 on success.
12
13 ##################################################################### */
14 /*}}}*/
15// Include Files /*{{{*/
ea542140
DK
16#include<config.h>
17
453b82a3 18#include <apt-pkg/algorithms.h>
6007c1d4 19#include <apt-pkg/cachefile.h>
8fde7239 20#include <apt-pkg/cacheset.h>
08e8f724 21#include <apt-pkg/cmndline.h>
453b82a3 22#include <apt-pkg/error.h>
472ff00e 23#include <apt-pkg/fileutl.h>
453b82a3
DK
24#include <apt-pkg/indexfile.h>
25#include <apt-pkg/init.h>
26#include <apt-pkg/metaindex.h>
9dbb421f 27#include <apt-pkg/pkgrecords.h>
453b82a3 28#include <apt-pkg/pkgsystem.h>
b2e465d6 29#include <apt-pkg/policy.h>
453b82a3
DK
30#include <apt-pkg/progress.h>
31#include <apt-pkg/sourcelist.h>
b2e465d6 32#include <apt-pkg/sptr.h>
453b82a3
DK
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>
31367812 43
b9179170 44#include <apt-private/private-cacheset.h>
453b82a3 45#include <apt-private/private-cmndline.h>
501cd23e 46#include <apt-private/private-show.h>
631800b1 47#include <apt-private/private-search.h>
b9179170 48
9dbb421f 49#include <regex.h>
453b82a3 50#include <stddef.h>
3e94da1b 51#include <stdio.h>
453b82a3
DK
52#include <stdlib.h>
53#include <unistd.h>
472ff00e 54#include <algorithm>
453b82a3
DK
55#include <cstring>
56#include <iomanip>
57#include <iostream>
58#include <list>
59#include <map>
60#include <set>
61#include <string>
62#include <vector>
ea542140
DK
63
64#include <apti18n.h>
1164783d
AL
65 /*}}}*/
66
8f312f45
AL
67using namespace std;
68
cc718e9a
AL
69// UnMet - Show unmet dependencies /*{{{*/
70// ---------------------------------------------------------------------
71/* */
c3ccac92 72static bool ShowUnMet(pkgCache::VerIterator const &V, bool const Important)
cc718e9a 73{
cc718e9a 74 bool Header = false;
018f1533 75 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false;)
cc718e9a
AL
76 {
77 // Collect or groups
78 pkgCache::DepIterator Start;
79 pkgCache::DepIterator End;
80 D.GlobOr(Start,End);
cc718e9a 81
018f1533
AL
82 // Important deps only
83 if (Important == true)
84 if (End->Type != pkgCache::Dep::PreDepends &&
7146a53c 85 End->Type != pkgCache::Dep::Depends)
018f1533 86 continue;
6ebaae9a
DK
87
88 // Skip conflicts and replaces
081c9d44 89 if (End.IsNegative() == true || End->Type == pkgCache::Dep::Replaces)
6ebaae9a
DK
90 continue;
91
cc718e9a
AL
92 // Verify the or group
93 bool OK = false;
94 pkgCache::DepIterator RealStart = Start;
95 do
96 {
97 // See if this dep is Ok
98 pkgCache::Version **VList = Start.AllTargets();
99 if (*VList != 0)
100 {
101 OK = true;
102 delete [] VList;
103 break;
104 }
105 delete [] VList;
081c9d44 106
cc718e9a
AL
107 if (Start == End)
108 break;
f7f0d6c7 109 ++Start;
cc718e9a
AL
110 }
111 while (1);
112
113 // The group is OK
114 if (OK == true)
115 continue;
116
117 // Oops, it failed..
118 if (Header == false)
b2e465d6 119 ioprintf(cout,_("Package %s version %s has an unmet dep:\n"),
6ebaae9a 120 V.ParentPkg().FullName(true).c_str(),V.VerStr());
cc718e9a
AL
121 Header = true;
122
123 // Print out the dep type
124 cout << " " << End.DepType() << ": ";
125
126 // Show the group
127 Start = RealStart;
128 do
129 {
75ce2062 130 cout << Start.TargetPkg().FullName(true);
cc718e9a
AL
131 if (Start.TargetVer() != 0)
132 cout << " (" << Start.CompType() << " " << Start.TargetVer() <<
133 ")";
134 if (Start == End)
135 break;
136 cout << " | ";
f7f0d6c7 137 ++Start;
cc718e9a
AL
138 }
139 while (1);
140
141 cout << endl;
6ebaae9a
DK
142 }
143 return true;
144}
c3ccac92 145static bool UnMet(CommandLine &CmdL)
6ebaae9a
DK
146{
147 bool const Important = _config->FindB("APT::Cache::Important",false);
148
149 pkgCacheFile CacheFile;
150 if (unlikely(CacheFile.GetPkgCache() == NULL))
151 return false;
152
153 if (CmdL.FileSize() <= 1)
154 {
f7f0d6c7 155 for (pkgCache::PkgIterator P = CacheFile.GetPkgCache()->PkgBegin(); P.end() == false; ++P)
6ebaae9a
DK
156 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
157 if (ShowUnMet(V, Important) == false)
158 return false;
159 }
160 else
161 {
65f81081 162 CacheSetHelperVirtuals helper(true, GlobalError::NOTICE);
c4cca791 163 APT::VersionList verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1,
e6f0c9bc 164 APT::CacheSetHelper::CANDIDATE, helper);
c4cca791 165 for (APT::VersionList::iterator V = verset.begin(); V != verset.end(); ++V)
6ebaae9a
DK
166 if (ShowUnMet(V, Important) == false)
167 return false;
168 }
cc718e9a
AL
169 return true;
170}
171 /*}}}*/
1164783d
AL
172// DumpPackage - Show a dump of a package record /*{{{*/
173// ---------------------------------------------------------------------
174/* */
c3ccac92 175static bool DumpPackage(CommandLine &CmdL)
d9eb210e
DK
176{
177 pkgCacheFile CacheFile;
cd7bbc47 178 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
c4cca791 179 APT::PackageList pkgset = APT::PackageList::FromCommandLine(CacheFile, CmdL.FileList + 1, helper);
1164783d 180
c4cca791 181 for (APT::PackageList::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
78c32596 182 {
75ce2062 183 cout << "Package: " << Pkg.FullName(true) << endl;
b2e465d6 184 cout << "Versions: " << endl;
f7f0d6c7 185 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; ++Cur)
03e39e59
AL
186 {
187 cout << Cur.VerStr();
f7f0d6c7 188 for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; ++Vf)
a52f938b
OS
189 cout << " (" << Vf.File().FileName() << ")";
190 cout << endl;
f7f0d6c7 191 for (pkgCache::DescIterator D = Cur.DescriptionList(); D.end() == false; ++D)
a52f938b
OS
192 {
193 cout << " Description Language: " << D.LanguageCode() << endl
194 << " File: " << D.FileList().File().FileName() << endl
195 << " MD5: " << D.md5() << endl;
196 }
b2e465d6 197 cout << endl;
03e39e59
AL
198 }
199
1164783d
AL
200 cout << endl;
201
202 cout << "Reverse Depends: " << endl;
f7f0d6c7 203 for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; ++D)
b2e465d6 204 {
75ce2062 205 cout << " " << D.ParentPkg().FullName(true) << ',' << D.TargetPkg().FullName(true);
b2e465d6 206 if (D->Version != 0)
b1b663d1 207 cout << ' ' << DeNull(D.TargetVer()) << endl;
b2e465d6
AL
208 else
209 cout << endl;
210 }
211
1164783d 212 cout << "Dependencies: " << endl;
f7f0d6c7 213 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; ++Cur)
1164783d
AL
214 {
215 cout << Cur.VerStr() << " - ";
f7f0d6c7 216 for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; ++Dep)
75ce2062 217 cout << Dep.TargetPkg().FullName(true) << " (" << (int)Dep->CompareOp << " " << DeNull(Dep.TargetVer()) << ") ";
1164783d
AL
218 cout << endl;
219 }
220
221 cout << "Provides: " << endl;
f7f0d6c7 222 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; ++Cur)
1164783d
AL
223 {
224 cout << Cur.VerStr() << " - ";
f7f0d6c7 225 for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; ++Prv)
ecc138f8 226 cout << Prv.ParentPkg().FullName(true) << " (= " << (Prv->ProvideVersion == 0 ? "" : Prv.ProvideVersion()) << ") ";
1164783d 227 cout << endl;
8efa2a3b
AL
228 }
229 cout << "Reverse Provides: " << endl;
f7f0d6c7 230 for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; ++Prv)
ecc138f8 231 cout << Prv.OwnerPkg().FullName(true) << " " << Prv.OwnerVer().VerStr() << " (= " << (Prv->ProvideVersion == 0 ? "" : Prv.ProvideVersion()) << ")"<< endl;
1164783d
AL
232 }
233
234 return true;
235}
236 /*}}}*/
637c3b23
MV
237// ShowHashTableStats - Show stats about a hashtable /*{{{*/
238// ---------------------------------------------------------------------
239/* */
32ab4bd0
DK
240static map_pointer_t PackageNext(pkgCache::Package const * const P) { return P->NextPackage; }
241static map_pointer_t GroupNext(pkgCache::Group const * const G) { return G->Next; }
637c3b23
MV
242template<class T>
243static void ShowHashTableStats(std::string Type,
244 T *StartP,
ac2c559b 245 map_pointer_t *Hashtable,
32ab4bd0
DK
246 unsigned long Size,
247 map_pointer_t(*Next)(T const * const))
637c3b23
MV
248{
249 // hashtable stats for the HashTable
ac2c559b
DK
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;
637c3b23
MV
256 for (unsigned int i=0; i < NumBuckets; ++i)
257 {
258 T *P = StartP + Hashtable[i];
259 if(P == 0 || P == StartP)
260 {
ac2c559b 261 ++UnusedBuckets;
637c3b23
MV
262 continue;
263 }
ac2c559b
DK
264 ++UsedBuckets;
265 unsigned long ThisBucketSize = 0;
32ab4bd0 266 for (; P != StartP; P = StartP + Next(P))
ac2c559b
DK
267 ++ThisBucketSize;
268 Entries += ThisBucketSize;
637c3b23
MV
269 LongestBucket = std::max(ThisBucketSize, LongestBucket);
270 ShortestBucket = std::min(ThisBucketSize, ShortestBucket);
637c3b23 271 }
ac2c559b
DK
272 cout << "Total buckets in " << Type << ": " << NumBuckets << std::endl;
273 cout << " Unused: " << UnusedBuckets << std::endl;
637c3b23 274 cout << " Used: " << UsedBuckets << std::endl;
ac2c559b 275 cout << " Average entries: " << Entries/(double)NumBuckets << std::endl;
637c3b23
MV
276 cout << " Longest: " << LongestBucket << std::endl;
277 cout << " Shortest: " << ShortestBucket << std::endl;
278}
279 /*}}}*/
1164783d
AL
280// Stats - Dump some nice statistics /*{{{*/
281// ---------------------------------------------------------------------
282/* */
714c23a7 283static bool Stats(CommandLine &CmdL)
1164783d 284{
714c23a7
JAK
285 if (CmdL.FileSize() > 1) {
286 _error->Error(_("apt-cache stats does not take any arguments"));
287 return false;
288 }
7414af7f
DK
289
290 pkgCacheFile CacheFile;
291 pkgCache *Cache = CacheFile.GetPkgCache();
292
d9eb210e
DK
293 if (unlikely(Cache == NULL))
294 return false;
295
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;
b2e465d6 300
1164783d
AL
301 int Normal = 0;
302 int Virtual = 0;
303 int NVirt = 0;
304 int DVirt = 0;
305 int Missing = 0;
d9eb210e 306 pkgCache::PkgIterator I = Cache->PkgBegin();
f7f0d6c7 307 for (;I.end() != true; ++I)
1164783d
AL
308 {
309 if (I->VersionList != 0 && I->ProvidesList == 0)
310 {
311 Normal++;
312 continue;
313 }
314
315 if (I->VersionList != 0 && I->ProvidesList != 0)
316 {
317 NVirt++;
318 continue;
319 }
320
321 if (I->VersionList == 0 && I->ProvidesList != 0)
322 {
323 // Only 1 provides
324 if (I.ProvidesList()->NextProvides == 0)
325 {
326 DVirt++;
327 }
328 else
329 Virtual++;
330 continue;
331 }
332 if (I->VersionList == 0 && I->ProvidesList == 0)
333 {
334 Missing++;
335 continue;
336 }
337 }
db0db9fe
CP
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;
b2e465d6 342 cout << _(" Missing: ") << Missing << endl;
71c9e95b 343
d9eb210e
DK
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;
71c9e95b
DK
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;
d9eb210e
DK
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;
b2e465d6 357
a3a91fd7
DK
358 // String list stats
359 std::set<map_stringitem_t> stritems;
360 for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G)
361 stritems.insert(G->Name);
f7f0d6c7 362 for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
b2e465d6 363 {
a3a91fd7 364 stritems.insert(P->Arch);
f7f0d6c7 365 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
b2e465d6 366 {
a3a91fd7
DK
367 if (V->VerStr != 0)
368 stritems.insert(V->VerStr);
369 if (V->Section != 0)
370 stritems.insert(V->Section);
a221efc3
DK
371 stritems.insert(V->SourcePkgName);
372 stritems.insert(V->SourceVerStr);
f7f0d6c7 373 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D)
b2e465d6
AL
374 {
375 if (D->Version != 0)
a3a91fd7
DK
376 stritems.insert(D->Version);
377 }
378 for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; ++D)
379 {
380 stritems.insert(D->md5sum);
381 stritems.insert(D->language_code);
b2e465d6
AL
382 }
383 }
a3a91fd7
DK
384 for (pkgCache::PrvIterator Prv = P.ProvidesList(); Prv.end() == false; ++Prv)
385 {
386 if (Prv->ProvideVersion != 0)
387 stritems.insert(Prv->ProvideVersion);
388 }
b2e465d6 389 }
b07aeb1a 390 for (pkgCache::RlsFileIterator F = Cache->RlsFileBegin(); F != Cache->RlsFileEnd(); ++F)
a3a91fd7
DK
391 {
392 stritems.insert(F->FileName);
393 stritems.insert(F->Archive);
394 stritems.insert(F->Codename);
a3a91fd7
DK
395 stritems.insert(F->Version);
396 stritems.insert(F->Origin);
397 stritems.insert(F->Label);
a3a91fd7 398 stritems.insert(F->Site);
b07aeb1a
DK
399 }
400 for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
401 {
402 stritems.insert(F->FileName);
403 stritems.insert(F->Architecture);
404 stritems.insert(F->Component);
a3a91fd7
DK
405 stritems.insert(F->IndexType);
406 }
4dc77823 407
a3a91fd7
DK
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;
a3a91fd7
DK
411 cout << _("Total globbed strings: ") << stritems.size() << " (" << SizeToStr(Size) << ')' << endl;
412 stritems.clear();
ac2c559b 413
f826cfaa
AL
414 unsigned long Slack = 0;
415 for (int I = 0; I != 7; I++)
d9eb210e 416 Slack += Cache->Head().Pools[I].ItemSize*Cache->Head().Pools[I].Count;
db0db9fe 417 cout << _("Total slack space: ") << SizeToStr(Slack) << endl;
ac2c559b 418
f826cfaa 419 unsigned long Total = 0;
ac2c559b
DK
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) +
71c9e95b 427 APT_CACHESIZE(DependsDataCount, DependencyDataSz) +
b07aeb1a 428 APT_CACHESIZE(ReleaseFileCount, ReleaseFileSz) +
ac2c559b
DK
429 APT_CACHESIZE(PackageFileCount, PackageFileSz) +
430 APT_CACHESIZE(VerFileCount, VerFileSz) +
431 APT_CACHESIZE(DescFileCount, DescFileSz) +
432 APT_CACHESIZE(ProvidesCount, ProvidesSz) +
32ab4bd0 433 (2 * Cache->Head().GetHashTableSize() * sizeof(map_id_t));
db0db9fe 434 cout << _("Total space accounted for: ") << SizeToStr(Total) << endl;
ac2c559b 435#undef APT_CACHESIZE
a93a32b5 436
637c3b23 437 // hashtable stats
32ab4bd0
DK
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);
a93a32b5 440
83d89a9f
AL
441 return true;
442}
443 /*}}}*/
1164783d
AL
444// Dump - show everything /*{{{*/
445// ---------------------------------------------------------------------
b2e465d6 446/* This is worthless except fer debugging things */
65512241 447static bool Dump(CommandLine &)
1164783d 448{
d9eb210e
DK
449 pkgCacheFile CacheFile;
450 pkgCache *Cache = CacheFile.GetPkgCache();
451 if (unlikely(Cache == NULL))
452 return false;
453
b9179170 454 std::cout << "Using Versioning System: " << Cache->VS->Label << std::endl;
b2e465d6 455
f7f0d6c7 456 for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
1164783d 457 {
b9179170 458 std::cout << "Package: " << P.FullName(true) << std::endl;
f7f0d6c7 459 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
1164783d 460 {
b9179170
MV
461 std::cout << " Version: " << V.VerStr() << std::endl;
462 std::cout << " File: " << V.FileList().File().FileName() << std::endl;
f7f0d6c7 463 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D)
b9179170
MV
464 std::cout << " Depends: " << D.TargetPkg().FullName(true) << ' ' <<
465 DeNull(D.TargetVer()) << std::endl;
f7f0d6c7 466 for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; ++D)
a52f938b 467 {
b9179170
MV
468 std::cout << " Description Language: " << D.LanguageCode() << std::endl
469 << " File: " << D.FileList().File().FileName() << std::endl
470 << " MD5: " << D.md5() << std::endl;
a52f938b 471 }
1164783d
AL
472 }
473 }
474
f7f0d6c7 475 for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F.end() == false; ++F)
1164783d 476 {
b9179170
MV
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;
1164783d
AL
490 }
491
492 return true;
493}
494 /*}}}*/
495// DumpAvail - Print out the available list /*{{{*/
496// ---------------------------------------------------------------------
b2e465d6
AL
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.. */
65512241 499static bool DumpAvail(CommandLine &)
1164783d 500{
d9eb210e
DK
501 pkgCacheFile CacheFile;
502 pkgCache *Cache = CacheFile.GetPkgCache();
503 if (unlikely(Cache == NULL || CacheFile.BuildPolicy() == false))
b2e465d6 504 return false;
d9eb210e
DK
505
506 unsigned long Count = Cache->HeaderP->PackageCount+1;
fe648919
AL
507 pkgCache::VerFile **VFList = new pkgCache::VerFile *[Count];
508 memset(VFList,0,sizeof(*VFList)*Count);
b2e465d6
AL
509
510 // Map versions that we want to write out onto the VerList array.
f7f0d6c7 511 for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
b2e465d6
AL
512 {
513 if (P->VersionList == 0)
5b8c90bf
AL
514 continue;
515
b2e465d6
AL
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. */
d9eb210e 519 pkgCache::VerIterator V = CacheFile.GetPolicy()->GetCandidateVer(P);
b2e465d6 520 if (V.end() == true)
ad00ae81 521 {
b2e465d6
AL
522 if (P->CurrentVer == 0)
523 continue;
524 V = P.CurrentVer();
ad00ae81 525 }
1164783d 526
b2e465d6 527 pkgCache::VerFileIterator VF = V.FileList();
f7f0d6c7 528 for (; VF.end() == false ; ++VF)
b2e465d6
AL
529 if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 0)
530 break;
531
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)
1164783d 541 {
f7f0d6c7 542 for (pkgCache::VerIterator Cur = P.VersionList(); Cur.end() != true; ++Cur)
b2e465d6 543 {
f7f0d6c7 544 for (VF = Cur.FileList(); VF.end() == false; ++VF)
b2e465d6
AL
545 {
546 if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 0)
547 {
548 VF = V.FileList();
549 break;
550 }
551 }
552
553 if (VF.end() == false)
554 break;
555 }
ad00ae81 556 }
b2e465d6
AL
557
558 VFList[P->ID] = VF;
559 }
560
fe648919 561 LocalitySort(VFList,Count,sizeof(*VFList));
ad00ae81 562
88593886
DK
563 std::vector<pkgTagSection::Tag> RW;
564 RW.push_back(pkgTagSection::Tag::Remove("Status"));
565 RW.push_back(pkgTagSection::Tag::Remove("Config-Version"));
566 FileFd stdoutfd;
567 stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false);
568
b2e465d6 569 // Iterate over all the package files and write them out.
d9eb210e 570 char *Buffer = new char[Cache->HeaderP->MaxVerFileSize+10];
b2e465d6
AL
571 for (pkgCache::VerFile **J = VFList; *J != 0;)
572 {
d9eb210e 573 pkgCache::PkgFileIterator File(*Cache,(*J)->File + Cache->PkgFileP);
b2e465d6 574 if (File.IsOk() == false)
ad00ae81 575 {
b2e465d6
AL
576 _error->Error(_("Package file %s is out of sync."),File.FileName());
577 break;
578 }
bd432be3 579
4dde2b42 580 FileFd PkgF(File.FileName(),FileFd::ReadOnly, FileFd::Extension);
b2e465d6
AL
581 if (_error->PendingError() == true)
582 break;
583
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;
590 for (; *J != 0; J++)
591 {
d9eb210e 592 if ((*J)->File + Cache->PkgFileP != File)
b2e465d6 593 break;
bd432be3 594
b2e465d6
AL
595 const pkgCache::VerFile &VF = **J;
596
bd432be3 597 // Read the record and then write it out again.
b2e465d6
AL
598 unsigned long Jitter = VF.Offset - Pos;
599 if (Jitter > 8)
1164783d 600 {
b2e465d6
AL
601 if (PkgF.Seek(VF.Offset) == false)
602 break;
603 Jitter = 0;
604 }
605
606 if (PkgF.Read(Buffer,VF.Size + Jitter) == false)
607 break;
608 Buffer[VF.Size + Jitter] = '\n';
88593886 609
b2e465d6
AL
610 // See above..
611 if ((File->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
612 {
613 pkgTagSection Tags;
b2e465d6 614 if (Tags.Scan(Buffer+Jitter,VF.Size+1) == false ||
88593886
DK
615 Tags.Write(stdoutfd, NULL, RW) == false ||
616 stdoutfd.Write("\n", 1) == false)
b2e465d6
AL
617 {
618 _error->Error("Internal Error, Unable to parse a package record");
619 break;
620 }
b2e465d6
AL
621 }
622 else
623 {
88593886 624 if (stdoutfd.Write(Buffer + Jitter, VF.Size + 1) == false)
b2e465d6
AL
625 break;
626 }
88593886 627
b2e465d6 628 Pos = VF.Offset + VF.Size;
1164783d 629 }
b2e465d6 630
b2e465d6
AL
631 if (_error->PendingError() == true)
632 break;
ad00ae81 633 }
88593886 634
b2e465d6
AL
635 delete [] Buffer;
636 delete [] VFList;
637 return !_error->PendingError();
349cd3b8
AL
638}
639 /*}}}*/
3de4647b 640// ShowDepends - Helper for printing out a dependency tree /*{{{*/
c3ccac92 641static bool ShowDepends(CommandLine &CmdL, bool const RevDepends)
349cd3b8 642{
d9eb210e
DK
643 pkgCacheFile CacheFile;
644 pkgCache *Cache = CacheFile.GetPkgCache();
645 if (unlikely(Cache == NULL))
646 return false;
78c32596 647
65f81081 648 CacheSetHelperVirtuals helper(false);
e6f0c9bc 649 APT::VersionList verset = APT::VersionList::FromCommandLine(CacheFile, CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper);
3de4647b 650 if (verset.empty() == true && helper.virtualPkgs.empty() == true)
f23fc0e0 651 return _error->Error(_("No packages found"));
3de4647b 652 std::vector<bool> Shown(Cache->Head().PackageCount);
78c32596 653
fe1af091
DK
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);
3de4647b 657 bool const ShowDepType = _config->FindB("APT::Cache::ShowDependencyType", RevDepends == false);
173c98da 658 bool const ShowVersion = _config->FindB("APT::Cache::ShowVersion", false);
fe1af091
DK
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);
a5032f84 667 bool const ShowOnlyFirstOr = _config->FindB("APT::Cache::ShowOnlyFirstOr", false);
8c7af4d4 668 bool const ShowImplicit = _config->FindB("APT::Cache::ShowImplicit", false);
3de4647b
DK
669
670 while (verset.empty() != true)
b2e465d6 671 {
3de4647b
DK
672 pkgCache::VerIterator Ver = *verset.begin();
673 verset.erase(verset.begin());
674 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
675 Shown[Pkg->ID] = true;
676
75ce2062 677 cout << Pkg.FullName(true) << endl;
3de4647b
DK
678
679 if (RevDepends == true)
680 cout << "Reverse Depends:" << endl;
681 for (pkgCache::DepIterator D = RevDepends ? Pkg.RevDependsList() : Ver.DependsList();
f7f0d6c7 682 D.end() == false; ++D)
b2e465d6 683 {
fe1af091
DK
684 switch (D->Type) {
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;
8c7af4d4
DK
689 case pkgCache::Dep::Replaces: if (!ShowReplaces) continue; break;
690 case pkgCache::Dep::Conflicts: if (!ShowConflicts) continue; break;
fe1af091
DK
691 case pkgCache::Dep::DpkgBreaks: if (!ShowBreaks) continue; break;
692 case pkgCache::Dep::Enhances: if (!ShowEnhances) continue; break;
693 }
8c7af4d4
DK
694 if (ShowImplicit == false && D.IsImplicit())
695 continue;
fe1af091 696
3de4647b 697 pkgCache::PkgIterator Trg = RevDepends ? D.ParentPkg() : D.TargetPkg();
eba2b51d
AL
698
699 if((Installed && Trg->CurrentVer != 0) || !Installed)
700 {
701
a5032f84 702 if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or && ShowOnlyFirstOr == false)
eba2b51d
AL
703 cout << " |";
704 else
705 cout << " ";
b2e465d6 706
eba2b51d 707 // Show the package
fe1af091
DK
708 if (ShowDepType == true)
709 cout << D.DepType() << ": ";
eba2b51d 710 if (Trg->VersionList == 0)
3addaba1 711 cout << "<" << Trg.FullName(true) << ">";
eba2b51d 712 else
3addaba1 713 cout << Trg.FullName(true);
173c98da
DK
714 if (ShowVersion == true && D->Version != 0)
715 cout << " (" << pkgCache::CompTypeDeb(D->CompareOp) << ' ' << D.TargetVer() << ')';
716 cout << std::endl;
717
3de4647b
DK
718 if (Recurse == true && Shown[Trg->ID] == false)
719 {
720 Shown[Trg->ID] = true;
e6f0c9bc 721 verset.insert(APT::VersionSet::FromPackage(CacheFile, Trg, APT::CacheSetHelper::CANDIDATE, helper));
3de4647b 722 }
eba2b51d
AL
723
724 }
b2e465d6
AL
725
726 // Display all solutions
98cc7fd2
JAK
727 std::unique_ptr<pkgCache::Version *[]> List(D.AllTargets());
728 pkgPrioSortList(*Cache,List.get());
729 for (pkgCache::Version **I = List.get(); *I != 0; I++)
b2e465d6 730 {
d9eb210e
DK
731 pkgCache::VerIterator V(*Cache,*I);
732 if (V != Cache->VerP + V.ParentPkg()->VersionList ||
b2e465d6
AL
733 V->ParentPkg == D->Package)
734 continue;
75ce2062 735 cout << " " << V.ParentPkg().FullName(true) << endl;
3de4647b
DK
736
737 if (Recurse == true && Shown[V.ParentPkg()->ID] == false)
738 {
739 Shown[V.ParentPkg()->ID] = true;
e6f0c9bc 740 verset.insert(APT::VersionSet::FromPackage(CacheFile, V.ParentPkg(), APT::CacheSetHelper::CANDIDATE, helper));
3de4647b 741 }
b2e465d6 742 }
a5032f84
DK
743
744 if (ShowOnlyFirstOr == true)
745 while ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) ++D;
b2e465d6 746 }
3de4647b
DK
747 }
748
749 for (APT::PackageSet::const_iterator Pkg = helper.virtualPkgs.begin();
750 Pkg != helper.virtualPkgs.end(); ++Pkg)
751 cout << '<' << Pkg.FullName(true) << '>' << endl;
752
3e94da1b
AL
753 return true;
754}
92fcbfc1 755 /*}}}*/
3de4647b
DK
756// Depends - Print out a dependency tree /*{{{*/
757// ---------------------------------------------------------------------
758/* */
c3ccac92 759static bool Depends(CommandLine &CmdL)
3de4647b
DK
760{
761 return ShowDepends(CmdL, false);
762}
763 /*}}}*/
764// RDepends - Print out a reverse dependency tree /*{{{*/
eba2b51d
AL
765// ---------------------------------------------------------------------
766/* */
c3ccac92 767static bool RDepends(CommandLine &CmdL)
eba2b51d 768{
3de4647b 769 return ShowDepends(CmdL, true);
eba2b51d 770}
3e94da1b 771 /*}}}*/
fff4b7f3
AL
772// xvcg - Generate a graph for xvcg /*{{{*/
773// ---------------------------------------------------------------------
774// Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
775
c3ccac92 776static bool XVcg(CommandLine &CmdL)
fff4b7f3 777{
d9eb210e
DK
778 pkgCacheFile CacheFile;
779 pkgCache *Cache = CacheFile.GetPkgCache();
780 if (unlikely(Cache == NULL))
781 return false;
782
fff4b7f3
AL
783 bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false);
784
785 /* Normal packages are boxes
786 Pure Provides are triangles
787 Mixed are diamonds
788 rhomb are missing packages*/
789 const char *Shapes[] = {"ellipse","triangle","box","rhomb"};
790
791 /* Initialize the list of packages to show.
792 1 = To Show
793 2 = To Show no recurse
794 3 = Emitted no recurse
795 4 = Emitted
796 0 = None */
797 enum States {None=0, ToShow, ToShowNR, DoneNR, Done};
798 enum TheFlags {ForceNR=(1<<0)};
d9eb210e
DK
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];
fff4b7f3
AL
802
803 // Show everything if no arguments given
804 if (CmdL.FileList[1] == 0)
d9eb210e 805 for (unsigned long I = 0; I != Cache->Head().PackageCount; I++)
fff4b7f3
AL
806 Show[I] = ToShow;
807 else
d9eb210e 808 for (unsigned long I = 0; I != Cache->Head().PackageCount; I++)
fff4b7f3 809 Show[I] = None;
d9eb210e 810 memset(Flags,0,sizeof(*Flags)*Cache->Head().PackageCount);
fff4b7f3
AL
811
812 // Map the shapes
f7f0d6c7 813 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
fff4b7f3
AL
814 {
815 if (Pkg->VersionList == 0)
816 {
817 // Missing
818 if (Pkg->ProvidesList == 0)
819 ShapeMap[Pkg->ID] = 0;
820 else
821 ShapeMap[Pkg->ID] = 1;
822 }
823 else
824 {
825 // Normal
826 if (Pkg->ProvidesList == 0)
827 ShapeMap[Pkg->ID] = 2;
828 else
829 ShapeMap[Pkg->ID] = 3;
830 }
831 }
3c977245 832
fff4b7f3 833 // Load the list of packages from the command line into the show list
cd7bbc47 834 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
fdba4d53
DK
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));
3c977245 838 std::map<unsigned short, APT::PackageSet> pkgsets =
cd7bbc47 839 APT::PackageSet::GroupedFromCommandLine(CacheFile, CmdL.FileList + 1, mods, 0, helper);
3c977245
DK
840
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)
fff4b7f3 846 {
fff4b7f3 847 Show[Pkg->ID] = ToShow;
3c977245 848 Flags[Pkg->ID] |= ForceNR;
fff4b7f3 849 }
3c977245 850
fff4b7f3
AL
851 // Little header
852 cout << "graph: { title: \"packages\"" << endl <<
853 "xmax: 700 ymax: 700 x: 30 y: 30" << endl <<
854 "layout_downfactor: 8" << endl;
855
856 bool Act = true;
857 while (Act == true)
858 {
859 Act = false;
f7f0d6c7 860 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
fff4b7f3
AL
861 {
862 // See we need to show this package
863 if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR)
864 continue;
865
866 //printf ("node: { title: \"%s\" label: \"%s\" }\n", Pkg.Name(), Pkg.Name());
867
868 // Colour as done
869 if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR)
870 {
871 // Pure Provides and missing packages have no deps!
872 if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1)
873 Show[Pkg->ID] = Done;
874 else
875 Show[Pkg->ID] = DoneNR;
876 }
877 else
878 Show[Pkg->ID] = Done;
879 Act = true;
880
881 // No deps to map out
882 if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR)
883 continue;
884
885 pkgCache::VerIterator Ver = Pkg.VersionList();
f7f0d6c7 886 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; ++D)
fff4b7f3
AL
887 {
888 // See if anything can meet this dep
889 // Walk along the actual package providing versions
890 bool Hit = false;
891 pkgCache::PkgIterator DPkg = D.TargetPkg();
892 for (pkgCache::VerIterator I = DPkg.VersionList();
f7f0d6c7 893 I.end() == false && Hit == false; ++I)
fff4b7f3 894 {
d9eb210e 895 if (Cache->VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true)
fff4b7f3
AL
896 Hit = true;
897 }
898
899 // Follow all provides
900 for (pkgCache::PrvIterator I = DPkg.ProvidesList();
f7f0d6c7 901 I.end() == false && Hit == false; ++I)
fff4b7f3 902 {
d9eb210e 903 if (Cache->VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false)
fff4b7f3
AL
904 Hit = true;
905 }
906
907
908 // Only graph critical deps
909 if (D.IsCritical() == true)
910 {
75ce2062 911 printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg.FullName(true).c_str(), D.TargetPkg().FullName(true).c_str() );
fff4b7f3
AL
912
913 // Colour the node for recursion
914 if (Show[D.TargetPkg()->ID] <= DoneNR)
915 {
916 /* If a conflicts does not meet anything in the database
917 then show the relation but do not recurse */
359e46db 918 if (Hit == false && D.IsNegative() == true)
fff4b7f3
AL
919 {
920 if (Show[D.TargetPkg()->ID] == None &&
921 Show[D.TargetPkg()->ID] != ToShow)
922 Show[D.TargetPkg()->ID] = ToShowNR;
923 }
924 else
925 {
926 if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow)
927 Show[D.TargetPkg()->ID] = ToShowNR;
928 else
929 Show[D.TargetPkg()->ID] = ToShow;
930 }
931 }
932
933 // Edge colour
934 switch(D->Type)
935 {
936 case pkgCache::Dep::Conflicts:
937 printf("label: \"conflicts\" color: lightgreen }\n");
938 break;
308c7d30
IJ
939 case pkgCache::Dep::DpkgBreaks:
940 printf("label: \"breaks\" color: lightgreen }\n");
941 break;
fff4b7f3
AL
942 case pkgCache::Dep::Obsoletes:
943 printf("label: \"obsoletes\" color: lightgreen }\n");
944 break;
945
946 case pkgCache::Dep::PreDepends:
947 printf("label: \"predepends\" color: blue }\n");
948 break;
949
950 default:
951 printf("}\n");
952 break;
953 }
954 }
955 }
956 }
957 }
958
959 /* Draw the box colours after the fact since we can not tell what colour
960 they should be until everything is finished drawing */
f7f0d6c7 961 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
fff4b7f3
AL
962 {
963 if (Show[Pkg->ID] < DoneNR)
964 continue;
965
966 if (Show[Pkg->ID] == DoneNR)
75ce2062 967 printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg.FullName(true).c_str(), Pkg.FullName(true).c_str(),
fff4b7f3
AL
968 Shapes[ShapeMap[Pkg->ID]]);
969 else
75ce2062 970 printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg.FullName(true).c_str(), Pkg.FullName(true).c_str(),
fff4b7f3
AL
971 Shapes[ShapeMap[Pkg->ID]]);
972
973 }
03496041
DK
974
975 delete[] Show;
976 delete[] Flags;
977 delete[] ShapeMap;
978
fff4b7f3
AL
979 printf("}\n");
980 return true;
981}
982 /*}}}*/
3e94da1b
AL
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/ */
c3ccac92 988static bool Dotty(CommandLine &CmdL)
3e94da1b 989{
d9eb210e
DK
990 pkgCacheFile CacheFile;
991 pkgCache *Cache = CacheFile.GetPkgCache();
992 if (unlikely(Cache == NULL))
993 return false;
994
3e94da1b
AL
995 bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false);
996
997 /* Normal packages are boxes
998 Pure Provides are triangles
999 Mixed are diamonds
1000 Hexagons are missing packages*/
1001 const char *Shapes[] = {"hexagon","triangle","box","diamond"};
1002
1003 /* Initialize the list of packages to show.
1004 1 = To Show
1005 2 = To Show no recurse
1006 3 = Emitted no recurse
1007 4 = Emitted
1008 0 = None */
1009 enum States {None=0, ToShow, ToShowNR, DoneNR, Done};
1010 enum TheFlags {ForceNR=(1<<0)};
d9eb210e
DK
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];
3e94da1b
AL
1014
1015 // Show everything if no arguments given
1016 if (CmdL.FileList[1] == 0)
d9eb210e 1017 for (unsigned long I = 0; I != Cache->Head().PackageCount; I++)
3e94da1b
AL
1018 Show[I] = ToShow;
1019 else
d9eb210e 1020 for (unsigned long I = 0; I != Cache->Head().PackageCount; I++)
3e94da1b 1021 Show[I] = None;
d9eb210e 1022 memset(Flags,0,sizeof(*Flags)*Cache->Head().PackageCount);
3e94da1b
AL
1023
1024 // Map the shapes
f7f0d6c7 1025 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
3e94da1b
AL
1026 {
1027 if (Pkg->VersionList == 0)
1028 {
1029 // Missing
1030 if (Pkg->ProvidesList == 0)
1031 ShapeMap[Pkg->ID] = 0;
1032 else
1033 ShapeMap[Pkg->ID] = 1;
1034 }
1035 else
1036 {
1037 // Normal
1038 if (Pkg->ProvidesList == 0)
1039 ShapeMap[Pkg->ID] = 2;
1040 else
1041 ShapeMap[Pkg->ID] = 3;
1042 }
1043 }
3c977245 1044
3e94da1b 1045 // Load the list of packages from the command line into the show list
cd7bbc47 1046 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
fdba4d53
DK
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));
3c977245 1050 std::map<unsigned short, APT::PackageSet> pkgsets =
cd7bbc47 1051 APT::PackageSet::GroupedFromCommandLine(CacheFile, CmdL.FileList + 1, mods, 0, helper);
3c977245
DK
1052
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)
3e94da1b 1058 {
3e94da1b 1059 Show[Pkg->ID] = ToShow;
3c977245 1060 Flags[Pkg->ID] |= ForceNR;
3e94da1b 1061 }
3c977245 1062
3e94da1b
AL
1063 // Little header
1064 printf("digraph packages {\n");
1065 printf("concentrate=true;\n");
1066 printf("size=\"30,40\";\n");
1067
1068 bool Act = true;
1069 while (Act == true)
1070 {
1071 Act = false;
f7f0d6c7 1072 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
3e94da1b
AL
1073 {
1074 // See we need to show this package
1075 if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR)
1076 continue;
1077
1078 // Colour as done
1079 if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR)
1080 {
1081 // Pure Provides and missing packages have no deps!
1082 if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1)
1083 Show[Pkg->ID] = Done;
1084 else
1085 Show[Pkg->ID] = DoneNR;
1086 }
1087 else
1088 Show[Pkg->ID] = Done;
1089 Act = true;
1090
1091 // No deps to map out
1092 if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR)
1093 continue;
1094
1095 pkgCache::VerIterator Ver = Pkg.VersionList();
f7f0d6c7 1096 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; ++D)
3e94da1b
AL
1097 {
1098 // See if anything can meet this dep
1099 // Walk along the actual package providing versions
1100 bool Hit = false;
1101 pkgCache::PkgIterator DPkg = D.TargetPkg();
1102 for (pkgCache::VerIterator I = DPkg.VersionList();
f7f0d6c7 1103 I.end() == false && Hit == false; ++I)
3e94da1b 1104 {
d9eb210e 1105 if (Cache->VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true)
3e94da1b
AL
1106 Hit = true;
1107 }
1108
1109 // Follow all provides
1110 for (pkgCache::PrvIterator I = DPkg.ProvidesList();
f7f0d6c7 1111 I.end() == false && Hit == false; ++I)
3e94da1b 1112 {
d9eb210e 1113 if (Cache->VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false)
3e94da1b
AL
1114 Hit = true;
1115 }
1116
1117 // Only graph critical deps
1118 if (D.IsCritical() == true)
1119 {
75ce2062 1120 printf("\"%s\" -> \"%s\"",Pkg.FullName(true).c_str(),D.TargetPkg().FullName(true).c_str());
3e94da1b
AL
1121
1122 // Colour the node for recursion
1123 if (Show[D.TargetPkg()->ID] <= DoneNR)
1124 {
1125 /* If a conflicts does not meet anything in the database
1126 then show the relation but do not recurse */
359e46db 1127 if (Hit == false && D.IsNegative() == true)
3e94da1b
AL
1128 {
1129 if (Show[D.TargetPkg()->ID] == None &&
1130 Show[D.TargetPkg()->ID] != ToShow)
1131 Show[D.TargetPkg()->ID] = ToShowNR;
1132 }
1133 else
1134 {
1135 if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow)
1136 Show[D.TargetPkg()->ID] = ToShowNR;
1137 else
1138 Show[D.TargetPkg()->ID] = ToShow;
1139 }
1140 }
1141
1142 // Edge colour
1143 switch(D->Type)
1144 {
1145 case pkgCache::Dep::Conflicts:
b2e465d6 1146 case pkgCache::Dep::Obsoletes:
359e46db 1147 case pkgCache::Dep::DpkgBreaks:
3e94da1b
AL
1148 printf("[color=springgreen];\n");
1149 break;
1150
1151 case pkgCache::Dep::PreDepends:
1152 printf("[color=blue];\n");
1153 break;
1154
1155 default:
1156 printf(";\n");
1157 break;
1158 }
1159 }
1160 }
1161 }
1162 }
1163
1164 /* Draw the box colours after the fact since we can not tell what colour
1165 they should be until everything is finished drawing */
f7f0d6c7 1166 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
3e94da1b
AL
1167 {
1168 if (Show[Pkg->ID] < DoneNR)
1169 continue;
1170
1171 // Orange box for early recursion stoppage
1172 if (Show[Pkg->ID] == DoneNR)
75ce2062 1173 printf("\"%s\" [color=orange,shape=%s];\n",Pkg.FullName(true).c_str(),
3e94da1b
AL
1174 Shapes[ShapeMap[Pkg->ID]]);
1175 else
75ce2062 1176 printf("\"%s\" [shape=%s];\n",Pkg.FullName(true).c_str(),
3e94da1b
AL
1177 Shapes[ShapeMap[Pkg->ID]]);
1178 }
1179
1180 printf("}\n");
6070a346
DK
1181 delete[] Show;
1182 delete[] Flags;
1183 delete[] ShapeMap;
ad00ae81 1184 return true;
7e2e2d5d
AL
1185}
1186 /*}}}*/
182a6a55 1187/* ShowAuto - show automatically installed packages (sorted) {{{*/
65512241 1188static bool ShowAuto(CommandLine &)
6007c1d4 1189{
d9eb210e
DK
1190 pkgCacheFile CacheFile;
1191 pkgCache *Cache = CacheFile.GetPkgCache();
1192 pkgDepCache *DepCache = CacheFile.GetDepCache();
1193 if (unlikely(Cache == NULL || DepCache == NULL))
1194 return false;
6007c1d4
JAK
1195
1196 std::vector<string> packages;
d9eb210e 1197 packages.reserve(Cache->HeaderP->PackageCount / 3);
6007c1d4 1198
f7f0d6c7 1199 for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
d9eb210e 1200 if ((*DepCache)[P].Flags & pkgCache::Flag::Auto)
6007c1d4
JAK
1201 packages.push_back(P.Name());
1202
1203 std::sort(packages.begin(), packages.end());
1204
f7f0d6c7 1205 for (vector<string>::iterator I = packages.begin(); I != packages.end(); ++I)
6007c1d4
JAK
1206 cout << *I << "\n";
1207
182a6a55 1208 _error->Notice(_("This command is deprecated. Please use 'apt-mark showauto' instead."));
6007c1d4
JAK
1209 return true;
1210}
1164783d 1211 /*}}}*/
7c1133fe
AL
1212// ShowPkgNames - Show package names /*{{{*/
1213// ---------------------------------------------------------------------
1214/* This does a prefix match on the first argument */
c3ccac92 1215static bool ShowPkgNames(CommandLine &CmdL)
7c1133fe 1216{
d9eb210e
DK
1217 pkgCacheFile CacheFile;
1218 if (unlikely(CacheFile.BuildCaches(NULL, false) == false))
1219 return false;
1220 pkgCache::GrpIterator I = CacheFile.GetPkgCache()->GrpBegin();
6293e04f
DK
1221 bool const All = _config->FindB("APT::Cache::AllNames","false");
1222
7c1133fe
AL
1223 if (CmdL.FileList[1] != 0)
1224 {
f7f0d6c7 1225 for (;I.end() != true; ++I)
7c1133fe 1226 {
6293e04f
DK
1227 if (All == false && I->FirstPackage == 0)
1228 continue;
1229 if (I.FindPkg("any")->VersionList == 0)
7c1133fe 1230 continue;
7c1133fe
AL
1231 if (strncmp(I.Name(),CmdL.FileList[1],strlen(CmdL.FileList[1])) == 0)
1232 cout << I.Name() << endl;
1233 }
1234
1235 return true;
1236 }
1237
1238 // Show all pkgs
f7f0d6c7 1239 for (;I.end() != true; ++I)
7c1133fe 1240 {
6293e04f
DK
1241 if (All == false && I->FirstPackage == 0)
1242 continue;
1243 if (I.FindPkg("any")->VersionList == 0)
7c1133fe
AL
1244 continue;
1245 cout << I.Name() << endl;
1246 }
1247
7e2e2d5d
AL
1248 return true;
1249}
1250 /*}}}*/
f8f410f5
AL
1251// ShowSrcPackage - Show source package records /*{{{*/
1252// ---------------------------------------------------------------------
1253/* */
c3ccac92 1254static bool ShowSrcPackage(CommandLine &CmdL)
f8f410f5 1255{
d9eb210e
DK
1256 pkgCacheFile CacheFile;
1257 pkgSourceList *List = CacheFile.GetSourceList();
1258 if (unlikely(List == NULL))
1259 return false;
1260
f8f410f5 1261 // Create the text record parsers
d9eb210e 1262 pkgSrcRecords SrcRecs(*List);
f8f410f5
AL
1263 if (_error->PendingError() == true)
1264 return false;
1265
0458a811 1266 unsigned found = 0;
f8f410f5
AL
1267 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1268 {
aaee8293
AL
1269 SrcRecs.Restart();
1270
f8f410f5 1271 pkgSrcRecords::Parser *Parse;
0458a811
JAK
1272 unsigned found_this = 0;
1273 while ((Parse = SrcRecs.Find(*I,false)) != 0) {
a8275acf
MV
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)
1277 continue;
0458a811
JAK
1278 cout << Parse->AsStr() << endl;;
1279 found++;
1280 found_this++;
1281 }
1282 if (found_this == 0) {
1283 _error->Warning(_("Unable to locate package %s"),*I);
1284 continue;
1285 }
65f81081
DK
1286 }
1287 if (found == 0)
1288 _error->Notice(_("No packages found"));
1289 return true;
af87ab54
AL
1290}
1291 /*}}}*/
1292// Policy - Show the results of the preferences file /*{{{*/
1293// ---------------------------------------------------------------------
1294/* */
c3ccac92 1295static bool Policy(CommandLine &CmdL)
af87ab54 1296{
d9eb210e
DK
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))
af87ab54 1302 return false;
d9eb210e 1303
0588779f
DK
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();
1309
af87ab54
AL
1310 // Print out all of the package files
1311 if (CmdL.FileList[1] == 0)
1312 {
db0db9fe 1313 cout << _("Package files:") << endl;
f7f0d6c7 1314 for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F.end() == false; ++F)
af87ab54 1315 {
d2cb5b15
DK
1316 if (F.Flagged(pkgCache::Flag::NoPackages))
1317 continue;
af87ab54
AL
1318 // Locate the associated index files so we can derive a description
1319 pkgIndexFile *Indx;
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"));
78acd650
MV
1323
1324 printf("%4i %s\n",
d9eb210e 1325 Plcy->GetPriority(F),Indx->Describe(true).c_str());
af87ab54
AL
1326
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());
1333 }
1334
1335 // Show any packages have explicit pins
db0db9fe 1336 cout << _("Pinned packages:") << endl;
d9eb210e 1337 pkgCache::PkgIterator I = Cache->PkgBegin();
f7f0d6c7 1338 for (;I.end() != true; ++I)
af87ab54 1339 {
e595c457
JAK
1340 // Old code for debugging
1341 if (_config->FindI("APT::Policy", 1) < 1) {
1342 if (Plcy->GetPriority(I) == 0)
1343 continue;
1344
1345 // Print the package name and the version we are forcing to
1346 cout << " " << I.FullName(true) << " -> ";
1347
1348 pkgCache::VerIterator V = Plcy->GetMatch(I);
1349 if (V.end() == true)
1350 cout << _("(not found)") << endl;
1351 else
1352 cout << V.VerStr() << endl;
1353
af87ab54 1354 continue;
e595c457
JAK
1355 }
1356 // New code
1357 for (pkgCache::VerIterator V = I.VersionList(); !V.end(); V++) {
1358 auto Prio = Plcy->GetPriority(V, false);
1359 if (Prio == 0)
1360 continue;
af87ab54 1361
f3f06cae 1362 cout << " ";
e595c457 1363 // Print the package name and the version we are forcing to
f3f06cae 1364 ioprintf(cout, _("%s -> %s with priority %d\n"), I.FullName(true).c_str(), V.VerStr(), Prio);
e595c457
JAK
1365 }
1366 }
af87ab54
AL
1367 return true;
1368 }
6293e04f 1369
ca964703
DK
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;
6293e04f 1378
af87ab54 1379 // Print out detailed information for each package
cd7bbc47 1380 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
c4cca791
DK
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)
af87ab54 1383 {
75ce2062 1384 cout << Pkg.FullName(true) << ":" << endl;
6293e04f 1385
af87ab54 1386 // Installed version
ca964703 1387 cout << msgInstalled << OutputInDepth(deepInstalled, " ");
af87ab54
AL
1388 if (Pkg->CurrentVer == 0)
1389 cout << _("(none)") << endl;
1390 else
1391 cout << Pkg.CurrentVer().VerStr() << endl;
1392
1393 // Candidate Version
ca964703 1394 cout << msgCandidate << OutputInDepth(deepCandidate, " ");
d9eb210e 1395 pkgCache::VerIterator V = Plcy->GetCandidateVer(Pkg);
af87ab54
AL
1396 if (V.end() == true)
1397 cout << _("(none)") << endl;
1398 else
1399 cout << V.VerStr() << endl;
1400
1401 // Pinned version
e595c457 1402 if (_config->FindI("APT::Policy", 1) < 1 && Plcy->GetPriority(Pkg) != 0)
af87ab54 1403 {
db0db9fe 1404 cout << _(" Package pin: ");
d9eb210e 1405 V = Plcy->GetMatch(Pkg);
af87ab54
AL
1406 if (V.end() == true)
1407 cout << _("(not found)") << endl;
1408 else
1409 cout << V.VerStr() << endl;
1410 }
1411
1412 // Show the priority tables
db0db9fe 1413 cout << _(" Version table:") << endl;
f7f0d6c7 1414 for (V = Pkg.VersionList(); V.end() == false; ++V)
af87ab54
AL
1415 {
1416 if (Pkg.CurrentVer() == V)
1417 cout << " *** " << V.VerStr();
1418 else
1419 cout << " " << V.VerStr();
e595c457
JAK
1420 if (_config->FindI("APT::Policy", 1) < 1)
1421 cout << " " << Plcy->GetPriority(Pkg) << endl;
1422 else
1423 cout << " " << Plcy->GetPriority(V) << endl;
f7f0d6c7 1424 for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; ++VF)
af87ab54
AL
1425 {
1426 // Locate the associated index files so we can derive a description
1427 pkgIndexFile *Indx;
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"));
d9eb210e 1431 printf(" %4i %s\n",Plcy->GetPriority(VF.File()),
af87ab54 1432 Indx->Describe(true).c_str());
6293e04f
DK
1433 }
1434 }
af87ab54
AL
1435 }
1436
f8f410f5
AL
1437 return true;
1438}
bd3d53ef
AL
1439 /*}}}*/
1440// Madison - Look a bit like katie's madison /*{{{*/
1441// ---------------------------------------------------------------------
1442/* */
c3ccac92 1443static bool Madison(CommandLine &CmdL)
bd3d53ef 1444{
d9eb210e
DK
1445 pkgCacheFile CacheFile;
1446 pkgSourceList *SrcList = CacheFile.GetSourceList();
bd3d53ef 1447
d9eb210e
DK
1448 if (SrcList == 0)
1449 return false;
bd3d53ef 1450
03cd434b
MV
1451 // Create the src text record parsers and ignore errors about missing
1452 // deb-src lines that are generated from pkgSrcRecords::pkgSrcRecords
bd3d53ef
AL
1453 pkgSrcRecords SrcRecs(*SrcList);
1454 if (_error->PendingError() == true)
03cd434b 1455 _error->Discard();
bd3d53ef 1456
cd7bbc47 1457 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
dc67d95f 1458 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
bd3d53ef 1459 {
dc67d95f 1460 _error->PushToStack();
c4cca791
DK
1461 APT::PackageList pkgset = APT::PackageList::FromString(CacheFile, *I, helper);
1462 for (APT::PackageList::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
bd3d53ef 1463 {
f7f0d6c7 1464 for (pkgCache::VerIterator V = Pkg.VersionList(); V.end() == false; ++V)
bd3d53ef 1465 {
f7f0d6c7 1466 for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; ++VF)
bd3d53ef 1467 {
a0e710af
AL
1468// This might be nice, but wouldn't uniquely identify the source -mdz
1469// if (VF.File().Archive() != 0)
1470// {
1471// cout << setw(10) << Pkg.Name() << " | " << setw(10) << V.VerStr() << " | "
1472// << VF.File().Archive() << endl;
1473// }
1474
1475 // Locate the associated index files so we can derive a description
f7f0d6c7 1476 for (pkgSourceList::const_iterator S = SrcList->begin(); S != SrcList->end(); ++S)
bd3d53ef 1477 {
7db98ffc
MZ
1478 vector<pkgIndexFile *> *Indexes = (*S)->GetIndexFiles();
1479 for (vector<pkgIndexFile *>::const_iterator IF = Indexes->begin();
f7f0d6c7 1480 IF != Indexes->end(); ++IF)
7db98ffc
MZ
1481 {
1482 if ((*IF)->FindInCache(*(VF.File().Cache())) == VF.File())
1483 {
75ce2062 1484 cout << setw(10) << Pkg.FullName(true) << " | " << setw(10) << V.VerStr() << " | "
7db98ffc
MZ
1485 << (*IF)->Describe(true) << endl;
1486 }
1487 }
bd3d53ef
AL
1488 }
1489 }
1490 }
1491 }
1492
bd3d53ef
AL
1493 SrcRecs.Restart();
1494 pkgSrcRecords::Parser *SrcParser;
dc67d95f
DK
1495 bool foundSomething = false;
1496 while ((SrcParser = SrcRecs.Find(*I, false)) != 0)
bd3d53ef 1497 {
dc67d95f 1498 foundSomething = true;
bd3d53ef
AL
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;
1503 }
dc67d95f
DK
1504 if (foundSomething == true)
1505 _error->RevertToStack();
1506 else
1507 _error->MergeWithStack();
bd3d53ef
AL
1508 }
1509
1510 return true;
1511}
f8f410f5 1512 /*}}}*/
880e9be4
AL
1513// GenCaches - Call the main cache generator /*{{{*/
1514// ---------------------------------------------------------------------
1515/* */
65512241 1516static bool GenCaches(CommandLine &)
880e9be4 1517{
0a8e3465 1518 OpTextProgress Progress(*_config);
d9eb210e
DK
1519
1520 pkgCacheFile CacheFile;
1521 return CacheFile.BuildCaches(&Progress, true);
880e9be4
AL
1522}
1523 /*}}}*/
e1b74f61
AL
1524// ShowHelp - Show a help screen /*{{{*/
1525// ---------------------------------------------------------------------
1526/* */
65512241 1527static bool ShowHelp(CommandLine &)
e1b74f61 1528{
249aec3b
JB
1529 ioprintf(cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH);
1530
b13af988
AL
1531 if (_config->FindB("version") == true)
1532 return true;
1533
b2e465d6
AL
1534 cout <<
1535 _("Usage: apt-cache [options] command\n"
b2e465d6 1536 " apt-cache [options] showpkg pkg1 [pkg2 ...]\n"
2d425135 1537 " apt-cache [options] showsrc pkg1 [pkg2 ...]\n"
b2e465d6 1538 "\n"
7fefa184
DK
1539 "apt-cache is a low-level tool used to query information\n"
1540 "from APT's binary cache files\n"
b2e465d6
AL
1541 "\n"
1542 "Commands:\n"
b2e465d6
AL
1543 " gencaches - Build both the package and source cache\n"
1544 " showpkg - Show some general information for a single package\n"
2d425135 1545 " showsrc - Show source records\n"
b2e465d6
AL
1546 " stats - Show some basic statistics\n"
1547 " dump - Show the entire file in a terse form\n"
1548 " dumpavail - Print an available file to stdout\n"
1549 " unmet - Show unmet dependencies\n"
b2e465d6
AL
1550 " search - Search the package list for a regex pattern\n"
1551 " show - Show a readable record for the package\n"
1552 " depends - Show raw dependency information for a package\n"
eba2b51d 1553 " rdepends - Show reverse dependency information for a package\n"
2c120e24
EL
1554 " pkgnames - List the names of all packages in the system\n"
1555 " dotty - Generate package graphs for GraphViz\n"
fff4b7f3 1556 " xvcg - Generate package graphs for xvcg\n"
eba05d54 1557 " policy - Show policy settings\n"
b2e465d6
AL
1558 "\n"
1559 "Options:\n"
1560 " -h This help text.\n"
1561 " -p=? The package cache.\n"
1562 " -s=? The source cache.\n"
1563 " -q Disable progress indicator.\n"
1564 " -i Show only important deps for the unmet command.\n"
1565 " -c=? Read this configuration file\n"
a2884e32 1566 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
b2e465d6
AL
1567 "See the apt-cache(8) and apt.conf(5) manual pages for more information.\n");
1568 return true;
e1b74f61
AL
1569}
1570 /*}}}*/
92fcbfc1 1571int main(int argc,const char *argv[]) /*{{{*/
1164783d 1572{
b9179170 1573 CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp},
b0b4efb9 1574 {"gencaches",&GenCaches},
f8f410f5 1575 {"showsrc",&ShowSrcPackage},
b9179170 1576 {"showpkg",&DumpPackage},
b0b4efb9
AL
1577 {"stats",&Stats},
1578 {"dump",&Dump},
1579 {"dumpavail",&DumpAvail},
1580 {"unmet",&UnMet},
631800b1 1581 {"search",&DoSearch},
349cd3b8 1582 {"depends",&Depends},
eba2b51d 1583 {"rdepends",&RDepends},
3e94da1b 1584 {"dotty",&Dotty},
fff4b7f3 1585 {"xvcg",&XVcg},
7e2e2d5d 1586 {"show",&ShowPackage},
7c1133fe 1587 {"pkgnames",&ShowPkgNames},
6007c1d4 1588 {"showauto",&ShowAuto},
af87ab54 1589 {"policy",&Policy},
bd3d53ef 1590 {"madison",&Madison},
b0b4efb9 1591 {0,0}};
0a8e3465 1592
b9179170
MV
1593 std::vector<CommandLine::Args> Args = getCommandArgs("apt-cache", CommandLine::GetCommand(Cmds, argc, argv));
1594
67111687
AL
1595 // Set up gettext support
1596 setlocale(LC_ALL,"");
1597 textdomain(PACKAGE);
1598
e1b74f61 1599 // Parse the command line and initialize the package library
ad7e0941
DK
1600 CommandLine CmdL;
1601 ParseCommandLine(CmdL, Cmds, Args.data(), &_config, &_system, argc, argv, ShowHelp);
8efa2a3b 1602
d9e518c6 1603 InitOutput();
a9a5908d 1604
320352e0
DK
1605 if (_config->Exists("APT::Cache::Generate") == true)
1606 _config->Set("pkgCacheFile::Generate", _config->FindB("APT::Cache::Generate", true));
1607
b9179170
MV
1608 // Match the operation
1609 CmdL.DispatchArg(Cmds);
f8f410f5 1610
1164783d 1611 // Print any errors or warnings found during parsing
65beb572
DK
1612 bool const Errors = _error->PendingError();
1613 if (_config->FindI("quiet",0) > 0)
1164783d 1614 _error->DumpErrors();
65beb572
DK
1615 else
1616 _error->DumpErrors(GlobalError::DEBUG);
1617 return Errors == true ? 100 : 0;
1164783d 1618}
92fcbfc1 1619 /*}}}*/