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