]> git.saurik.com Git - apt.git/blame - cmdline/apt-cache.cc
avoid triggering gpg2 migration in apt-key
[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>
9055d5e6 46#include <apt-private/private-depends.h>
501cd23e 47#include <apt-private/private-show.h>
631800b1 48#include <apt-private/private-search.h>
0a778f71 49#include <apt-private/private-unmet.h>
e7e10e47 50#include <apt-private/private-main.h>
b9179170 51
9dbb421f 52#include <regex.h>
453b82a3 53#include <stddef.h>
3e94da1b 54#include <stdio.h>
453b82a3
DK
55#include <stdlib.h>
56#include <unistd.h>
472ff00e 57#include <algorithm>
453b82a3
DK
58#include <cstring>
59#include <iomanip>
60#include <iostream>
61#include <list>
62#include <map>
63#include <set>
64#include <string>
65#include <vector>
ea542140
DK
66
67#include <apti18n.h>
1164783d
AL
68 /*}}}*/
69
8f312f45
AL
70using namespace std;
71
1164783d
AL
72// DumpPackage - Show a dump of a package record /*{{{*/
73// ---------------------------------------------------------------------
74/* */
c3ccac92 75static bool DumpPackage(CommandLine &CmdL)
d9eb210e
DK
76{
77 pkgCacheFile CacheFile;
cd7bbc47 78 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
c4cca791 79 APT::PackageList pkgset = APT::PackageList::FromCommandLine(CacheFile, CmdL.FileList + 1, helper);
1164783d 80
c4cca791 81 for (APT::PackageList::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
78c32596 82 {
75ce2062 83 cout << "Package: " << Pkg.FullName(true) << endl;
b2e465d6 84 cout << "Versions: " << endl;
f7f0d6c7 85 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; ++Cur)
03e39e59
AL
86 {
87 cout << Cur.VerStr();
f7f0d6c7 88 for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; ++Vf)
a52f938b
OS
89 cout << " (" << Vf.File().FileName() << ")";
90 cout << endl;
f7f0d6c7 91 for (pkgCache::DescIterator D = Cur.DescriptionList(); D.end() == false; ++D)
a52f938b
OS
92 {
93 cout << " Description Language: " << D.LanguageCode() << endl
94 << " File: " << D.FileList().File().FileName() << endl
95 << " MD5: " << D.md5() << endl;
96 }
b2e465d6 97 cout << endl;
03e39e59
AL
98 }
99
1164783d
AL
100 cout << endl;
101
102 cout << "Reverse Depends: " << endl;
f7f0d6c7 103 for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; ++D)
b2e465d6 104 {
75ce2062 105 cout << " " << D.ParentPkg().FullName(true) << ',' << D.TargetPkg().FullName(true);
b2e465d6 106 if (D->Version != 0)
b1b663d1 107 cout << ' ' << DeNull(D.TargetVer()) << endl;
b2e465d6
AL
108 else
109 cout << endl;
110 }
111
1164783d 112 cout << "Dependencies: " << endl;
f7f0d6c7 113 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; ++Cur)
1164783d
AL
114 {
115 cout << Cur.VerStr() << " - ";
f7f0d6c7 116 for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; ++Dep)
75ce2062 117 cout << Dep.TargetPkg().FullName(true) << " (" << (int)Dep->CompareOp << " " << DeNull(Dep.TargetVer()) << ") ";
1164783d
AL
118 cout << endl;
119 }
120
121 cout << "Provides: " << endl;
f7f0d6c7 122 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; ++Cur)
1164783d
AL
123 {
124 cout << Cur.VerStr() << " - ";
f7f0d6c7 125 for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; ++Prv)
ecc138f8 126 cout << Prv.ParentPkg().FullName(true) << " (= " << (Prv->ProvideVersion == 0 ? "" : Prv.ProvideVersion()) << ") ";
1164783d 127 cout << endl;
8efa2a3b
AL
128 }
129 cout << "Reverse Provides: " << endl;
f7f0d6c7 130 for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; ++Prv)
ecc138f8 131 cout << Prv.OwnerPkg().FullName(true) << " " << Prv.OwnerVer().VerStr() << " (= " << (Prv->ProvideVersion == 0 ? "" : Prv.ProvideVersion()) << ")"<< endl;
1164783d
AL
132 }
133
134 return true;
135}
136 /*}}}*/
637c3b23
MV
137// ShowHashTableStats - Show stats about a hashtable /*{{{*/
138// ---------------------------------------------------------------------
139/* */
32ab4bd0
DK
140static map_pointer_t PackageNext(pkgCache::Package const * const P) { return P->NextPackage; }
141static map_pointer_t GroupNext(pkgCache::Group const * const G) { return G->Next; }
637c3b23
MV
142template<class T>
143static void ShowHashTableStats(std::string Type,
144 T *StartP,
ac2c559b 145 map_pointer_t *Hashtable,
32ab4bd0
DK
146 unsigned long Size,
147 map_pointer_t(*Next)(T const * const))
637c3b23
MV
148{
149 // hashtable stats for the HashTable
ac2c559b
DK
150 unsigned long NumBuckets = Size;
151 unsigned long UsedBuckets = 0;
152 unsigned long UnusedBuckets = 0;
153 unsigned long LongestBucket = 0;
154 unsigned long ShortestBucket = NumBuckets;
155 unsigned long Entries = 0;
637c3b23
MV
156 for (unsigned int i=0; i < NumBuckets; ++i)
157 {
158 T *P = StartP + Hashtable[i];
159 if(P == 0 || P == StartP)
160 {
ac2c559b 161 ++UnusedBuckets;
637c3b23
MV
162 continue;
163 }
ac2c559b
DK
164 ++UsedBuckets;
165 unsigned long ThisBucketSize = 0;
32ab4bd0 166 for (; P != StartP; P = StartP + Next(P))
ac2c559b
DK
167 ++ThisBucketSize;
168 Entries += ThisBucketSize;
637c3b23
MV
169 LongestBucket = std::max(ThisBucketSize, LongestBucket);
170 ShortestBucket = std::min(ThisBucketSize, ShortestBucket);
637c3b23 171 }
ac2c559b
DK
172 cout << "Total buckets in " << Type << ": " << NumBuckets << std::endl;
173 cout << " Unused: " << UnusedBuckets << std::endl;
637c3b23 174 cout << " Used: " << UsedBuckets << std::endl;
ac2c559b 175 cout << " Average entries: " << Entries/(double)NumBuckets << std::endl;
637c3b23
MV
176 cout << " Longest: " << LongestBucket << std::endl;
177 cout << " Shortest: " << ShortestBucket << std::endl;
178}
179 /*}}}*/
1164783d
AL
180// Stats - Dump some nice statistics /*{{{*/
181// ---------------------------------------------------------------------
182/* */
714c23a7 183static bool Stats(CommandLine &CmdL)
1164783d 184{
714c23a7
JAK
185 if (CmdL.FileSize() > 1) {
186 _error->Error(_("apt-cache stats does not take any arguments"));
187 return false;
188 }
7414af7f
DK
189
190 pkgCacheFile CacheFile;
191 pkgCache *Cache = CacheFile.GetPkgCache();
192
d9eb210e
DK
193 if (unlikely(Cache == NULL))
194 return false;
195
196 cout << _("Total package names: ") << Cache->Head().GroupCount << " (" <<
197 SizeToStr(Cache->Head().GroupCount*Cache->Head().GroupSz) << ')' << endl
198 << _("Total package structures: ") << Cache->Head().PackageCount << " (" <<
199 SizeToStr(Cache->Head().PackageCount*Cache->Head().PackageSz) << ')' << endl;
b2e465d6 200
1164783d
AL
201 int Normal = 0;
202 int Virtual = 0;
203 int NVirt = 0;
204 int DVirt = 0;
205 int Missing = 0;
d9eb210e 206 pkgCache::PkgIterator I = Cache->PkgBegin();
f7f0d6c7 207 for (;I.end() != true; ++I)
1164783d
AL
208 {
209 if (I->VersionList != 0 && I->ProvidesList == 0)
210 {
211 Normal++;
212 continue;
213 }
214
215 if (I->VersionList != 0 && I->ProvidesList != 0)
216 {
217 NVirt++;
218 continue;
219 }
220
221 if (I->VersionList == 0 && I->ProvidesList != 0)
222 {
223 // Only 1 provides
224 if (I.ProvidesList()->NextProvides == 0)
225 {
226 DVirt++;
227 }
228 else
229 Virtual++;
230 continue;
231 }
232 if (I->VersionList == 0 && I->ProvidesList == 0)
233 {
234 Missing++;
235 continue;
236 }
237 }
db0db9fe
CP
238 cout << _(" Normal packages: ") << Normal << endl;
239 cout << _(" Pure virtual packages: ") << Virtual << endl;
240 cout << _(" Single virtual packages: ") << DVirt << endl;
241 cout << _(" Mixed virtual packages: ") << NVirt << endl;
b2e465d6 242 cout << _(" Missing: ") << Missing << endl;
71c9e95b 243
d9eb210e
DK
244 cout << _("Total distinct versions: ") << Cache->Head().VersionCount << " (" <<
245 SizeToStr(Cache->Head().VersionCount*Cache->Head().VersionSz) << ')' << endl;
246 cout << _("Total distinct descriptions: ") << Cache->Head().DescriptionCount << " (" <<
247 SizeToStr(Cache->Head().DescriptionCount*Cache->Head().DescriptionSz) << ')' << endl;
71c9e95b
DK
248 cout << _("Total dependencies: ") << Cache->Head().DependsCount << "/" << Cache->Head().DependsDataCount << " (" <<
249 SizeToStr((Cache->Head().DependsCount*Cache->Head().DependencySz) +
250 (Cache->Head().DependsDataCount*Cache->Head().DependencyDataSz)) << ')' << endl;
d9eb210e
DK
251 cout << _("Total ver/file relations: ") << Cache->Head().VerFileCount << " (" <<
252 SizeToStr(Cache->Head().VerFileCount*Cache->Head().VerFileSz) << ')' << endl;
253 cout << _("Total Desc/File relations: ") << Cache->Head().DescFileCount << " (" <<
254 SizeToStr(Cache->Head().DescFileCount*Cache->Head().DescFileSz) << ')' << endl;
255 cout << _("Total Provides mappings: ") << Cache->Head().ProvidesCount << " (" <<
256 SizeToStr(Cache->Head().ProvidesCount*Cache->Head().ProvidesSz) << ')' << endl;
b2e465d6 257
a3a91fd7
DK
258 // String list stats
259 std::set<map_stringitem_t> stritems;
260 for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G)
261 stritems.insert(G->Name);
f7f0d6c7 262 for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
b2e465d6 263 {
a3a91fd7 264 stritems.insert(P->Arch);
f7f0d6c7 265 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
b2e465d6 266 {
a3a91fd7
DK
267 if (V->VerStr != 0)
268 stritems.insert(V->VerStr);
269 if (V->Section != 0)
270 stritems.insert(V->Section);
a221efc3
DK
271 stritems.insert(V->SourcePkgName);
272 stritems.insert(V->SourceVerStr);
f7f0d6c7 273 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D)
b2e465d6
AL
274 {
275 if (D->Version != 0)
a3a91fd7
DK
276 stritems.insert(D->Version);
277 }
278 for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; ++D)
279 {
280 stritems.insert(D->md5sum);
281 stritems.insert(D->language_code);
b2e465d6
AL
282 }
283 }
a3a91fd7
DK
284 for (pkgCache::PrvIterator Prv = P.ProvidesList(); Prv.end() == false; ++Prv)
285 {
286 if (Prv->ProvideVersion != 0)
287 stritems.insert(Prv->ProvideVersion);
288 }
b2e465d6 289 }
b07aeb1a 290 for (pkgCache::RlsFileIterator F = Cache->RlsFileBegin(); F != Cache->RlsFileEnd(); ++F)
a3a91fd7
DK
291 {
292 stritems.insert(F->FileName);
293 stritems.insert(F->Archive);
294 stritems.insert(F->Codename);
a3a91fd7
DK
295 stritems.insert(F->Version);
296 stritems.insert(F->Origin);
297 stritems.insert(F->Label);
a3a91fd7 298 stritems.insert(F->Site);
b07aeb1a
DK
299 }
300 for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
301 {
302 stritems.insert(F->FileName);
303 stritems.insert(F->Architecture);
304 stritems.insert(F->Component);
a3a91fd7
DK
305 stritems.insert(F->IndexType);
306 }
4dc77823 307
a3a91fd7
DK
308 unsigned long Size = 0;
309 for (std::set<map_stringitem_t>::const_iterator i = stritems.begin(); i != stritems.end(); ++i)
310 Size += strlen(Cache->StrP + *i) + 1;
a3a91fd7
DK
311 cout << _("Total globbed strings: ") << stritems.size() << " (" << SizeToStr(Size) << ')' << endl;
312 stritems.clear();
ac2c559b 313
f826cfaa
AL
314 unsigned long Slack = 0;
315 for (int I = 0; I != 7; I++)
d9eb210e 316 Slack += Cache->Head().Pools[I].ItemSize*Cache->Head().Pools[I].Count;
db0db9fe 317 cout << _("Total slack space: ") << SizeToStr(Slack) << endl;
ac2c559b 318
f826cfaa 319 unsigned long Total = 0;
ac2c559b
DK
320#define APT_CACHESIZE(X,Y) (Cache->Head().X * Cache->Head().Y)
321 Total = Slack + Size +
322 APT_CACHESIZE(GroupCount, GroupSz) +
323 APT_CACHESIZE(PackageCount, PackageSz) +
324 APT_CACHESIZE(VersionCount, VersionSz) +
325 APT_CACHESIZE(DescriptionCount, DescriptionSz) +
326 APT_CACHESIZE(DependsCount, DependencySz) +
71c9e95b 327 APT_CACHESIZE(DependsDataCount, DependencyDataSz) +
b07aeb1a 328 APT_CACHESIZE(ReleaseFileCount, ReleaseFileSz) +
ac2c559b
DK
329 APT_CACHESIZE(PackageFileCount, PackageFileSz) +
330 APT_CACHESIZE(VerFileCount, VerFileSz) +
331 APT_CACHESIZE(DescFileCount, DescFileSz) +
332 APT_CACHESIZE(ProvidesCount, ProvidesSz) +
32ab4bd0 333 (2 * Cache->Head().GetHashTableSize() * sizeof(map_id_t));
db0db9fe 334 cout << _("Total space accounted for: ") << SizeToStr(Total) << endl;
ac2c559b 335#undef APT_CACHESIZE
a93a32b5 336
637c3b23 337 // hashtable stats
32ab4bd0
DK
338 ShowHashTableStats<pkgCache::Package>("PkgHashTable", Cache->PkgP, Cache->Head().PkgHashTableP(), Cache->Head().GetHashTableSize(), PackageNext);
339 ShowHashTableStats<pkgCache::Group>("GrpHashTable", Cache->GrpP, Cache->Head().GrpHashTableP(), Cache->Head().GetHashTableSize(), GroupNext);
a93a32b5 340
83d89a9f
AL
341 return true;
342}
343 /*}}}*/
1164783d
AL
344// Dump - show everything /*{{{*/
345// ---------------------------------------------------------------------
b2e465d6 346/* This is worthless except fer debugging things */
65512241 347static bool Dump(CommandLine &)
1164783d 348{
d9eb210e
DK
349 pkgCacheFile CacheFile;
350 pkgCache *Cache = CacheFile.GetPkgCache();
351 if (unlikely(Cache == NULL))
352 return false;
353
b9179170 354 std::cout << "Using Versioning System: " << Cache->VS->Label << std::endl;
b2e465d6 355
f7f0d6c7 356 for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
1164783d 357 {
b9179170 358 std::cout << "Package: " << P.FullName(true) << std::endl;
f7f0d6c7 359 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
1164783d 360 {
b9179170
MV
361 std::cout << " Version: " << V.VerStr() << std::endl;
362 std::cout << " File: " << V.FileList().File().FileName() << std::endl;
f7f0d6c7 363 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D)
b9179170
MV
364 std::cout << " Depends: " << D.TargetPkg().FullName(true) << ' ' <<
365 DeNull(D.TargetVer()) << std::endl;
f7f0d6c7 366 for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; ++D)
a52f938b 367 {
b9179170
MV
368 std::cout << " Description Language: " << D.LanguageCode() << std::endl
369 << " File: " << D.FileList().File().FileName() << std::endl
370 << " MD5: " << D.md5() << std::endl;
a52f938b 371 }
1164783d
AL
372 }
373 }
374
f7f0d6c7 375 for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F.end() == false; ++F)
1164783d 376 {
b9179170
MV
377 std::cout << "File: " << F.FileName() << std::endl;
378 std::cout << " Type: " << F.IndexType() << std::endl;
379 std::cout << " Size: " << F->Size << std::endl;
380 std::cout << " ID: " << F->ID << std::endl;
381 std::cout << " Flags: " << F->Flags << std::endl;
382 std::cout << " Time: " << TimeRFC1123(F->mtime) << std::endl;
383 std::cout << " Archive: " << DeNull(F.Archive()) << std::endl;
384 std::cout << " Component: " << DeNull(F.Component()) << std::endl;
385 std::cout << " Version: " << DeNull(F.Version()) << std::endl;
386 std::cout << " Origin: " << DeNull(F.Origin()) << std::endl;
387 std::cout << " Site: " << DeNull(F.Site()) << std::endl;
388 std::cout << " Label: " << DeNull(F.Label()) << std::endl;
389 std::cout << " Architecture: " << DeNull(F.Architecture()) << std::endl;
1164783d
AL
390 }
391
392 return true;
393}
394 /*}}}*/
395// DumpAvail - Print out the available list /*{{{*/
396// ---------------------------------------------------------------------
b2e465d6
AL
397/* This is needed to make dpkg --merge happy.. I spent a bit of time to
398 make this run really fast, perhaps I went a little overboard.. */
65512241 399static bool DumpAvail(CommandLine &)
1164783d 400{
d9eb210e
DK
401 pkgCacheFile CacheFile;
402 pkgCache *Cache = CacheFile.GetPkgCache();
403 if (unlikely(Cache == NULL || CacheFile.BuildPolicy() == false))
b2e465d6 404 return false;
d9eb210e
DK
405
406 unsigned long Count = Cache->HeaderP->PackageCount+1;
fe648919
AL
407 pkgCache::VerFile **VFList = new pkgCache::VerFile *[Count];
408 memset(VFList,0,sizeof(*VFList)*Count);
b2e465d6
AL
409
410 // Map versions that we want to write out onto the VerList array.
f7f0d6c7 411 for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
b2e465d6
AL
412 {
413 if (P->VersionList == 0)
5b8c90bf
AL
414 continue;
415
b2e465d6
AL
416 /* Find the proper version to use. If the policy says there are no
417 possible selections we return the installed version, if available..
418 This prevents dselect from making it obsolete. */
d9eb210e 419 pkgCache::VerIterator V = CacheFile.GetPolicy()->GetCandidateVer(P);
b2e465d6 420 if (V.end() == true)
ad00ae81 421 {
b2e465d6
AL
422 if (P->CurrentVer == 0)
423 continue;
424 V = P.CurrentVer();
ad00ae81 425 }
1164783d 426
b2e465d6 427 pkgCache::VerFileIterator VF = V.FileList();
f7f0d6c7 428 for (; VF.end() == false ; ++VF)
b2e465d6
AL
429 if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 0)
430 break;
431
432 /* Okay, here we have a bit of a problem.. The policy has selected the
433 currently installed package - however it only exists in the
434 status file.. We need to write out something or dselect will mark
435 the package as obsolete! Thus we emit the status file entry, but
436 below we remove the status line to make it valid for the
437 available file. However! We only do this if their do exist *any*
438 non-source versions of the package - that way the dselect obsolete
439 handling works OK. */
440 if (VF.end() == true)
1164783d 441 {
f7f0d6c7 442 for (pkgCache::VerIterator Cur = P.VersionList(); Cur.end() != true; ++Cur)
b2e465d6 443 {
f7f0d6c7 444 for (VF = Cur.FileList(); VF.end() == false; ++VF)
b2e465d6
AL
445 {
446 if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 0)
447 {
448 VF = V.FileList();
449 break;
450 }
451 }
452
453 if (VF.end() == false)
454 break;
455 }
ad00ae81 456 }
b2e465d6
AL
457
458 VFList[P->ID] = VF;
459 }
460
fe648919 461 LocalitySort(VFList,Count,sizeof(*VFList));
ad00ae81 462
88593886
DK
463 std::vector<pkgTagSection::Tag> RW;
464 RW.push_back(pkgTagSection::Tag::Remove("Status"));
465 RW.push_back(pkgTagSection::Tag::Remove("Config-Version"));
466 FileFd stdoutfd;
467 stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false);
468
b2e465d6 469 // Iterate over all the package files and write them out.
d9eb210e 470 char *Buffer = new char[Cache->HeaderP->MaxVerFileSize+10];
b2e465d6
AL
471 for (pkgCache::VerFile **J = VFList; *J != 0;)
472 {
d9eb210e 473 pkgCache::PkgFileIterator File(*Cache,(*J)->File + Cache->PkgFileP);
b2e465d6 474 if (File.IsOk() == false)
ad00ae81 475 {
b2e465d6
AL
476 _error->Error(_("Package file %s is out of sync."),File.FileName());
477 break;
478 }
bd432be3 479
4dde2b42 480 FileFd PkgF(File.FileName(),FileFd::ReadOnly, FileFd::Extension);
b2e465d6
AL
481 if (_error->PendingError() == true)
482 break;
483
484 /* Write all of the records from this package file, since we
485 already did locality sorting we can now just seek through the
486 file in read order. We apply 1 more optimization here, since often
487 there will be < 1 byte gaps between records (for the \n) we read that
488 into the next buffer and offset a bit.. */
489 unsigned long Pos = 0;
490 for (; *J != 0; J++)
491 {
d9eb210e 492 if ((*J)->File + Cache->PkgFileP != File)
b2e465d6 493 break;
bd432be3 494
b2e465d6
AL
495 const pkgCache::VerFile &VF = **J;
496
bd432be3 497 // Read the record and then write it out again.
b2e465d6
AL
498 unsigned long Jitter = VF.Offset - Pos;
499 if (Jitter > 8)
1164783d 500 {
b2e465d6
AL
501 if (PkgF.Seek(VF.Offset) == false)
502 break;
503 Jitter = 0;
504 }
505
506 if (PkgF.Read(Buffer,VF.Size + Jitter) == false)
507 break;
508 Buffer[VF.Size + Jitter] = '\n';
88593886 509
b2e465d6
AL
510 // See above..
511 if ((File->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
512 {
513 pkgTagSection Tags;
b2e465d6 514 if (Tags.Scan(Buffer+Jitter,VF.Size+1) == false ||
88593886
DK
515 Tags.Write(stdoutfd, NULL, RW) == false ||
516 stdoutfd.Write("\n", 1) == false)
b2e465d6
AL
517 {
518 _error->Error("Internal Error, Unable to parse a package record");
519 break;
520 }
b2e465d6
AL
521 }
522 else
523 {
88593886 524 if (stdoutfd.Write(Buffer + Jitter, VF.Size + 1) == false)
b2e465d6
AL
525 break;
526 }
88593886 527
b2e465d6 528 Pos = VF.Offset + VF.Size;
1164783d 529 }
b2e465d6 530
b2e465d6
AL
531 if (_error->PendingError() == true)
532 break;
ad00ae81 533 }
88593886 534
b2e465d6
AL
535 delete [] Buffer;
536 delete [] VFList;
537 return !_error->PendingError();
349cd3b8
AL
538}
539 /*}}}*/
fff4b7f3
AL
540// xvcg - Generate a graph for xvcg /*{{{*/
541// ---------------------------------------------------------------------
542// Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
543
c3ccac92 544static bool XVcg(CommandLine &CmdL)
fff4b7f3 545{
d9eb210e
DK
546 pkgCacheFile CacheFile;
547 pkgCache *Cache = CacheFile.GetPkgCache();
548 if (unlikely(Cache == NULL))
549 return false;
550
fff4b7f3
AL
551 bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false);
552
553 /* Normal packages are boxes
554 Pure Provides are triangles
555 Mixed are diamonds
556 rhomb are missing packages*/
557 const char *Shapes[] = {"ellipse","triangle","box","rhomb"};
558
559 /* Initialize the list of packages to show.
560 1 = To Show
561 2 = To Show no recurse
562 3 = Emitted no recurse
563 4 = Emitted
564 0 = None */
565 enum States {None=0, ToShow, ToShowNR, DoneNR, Done};
566 enum TheFlags {ForceNR=(1<<0)};
d9eb210e
DK
567 unsigned char *Show = new unsigned char[Cache->Head().PackageCount];
568 unsigned char *Flags = new unsigned char[Cache->Head().PackageCount];
569 unsigned char *ShapeMap = new unsigned char[Cache->Head().PackageCount];
fff4b7f3
AL
570
571 // Show everything if no arguments given
572 if (CmdL.FileList[1] == 0)
d9eb210e 573 for (unsigned long I = 0; I != Cache->Head().PackageCount; I++)
fff4b7f3
AL
574 Show[I] = ToShow;
575 else
d9eb210e 576 for (unsigned long I = 0; I != Cache->Head().PackageCount; I++)
fff4b7f3 577 Show[I] = None;
d9eb210e 578 memset(Flags,0,sizeof(*Flags)*Cache->Head().PackageCount);
fff4b7f3
AL
579
580 // Map the shapes
f7f0d6c7 581 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
fff4b7f3
AL
582 {
583 if (Pkg->VersionList == 0)
584 {
585 // Missing
586 if (Pkg->ProvidesList == 0)
587 ShapeMap[Pkg->ID] = 0;
588 else
589 ShapeMap[Pkg->ID] = 1;
590 }
591 else
592 {
593 // Normal
594 if (Pkg->ProvidesList == 0)
595 ShapeMap[Pkg->ID] = 2;
596 else
597 ShapeMap[Pkg->ID] = 3;
598 }
599 }
3c977245 600
fff4b7f3 601 // Load the list of packages from the command line into the show list
cd7bbc47 602 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
fdba4d53
DK
603 std::list<APT::CacheSetHelper::PkgModifier> mods;
604 mods.push_back(APT::CacheSetHelper::PkgModifier(0, ",", APT::PackageSet::Modifier::POSTFIX));
605 mods.push_back(APT::CacheSetHelper::PkgModifier(1, "^", APT::PackageSet::Modifier::POSTFIX));
3c977245 606 std::map<unsigned short, APT::PackageSet> pkgsets =
cd7bbc47 607 APT::PackageSet::GroupedFromCommandLine(CacheFile, CmdL.FileList + 1, mods, 0, helper);
3c977245
DK
608
609 for (APT::PackageSet::const_iterator Pkg = pkgsets[0].begin();
610 Pkg != pkgsets[0].end(); ++Pkg)
611 Show[Pkg->ID] = ToShow;
612 for (APT::PackageSet::const_iterator Pkg = pkgsets[1].begin();
613 Pkg != pkgsets[1].end(); ++Pkg)
fff4b7f3 614 {
fff4b7f3 615 Show[Pkg->ID] = ToShow;
3c977245 616 Flags[Pkg->ID] |= ForceNR;
fff4b7f3 617 }
3c977245 618
fff4b7f3
AL
619 // Little header
620 cout << "graph: { title: \"packages\"" << endl <<
621 "xmax: 700 ymax: 700 x: 30 y: 30" << endl <<
622 "layout_downfactor: 8" << endl;
623
624 bool Act = true;
625 while (Act == true)
626 {
627 Act = false;
f7f0d6c7 628 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
fff4b7f3
AL
629 {
630 // See we need to show this package
631 if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR)
632 continue;
633
634 //printf ("node: { title: \"%s\" label: \"%s\" }\n", Pkg.Name(), Pkg.Name());
635
636 // Colour as done
637 if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR)
638 {
639 // Pure Provides and missing packages have no deps!
640 if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1)
641 Show[Pkg->ID] = Done;
642 else
643 Show[Pkg->ID] = DoneNR;
644 }
645 else
646 Show[Pkg->ID] = Done;
647 Act = true;
648
649 // No deps to map out
650 if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR)
651 continue;
652
653 pkgCache::VerIterator Ver = Pkg.VersionList();
f7f0d6c7 654 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; ++D)
fff4b7f3
AL
655 {
656 // See if anything can meet this dep
657 // Walk along the actual package providing versions
658 bool Hit = false;
659 pkgCache::PkgIterator DPkg = D.TargetPkg();
660 for (pkgCache::VerIterator I = DPkg.VersionList();
f7f0d6c7 661 I.end() == false && Hit == false; ++I)
fff4b7f3 662 {
d9eb210e 663 if (Cache->VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true)
fff4b7f3
AL
664 Hit = true;
665 }
666
667 // Follow all provides
668 for (pkgCache::PrvIterator I = DPkg.ProvidesList();
f7f0d6c7 669 I.end() == false && Hit == false; ++I)
fff4b7f3 670 {
d9eb210e 671 if (Cache->VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false)
fff4b7f3
AL
672 Hit = true;
673 }
674
675
676 // Only graph critical deps
677 if (D.IsCritical() == true)
678 {
75ce2062 679 printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg.FullName(true).c_str(), D.TargetPkg().FullName(true).c_str() );
fff4b7f3
AL
680
681 // Colour the node for recursion
682 if (Show[D.TargetPkg()->ID] <= DoneNR)
683 {
684 /* If a conflicts does not meet anything in the database
685 then show the relation but do not recurse */
359e46db 686 if (Hit == false && D.IsNegative() == true)
fff4b7f3
AL
687 {
688 if (Show[D.TargetPkg()->ID] == None &&
689 Show[D.TargetPkg()->ID] != ToShow)
690 Show[D.TargetPkg()->ID] = ToShowNR;
691 }
692 else
693 {
694 if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow)
695 Show[D.TargetPkg()->ID] = ToShowNR;
696 else
697 Show[D.TargetPkg()->ID] = ToShow;
698 }
699 }
700
701 // Edge colour
702 switch(D->Type)
703 {
704 case pkgCache::Dep::Conflicts:
705 printf("label: \"conflicts\" color: lightgreen }\n");
706 break;
308c7d30
IJ
707 case pkgCache::Dep::DpkgBreaks:
708 printf("label: \"breaks\" color: lightgreen }\n");
709 break;
fff4b7f3
AL
710 case pkgCache::Dep::Obsoletes:
711 printf("label: \"obsoletes\" color: lightgreen }\n");
712 break;
713
714 case pkgCache::Dep::PreDepends:
715 printf("label: \"predepends\" color: blue }\n");
716 break;
717
718 default:
719 printf("}\n");
720 break;
721 }
722 }
723 }
724 }
725 }
726
727 /* Draw the box colours after the fact since we can not tell what colour
728 they should be until everything is finished drawing */
f7f0d6c7 729 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
fff4b7f3
AL
730 {
731 if (Show[Pkg->ID] < DoneNR)
732 continue;
733
734 if (Show[Pkg->ID] == DoneNR)
75ce2062 735 printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg.FullName(true).c_str(), Pkg.FullName(true).c_str(),
fff4b7f3
AL
736 Shapes[ShapeMap[Pkg->ID]]);
737 else
75ce2062 738 printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg.FullName(true).c_str(), Pkg.FullName(true).c_str(),
fff4b7f3
AL
739 Shapes[ShapeMap[Pkg->ID]]);
740
741 }
03496041
DK
742
743 delete[] Show;
744 delete[] Flags;
745 delete[] ShapeMap;
746
fff4b7f3
AL
747 printf("}\n");
748 return true;
749}
750 /*}}}*/
3e94da1b
AL
751// Dotty - Generate a graph for Dotty /*{{{*/
752// ---------------------------------------------------------------------
753/* Dotty is the graphvis program for generating graphs. It is a fairly
754 simple queuing algorithm that just writes dependencies and nodes.
755 http://www.research.att.com/sw/tools/graphviz/ */
c3ccac92 756static bool Dotty(CommandLine &CmdL)
3e94da1b 757{
d9eb210e
DK
758 pkgCacheFile CacheFile;
759 pkgCache *Cache = CacheFile.GetPkgCache();
760 if (unlikely(Cache == NULL))
761 return false;
762
3e94da1b
AL
763 bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false);
764
765 /* Normal packages are boxes
766 Pure Provides are triangles
767 Mixed are diamonds
768 Hexagons are missing packages*/
769 const char *Shapes[] = {"hexagon","triangle","box","diamond"};
770
771 /* Initialize the list of packages to show.
772 1 = To Show
773 2 = To Show no recurse
774 3 = Emitted no recurse
775 4 = Emitted
776 0 = None */
777 enum States {None=0, ToShow, ToShowNR, DoneNR, Done};
778 enum TheFlags {ForceNR=(1<<0)};
d9eb210e
DK
779 unsigned char *Show = new unsigned char[Cache->Head().PackageCount];
780 unsigned char *Flags = new unsigned char[Cache->Head().PackageCount];
781 unsigned char *ShapeMap = new unsigned char[Cache->Head().PackageCount];
3e94da1b
AL
782
783 // Show everything if no arguments given
784 if (CmdL.FileList[1] == 0)
d9eb210e 785 for (unsigned long I = 0; I != Cache->Head().PackageCount; I++)
3e94da1b
AL
786 Show[I] = ToShow;
787 else
d9eb210e 788 for (unsigned long I = 0; I != Cache->Head().PackageCount; I++)
3e94da1b 789 Show[I] = None;
d9eb210e 790 memset(Flags,0,sizeof(*Flags)*Cache->Head().PackageCount);
3e94da1b
AL
791
792 // Map the shapes
f7f0d6c7 793 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
3e94da1b
AL
794 {
795 if (Pkg->VersionList == 0)
796 {
797 // Missing
798 if (Pkg->ProvidesList == 0)
799 ShapeMap[Pkg->ID] = 0;
800 else
801 ShapeMap[Pkg->ID] = 1;
802 }
803 else
804 {
805 // Normal
806 if (Pkg->ProvidesList == 0)
807 ShapeMap[Pkg->ID] = 2;
808 else
809 ShapeMap[Pkg->ID] = 3;
810 }
811 }
3c977245 812
3e94da1b 813 // Load the list of packages from the command line into the show list
cd7bbc47 814 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
fdba4d53
DK
815 std::list<APT::CacheSetHelper::PkgModifier> mods;
816 mods.push_back(APT::CacheSetHelper::PkgModifier(0, ",", APT::PackageSet::Modifier::POSTFIX));
817 mods.push_back(APT::CacheSetHelper::PkgModifier(1, "^", APT::PackageSet::Modifier::POSTFIX));
3c977245 818 std::map<unsigned short, APT::PackageSet> pkgsets =
cd7bbc47 819 APT::PackageSet::GroupedFromCommandLine(CacheFile, CmdL.FileList + 1, mods, 0, helper);
3c977245
DK
820
821 for (APT::PackageSet::const_iterator Pkg = pkgsets[0].begin();
822 Pkg != pkgsets[0].end(); ++Pkg)
823 Show[Pkg->ID] = ToShow;
824 for (APT::PackageSet::const_iterator Pkg = pkgsets[1].begin();
825 Pkg != pkgsets[1].end(); ++Pkg)
3e94da1b 826 {
3e94da1b 827 Show[Pkg->ID] = ToShow;
3c977245 828 Flags[Pkg->ID] |= ForceNR;
3e94da1b 829 }
3c977245 830
3e94da1b
AL
831 // Little header
832 printf("digraph packages {\n");
833 printf("concentrate=true;\n");
834 printf("size=\"30,40\";\n");
835
836 bool Act = true;
837 while (Act == true)
838 {
839 Act = false;
f7f0d6c7 840 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
3e94da1b
AL
841 {
842 // See we need to show this package
843 if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR)
844 continue;
845
846 // Colour as done
847 if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR)
848 {
849 // Pure Provides and missing packages have no deps!
850 if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1)
851 Show[Pkg->ID] = Done;
852 else
853 Show[Pkg->ID] = DoneNR;
854 }
855 else
856 Show[Pkg->ID] = Done;
857 Act = true;
858
859 // No deps to map out
860 if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR)
861 continue;
862
863 pkgCache::VerIterator Ver = Pkg.VersionList();
f7f0d6c7 864 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; ++D)
3e94da1b
AL
865 {
866 // See if anything can meet this dep
867 // Walk along the actual package providing versions
868 bool Hit = false;
869 pkgCache::PkgIterator DPkg = D.TargetPkg();
870 for (pkgCache::VerIterator I = DPkg.VersionList();
f7f0d6c7 871 I.end() == false && Hit == false; ++I)
3e94da1b 872 {
d9eb210e 873 if (Cache->VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true)
3e94da1b
AL
874 Hit = true;
875 }
876
877 // Follow all provides
878 for (pkgCache::PrvIterator I = DPkg.ProvidesList();
f7f0d6c7 879 I.end() == false && Hit == false; ++I)
3e94da1b 880 {
d9eb210e 881 if (Cache->VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false)
3e94da1b
AL
882 Hit = true;
883 }
884
885 // Only graph critical deps
886 if (D.IsCritical() == true)
887 {
75ce2062 888 printf("\"%s\" -> \"%s\"",Pkg.FullName(true).c_str(),D.TargetPkg().FullName(true).c_str());
3e94da1b
AL
889
890 // Colour the node for recursion
891 if (Show[D.TargetPkg()->ID] <= DoneNR)
892 {
893 /* If a conflicts does not meet anything in the database
894 then show the relation but do not recurse */
359e46db 895 if (Hit == false && D.IsNegative() == true)
3e94da1b
AL
896 {
897 if (Show[D.TargetPkg()->ID] == None &&
898 Show[D.TargetPkg()->ID] != ToShow)
899 Show[D.TargetPkg()->ID] = ToShowNR;
900 }
901 else
902 {
903 if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow)
904 Show[D.TargetPkg()->ID] = ToShowNR;
905 else
906 Show[D.TargetPkg()->ID] = ToShow;
907 }
908 }
909
910 // Edge colour
911 switch(D->Type)
912 {
913 case pkgCache::Dep::Conflicts:
b2e465d6 914 case pkgCache::Dep::Obsoletes:
359e46db 915 case pkgCache::Dep::DpkgBreaks:
3e94da1b
AL
916 printf("[color=springgreen];\n");
917 break;
918
919 case pkgCache::Dep::PreDepends:
920 printf("[color=blue];\n");
921 break;
922
923 default:
924 printf(";\n");
925 break;
926 }
927 }
928 }
929 }
930 }
931
932 /* Draw the box colours after the fact since we can not tell what colour
933 they should be until everything is finished drawing */
f7f0d6c7 934 for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
3e94da1b
AL
935 {
936 if (Show[Pkg->ID] < DoneNR)
937 continue;
938
939 // Orange box for early recursion stoppage
940 if (Show[Pkg->ID] == DoneNR)
75ce2062 941 printf("\"%s\" [color=orange,shape=%s];\n",Pkg.FullName(true).c_str(),
3e94da1b
AL
942 Shapes[ShapeMap[Pkg->ID]]);
943 else
75ce2062 944 printf("\"%s\" [shape=%s];\n",Pkg.FullName(true).c_str(),
3e94da1b
AL
945 Shapes[ShapeMap[Pkg->ID]]);
946 }
947
948 printf("}\n");
6070a346
DK
949 delete[] Show;
950 delete[] Flags;
951 delete[] ShapeMap;
ad00ae81 952 return true;
7e2e2d5d
AL
953}
954 /*}}}*/
182a6a55 955/* ShowAuto - show automatically installed packages (sorted) {{{*/
65512241 956static bool ShowAuto(CommandLine &)
6007c1d4 957{
d9eb210e
DK
958 pkgCacheFile CacheFile;
959 pkgCache *Cache = CacheFile.GetPkgCache();
960 pkgDepCache *DepCache = CacheFile.GetDepCache();
961 if (unlikely(Cache == NULL || DepCache == NULL))
962 return false;
6007c1d4
JAK
963
964 std::vector<string> packages;
d9eb210e 965 packages.reserve(Cache->HeaderP->PackageCount / 3);
6007c1d4 966
f7f0d6c7 967 for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
d9eb210e 968 if ((*DepCache)[P].Flags & pkgCache::Flag::Auto)
6007c1d4
JAK
969 packages.push_back(P.Name());
970
971 std::sort(packages.begin(), packages.end());
972
f7f0d6c7 973 for (vector<string>::iterator I = packages.begin(); I != packages.end(); ++I)
6007c1d4
JAK
974 cout << *I << "\n";
975
182a6a55 976 _error->Notice(_("This command is deprecated. Please use 'apt-mark showauto' instead."));
6007c1d4
JAK
977 return true;
978}
1164783d 979 /*}}}*/
7c1133fe
AL
980// ShowPkgNames - Show package names /*{{{*/
981// ---------------------------------------------------------------------
982/* This does a prefix match on the first argument */
c3ccac92 983static bool ShowPkgNames(CommandLine &CmdL)
7c1133fe 984{
d9eb210e
DK
985 pkgCacheFile CacheFile;
986 if (unlikely(CacheFile.BuildCaches(NULL, false) == false))
987 return false;
988 pkgCache::GrpIterator I = CacheFile.GetPkgCache()->GrpBegin();
6293e04f
DK
989 bool const All = _config->FindB("APT::Cache::AllNames","false");
990
7c1133fe
AL
991 if (CmdL.FileList[1] != 0)
992 {
f7f0d6c7 993 for (;I.end() != true; ++I)
7c1133fe 994 {
6293e04f
DK
995 if (All == false && I->FirstPackage == 0)
996 continue;
997 if (I.FindPkg("any")->VersionList == 0)
7c1133fe 998 continue;
7c1133fe
AL
999 if (strncmp(I.Name(),CmdL.FileList[1],strlen(CmdL.FileList[1])) == 0)
1000 cout << I.Name() << endl;
1001 }
1002
1003 return true;
1004 }
1005
1006 // Show all pkgs
f7f0d6c7 1007 for (;I.end() != true; ++I)
7c1133fe 1008 {
6293e04f
DK
1009 if (All == false && I->FirstPackage == 0)
1010 continue;
1011 if (I.FindPkg("any")->VersionList == 0)
7c1133fe
AL
1012 continue;
1013 cout << I.Name() << endl;
1014 }
1015
f8f410f5
AL
1016 return true;
1017}
bd3d53ef
AL
1018 /*}}}*/
1019// Madison - Look a bit like katie's madison /*{{{*/
1020// ---------------------------------------------------------------------
1021/* */
c3ccac92 1022static bool Madison(CommandLine &CmdL)
bd3d53ef 1023{
d9eb210e
DK
1024 pkgCacheFile CacheFile;
1025 pkgSourceList *SrcList = CacheFile.GetSourceList();
bd3d53ef 1026
d9eb210e
DK
1027 if (SrcList == 0)
1028 return false;
bd3d53ef 1029
03cd434b
MV
1030 // Create the src text record parsers and ignore errors about missing
1031 // deb-src lines that are generated from pkgSrcRecords::pkgSrcRecords
bd3d53ef
AL
1032 pkgSrcRecords SrcRecs(*SrcList);
1033 if (_error->PendingError() == true)
03cd434b 1034 _error->Discard();
bd3d53ef 1035
cd7bbc47 1036 APT::CacheSetHelper helper(true, GlobalError::NOTICE);
dc67d95f 1037 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
bd3d53ef 1038 {
dc67d95f 1039 _error->PushToStack();
c4cca791
DK
1040 APT::PackageList pkgset = APT::PackageList::FromString(CacheFile, *I, helper);
1041 for (APT::PackageList::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
bd3d53ef 1042 {
f7f0d6c7 1043 for (pkgCache::VerIterator V = Pkg.VersionList(); V.end() == false; ++V)
bd3d53ef 1044 {
f7f0d6c7 1045 for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; ++VF)
bd3d53ef 1046 {
a0e710af
AL
1047// This might be nice, but wouldn't uniquely identify the source -mdz
1048// if (VF.File().Archive() != 0)
1049// {
1050// cout << setw(10) << Pkg.Name() << " | " << setw(10) << V.VerStr() << " | "
1051// << VF.File().Archive() << endl;
1052// }
1053
1054 // Locate the associated index files so we can derive a description
f7f0d6c7 1055 for (pkgSourceList::const_iterator S = SrcList->begin(); S != SrcList->end(); ++S)
bd3d53ef 1056 {
7db98ffc
MZ
1057 vector<pkgIndexFile *> *Indexes = (*S)->GetIndexFiles();
1058 for (vector<pkgIndexFile *>::const_iterator IF = Indexes->begin();
f7f0d6c7 1059 IF != Indexes->end(); ++IF)
7db98ffc
MZ
1060 {
1061 if ((*IF)->FindInCache(*(VF.File().Cache())) == VF.File())
1062 {
75ce2062 1063 cout << setw(10) << Pkg.FullName(true) << " | " << setw(10) << V.VerStr() << " | "
7db98ffc
MZ
1064 << (*IF)->Describe(true) << endl;
1065 }
1066 }
bd3d53ef
AL
1067 }
1068 }
1069 }
1070 }
1071
bd3d53ef
AL
1072 SrcRecs.Restart();
1073 pkgSrcRecords::Parser *SrcParser;
dc67d95f
DK
1074 bool foundSomething = false;
1075 while ((SrcParser = SrcRecs.Find(*I, false)) != 0)
bd3d53ef 1076 {
dc67d95f 1077 foundSomething = true;
bd3d53ef
AL
1078 // Maybe support Release info here too eventually
1079 cout << setw(10) << SrcParser->Package() << " | "
1080 << setw(10) << SrcParser->Version() << " | "
1081 << SrcParser->Index().Describe(true) << endl;
1082 }
dc67d95f
DK
1083 if (foundSomething == true)
1084 _error->RevertToStack();
1085 else
1086 _error->MergeWithStack();
bd3d53ef
AL
1087 }
1088
1089 return true;
1090}
f8f410f5 1091 /*}}}*/
880e9be4
AL
1092// GenCaches - Call the main cache generator /*{{{*/
1093// ---------------------------------------------------------------------
1094/* */
65512241 1095static bool GenCaches(CommandLine &)
880e9be4 1096{
0a8e3465 1097 OpTextProgress Progress(*_config);
d9eb210e
DK
1098
1099 pkgCacheFile CacheFile;
1100 return CacheFile.BuildCaches(&Progress, true);
880e9be4
AL
1101}
1102 /*}}}*/
f6777222 1103static bool ShowHelp(CommandLine &) /*{{{*/
e1b74f61 1104{
cbbee23e 1105 std::cout <<
b2e465d6 1106 _("Usage: apt-cache [options] command\n"
cbbee23e 1107 " apt-cache [options] show pkg1 [pkg2 ...]\n"
b2e465d6 1108 "\n"
8561c2fe 1109 "apt-cache queries and displays available information about installed\n"
d04e44ac
JR
1110 "and installable packages. It works exclusively on the data acquired\n"
1111 "into the local cache via the 'update' command of e.g. apt-get. The\n"
1112 "displayed information may therefore be outdated if the last update was\n"
1113 "too long ago, but in exchange apt-cache works independently of the\n"
8561c2fe 1114 "availability of the configured sources (e.g. offline).\n");
b2e465d6 1115 return true;
e1b74f61
AL
1116}
1117 /*}}}*/
f6777222 1118static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
1164783d 1119{
011188e3 1120 return {
cbbee23e
DK
1121 {"gencaches",&GenCaches, nullptr},
1122 {"showsrc",&ShowSrcPackage, _("Show source records")},
1123 {"showpkg",&DumpPackage, nullptr},
1124 {"stats",&Stats, nullptr},
1125 {"dump",&Dump, nullptr},
1126 {"dumpavail",&DumpAvail, nullptr},
1127 {"unmet",&UnMet, nullptr},
1128 {"search",&DoSearch, _("Search the package list for a regex pattern")},
1129 {"depends",&Depends, _("Show raw dependency information for a package")},
1130 {"rdepends",&RDepends, _("Show reverse dependency information for a package")},
1131 {"dotty",&Dotty, nullptr},
1132 {"xvcg",&XVcg, nullptr},
1133 {"show",&ShowPackage, _("Show a readable record for the package")},
1134 {"pkgnames",&ShowPkgNames, _("List the names of all packages in the system")},
1135 {"showauto",&ShowAuto, nullptr},
1136 {"policy",&Policy, _("Show policy settings")},
1137 {"madison",&Madison, nullptr},
1138 {nullptr, nullptr, nullptr}
1139 };
011188e3
DK
1140}
1141 /*}}}*/
1142int main(int argc,const char *argv[]) /*{{{*/
1143{
1144 InitLocale();
0a8e3465 1145
e1b74f61 1146 // Parse the command line and initialize the package library
ad7e0941 1147 CommandLine CmdL;
90986d4d 1148 auto const Cmds = ParseCommandLine(CmdL, APT_CMD::APT_CACHE, &_config, &_system, argc, argv, &ShowHelp, &GetCommands);
8efa2a3b 1149
d9e518c6 1150 InitOutput();
a9a5908d 1151
320352e0
DK
1152 if (_config->Exists("APT::Cache::Generate") == true)
1153 _config->Set("pkgCacheFile::Generate", _config->FindB("APT::Cache::Generate", true));
1154
e7e10e47 1155 return DispatchCommandLine(CmdL, Cmds);
1164783d 1156}
92fcbfc1 1157 /*}}}*/