]> git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
Fixed some more bugs
[apt.git] / cmdline / apt-cache.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-cache.cc,v 1.35 1999/05/11 05:45:10 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() << endl;
180 }
181
182 return true;
183 }
184 /*}}}*/
185 // Stats - Dump some nice statistics /*{{{*/
186 // ---------------------------------------------------------------------
187 /* */
188 bool Stats(CommandLine &Cmd)
189 {
190 pkgCache &Cache = *GCache;
191 cout << "Total Package Names : " << Cache.Head().PackageCount << " (" <<
192 SizeToStr(Cache.Head().PackageCount*Cache.Head().PackageSz) << ')' << endl;
193 pkgCache::PkgIterator I = Cache.PkgBegin();
194
195 int Normal = 0;
196 int Virtual = 0;
197 int NVirt = 0;
198 int DVirt = 0;
199 int Missing = 0;
200 for (;I.end() != true; I++)
201 {
202 if (I->VersionList != 0 && I->ProvidesList == 0)
203 {
204 Normal++;
205 continue;
206 }
207
208 if (I->VersionList != 0 && I->ProvidesList != 0)
209 {
210 NVirt++;
211 continue;
212 }
213
214 if (I->VersionList == 0 && I->ProvidesList != 0)
215 {
216 // Only 1 provides
217 if (I.ProvidesList()->NextProvides == 0)
218 {
219 DVirt++;
220 }
221 else
222 Virtual++;
223 continue;
224 }
225 if (I->VersionList == 0 && I->ProvidesList == 0)
226 {
227 Missing++;
228 continue;
229 }
230 }
231 cout << " Normal Packages: " << Normal << endl;
232 cout << " Pure Virtual Packages: " << Virtual << endl;
233 cout << " Single Virtual Packages: " << DVirt << endl;
234 cout << " Mixed Virtual Packages: " << NVirt << endl;
235 cout << " Missing: " << Missing << endl;
236
237 cout << "Total Distinct Versions: " << Cache.Head().VersionCount << " (" <<
238 SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl;
239 cout << "Total Dependencies: " << Cache.Head().DependsCount << " (" <<
240 SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl;
241
242 cout << "Total Ver/File relations: " << Cache.Head().VerFileCount << " (" <<
243 SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl;
244 cout << "Total Provides Mappings: " << Cache.Head().ProvidesCount << " (" <<
245 SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl;
246
247 // String list stats
248 unsigned long Size = 0;
249 unsigned long Count = 0;
250 for (pkgCache::StringItem *I = Cache.StringItemP + Cache.Head().StringList;
251 I!= Cache.StringItemP; I = Cache.StringItemP + I->NextItem)
252 {
253 Count++;
254 Size += strlen(Cache.StrP + I->String);
255 }
256 cout << "Total Globbed Strings: " << Count << " (" << SizeToStr(Size) << ')' << endl;
257
258 unsigned long Slack = 0;
259 for (int I = 0; I != 7; I++)
260 Slack += Cache.Head().Pools[I].ItemSize*Cache.Head().Pools[I].Count;
261 cout << "Total Slack space: " << SizeToStr(Slack) << endl;
262
263 unsigned long Total = 0;
264 Total = Slack + Size + Cache.Head().DependsCount*Cache.Head().DependencySz +
265 Cache.Head().VersionCount*Cache.Head().VersionSz +
266 Cache.Head().PackageCount*Cache.Head().PackageSz +
267 Cache.Head().VerFileCount*Cache.Head().VerFileSz +
268 Cache.Head().ProvidesCount*Cache.Head().ProvidesSz;
269 cout << "Total Space Accounted for: " << SizeToStr(Total) << endl;
270
271 return true;
272 }
273 /*}}}*/
274 // Check - Check some things about the cache /*{{{*/
275 // ---------------------------------------------------------------------
276 /* Debug aide mostly */
277 bool Check(CommandLine &Cmd)
278 {
279 pkgCache &Cache = *GCache;
280 pkgCache::PkgIterator Pkg = Cache.PkgBegin();
281 for (;Pkg.end() != true; Pkg++)
282 {
283 if (Pkg.Section() == 0 && Pkg->VersionList != 0)
284 cout << "Bad section " << Pkg.Name() << endl;
285
286 for (pkgCache::VerIterator Cur = Pkg.VersionList();
287 Cur.end() != true; Cur++)
288 {
289 if (Cur->Priority < 1 || Cur->Priority > 5)
290 cout << "Bad prio " << Pkg.Name() << ',' << Cur.VerStr() << " == " << (int)Cur->Priority << endl;
291 }
292 }
293 return true;
294 }
295 /*}}}*/
296 // Dump - show everything /*{{{*/
297 // ---------------------------------------------------------------------
298 /* */
299 bool Dump(CommandLine &Cmd)
300 {
301 pkgCache &Cache = *GCache;
302 for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
303 {
304 cout << "Package: " << P.Name() << endl;
305 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
306 {
307 cout << " Version: " << V.VerStr() << endl;
308 cout << " File: " << V.FileList().File().FileName() << endl;
309 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
310 cout << " Depends: " << D.TargetPkg().Name() << ' ' << D.TargetVer() << endl;
311 }
312 }
313
314 for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++)
315 {
316 cout << "File: " << F.FileName() << endl;
317 cout << " Size: " << F->Size << endl;
318 cout << " ID: " << F->ID << endl;
319 cout << " Flags: " << F->Flags << endl;
320 cout << " Time: " << TimeRFC1123(F->mtime) << endl;
321 cout << " Archive: " << F.Archive() << endl;
322 cout << " Component: " << F.Component() << endl;
323 cout << " Version: " << F.Version() << endl;
324 cout << " Origin: " << F.Origin() << endl;
325 cout << " Label: " << F.Label() << endl;
326 cout << " Architecture: " << F.Architecture() << endl;
327 }
328
329 return true;
330 }
331 /*}}}*/
332 // DumpAvail - Print out the available list /*{{{*/
333 // ---------------------------------------------------------------------
334 /* This is needed to make dpkg --merge happy */
335 bool DumpAvail(CommandLine &Cmd)
336 {
337 pkgCache &Cache = *GCache;
338 unsigned char *Buffer = new unsigned char[Cache.HeaderP->MaxVerFileSize];
339
340 for (pkgCache::PkgFileIterator I = Cache.FileBegin(); I.end() == false; I++)
341 {
342 if ((I->Flags & pkgCache::Flag::NotSource) != 0)
343 continue;
344
345 if (I.IsOk() == false)
346 {
347 delete [] Buffer;
348 return _error->Error("Package file %s is out of sync.",I.FileName());
349 }
350
351 FileFd PkgF(I.FileName(),FileFd::ReadOnly);
352 if (_error->PendingError() == true)
353 {
354 delete [] Buffer;
355 return false;
356 }
357
358 /* Write all of the records from this package file, we search the entire
359 structure to find them */
360 for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
361 {
362 // Find the proper version to use. We should probably use the DepCache.
363 pkgCache::VerIterator V = Cache.GetCandidateVer(P,false);
364
365 if (V.end() == true || V.FileList().File() != I)
366 continue;
367
368 // Read the record and then write it out again.
369 if (PkgF.Seek(V.FileList()->Offset) == false ||
370 PkgF.Read(Buffer,V.FileList()->Size) == false ||
371 write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size)
372 {
373 delete [] Buffer;
374 return false;
375 }
376 }
377 }
378
379 return true;
380 }
381 /*}}}*/
382 // DoAdd - Perform an adding operation /*{{{*/
383 // ---------------------------------------------------------------------
384 /* */
385 bool DoAdd(CommandLine &CmdL)
386 {
387 // Make sure there is at least one argument
388 if (CmdL.FileSize() <= 1)
389 return _error->Error("You must give at least one file name");
390
391 // Open the cache
392 FileFd CacheF(_config->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny);
393 if (_error->PendingError() == true)
394 return false;
395
396 DynamicMMap Map(CacheF,MMap::Public);
397 if (_error->PendingError() == true)
398 return false;
399
400 OpTextProgress Progress(*_config);
401 pkgCacheGenerator Gen(Map,Progress);
402 if (_error->PendingError() == true)
403 return false;
404
405 unsigned long Length = CmdL.FileSize() - 1;
406 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
407 {
408 Progress.OverallProgress(I - CmdL.FileList,Length,1,"Generating cache");
409 Progress.SubProgress(Length);
410
411 // Do the merge
412 FileFd TagF(*I,FileFd::ReadOnly);
413 debListParser Parser(TagF);
414 if (_error->PendingError() == true)
415 return _error->Error("Problem opening %s",*I);
416
417 if (Gen.SelectFile(*I) == false)
418 return _error->Error("Problem with SelectFile");
419
420 if (Gen.MergeList(Parser) == false)
421 return _error->Error("Problem with MergeList");
422 }
423
424 Progress.Done();
425 GCache = &Gen.GetCache();
426 Stats(CmdL);
427
428 return true;
429 }
430 /*}}}*/
431 // DisplayRecord - Displays the complete record for the package /*{{{*/
432 // ---------------------------------------------------------------------
433 /* This displays the package record from the proper package index file.
434 It is not used by DumpAvail for performance reasons. */
435 bool DisplayRecord(pkgCache::VerIterator V)
436 {
437 // Find an appropriate file
438 pkgCache::VerFileIterator Vf = V.FileList();
439 for (; Vf.end() == false; Vf++)
440 if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
441 break;
442 if (Vf.end() == true)
443 Vf = V.FileList();
444
445 // Check and load the package list file
446 pkgCache::PkgFileIterator I = Vf.File();
447 if (I.IsOk() == false)
448 return _error->Error("Package file %s is out of sync.",I.FileName());
449
450 FileFd PkgF(I.FileName(),FileFd::ReadOnly);
451 if (_error->PendingError() == true)
452 return false;
453
454 // Read the record and then write it out again.
455 unsigned char *Buffer = new unsigned char[GCache->HeaderP->MaxVerFileSize];
456 if (PkgF.Seek(V.FileList()->Offset) == false ||
457 PkgF.Read(Buffer,V.FileList()->Size) == false ||
458 write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size)
459 {
460 delete [] Buffer;
461 return false;
462 }
463
464 delete [] Buffer;
465
466 return true;
467 }
468 /*}}}*/
469 // Search - Perform a search /*{{{*/
470 // ---------------------------------------------------------------------
471 /* This searches the package names and pacakge descriptions for a pattern */
472 bool Search(CommandLine &CmdL)
473 {
474 pkgCache &Cache = *GCache;
475 bool ShowFull = _config->FindB("APT::Cache::ShowFull",false);
476 bool NamesOnly = _config->FindB("APT::Cache::NamesOnly",false);
477
478 // Make sure there is at least one argument
479 if (CmdL.FileSize() != 2)
480 return _error->Error("You must give exactly one pattern");
481
482 // Compile the regex pattern
483 regex_t Pattern;
484 if (regcomp(&Pattern,CmdL.FileList[1],REG_EXTENDED | REG_ICASE |
485 REG_NOSUB) != 0)
486 return _error->Error("Regex compilation error");
487
488 // Create the text record parser
489 pkgRecords Recs(Cache);
490 if (_error->PendingError() == true)
491 return false;
492
493 // Search package names
494 pkgCache::PkgIterator I = Cache.PkgBegin();
495 for (;I.end() != true; I++)
496 {
497 // We search against the install version as that makes the most sense..
498 pkgCache::VerIterator V = Cache.GetCandidateVer(I);
499 if (V.end() == true)
500 continue;
501
502 pkgRecords::Parser &P = Recs.Lookup(V.FileList());
503
504 if (regexec(&Pattern,I.Name(),0,0,0) == 0 ||
505 (NamesOnly == false &&
506 regexec(&Pattern,P.LongDesc().c_str(),0,0,0) == 0))
507 {
508 if (ShowFull == true)
509 DisplayRecord(V);
510 else
511 cout << I.Name() << " - " << P.ShortDesc() << endl;
512 }
513 }
514
515 regfree(&Pattern);
516 return true;
517 }
518 /*}}}*/
519 // ShowPackage - Dump the package record to the screen /*{{{*/
520 // ---------------------------------------------------------------------
521 /* */
522 bool ShowPackage(CommandLine &CmdL)
523 {
524 pkgCache &Cache = *GCache;
525 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
526 {
527 pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
528 if (Pkg.end() == true)
529 {
530 _error->Warning("Unable to locate package %s",*I);
531 continue;
532 }
533
534 // Find the proper version to use. We should probably use the DepCache.
535 pkgCache::VerIterator V = Cache.GetCandidateVer(Pkg);
536 if (V.end() == true || V.FileList().end() == true)
537 continue;
538 if (DisplayRecord(V) == false)
539 return false;
540 }
541 return true;
542 }
543 /*}}}*/
544 // GenCaches - Call the main cache generator /*{{{*/
545 // ---------------------------------------------------------------------
546 /* */
547 bool GenCaches(CommandLine &Cmd)
548 {
549 OpTextProgress Progress(*_config);
550
551 pkgSourceList List;
552 List.ReadMainList();
553 return pkgMakeStatusCache(List,Progress);
554 }
555 /*}}}*/
556 // ShowHelp - Show a help screen /*{{{*/
557 // ---------------------------------------------------------------------
558 /* */
559 bool ShowHelp(CommandLine &Cmd)
560 {
561 cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE <<
562 " compiled on " << __DATE__ << " " << __TIME__ << endl;
563 if (_config->FindB("version") == true)
564 return 100;
565
566 cout << "Usage: apt-cache [options] command" << endl;
567 cout << " apt-cache [options] add file1 [file1 ...]" << endl;
568 cout << " apt-cache [options] showpkg pkg1 [pkg2 ...]" << endl;
569 cout << endl;
570 cout << "apt-cache is a low-level tool used to manipulate APT's binary" << endl;
571 cout << "cache files stored in " << _config->FindFile("Dir::Cache") << endl;
572 cout << "It is not ment for ordinary use only as a debug aide." << endl;
573 cout << endl;
574 cout << "Commands:" << endl;
575 cout << " add - Add an package file to the source cache" << endl;
576 cout << " gencaches - Build both the package and source cache" << endl;
577 cout << " showpkg - Show some general information for a single package" << endl;
578 cout << " stats - Show some basic statistics" << endl;
579 cout << " dump - Show the entire file in a terse form" << endl;
580 cout << " dumpavail - Print an available file to stdout" << endl;
581 cout << " unmet - Show unmet dependencies" << endl;
582 cout << " check - Check the cache a bit" << endl;
583 cout << " search - Search the package list for a regex pattern" << endl;
584 cout << " show - Show a readable record for the package" << endl;
585 cout << endl;
586 cout << "Options:" << endl;
587 cout << " -h This help text." << endl;
588 cout << " -p=? The package cache. [" << _config->FindFile("Dir::Cache::pkgcache") << ']' << endl;
589 cout << " -s=? The source cache. [" << _config->FindFile("Dir::Cache::srcpkgcache") << ']' << endl;
590 cout << " -q Disable progress indicator." << endl;
591 cout << " -i Show only important deps for the unmet command." << endl;
592 cout << " -c=? Read this configuration file" << endl;
593 cout << " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" << endl;
594 cout << "See the apt-cache(8) and apt.conf(5) manual pages for more information." << endl;
595 return 100;
596 }
597 /*}}}*/
598 // CacheInitialize - Initialize things for apt-cache /*{{{*/
599 // ---------------------------------------------------------------------
600 /* */
601 void CacheInitialize()
602 {
603 _config->Set("quiet",0);
604 _config->Set("help",false);
605 }
606 /*}}}*/
607
608 int main(int argc,const char *argv[])
609 {
610 CommandLine::Args Args[] = {
611 {'h',"help","help",0},
612 {'v',"version","version",0},
613 {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg},
614 {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg},
615 {'q',"quiet","quiet",CommandLine::IntLevel},
616 {'i',"important","APT::Cache::Important",0},
617 {'f',"full","APT::Cache::ShowFull",0},
618 {0,"names-only","APT::Cache::NamesOnly",0},
619 {'c',"config-file",0,CommandLine::ConfigFile},
620 {'o',"option",0,CommandLine::ArbItem},
621 {0,0,0,0}};
622 CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp},
623 {"add",&DoAdd},
624 {"gencaches",&GenCaches},
625 {0,0}};
626 CommandLine::Dispatch CmdsB[] = {{"showpkg",&DumpPackage},
627 {"stats",&Stats},
628 {"dump",&Dump},
629 {"dumpavail",&DumpAvail},
630 {"unmet",&UnMet},
631 {"check",&Check},
632 {"search",&Search},
633 {"show",&ShowPackage},
634 {0,0}};
635
636 CacheInitialize();
637
638 // Parse the command line and initialize the package library
639 CommandLine CmdL(Args,_config);
640 if (pkgInitialize(*_config) == false ||
641 CmdL.Parse(argc,argv) == false)
642 {
643 _error->DumpErrors();
644 return 100;
645 }
646
647 // See if the help should be shown
648 if (_config->FindB("help") == true ||
649 CmdL.FileSize() == 0)
650 return ShowHelp(CmdL);
651
652 // Deal with stdout not being a tty
653 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
654 _config->Set("quiet","1");
655
656 if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false)
657 {
658 // Open the cache file
659 pkgSourceList List;
660 List.ReadMainList();
661
662 // Generate it and map it
663 OpProgress Prog;
664 MMap *Map = pkgMakeStatusCacheMem(List,Prog);
665 if (_error->PendingError() == false)
666 {
667 pkgCache Cache(*Map);
668 GCache = &Cache;
669 if (_error->PendingError() == false)
670 CmdL.DispatchArg(CmdsB);
671 }
672 delete Map;
673 }
674
675 // Print any errors or warnings found during parsing
676 if (_error->empty() == false)
677 {
678 bool Errors = _error->PendingError();
679 _error->DumpErrors();
680 return Errors == true?100:0;
681 }
682
683 return 0;
684 }