]>
git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-cache.cc,v 1.62 2003/04/27 01:32:48 doogie Exp $
4 /* ######################################################################
6 apt-cache - Manages the cache files
8 apt-cache provides some functions fo manipulating the cache files.
9 It uses the command line interface common to all the APT tools.
11 Returns 100 on failure, 0 on success.
13 ##################################################################### */
15 // Include Files /*{{{*/
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/pkgcachegen.h>
18 #include <apt-pkg/init.h>
19 #include <apt-pkg/progress.h>
20 #include <apt-pkg/sourcelist.h>
21 #include <apt-pkg/cmndline.h>
22 #include <apt-pkg/strutl.h>
23 #include <apt-pkg/pkgrecords.h>
24 #include <apt-pkg/srcrecords.h>
25 #include <apt-pkg/version.h>
26 #include <apt-pkg/policy.h>
27 #include <apt-pkg/tagfile.h>
28 #include <apt-pkg/algorithms.h>
29 #include <apt-pkg/sptr.h>
45 pkgSourceList
*SrcList
= 0;
47 // LocalitySort - Sort a version list by package file locality /*{{{*/
48 // ---------------------------------------------------------------------
50 int LocalityCompare(const void *a
, const void *b
)
52 pkgCache::VerFile
*A
= *(pkgCache::VerFile
**)a
;
53 pkgCache::VerFile
*B
= *(pkgCache::VerFile
**)b
;
62 if (A
->File
== B
->File
)
63 return A
->Offset
- B
->Offset
;
64 return A
->File
- B
->File
;
67 void LocalitySort(pkgCache::VerFile
**begin
,
68 unsigned long Count
,size_t Size
)
70 qsort(begin
,Count
,Size
,LocalityCompare
);
73 // UnMet - Show unmet dependencies /*{{{*/
74 // ---------------------------------------------------------------------
76 bool UnMet(CommandLine
&CmdL
)
78 pkgCache
&Cache
= *GCache
;
79 bool Important
= _config
->FindB("APT::Cache::Important",false);
81 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
83 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
86 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false;)
89 pkgCache::DepIterator Start
;
90 pkgCache::DepIterator End
;
93 // Skip conflicts and replaces
94 if (End
->Type
!= pkgCache::Dep::PreDepends
&&
95 End
->Type
!= pkgCache::Dep::Depends
&&
96 End
->Type
!= pkgCache::Dep::Suggests
&&
97 End
->Type
!= pkgCache::Dep::Recommends
)
100 // Important deps only
101 if (Important
== true)
102 if (End
->Type
!= pkgCache::Dep::PreDepends
&&
103 End
->Type
!= pkgCache::Dep::Depends
)
106 // Verify the or group
108 pkgCache::DepIterator RealStart
= Start
;
111 // See if this dep is Ok
112 pkgCache::Version
**VList
= Start
.AllTargets();
133 ioprintf(cout
,_("Package %s version %s has an unmet dep:\n"),
134 P
.Name(),V
.VerStr());
137 // Print out the dep type
138 cout
<< " " << End
.DepType() << ": ";
144 cout
<< Start
.TargetPkg().Name();
145 if (Start
.TargetVer() != 0)
146 cout
<< " (" << Start
.CompType() << " " << Start
.TargetVer() <<
162 // DumpPackage - Show a dump of a package record /*{{{*/
163 // ---------------------------------------------------------------------
165 bool DumpPackage(CommandLine
&CmdL
)
167 pkgCache
&Cache
= *GCache
;
168 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
170 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(*I
);
171 if (Pkg
.end() == true)
173 _error
->Warning(_("Unable to locate package %s"),*I
);
177 cout
<< "Package: " << Pkg
.Name() << endl
;
178 cout
<< "Versions: " << endl
;
179 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
181 cout
<< Cur
.VerStr();
182 for (pkgCache::VerFileIterator Vf
= Cur
.FileList(); Vf
.end() == false; Vf
++)
183 cout
<< "(" << Vf
.File().FileName() << ")";
189 cout
<< "Reverse Depends: " << endl
;
190 for (pkgCache::DepIterator D
= Pkg
.RevDependsList(); D
.end() != true; D
++)
192 cout
<< " " << D
.ParentPkg().Name() << ',' << D
.TargetPkg().Name();
194 cout
<< ' ' << DeNull(D
.TargetVer()) << endl
;
199 cout
<< "Dependencies: " << endl
;
200 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
202 cout
<< Cur
.VerStr() << " - ";
203 for (pkgCache::DepIterator Dep
= Cur
.DependsList(); Dep
.end() != true; Dep
++)
204 cout
<< Dep
.TargetPkg().Name() << " (" << (int)Dep
->CompareOp
<< " " << DeNull(Dep
.TargetVer()) << ") ";
208 cout
<< "Provides: " << endl
;
209 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
211 cout
<< Cur
.VerStr() << " - ";
212 for (pkgCache::PrvIterator Prv
= Cur
.ProvidesList(); Prv
.end() != true; Prv
++)
213 cout
<< Prv
.ParentPkg().Name() << " ";
216 cout
<< "Reverse Provides: " << endl
;
217 for (pkgCache::PrvIterator Prv
= Pkg
.ProvidesList(); Prv
.end() != true; Prv
++)
218 cout
<< Prv
.OwnerPkg().Name() << " " << Prv
.OwnerVer().VerStr() << endl
;
224 // Stats - Dump some nice statistics /*{{{*/
225 // ---------------------------------------------------------------------
227 bool Stats(CommandLine
&Cmd
)
229 pkgCache
&Cache
= *GCache
;
230 cout
<< _("Total Package Names : ") << Cache
.Head().PackageCount
<< " (" <<
231 SizeToStr(Cache
.Head().PackageCount
*Cache
.Head().PackageSz
) << ')' << endl
;
238 pkgCache::PkgIterator I
= Cache
.PkgBegin();
239 for (;I
.end() != true; I
++)
241 if (I
->VersionList
!= 0 && I
->ProvidesList
== 0)
247 if (I
->VersionList
!= 0 && I
->ProvidesList
!= 0)
253 if (I
->VersionList
== 0 && I
->ProvidesList
!= 0)
256 if (I
.ProvidesList()->NextProvides
== 0)
264 if (I
->VersionList
== 0 && I
->ProvidesList
== 0)
270 cout
<< _(" Normal Packages: ") << Normal
<< endl
;
271 cout
<< _(" Pure Virtual Packages: ") << Virtual
<< endl
;
272 cout
<< _(" Single Virtual Packages: ") << DVirt
<< endl
;
273 cout
<< _(" Mixed Virtual Packages: ") << NVirt
<< endl
;
274 cout
<< _(" Missing: ") << Missing
<< endl
;
276 cout
<< _("Total Distinct Versions: ") << Cache
.Head().VersionCount
<< " (" <<
277 SizeToStr(Cache
.Head().VersionCount
*Cache
.Head().VersionSz
) << ')' << endl
;
278 cout
<< _("Total Dependencies: ") << Cache
.Head().DependsCount
<< " (" <<
279 SizeToStr(Cache
.Head().DependsCount
*Cache
.Head().DependencySz
) << ')' << endl
;
281 cout
<< _("Total Ver/File relations: ") << Cache
.Head().VerFileCount
<< " (" <<
282 SizeToStr(Cache
.Head().VerFileCount
*Cache
.Head().VerFileSz
) << ')' << endl
;
283 cout
<< _("Total Provides Mappings: ") << Cache
.Head().ProvidesCount
<< " (" <<
284 SizeToStr(Cache
.Head().ProvidesCount
*Cache
.Head().ProvidesSz
) << ')' << endl
;
287 unsigned long Size
= 0;
288 unsigned long Count
= 0;
289 for (pkgCache::StringItem
*I
= Cache
.StringItemP
+ Cache
.Head().StringList
;
290 I
!= Cache
.StringItemP
; I
= Cache
.StringItemP
+ I
->NextItem
)
293 Size
+= strlen(Cache
.StrP
+ I
->String
) + 1;
295 cout
<< _("Total Globbed Strings: ") << Count
<< " (" << SizeToStr(Size
) << ')' << endl
;
297 unsigned long DepVerSize
= 0;
298 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
300 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
302 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; D
++)
305 DepVerSize
+= strlen(D
.TargetVer()) + 1;
309 cout
<< _("Total Dependency Version space: ") << SizeToStr(DepVerSize
) << endl
;
311 unsigned long Slack
= 0;
312 for (int I
= 0; I
!= 7; I
++)
313 Slack
+= Cache
.Head().Pools
[I
].ItemSize
*Cache
.Head().Pools
[I
].Count
;
314 cout
<< _("Total Slack space: ") << SizeToStr(Slack
) << endl
;
316 unsigned long Total
= 0;
317 Total
= Slack
+ Size
+ Cache
.Head().DependsCount
*Cache
.Head().DependencySz
+
318 Cache
.Head().VersionCount
*Cache
.Head().VersionSz
+
319 Cache
.Head().PackageCount
*Cache
.Head().PackageSz
+
320 Cache
.Head().VerFileCount
*Cache
.Head().VerFileSz
+
321 Cache
.Head().ProvidesCount
*Cache
.Head().ProvidesSz
;
322 cout
<< _("Total Space Accounted for: ") << SizeToStr(Total
) << endl
;
327 // Dump - show everything /*{{{*/
328 // ---------------------------------------------------------------------
329 /* This is worthless except fer debugging things */
330 bool Dump(CommandLine
&Cmd
)
332 pkgCache
&Cache
= *GCache
;
333 cout
<< "Using Versioning System: " << Cache
.VS
->Label
<< endl
;
335 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
337 cout
<< "Package: " << P
.Name() << endl
;
338 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
340 cout
<< " Version: " << V
.VerStr() << endl
;
341 cout
<< " File: " << V
.FileList().File().FileName() << endl
;
342 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; D
++)
343 cout
<< " Depends: " << D
.TargetPkg().Name() << ' ' <<
344 DeNull(D
.TargetVer()) << endl
;
348 for (pkgCache::PkgFileIterator F
= Cache
.FileBegin(); F
.end() == false; F
++)
350 cout
<< "File: " << F
.FileName() << endl
;
351 cout
<< " Type: " << F
.IndexType() << endl
;
352 cout
<< " Size: " << F
->Size
<< endl
;
353 cout
<< " ID: " << F
->ID
<< endl
;
354 cout
<< " Flags: " << F
->Flags
<< endl
;
355 cout
<< " Time: " << TimeRFC1123(F
->mtime
) << endl
;
356 cout
<< " Archive: " << DeNull(F
.Archive()) << endl
;
357 cout
<< " Component: " << DeNull(F
.Component()) << endl
;
358 cout
<< " Version: " << DeNull(F
.Version()) << endl
;
359 cout
<< " Origin: " << DeNull(F
.Origin()) << endl
;
360 cout
<< " Site: " << DeNull(F
.Site()) << endl
;
361 cout
<< " Label: " << DeNull(F
.Label()) << endl
;
362 cout
<< " Architecture: " << DeNull(F
.Architecture()) << endl
;
368 // DumpAvail - Print out the available list /*{{{*/
369 // ---------------------------------------------------------------------
370 /* This is needed to make dpkg --merge happy.. I spent a bit of time to
371 make this run really fast, perhaps I went a little overboard.. */
372 bool DumpAvail(CommandLine
&Cmd
)
374 pkgCache
&Cache
= *GCache
;
376 pkgPolicy
Plcy(&Cache
);
377 if (ReadPinFile(Plcy
) == false)
380 unsigned long Count
= Cache
.HeaderP
->PackageCount
+1;
381 pkgCache::VerFile
**VFList
= new pkgCache::VerFile
*[Count
];
382 memset(VFList
,0,sizeof(*VFList
)*Count
);
384 // Map versions that we want to write out onto the VerList array.
385 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
387 if (P
->VersionList
== 0)
390 /* Find the proper version to use. If the policy says there are no
391 possible selections we return the installed version, if available..
392 This prevents dselect from making it obsolete. */
393 pkgCache::VerIterator V
= Plcy
.GetCandidateVer(P
);
396 if (P
->CurrentVer
== 0)
401 pkgCache::VerFileIterator VF
= V
.FileList();
402 for (; VF
.end() == false ; VF
++)
403 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
406 /* Okay, here we have a bit of a problem.. The policy has selected the
407 currently installed package - however it only exists in the
408 status file.. We need to write out something or dselect will mark
409 the package as obsolete! Thus we emit the status file entry, but
410 below we remove the status line to make it valid for the
411 available file. However! We only do this if their do exist *any*
412 non-source versions of the package - that way the dselect obsolete
413 handling works OK. */
414 if (VF
.end() == true)
416 for (pkgCache::VerIterator Cur
= P
.VersionList(); Cur
.end() != true; Cur
++)
418 for (VF
= Cur
.FileList(); VF
.end() == false; VF
++)
420 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
427 if (VF
.end() == false)
435 LocalitySort(VFList
,Count
,sizeof(*VFList
));
437 // Iterate over all the package files and write them out.
438 char *Buffer
= new char[Cache
.HeaderP
->MaxVerFileSize
+10];
439 for (pkgCache::VerFile
**J
= VFList
; *J
!= 0;)
441 pkgCache::PkgFileIterator
File(Cache
,(*J
)->File
+ Cache
.PkgFileP
);
442 if (File
.IsOk() == false)
444 _error
->Error(_("Package file %s is out of sync."),File
.FileName());
448 FileFd
PkgF(File
.FileName(),FileFd::ReadOnly
);
449 if (_error
->PendingError() == true)
452 /* Write all of the records from this package file, since we
453 already did locality sorting we can now just seek through the
454 file in read order. We apply 1 more optimization here, since often
455 there will be < 1 byte gaps between records (for the \n) we read that
456 into the next buffer and offset a bit.. */
457 unsigned long Pos
= 0;
460 if ((*J
)->File
+ Cache
.PkgFileP
!= File
)
463 const pkgCache::VerFile
&VF
= **J
;
465 // Read the record and then write it out again.
466 unsigned long Jitter
= VF
.Offset
- Pos
;
469 if (PkgF
.Seek(VF
.Offset
) == false)
474 if (PkgF
.Read(Buffer
,VF
.Size
+ Jitter
) == false)
476 Buffer
[VF
.Size
+ Jitter
] = '\n';
479 if ((File
->Flags
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
)
482 TFRewriteData RW
[] = {{"Status",0},{"Config-Version",0},{}};
483 const char *Zero
= 0;
484 if (Tags
.Scan(Buffer
+Jitter
,VF
.Size
+1) == false ||
485 TFRewrite(stdout
,Tags
,&Zero
,RW
) == false)
487 _error
->Error("Internal Error, Unable to parse a package record");
494 if (fwrite(Buffer
+Jitter
,VF
.Size
+1,1,stdout
) != 1)
498 Pos
= VF
.Offset
+ VF
.Size
;
502 if (_error
->PendingError() == true)
508 return !_error
->PendingError();
511 // Depends - Print out a dependency tree /*{{{*/
512 // ---------------------------------------------------------------------
514 bool Depends(CommandLine
&CmdL
)
516 pkgCache
&Cache
= *GCache
;
517 SPtrArray
<unsigned> Colours
= new unsigned[Cache
.Head().PackageCount
];
518 memset(Colours
,0,sizeof(*Colours
)*Cache
.Head().PackageCount
);
520 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
522 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(*I
);
523 if (Pkg
.end() == true)
525 _error
->Warning(_("Unable to locate package %s"),*I
);
528 Colours
[Pkg
->ID
] = 1;
531 bool Recurse
= _config
->FindB("APT::Cache::RecurseDepends",false);
535 DidSomething
= false;
536 for (pkgCache::PkgIterator Pkg
= Cache
.PkgBegin(); Pkg
.end() == false; Pkg
++)
538 if (Colours
[Pkg
->ID
] != 1)
540 Colours
[Pkg
->ID
] = 2;
543 pkgCache::VerIterator Ver
= Pkg
.VersionList();
544 if (Ver
.end() == true)
546 cout
<< '<' << Pkg
.Name() << '>' << endl
;
550 cout
<< Pkg
.Name() << endl
;
552 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; D
++)
554 if ((D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
)
560 pkgCache::PkgIterator Trg
= D
.TargetPkg();
561 if (Trg
->VersionList
== 0)
562 cout
<< D
.DepType() << ": <" << Trg
.Name() << ">" << endl
;
564 cout
<< D
.DepType() << ": " << Trg
.Name() << endl
;
567 Colours
[D
.TargetPkg()->ID
]++;
569 // Display all solutions
570 SPtrArray
<pkgCache::Version
*> List
= D
.AllTargets();
571 pkgPrioSortList(Cache
,List
);
572 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
574 pkgCache::VerIterator
V(Cache
,*I
);
575 if (V
!= Cache
.VerP
+ V
.ParentPkg()->VersionList
||
576 V
->ParentPkg
== D
->Package
)
578 cout
<< " " << V
.ParentPkg().Name() << endl
;
581 Colours
[D
.ParentPkg()->ID
]++;
586 while (DidSomething
== true);
593 // xvcg - Generate a graph for xvcg /*{{{*/
594 // ---------------------------------------------------------------------
595 // Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
597 bool XVcg(CommandLine
&CmdL
)
599 pkgCache
&Cache
= *GCache
;
600 bool GivenOnly
= _config
->FindB("APT::Cache::GivenOnly",false);
602 /* Normal packages are boxes
603 Pure Provides are triangles
605 rhomb are missing packages*/
606 const char *Shapes
[] = {"ellipse","triangle","box","rhomb"};
608 /* Initialize the list of packages to show.
610 2 = To Show no recurse
611 3 = Emitted no recurse
614 enum States
{None
=0, ToShow
, ToShowNR
, DoneNR
, Done
};
615 enum TheFlags
{ForceNR
=(1<<0)};
616 unsigned char *Show
= new unsigned char[Cache
.Head().PackageCount
];
617 unsigned char *Flags
= new unsigned char[Cache
.Head().PackageCount
];
618 unsigned char *ShapeMap
= new unsigned char[Cache
.Head().PackageCount
];
620 // Show everything if no arguments given
621 if (CmdL
.FileList
[1] == 0)
622 for (unsigned long I
= 0; I
!= Cache
.Head().PackageCount
; I
++)
625 for (unsigned long I
= 0; I
!= Cache
.Head().PackageCount
; I
++)
627 memset(Flags
,0,sizeof(*Flags
)*Cache
.Head().PackageCount
);
630 for (pkgCache::PkgIterator Pkg
= Cache
.PkgBegin(); Pkg
.end() == false; Pkg
++)
632 if (Pkg
->VersionList
== 0)
635 if (Pkg
->ProvidesList
== 0)
636 ShapeMap
[Pkg
->ID
] = 0;
638 ShapeMap
[Pkg
->ID
] = 1;
643 if (Pkg
->ProvidesList
== 0)
644 ShapeMap
[Pkg
->ID
] = 2;
646 ShapeMap
[Pkg
->ID
] = 3;
650 // Load the list of packages from the command line into the show list
651 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
653 // Process per-package flags
658 if (P
.end()[-1] == '^')
664 if (P
.end()[-1] == ',')
668 // Locate the package
669 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(P
);
670 if (Pkg
.end() == true)
672 _error
->Warning(_("Unable to locate package %s"),*I
);
675 Show
[Pkg
->ID
] = ToShow
;
678 Flags
[Pkg
->ID
] |= ForceNR
;
682 cout
<< "graph: { title: \"packages\"" << endl
<<
683 "xmax: 700 ymax: 700 x: 30 y: 30" << endl
<<
684 "layout_downfactor: 8" << endl
;
690 for (pkgCache::PkgIterator Pkg
= Cache
.PkgBegin(); Pkg
.end() == false; Pkg
++)
692 // See we need to show this package
693 if (Show
[Pkg
->ID
] == None
|| Show
[Pkg
->ID
] >= DoneNR
)
696 //printf ("node: { title: \"%s\" label: \"%s\" }\n", Pkg.Name(), Pkg.Name());
699 if (Show
[Pkg
->ID
] == ToShowNR
|| (Flags
[Pkg
->ID
] & ForceNR
) == ForceNR
)
701 // Pure Provides and missing packages have no deps!
702 if (ShapeMap
[Pkg
->ID
] == 0 || ShapeMap
[Pkg
->ID
] == 1)
703 Show
[Pkg
->ID
] = Done
;
705 Show
[Pkg
->ID
] = DoneNR
;
708 Show
[Pkg
->ID
] = Done
;
711 // No deps to map out
712 if (Pkg
->VersionList
== 0 || Show
[Pkg
->ID
] == DoneNR
)
715 pkgCache::VerIterator Ver
= Pkg
.VersionList();
716 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; D
++)
718 // See if anything can meet this dep
719 // Walk along the actual package providing versions
721 pkgCache::PkgIterator DPkg
= D
.TargetPkg();
722 for (pkgCache::VerIterator I
= DPkg
.VersionList();
723 I
.end() == false && Hit
== false; I
++)
725 if (Cache
.VS
->CheckDep(I
.VerStr(),D
->CompareOp
,D
.TargetVer()) == true)
729 // Follow all provides
730 for (pkgCache::PrvIterator I
= DPkg
.ProvidesList();
731 I
.end() == false && Hit
== false; I
++)
733 if (Cache
.VS
->CheckDep(I
.ProvideVersion(),D
->CompareOp
,D
.TargetVer()) == false)
738 // Only graph critical deps
739 if (D
.IsCritical() == true)
741 printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg
.Name(), D
.TargetPkg().Name() );
743 // Colour the node for recursion
744 if (Show
[D
.TargetPkg()->ID
] <= DoneNR
)
746 /* If a conflicts does not meet anything in the database
747 then show the relation but do not recurse */
749 (D
->Type
== pkgCache::Dep::Conflicts
||
750 D
->Type
== pkgCache::Dep::Obsoletes
))
752 if (Show
[D
.TargetPkg()->ID
] == None
&&
753 Show
[D
.TargetPkg()->ID
] != ToShow
)
754 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
758 if (GivenOnly
== true && Show
[D
.TargetPkg()->ID
] != ToShow
)
759 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
761 Show
[D
.TargetPkg()->ID
] = ToShow
;
768 case pkgCache::Dep::Conflicts
:
769 printf("label: \"conflicts\" color: lightgreen }\n");
771 case pkgCache::Dep::Obsoletes
:
772 printf("label: \"obsoletes\" color: lightgreen }\n");
775 case pkgCache::Dep::PreDepends
:
776 printf("label: \"predepends\" color: blue }\n");
788 /* Draw the box colours after the fact since we can not tell what colour
789 they should be until everything is finished drawing */
790 for (pkgCache::PkgIterator Pkg
= Cache
.PkgBegin(); Pkg
.end() == false; Pkg
++)
792 if (Show
[Pkg
->ID
] < DoneNR
)
795 if (Show
[Pkg
->ID
] == DoneNR
)
796 printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg
.Name(), Pkg
.Name(),
797 Shapes
[ShapeMap
[Pkg
->ID
]]);
799 printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg
.Name(), Pkg
.Name(),
800 Shapes
[ShapeMap
[Pkg
->ID
]]);
810 // Dotty - Generate a graph for Dotty /*{{{*/
811 // ---------------------------------------------------------------------
812 /* Dotty is the graphvis program for generating graphs. It is a fairly
813 simple queuing algorithm that just writes dependencies and nodes.
814 http://www.research.att.com/sw/tools/graphviz/ */
815 bool Dotty(CommandLine
&CmdL
)
817 pkgCache
&Cache
= *GCache
;
818 bool GivenOnly
= _config
->FindB("APT::Cache::GivenOnly",false);
820 /* Normal packages are boxes
821 Pure Provides are triangles
823 Hexagons are missing packages*/
824 const char *Shapes
[] = {"hexagon","triangle","box","diamond"};
826 /* Initialize the list of packages to show.
828 2 = To Show no recurse
829 3 = Emitted no recurse
832 enum States
{None
=0, ToShow
, ToShowNR
, DoneNR
, Done
};
833 enum TheFlags
{ForceNR
=(1<<0)};
834 unsigned char *Show
= new unsigned char[Cache
.Head().PackageCount
];
835 unsigned char *Flags
= new unsigned char[Cache
.Head().PackageCount
];
836 unsigned char *ShapeMap
= new unsigned char[Cache
.Head().PackageCount
];
838 // Show everything if no arguments given
839 if (CmdL
.FileList
[1] == 0)
840 for (unsigned long I
= 0; I
!= Cache
.Head().PackageCount
; I
++)
843 for (unsigned long I
= 0; I
!= Cache
.Head().PackageCount
; I
++)
845 memset(Flags
,0,sizeof(*Flags
)*Cache
.Head().PackageCount
);
848 for (pkgCache::PkgIterator Pkg
= Cache
.PkgBegin(); Pkg
.end() == false; Pkg
++)
850 if (Pkg
->VersionList
== 0)
853 if (Pkg
->ProvidesList
== 0)
854 ShapeMap
[Pkg
->ID
] = 0;
856 ShapeMap
[Pkg
->ID
] = 1;
861 if (Pkg
->ProvidesList
== 0)
862 ShapeMap
[Pkg
->ID
] = 2;
864 ShapeMap
[Pkg
->ID
] = 3;
868 // Load the list of packages from the command line into the show list
869 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
871 // Process per-package flags
876 if (P
.end()[-1] == '^')
882 if (P
.end()[-1] == ',')
886 // Locate the package
887 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(P
);
888 if (Pkg
.end() == true)
890 _error
->Warning(_("Unable to locate package %s"),*I
);
893 Show
[Pkg
->ID
] = ToShow
;
896 Flags
[Pkg
->ID
] |= ForceNR
;
900 printf("digraph packages {\n");
901 printf("concentrate=true;\n");
902 printf("size=\"30,40\";\n");
908 for (pkgCache::PkgIterator Pkg
= Cache
.PkgBegin(); Pkg
.end() == false; Pkg
++)
910 // See we need to show this package
911 if (Show
[Pkg
->ID
] == None
|| Show
[Pkg
->ID
] >= DoneNR
)
915 if (Show
[Pkg
->ID
] == ToShowNR
|| (Flags
[Pkg
->ID
] & ForceNR
) == ForceNR
)
917 // Pure Provides and missing packages have no deps!
918 if (ShapeMap
[Pkg
->ID
] == 0 || ShapeMap
[Pkg
->ID
] == 1)
919 Show
[Pkg
->ID
] = Done
;
921 Show
[Pkg
->ID
] = DoneNR
;
924 Show
[Pkg
->ID
] = Done
;
927 // No deps to map out
928 if (Pkg
->VersionList
== 0 || Show
[Pkg
->ID
] == DoneNR
)
931 pkgCache::VerIterator Ver
= Pkg
.VersionList();
932 for (pkgCache::DepIterator D
= Ver
.DependsList(); D
.end() == false; D
++)
934 // See if anything can meet this dep
935 // Walk along the actual package providing versions
937 pkgCache::PkgIterator DPkg
= D
.TargetPkg();
938 for (pkgCache::VerIterator I
= DPkg
.VersionList();
939 I
.end() == false && Hit
== false; I
++)
941 if (Cache
.VS
->CheckDep(I
.VerStr(),D
->CompareOp
,D
.TargetVer()) == true)
945 // Follow all provides
946 for (pkgCache::PrvIterator I
= DPkg
.ProvidesList();
947 I
.end() == false && Hit
== false; I
++)
949 if (Cache
.VS
->CheckDep(I
.ProvideVersion(),D
->CompareOp
,D
.TargetVer()) == false)
953 // Only graph critical deps
954 if (D
.IsCritical() == true)
956 printf("\"%s\" -> \"%s\"",Pkg
.Name(),D
.TargetPkg().Name());
958 // Colour the node for recursion
959 if (Show
[D
.TargetPkg()->ID
] <= DoneNR
)
961 /* If a conflicts does not meet anything in the database
962 then show the relation but do not recurse */
964 (D
->Type
== pkgCache::Dep::Conflicts
||
965 D
->Type
== pkgCache::Dep::Obsoletes
))
967 if (Show
[D
.TargetPkg()->ID
] == None
&&
968 Show
[D
.TargetPkg()->ID
] != ToShow
)
969 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
973 if (GivenOnly
== true && Show
[D
.TargetPkg()->ID
] != ToShow
)
974 Show
[D
.TargetPkg()->ID
] = ToShowNR
;
976 Show
[D
.TargetPkg()->ID
] = ToShow
;
983 case pkgCache::Dep::Conflicts
:
984 case pkgCache::Dep::Obsoletes
:
985 printf("[color=springgreen];\n");
988 case pkgCache::Dep::PreDepends
:
989 printf("[color=blue];\n");
1001 /* Draw the box colours after the fact since we can not tell what colour
1002 they should be until everything is finished drawing */
1003 for (pkgCache::PkgIterator Pkg
= Cache
.PkgBegin(); Pkg
.end() == false; Pkg
++)
1005 if (Show
[Pkg
->ID
] < DoneNR
)
1008 // Orange box for early recursion stoppage
1009 if (Show
[Pkg
->ID
] == DoneNR
)
1010 printf("\"%s\" [color=orange,shape=%s];\n",Pkg
.Name(),
1011 Shapes
[ShapeMap
[Pkg
->ID
]]);
1013 printf("\"%s\" [shape=%s];\n",Pkg
.Name(),
1014 Shapes
[ShapeMap
[Pkg
->ID
]]);
1021 // DoAdd - Perform an adding operation /*{{{*/
1022 // ---------------------------------------------------------------------
1024 bool DoAdd(CommandLine
&CmdL
)
1026 return _error
->Error("Unimplemented");
1028 // Make sure there is at least one argument
1029 if (CmdL
.FileSize() <= 1)
1030 return _error
->Error("You must give at least one file name");
1033 FileFd
CacheF(_config
->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny
);
1034 if (_error
->PendingError() == true)
1037 DynamicMMap
Map(CacheF
,MMap::Public
);
1038 if (_error
->PendingError() == true)
1041 OpTextProgress
Progress(*_config
);
1042 pkgCacheGenerator
Gen(Map
,Progress
);
1043 if (_error
->PendingError() == true)
1046 unsigned long Length
= CmdL
.FileSize() - 1;
1047 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1049 Progress
.OverallProgress(I
- CmdL
.FileList
,Length
,1,"Generating cache");
1050 Progress
.SubProgress(Length
);
1053 FileFd
TagF(*I
,FileFd::ReadOnly
);
1054 debListParser
Parser(TagF
);
1055 if (_error
->PendingError() == true)
1056 return _error
->Error("Problem opening %s",*I
);
1058 if (Gen
.SelectFile(*I
,"") == false)
1059 return _error
->Error("Problem with SelectFile");
1061 if (Gen
.MergeList(Parser
) == false)
1062 return _error
->Error("Problem with MergeList");
1066 GCache
= &Gen
.GetCache();
1073 // DisplayRecord - Displays the complete record for the package /*{{{*/
1074 // ---------------------------------------------------------------------
1075 /* This displays the package record from the proper package index file.
1076 It is not used by DumpAvail for performance reasons. */
1077 bool DisplayRecord(pkgCache::VerIterator V
)
1079 // Find an appropriate file
1080 pkgCache::VerFileIterator Vf
= V
.FileList();
1081 for (; Vf
.end() == false; Vf
++)
1082 if ((Vf
.File()->Flags
& pkgCache::Flag::NotSource
) == 0)
1084 if (Vf
.end() == true)
1087 // Check and load the package list file
1088 pkgCache::PkgFileIterator I
= Vf
.File();
1089 if (I
.IsOk() == false)
1090 return _error
->Error(_("Package file %s is out of sync."),I
.FileName());
1092 FileFd
PkgF(I
.FileName(),FileFd::ReadOnly
);
1093 if (_error
->PendingError() == true)
1096 // Read the record and then write it out again.
1097 unsigned char *Buffer
= new unsigned char[GCache
->HeaderP
->MaxVerFileSize
+1];
1098 Buffer
[V
.FileList()->Size
] = '\n';
1099 if (PkgF
.Seek(V
.FileList()->Offset
) == false ||
1100 PkgF
.Read(Buffer
,V
.FileList()->Size
) == false ||
1101 write(STDOUT_FILENO
,Buffer
,V
.FileList()->Size
+1) != V
.FileList()->Size
+1)
1112 // Search - Perform a search /*{{{*/
1113 // ---------------------------------------------------------------------
1114 /* This searches the package names and pacakge descriptions for a pattern */
1117 pkgCache::VerFile
*Vf
;
1121 bool Search(CommandLine
&CmdL
)
1123 pkgCache
&Cache
= *GCache
;
1124 bool ShowFull
= _config
->FindB("APT::Cache::ShowFull",false);
1125 bool NamesOnly
= _config
->FindB("APT::Cache::NamesOnly",false);
1126 unsigned NumPatterns
= CmdL
.FileSize() -1;
1128 pkgDepCache::Policy Plcy
;
1130 // Make sure there is at least one argument
1131 if (NumPatterns
< 1)
1132 return _error
->Error(_("You must give exactly one pattern"));
1134 // Compile the regex pattern
1135 regex_t
*Patterns
= new regex_t
[NumPatterns
];
1136 memset(Patterns
,0,sizeof(*Patterns
)*NumPatterns
);
1137 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1139 if (regcomp(&Patterns
[I
],CmdL
.FileList
[I
+1],REG_EXTENDED
| REG_ICASE
|
1143 regfree(&Patterns
[I
]);
1144 return _error
->Error("Regex compilation error");
1148 // Create the text record parser
1149 pkgRecords
Recs(Cache
);
1150 if (_error
->PendingError() == true)
1152 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1153 regfree(&Patterns
[I
]);
1157 ExVerFile
*VFList
= new ExVerFile
[Cache
.HeaderP
->PackageCount
+1];
1158 memset(VFList
,0,sizeof(*VFList
)*Cache
.HeaderP
->PackageCount
+1);
1160 // Map versions that we want to write out onto the VerList array.
1161 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
1163 VFList
[P
->ID
].NameMatch
= NumPatterns
!= 0;
1164 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1166 if (regexec(&Patterns
[I
],P
.Name(),0,0,0) == 0)
1167 VFList
[P
->ID
].NameMatch
&= true;
1169 VFList
[P
->ID
].NameMatch
= false;
1172 // Doing names only, drop any that dont match..
1173 if (NamesOnly
== true && VFList
[P
->ID
].NameMatch
== false)
1176 // Find the proper version to use.
1177 pkgCache::VerIterator V
= Plcy
.GetCandidateVer(P
);
1178 if (V
.end() == false)
1179 VFList
[P
->ID
].Vf
= V
.FileList();
1182 // Include all the packages that provide matching names too
1183 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
1185 if (VFList
[P
->ID
].NameMatch
== false)
1188 for (pkgCache::PrvIterator Prv
= P
.ProvidesList() ; Prv
.end() == false; Prv
++)
1190 pkgCache::VerIterator V
= Plcy
.GetCandidateVer(Prv
.OwnerPkg());
1191 if (V
.end() == false)
1193 VFList
[Prv
.OwnerPkg()->ID
].Vf
= V
.FileList();
1194 VFList
[Prv
.OwnerPkg()->ID
].NameMatch
= true;
1199 LocalitySort(&VFList
->Vf
,Cache
.HeaderP
->PackageCount
,sizeof(*VFList
));
1201 // Iterate over all the version records and check them
1202 for (ExVerFile
*J
= VFList
; J
->Vf
!= 0; J
++)
1204 pkgRecords::Parser
&P
= Recs
.Lookup(pkgCache::VerFileIterator(Cache
,J
->Vf
));
1207 if (J
->NameMatch
== false)
1209 string LongDesc
= P
.LongDesc();
1210 Match
= NumPatterns
!= 0;
1211 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1213 if (regexec(&Patterns
[I
],LongDesc
.c_str(),0,0,0) == 0)
1222 if (ShowFull
== true)
1226 P
.GetRec(Start
,End
);
1227 fwrite(Start
,End
-Start
,1,stdout
);
1231 printf("%s - %s\n",P
.Name().c_str(),P
.ShortDesc().c_str());
1236 for (unsigned I
= 0; I
!= NumPatterns
; I
++)
1237 regfree(&Patterns
[I
]);
1239 return _error
->Error("Write to stdout failed");
1243 // ShowPackage - Dump the package record to the screen /*{{{*/
1244 // ---------------------------------------------------------------------
1246 bool ShowPackage(CommandLine
&CmdL
)
1248 pkgCache
&Cache
= *GCache
;
1249 pkgDepCache::Policy Plcy
;
1251 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1253 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(*I
);
1254 if (Pkg
.end() == true)
1256 _error
->Warning(_("Unable to locate package %s"),*I
);
1260 // Find the proper version to use.
1261 if (_config
->FindB("APT::Cache::AllVersions","true") == true)
1263 pkgCache::VerIterator V
;
1264 for (V
= Pkg
.VersionList(); V
.end() == false; V
++)
1266 if (DisplayRecord(V
) == false)
1272 pkgCache::VerIterator V
= Plcy
.GetCandidateVer(Pkg
);
1273 if (V
.end() == true || V
.FileList().end() == true)
1275 if (DisplayRecord(V
) == false)
1282 // ShowPkgNames - Show package names /*{{{*/
1283 // ---------------------------------------------------------------------
1284 /* This does a prefix match on the first argument */
1285 bool ShowPkgNames(CommandLine
&CmdL
)
1287 pkgCache
&Cache
= *GCache
;
1288 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1289 bool All
= _config
->FindB("APT::Cache::AllNames","false");
1291 if (CmdL
.FileList
[1] != 0)
1293 for (;I
.end() != true; I
++)
1295 if (All
== false && I
->VersionList
== 0)
1298 if (strncmp(I
.Name(),CmdL
.FileList
[1],strlen(CmdL
.FileList
[1])) == 0)
1299 cout
<< I
.Name() << endl
;
1306 for (;I
.end() != true; I
++)
1308 if (All
== false && I
->VersionList
== 0)
1310 cout
<< I
.Name() << endl
;
1316 // ShowSrcPackage - Show source package records /*{{{*/
1317 // ---------------------------------------------------------------------
1319 bool ShowSrcPackage(CommandLine
&CmdL
)
1322 List
.ReadMainList();
1324 // Create the text record parsers
1325 pkgSrcRecords
SrcRecs(List
);
1326 if (_error
->PendingError() == true)
1329 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1333 pkgSrcRecords::Parser
*Parse
;
1334 while ((Parse
= SrcRecs
.Find(*I
,false)) != 0)
1335 cout
<< Parse
->AsStr() << endl
;;
1340 // Policy - Show the results of the preferences file /*{{{*/
1341 // ---------------------------------------------------------------------
1343 bool Policy(CommandLine
&CmdL
)
1346 return _error
->Error("Generate must be enabled for this function");
1348 pkgCache
&Cache
= *GCache
;
1349 pkgPolicy
Plcy(&Cache
);
1350 if (ReadPinFile(Plcy
) == false)
1353 // Print out all of the package files
1354 if (CmdL
.FileList
[1] == 0)
1356 cout
<< _("Package Files:") << endl
;
1357 for (pkgCache::PkgFileIterator F
= Cache
.FileBegin(); F
.end() == false; F
++)
1359 // Locate the associated index files so we can derive a description
1361 if (SrcList
->FindIndex(F
,Indx
) == false &&
1362 _system
->FindIndex(F
,Indx
) == false)
1363 return _error
->Error(_("Cache is out of sync, can't x-ref a package file"));
1364 printf(_("%4i %s\n"),
1365 Plcy
.GetPriority(F
),Indx
->Describe(true).c_str());
1367 // Print the reference information for the package
1368 string Str
= F
.RelStr();
1369 if (Str
.empty() == false)
1370 printf(" release %s\n",F
.RelStr().c_str());
1371 if (F
.Site() != 0 && F
.Site()[0] != 0)
1372 printf(" origin %s\n",F
.Site());
1375 // Show any packages have explicit pins
1376 cout
<< _("Pinned Packages:") << endl
;
1377 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1378 for (;I
.end() != true; I
++)
1380 if (Plcy
.GetPriority(I
) == 0)
1383 // Print the package name and the version we are forcing to
1384 cout
<< " " << I
.Name() << " -> ";
1386 pkgCache::VerIterator V
= Plcy
.GetMatch(I
);
1387 if (V
.end() == true)
1388 cout
<< _("(not found)") << endl
;
1390 cout
<< V
.VerStr() << endl
;
1396 // Print out detailed information for each package
1397 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
1399 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(*I
);
1400 if (Pkg
.end() == true)
1402 _error
->Warning(_("Unable to locate package %s"),*I
);
1406 cout
<< Pkg
.Name() << ":" << endl
;
1408 // Installed version
1409 cout
<< _(" Installed: ");
1410 if (Pkg
->CurrentVer
== 0)
1411 cout
<< _("(none)") << endl
;
1413 cout
<< Pkg
.CurrentVer().VerStr() << endl
;
1415 // Candidate Version
1416 cout
<< _(" Candidate: ");
1417 pkgCache::VerIterator V
= Plcy
.GetCandidateVer(Pkg
);
1418 if (V
.end() == true)
1419 cout
<< _("(none)") << endl
;
1421 cout
<< V
.VerStr() << endl
;
1424 if (Plcy
.GetPriority(Pkg
) != 0)
1426 cout
<< _(" Package Pin: ");
1427 V
= Plcy
.GetMatch(Pkg
);
1428 if (V
.end() == true)
1429 cout
<< _("(not found)") << endl
;
1431 cout
<< V
.VerStr() << endl
;
1434 // Show the priority tables
1435 cout
<< _(" Version Table:") << endl
;
1436 for (V
= Pkg
.VersionList(); V
.end() == false; V
++)
1438 if (Pkg
.CurrentVer() == V
)
1439 cout
<< " *** " << V
.VerStr();
1441 cout
<< " " << V
.VerStr();
1442 cout
<< " " << Plcy
.GetPriority(Pkg
) << endl
;
1443 for (pkgCache::VerFileIterator VF
= V
.FileList(); VF
.end() == false; VF
++)
1445 // Locate the associated index files so we can derive a description
1447 if (SrcList
->FindIndex(VF
.File(),Indx
) == false &&
1448 _system
->FindIndex(VF
.File(),Indx
) == false)
1449 return _error
->Error(_("Cache is out of sync, can't x-ref a package file"));
1450 printf(_(" %4i %s\n"),Plcy
.GetPriority(VF
.File()),
1451 Indx
->Describe(true).c_str());
1459 // GenCaches - Call the main cache generator /*{{{*/
1460 // ---------------------------------------------------------------------
1462 bool GenCaches(CommandLine
&Cmd
)
1464 OpTextProgress
Progress(*_config
);
1467 if (List
.ReadMainList() == false)
1469 return pkgMakeStatusCache(List
,Progress
);
1472 // ShowHelp - Show a help screen /*{{{*/
1473 // ---------------------------------------------------------------------
1475 bool ShowHelp(CommandLine
&Cmd
)
1477 ioprintf(cout
,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE
,VERSION
,
1478 COMMON_OS
,COMMON_CPU
,__DATE__
,__TIME__
);
1481 _("Usage: apt-cache [options] command\n"
1482 " apt-cache [options] add file1 [file1 ...]\n"
1483 " apt-cache [options] showpkg pkg1 [pkg2 ...]\n"
1484 " apt-cache [options] showsrc pkg1 [pkg2 ...]\n"
1486 "apt-cache is a low-level tool used to manipulate APT's binary\n"
1487 "cache files, and query information from them\n"
1490 " add - Add a package file to the source cache\n"
1491 " gencaches - Build both the package and source cache\n"
1492 " showpkg - Show some general information for a single package\n"
1493 " showsrc - Show source records\n"
1494 " stats - Show some basic statistics\n"
1495 " dump - Show the entire file in a terse form\n"
1496 " dumpavail - Print an available file to stdout\n"
1497 " unmet - Show unmet dependencies\n"
1498 " search - Search the package list for a regex pattern\n"
1499 " show - Show a readable record for the package\n"
1500 " depends - Show raw dependency information for a package\n"
1501 " pkgnames - List the names of all packages\n"
1502 " dotty - Generate package graphs for GraphVis\n"
1503 " xvcg - Generate package graphs for xvcg\n"
1504 " policy - Show policy settings\n"
1507 " -h This help text.\n"
1508 " -p=? The package cache.\n"
1509 " -s=? The source cache.\n"
1510 " -q Disable progress indicator.\n"
1511 " -i Show only important deps for the unmet command.\n"
1512 " -c=? Read this configuration file\n"
1513 " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
1514 "See the apt-cache(8) and apt.conf(5) manual pages for more information.\n");
1518 // CacheInitialize - Initialize things for apt-cache /*{{{*/
1519 // ---------------------------------------------------------------------
1521 void CacheInitialize()
1523 _config
->Set("quiet",0);
1524 _config
->Set("help",false);
1528 int main(int argc
,const char *argv
[])
1530 CommandLine::Args Args
[] = {
1531 {'h',"help","help",0},
1532 {'v',"version","version",0},
1533 {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg
},
1534 {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg
},
1535 {'q',"quiet","quiet",CommandLine::IntLevel
},
1536 {'i',"important","APT::Cache::Important",0},
1537 {'f',"full","APT::Cache::ShowFull",0},
1538 {'g',"generate","APT::Cache::Generate",0},
1539 {'a',"all-versions","APT::Cache::AllVersions",0},
1540 {0,"names-only","APT::Cache::NamesOnly",0},
1541 {'n',"all-names","APT::Cache::AllNames",0},
1542 {0,"recurse","APT::Cache::RecurseDepends",0},
1543 {'c',"config-file",0,CommandLine::ConfigFile
},
1544 {'o',"option",0,CommandLine::ArbItem
},
1546 CommandLine::Dispatch CmdsA
[] = {{"help",&ShowHelp
},
1548 {"gencaches",&GenCaches
},
1549 {"showsrc",&ShowSrcPackage
},
1551 CommandLine::Dispatch CmdsB
[] = {{"showpkg",&DumpPackage
},
1554 {"dumpavail",&DumpAvail
},
1557 {"depends",&Depends
},
1560 {"show",&ShowPackage
},
1561 {"pkgnames",&ShowPkgNames
},
1567 // Set up gettext support
1568 setlocale(LC_ALL
,"");
1569 textdomain(PACKAGE
);
1571 // Parse the command line and initialize the package library
1572 CommandLine
CmdL(Args
,_config
);
1573 if (pkgInitConfig(*_config
) == false ||
1574 CmdL
.Parse(argc
,argv
) == false ||
1575 pkgInitSystem(*_config
,_system
) == false)
1577 _error
->DumpErrors();
1581 // See if the help should be shown
1582 if (_config
->FindB("help") == true ||
1583 CmdL
.FileSize() == 0)
1589 // Deal with stdout not being a tty
1590 if (ttyname(STDOUT_FILENO
) == 0 && _config
->FindI("quiet",0) < 1)
1591 _config
->Set("quiet","1");
1593 if (CmdL
.DispatchArg(CmdsA
,false) == false && _error
->PendingError() == false)
1596 if (_config
->FindB("APT::Cache::Generate",true) == false)
1598 Map
= new MMap(*new FileFd(_config
->FindFile("Dir::Cache::pkgcache"),
1599 FileFd::ReadOnly
),MMap::Public
|MMap::ReadOnly
);
1603 // Open the cache file
1604 SrcList
= new pkgSourceList
;
1605 SrcList
->ReadMainList();
1607 // Generate it and map it
1609 pkgMakeStatusCache(*SrcList
,Prog
,&Map
,true);
1612 if (_error
->PendingError() == false)
1614 pkgCache
Cache(Map
);
1616 if (_error
->PendingError() == false)
1617 CmdL
.DispatchArg(CmdsB
);
1622 // Print any errors or warnings found during parsing
1623 if (_error
->empty() == false)
1625 bool Errors
= _error
->PendingError();
1626 _error
->DumpErrors();
1627 return Errors
== true?100:0;