]> git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
Change log updates
[apt.git] / cmdline / apt-cache.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-cache.cc,v 1.34 1999/04/19 02:35:38 jgg Exp $
4 /* ######################################################################
5
6 apt-cache - Manages the cache files
7
8 apt-cache provides some functions fo manipulating the cache files.
9 It uses the command line interface common to all the APT tools. The
10 only really usefull function right now is dumpavail which is used
11 by the dselect method. Everything else is ment as a debug aide.
12
13 Returns 100 on failure, 0 on success.
14
15 ##################################################################### */
16 /*}}}*/
17 // Include Files /*{{{*/
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/pkgcachegen.h>
20 #include <apt-pkg/deblistparser.h>
21 #include <apt-pkg/init.h>
22 #include <apt-pkg/progress.h>
23 #include <apt-pkg/sourcelist.h>
24 #include <apt-pkg/cmndline.h>
25 #include <apt-pkg/strutl.h>
26 #include <apt-pkg/pkgrecords.h>
27 #include <config.h>
28
29 #include <iostream.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <regex.h>
33 /*}}}*/
34
35 pkgCache *GCache = 0;
36
37 // UnMet - Show unmet dependencies /*{{{*/
38 // ---------------------------------------------------------------------
39 /* */
40 bool UnMet(CommandLine &CmdL)
41 {
42 pkgCache &Cache = *GCache;
43 bool Important = _config->FindB("APT::Cache::Important",false);
44
45 for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
46 {
47 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
48 {
49 bool Header = false;
50 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false;)
51 {
52 // Collect or groups
53 pkgCache::DepIterator Start;
54 pkgCache::DepIterator End;
55 D.GlobOr(Start,End);
56
57 /* cout << "s: Check " << Start.TargetPkg().Name() << ',' <<
58 End.TargetPkg().Name() << endl;*/
59
60 // Skip conflicts and replaces
61 if (End->Type != pkgCache::Dep::PreDepends &&
62 End->Type != pkgCache::Dep::Depends &&
63 End->Type != pkgCache::Dep::Suggests &&
64 End->Type != pkgCache::Dep::Recommends)
65 continue;
66
67 // Important deps only
68 if (Important == true)
69 if (End->Type != pkgCache::Dep::PreDepends &&
70 End->Type != pkgCache::Dep::Depends)
71 continue;
72
73 // Verify the or group
74 bool OK = false;
75 pkgCache::DepIterator RealStart = Start;
76 do
77 {
78 // See if this dep is Ok
79 pkgCache::Version **VList = Start.AllTargets();
80 if (*VList != 0)
81 {
82 OK = true;
83 delete [] VList;
84 break;
85 }
86 delete [] VList;
87
88 if (Start == End)
89 break;
90 Start++;
91 }
92 while (1);
93
94 // The group is OK
95 if (OK == true)
96 continue;
97
98 // Oops, it failed..
99 if (Header == false)
100 cout << "Package " << P.Name() << " version " <<
101 V.VerStr() << " has an unmet dep:" << endl;
102 Header = true;
103
104 // Print out the dep type
105 cout << " " << End.DepType() << ": ";
106
107 // Show the group
108 Start = RealStart;
109 do
110 {
111 cout << Start.TargetPkg().Name();
112 if (Start.TargetVer() != 0)
113 cout << " (" << Start.CompType() << " " << Start.TargetVer() <<
114 ")";
115 if (Start == End)
116 break;
117 cout << " | ";
118 Start++;
119 }
120 while (1);
121
122 cout << endl;
123 }
124 }
125 }
126 return true;
127 }
128 /*}}}*/
129 // DumpPackage - Show a dump of a package record /*{{{*/
130 // ---------------------------------------------------------------------
131 /* */
132 bool DumpPackage(CommandLine &CmdL)
133 {
134 pkgCache &Cache = *GCache;
135 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
136 {
137 pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
138 if (Pkg.end() == true)
139 {
140 _error->Warning("Unable to locate package %s",*I);
141 continue;
142 }
143
144 cout << "Package: " << Pkg.Name() << endl;
145 cout << "Versions: ";
146 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
147 {
148 cout << Cur.VerStr();
149 for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; Vf++)
150 cout << "(" << Vf.File().FileName() << ")";
151 cout << ',';
152 }
153
154 cout << endl;
155
156 cout << "Reverse Depends: " << endl;
157 for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++)
158 cout << " " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name() << endl;
159
160 cout << "Dependencies: " << endl;
161 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
162 {
163 cout << Cur.VerStr() << " - ";
164 for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++)
165 cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << Dep.TargetVer() << ") ";
166 cout << endl;
167 }
168
169 cout << "Provides: " << endl;
170 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
171 {
172 cout << Cur.VerStr() << " - ";
173 for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++)
174 cout << Prv.ParentPkg().Name() << " ";
175 cout << endl;
176 }
177 cout << "Reverse Provides: " << endl;
178 for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; Prv++)
179 cout << Prv.OwnerPkg().Name() << " " << Prv.OwnerVer().VerStr();
180 cout << endl;
181
182 }
183
184 return true;
185 }
186 /*}}}*/
187 // Stats - Dump some nice statistics /*{{{*/
188 // ---------------------------------------------------------------------
189 /* */
190 bool Stats(CommandLine &Cmd)
191 {
192 pkgCache &Cache = *GCache;
193 cout << "Total Package Names : " << Cache.Head().PackageCount << " (" <<
194 SizeToStr(Cache.Head().PackageCount*Cache.Head().PackageSz) << ')' << endl;
195 pkgCache::PkgIterator I = Cache.PkgBegin();
196
197 int Normal = 0;
198 int Virtual = 0;
199 int NVirt = 0;
200 int DVirt = 0;
201 int Missing = 0;
202 for (;I.end() != true; I++)
203 {
204 if (I->VersionList != 0 && I->ProvidesList == 0)
205 {
206 Normal++;
207 continue;
208 }
209
210 if (I->VersionList != 0 && I->ProvidesList != 0)
211 {
212 NVirt++;
213 continue;
214 }
215
216 if (I->VersionList == 0 && I->ProvidesList != 0)
217 {
218 // Only 1 provides
219 if (I.ProvidesList()->NextProvides == 0)
220 {
221 DVirt++;
222 }
223 else
224 Virtual++;
225 continue;
226 }
227 if (I->VersionList == 0 && I->ProvidesList == 0)
228 {
229 Missing++;
230 continue;
231 }
232 }
233 cout << " Normal Packages: " << Normal << endl;
234 cout << " Pure Virtual Packages: " << Virtual << endl;
235 cout << " Single Virtual Packages: " << DVirt << endl;
236 cout << " Mixed Virtual Packages: " << NVirt << endl;
237 cout << " Missing: " << Missing << endl;
238
239 cout << "Total Distinct Versions: " << Cache.Head().VersionCount << " (" <<
240 SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl;
241 cout << "Total Dependencies: " << Cache.Head().DependsCount << " (" <<
242 SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl;
243
244 cout << "Total Ver/File relations: " << Cache.Head().VerFileCount << " (" <<
245 SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl;
246 cout << "Total Provides Mappings: " << Cache.Head().ProvidesCount << " (" <<
247 SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl;
248
249 // String list stats
250 unsigned long Size = 0;
251 unsigned long Count = 0;
252 for (pkgCache::StringItem *I = Cache.StringItemP + Cache.Head().StringList;
253 I!= Cache.StringItemP; I = Cache.StringItemP + I->NextItem)
254 {
255 Count++;
256 Size += strlen(Cache.StrP + I->String);
257 }
258 cout << "Total Globbed Strings: " << Count << " (" << SizeToStr(Size) << ')' << endl;
259
260 unsigned long Slack = 0;
261 for (int I = 0; I != 7; I++)
262 Slack += Cache.Head().Pools[I].ItemSize*Cache.Head().Pools[I].Count;
263 cout << "Total Slack space: " << SizeToStr(Slack) << endl;
264
265 unsigned long Total = 0;
266 Total = Slack + Size + Cache.Head().DependsCount*Cache.Head().DependencySz +
267 Cache.Head().VersionCount*Cache.Head().VersionSz +
268 Cache.Head().PackageCount*Cache.Head().PackageSz +
269 Cache.Head().VerFileCount*Cache.Head().VerFileSz +
270 Cache.Head().ProvidesCount*Cache.Head().ProvidesSz;
271 cout << "Total Space Accounted for: " << SizeToStr(Total) << endl;
272
273 return true;
274 }
275 /*}}}*/
276 // Check - Check some things about the cache /*{{{*/
277 // ---------------------------------------------------------------------
278 /* Debug aide mostly */
279 bool Check(CommandLine &Cmd)
280 {
281 pkgCache &Cache = *GCache;
282 pkgCache::PkgIterator Pkg = Cache.PkgBegin();
283 for (;Pkg.end() != true; Pkg++)
284 {
285 if (Pkg.Section() == 0 && Pkg->VersionList != 0)
286 cout << "Bad section " << Pkg.Name() << endl;
287
288 for (pkgCache::VerIterator Cur = Pkg.VersionList();
289 Cur.end() != true; Cur++)
290 {
291 if (Cur->Priority < 1 || Cur->Priority > 5)
292 cout << "Bad prio " << Pkg.Name() << ',' << Cur.VerStr() << " == " << (int)Cur->Priority << endl;
293 }
294 }
295 return true;
296 }
297 /*}}}*/
298 // Dump - show everything /*{{{*/
299 // ---------------------------------------------------------------------
300 /* */
301 bool Dump(CommandLine &Cmd)
302 {
303 pkgCache &Cache = *GCache;
304 for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
305 {
306 cout << "Package: " << P.Name() << endl;
307 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
308 {
309 cout << " Version: " << V.VerStr() << endl;
310 cout << " File: " << V.FileList().File().FileName() << endl;
311 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
312 cout << " Depends: " << D.TargetPkg().Name() << ' ' << D.TargetVer() << endl;
313 }
314 }
315
316 for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++)
317 {
318 cout << "File: " << F.FileName() << endl;
319 cout << " Size: " << F->Size << endl;
320 cout << " ID: " << F->ID << endl;
321 cout << " Flags: " << F->Flags << endl;
322 cout << " Time: " << TimeRFC1123(F->mtime) << endl;
323 cout << " Archive: " << F.Archive() << endl;
324 cout << " Component: " << F.Component() << endl;
325 cout << " Version: " << F.Version() << endl;
326 cout << " Origin: " << F.Origin() << endl;
327 cout << " Label: " << F.Label() << endl;
328 cout << " Architecture: " << F.Architecture() << endl;
329 }
330
331 return true;
332 }
333 /*}}}*/
334 // DumpAvail - Print out the available list /*{{{*/
335 // ---------------------------------------------------------------------
336 /* This is needed to make dpkg --merge happy */
337 bool DumpAvail(CommandLine &Cmd)
338 {
339 pkgCache &Cache = *GCache;
340 unsigned char *Buffer = new unsigned char[Cache.HeaderP->MaxVerFileSize];
341
342 for (pkgCache::PkgFileIterator I = Cache.FileBegin(); I.end() == false; I++)
343 {
344 if ((I->Flags & pkgCache::Flag::NotSource) != 0)
345 continue;
346
347 if (I.IsOk() == false)
348 {
349 delete [] Buffer;
350 return _error->Error("Package file %s is out of sync.",I.FileName());
351 }
352
353 FileFd PkgF(I.FileName(),FileFd::ReadOnly);
354 if (_error->PendingError() == true)
355 {
356 delete [] Buffer;
357 return false;
358 }
359
360 /* Write all of the records from this package file, we search the entire
361 structure to find them */
362 for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
363 {
364 // Find the proper version to use. We should probably use the DepCache.
365 pkgCache::VerIterator V = Cache.GetCandidateVer(P,false);
366
367 if (V.end() == true || V.FileList().File() != I)
368 continue;
369
370 // Read the record and then write it out again.
371 if (PkgF.Seek(V.FileList()->Offset) == false ||
372 PkgF.Read(Buffer,V.FileList()->Size) == false ||
373 write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size)
374 {
375 delete [] Buffer;
376 return false;
377 }
378 }
379 }
380
381 return true;
382 }
383 /*}}}*/
384 // DoAdd - Perform an adding operation /*{{{*/
385 // ---------------------------------------------------------------------
386 /* */
387 bool DoAdd(CommandLine &CmdL)
388 {
389 // Make sure there is at least one argument
390 if (CmdL.FileSize() <= 1)
391 return _error->Error("You must give at least one file name");
392
393 // Open the cache
394 FileFd CacheF(_config->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny);
395 if (_error->PendingError() == true)
396 return false;
397
398 DynamicMMap Map(CacheF,MMap::Public);
399 if (_error->PendingError() == true)
400 return false;
401
402 OpTextProgress Progress(*_config);
403 pkgCacheGenerator Gen(Map,Progress);
404 if (_error->PendingError() == true)
405 return false;
406
407 unsigned long Length = CmdL.FileSize() - 1;
408 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
409 {
410 Progress.OverallProgress(I - CmdL.FileList,Length,1,"Generating cache");
411 Progress.SubProgress(Length);
412
413 // Do the merge
414 FileFd TagF(*I,FileFd::ReadOnly);
415 debListParser Parser(TagF);
416 if (_error->PendingError() == true)
417 return _error->Error("Problem opening %s",*I);
418
419 if (Gen.SelectFile(*I) == false)
420 return _error->Error("Problem with SelectFile");
421
422 if (Gen.MergeList(Parser) == false)
423 return _error->Error("Problem with MergeList");
424 }
425
426 Progress.Done();
427 GCache = &Gen.GetCache();
428 Stats(CmdL);
429
430 return true;
431 }
432 /*}}}*/
433 // DisplayRecord - Displays the complete record for the package /*{{{*/
434 // ---------------------------------------------------------------------
435 /* This displays the package record from the proper package index file.
436 It is not used by DumpAvail for performance reasons. */
437 bool DisplayRecord(pkgCache::VerIterator V)
438 {
439 // Find an appropriate file
440 pkgCache::VerFileIterator Vf = V.FileList();
441 for (; Vf.end() == false; Vf++)
442 if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
443 break;
444 if (Vf.end() == true)
445 Vf = V.FileList();
446
447 // Check and load the package list file
448 pkgCache::PkgFileIterator I = Vf.File();
449 if (I.IsOk() == false)
450 return _error->Error("Package file %s is out of sync.",I.FileName());
451
452 FileFd PkgF(I.FileName(),FileFd::ReadOnly);
453 if (_error->PendingError() == true)
454 return false;
455
456 // Read the record and then write it out again.
457 unsigned char *Buffer = new unsigned char[GCache->HeaderP->MaxVerFileSize];
458 if (PkgF.Seek(V.FileList()->Offset) == false ||
459 PkgF.Read(Buffer,V.FileList()->Size) == false ||
460 write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size)
461 {
462 delete [] Buffer;
463 return false;
464 }
465
466 delete [] Buffer;
467
468 return true;
469 }
470 /*}}}*/
471 // Search - Perform a search /*{{{*/
472 // ---------------------------------------------------------------------
473 /* This searches the package names and pacakge descriptions for a pattern */
474 bool Search(CommandLine &CmdL)
475 {
476 pkgCache &Cache = *GCache;
477 bool ShowFull = _config->FindB("APT::Cache::ShowFull",false);
478 bool NamesOnly = _config->FindB("APT::Cache::NamesOnly",false);
479
480 // Make sure there is at least one argument
481 if (CmdL.FileSize() != 2)
482 return _error->Error("You must give exactly one pattern");
483
484 // Compile the regex pattern
485 regex_t Pattern;
486 if (regcomp(&Pattern,CmdL.FileList[1],REG_EXTENDED | REG_ICASE |
487 REG_NOSUB) != 0)
488 return _error->Error("Regex compilation error");
489
490 // Create the text record parser
491 pkgRecords Recs(Cache);
492 if (_error->PendingError() == true)
493 return false;
494
495 // Search package names
496 pkgCache::PkgIterator I = Cache.PkgBegin();
497 for (;I.end() != true; I++)
498 {
499 // We search against the install version as that makes the most sense..
500 pkgCache::VerIterator V = Cache.GetCandidateVer(I);
501 if (V.end() == true)
502 continue;
503
504 pkgRecords::Parser &P = Recs.Lookup(V.FileList());
505
506 if (regexec(&Pattern,I.Name(),0,0,0) == 0 ||
507 (NamesOnly == false &&
508 regexec(&Pattern,P.LongDesc().c_str(),0,0,0) == 0))
509 {
510 if (ShowFull == true)
511 DisplayRecord(V);
512 else
513 cout << I.Name() << " - " << P.ShortDesc() << endl;
514 }
515 }
516
517 regfree(&Pattern);
518 return true;
519 }
520 /*}}}*/
521 // ShowPackage - Dump the package record to the screen /*{{{*/
522 // ---------------------------------------------------------------------
523 /* */
524 bool ShowPackage(CommandLine &CmdL)
525 {
526 pkgCache &Cache = *GCache;
527 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
528 {
529 pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
530 if (Pkg.end() == true)
531 {
532 _error->Warning("Unable to locate package %s",*I);
533 continue;
534 }
535
536 // Find the proper version to use. We should probably use the DepCache.
537 pkgCache::VerIterator V = Cache.GetCandidateVer(Pkg);
538 if (V.end() == true || V.FileList().end() == true)
539 continue;
540 if (DisplayRecord(V) == false)
541 return false;
542 }
543 return true;
544 }
545 /*}}}*/
546 // GenCaches - Call the main cache generator /*{{{*/
547 // ---------------------------------------------------------------------
548 /* */
549 bool GenCaches(CommandLine &Cmd)
550 {
551 OpTextProgress Progress(*_config);
552
553 pkgSourceList List;
554 List.ReadMainList();
555 return pkgMakeStatusCache(List,Progress);
556 }
557 /*}}}*/
558 // ShowHelp - Show a help screen /*{{{*/
559 // ---------------------------------------------------------------------
560 /* */
561 bool ShowHelp(CommandLine &Cmd)
562 {
563 cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE <<
564 " compiled on " << __DATE__ << " " << __TIME__ << endl;
565 if (_config->FindB("version") == true)
566 return 100;
567
568 cout << "Usage: apt-cache [options] command" << endl;
569 cout << " apt-cache [options] add file1 [file1 ...]" << endl;
570 cout << " apt-cache [options] showpkg pkg1 [pkg2 ...]" << endl;
571 cout << endl;
572 cout << "apt-cache is a low-level tool used to manipulate APT's binary" << endl;
573 cout << "cache files stored in " << _config->FindFile("Dir::Cache") << endl;
574 cout << "It is not ment for ordinary use only as a debug aide." << endl;
575 cout << endl;
576 cout << "Commands:" << endl;
577 cout << " add - Add an package file to the source cache" << endl;
578 cout << " gencaches - Build both the package and source cache" << endl;
579 cout << " showpkg - Show some general information for a single package" << endl;
580 cout << " stats - Show some basic statistics" << endl;
581 cout << " dump - Show the entire file in a terse form" << endl;
582 cout << " dumpavail - Print an available file to stdout" << endl;
583 cout << " unmet - Show unmet dependencies" << endl;
584 cout << " check - Check the cache a bit" << endl;
585 cout << " search - Search the package list for a regex pattern" << endl;
586 cout << " show - Show a readable record for the package" << endl;
587 cout << endl;
588 cout << "Options:" << endl;
589 cout << " -h This help text." << endl;
590 cout << " -p=? The package cache. [" << _config->FindFile("Dir::Cache::pkgcache") << ']' << endl;
591 cout << " -s=? The source cache. [" << _config->FindFile("Dir::Cache::srcpkgcache") << ']' << endl;
592 cout << " -q Disable progress indicator." << endl;
593 cout << " -i Show only important deps for the unmet command." << endl;
594 cout << " -c=? Read this configuration file" << endl;
595 cout << " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" << endl;
596 cout << "See the apt-cache(8) and apt.conf(5) manual pages for more information." << endl;
597 return 100;
598 }
599 /*}}}*/
600 // CacheInitialize - Initialize things for apt-cache /*{{{*/
601 // ---------------------------------------------------------------------
602 /* */
603 void CacheInitialize()
604 {
605 _config->Set("quiet",0);
606 _config->Set("help",false);
607 }
608 /*}}}*/
609
610 int main(int argc,const char *argv[])
611 {
612 CommandLine::Args Args[] = {
613 {'h',"help","help",0},
614 {'v',"version","version",0},
615 {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg},
616 {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg},
617 {'q',"quiet","quiet",CommandLine::IntLevel},
618 {'i',"important","APT::Cache::Important",0},
619 {'f',"full","APT::Cache::ShowFull",0},
620 {0,"names-only","APT::Cache::NamesOnly",0},
621 {'c',"config-file",0,CommandLine::ConfigFile},
622 {'o',"option",0,CommandLine::ArbItem},
623 {0,0,0,0}};
624 CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp},
625 {"add",&DoAdd},
626 {"gencaches",&GenCaches},
627 {0,0}};
628 CommandLine::Dispatch CmdsB[] = {{"showpkg",&DumpPackage},
629 {"stats",&Stats},
630 {"dump",&Dump},
631 {"dumpavail",&DumpAvail},
632 {"unmet",&UnMet},
633 {"check",&Check},
634 {"search",&Search},
635 {"show",&ShowPackage},
636 {0,0}};
637
638 CacheInitialize();
639
640 // Parse the command line and initialize the package library
641 CommandLine CmdL(Args,_config);
642 if (pkgInitialize(*_config) == false ||
643 CmdL.Parse(argc,argv) == false)
644 {
645 _error->DumpErrors();
646 return 100;
647 }
648
649 // See if the help should be shown
650 if (_config->FindB("help") == true ||
651 CmdL.FileSize() == 0)
652 return ShowHelp(CmdL);
653
654 // Deal with stdout not being a tty
655 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
656 _config->Set("quiet","1");
657
658 if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false)
659 {
660 // Open the cache file
661 pkgSourceList List;
662 List.ReadMainList();
663
664 // Generate it and map it
665 OpProgress Prog;
666 MMap *Map = pkgMakeStatusCacheMem(List,Prog);
667 if (_error->PendingError() == false)
668 {
669 pkgCache Cache(*Map);
670 GCache = &Cache;
671 if (_error->PendingError() == false)
672 CmdL.DispatchArg(CmdsB);
673 }
674 delete Map;
675 }
676
677 // Print any errors or warnings found during parsing
678 if (_error->empty() == false)
679 {
680 bool Errors = _error->PendingError();
681 _error->DumpErrors();
682 return Errors == true?100:0;
683 }
684
685 return 0;
686 }