]>
git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-cache.cc,v 1.14 1998/12/04 22:56:53 jgg 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. 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.
13 Returns 100 on failure, 0 on success.
15 ##################################################################### */
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>
30 // UnMet - Show unmet dependencies /*{{{*/
31 // ---------------------------------------------------------------------
33 bool UnMet(pkgCache
&Cache
)
35 bool Important
= _config
->FindB("Important",false);
37 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
39 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
42 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false;)
45 pkgCache::DepIterator Start
;
46 pkgCache::DepIterator End
;
49 /* cout << "s: Check " << Start.TargetPkg().Name() << ',' <<
50 End.TargetPkg().Name() << endl;*/
52 // Skip conflicts and replaces
53 if (End
->Type
!= pkgCache::Dep::PreDepends
&&
54 End
->Type
!= pkgCache::Dep::Depends
&&
55 End
->Type
!= pkgCache::Dep::Suggests
&&
56 End
->Type
!= pkgCache::Dep::Recommends
)
59 // Important deps only
60 if (Important
== true)
61 if (End
->Type
!= pkgCache::Dep::PreDepends
&&
62 End
->Type
!= pkgCache::Dep::Depends
)
65 // Verify the or group
67 pkgCache::DepIterator RealStart
= Start
;
70 // See if this dep is Ok
71 pkgCache::Version
**VList
= Start
.AllTargets();
92 cout
<< "Package " << P
.Name() << " version " <<
93 V
.VerStr() << " has an unmet dep:" << endl
;
96 // Print out the dep type
97 cout
<< " " << End
.DepType() << ": ";
103 cout
<< Start
.TargetPkg().Name();
104 if (Start
.TargetVer() != 0)
105 cout
<< " (" << Start
.CompType() << " " << Start
.TargetVer() <<
121 // DumpPackage - Show a dump of a package record /*{{{*/
122 // ---------------------------------------------------------------------
124 bool DumpPackage(pkgCache
&Cache
,CommandLine
&CmdL
)
126 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
128 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(*I
);
129 if (Pkg
.end() == true)
131 _error
->Warning("Unable to locate package %s",*I
);
135 cout
<< "Package: " << Pkg
.Name() << endl
;
136 cout
<< "Versions: ";
137 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
139 cout
<< Cur
.VerStr();
140 for (pkgCache::VerFileIterator Vf
= Cur
.FileList(); Vf
.end() == false; Vf
++)
141 cout
<< "(" << Vf
.File().FileName() << ")";
147 cout
<< "Reverse Depends: " << endl
;
148 for (pkgCache::DepIterator D
= Pkg
.RevDependsList(); D
.end() != true; D
++)
149 cout
<< " " << D
.ParentPkg().Name() << ',' << D
.TargetPkg().Name() << endl
;
151 cout
<< "Dependencies: " << endl
;
152 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
154 cout
<< Cur
.VerStr() << " - ";
155 for (pkgCache::DepIterator Dep
= Cur
.DependsList(); Dep
.end() != true; Dep
++)
156 cout
<< Dep
.TargetPkg().Name() << " (" << (int)Dep
->CompareOp
<< " " << Dep
.TargetVer() << ") ";
160 cout
<< "Provides: " << endl
;
161 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
163 cout
<< Cur
.VerStr() << " - ";
164 for (pkgCache::PrvIterator Prv
= Cur
.ProvidesList(); Prv
.end() != true; Prv
++)
165 cout
<< Prv
.ParentPkg().Name() << " ";
168 cout
<< "Reverse Provides: " << endl
;
169 for (pkgCache::PrvIterator Prv
= Pkg
.ProvidesList(); Prv
.end() != true; Prv
++)
170 cout
<< Prv
.OwnerPkg().Name() << " " << Prv
.OwnerVer().VerStr();
178 // Stats - Dump some nice statistics /*{{{*/
179 // ---------------------------------------------------------------------
181 bool Stats(pkgCache
&Cache
)
183 cout
<< "Total Package Names : " << Cache
.Head().PackageCount
<< endl
;
184 pkgCache::PkgIterator I
= Cache
.PkgBegin();
191 for (;I
.end() != true; I
++)
193 if (I
->VersionList
!= 0 && I
->ProvidesList
== 0)
199 if (I
->VersionList
!= 0 && I
->ProvidesList
!= 0)
205 if (I
->VersionList
== 0 && I
->ProvidesList
!= 0)
208 if (I
.ProvidesList()->NextProvides
== 0)
216 if (I
->VersionList
== 0 && I
->ProvidesList
== 0)
222 cout
<< " Normal Packages: " << Normal
<< endl
;
223 cout
<< " Pure Virtual Packages: " << Virtual
<< endl
;
224 cout
<< " Single Virtual Packages: " << DVirt
<< endl
;
225 cout
<< " Mixed Virtual Packages: " << NVirt
<< endl
;
226 cout
<< " Missing: " << Missing
<< endl
;
228 cout
<< "Total Distinct Versions: " << Cache
.Head().VersionCount
<< endl
;
229 cout
<< "Total Dependencies: " << Cache
.Head().DependsCount
<< endl
;
233 // Check - Check some things about the cache /*{{{*/
234 // ---------------------------------------------------------------------
235 /* Debug aide mostly */
236 bool Check(pkgCache
&Cache
)
238 pkgCache::PkgIterator Pkg
= Cache
.PkgBegin();
239 for (;Pkg
.end() != true; Pkg
++)
241 if (Pkg
.Section() == 0 && Pkg
->VersionList
!= 0)
242 cout
<< "Bad section " << Pkg
.Name() << endl
;
244 for (pkgCache::VerIterator Cur
= Pkg
.VersionList();
245 Cur
.end() != true; Cur
++)
247 if (Cur
->Priority
< 1 || Cur
->Priority
> 5)
248 cout
<< "Bad prio " << Pkg
.Name() << ',' << Cur
.VerStr() << " == " << (int)Cur
->Priority
<< endl
;
254 // Dump - show everything /*{{{*/
255 // ---------------------------------------------------------------------
257 bool Dump(pkgCache
&Cache
)
259 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
261 cout
<< "Package: " << P
.Name() << endl
;
262 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
264 cout
<< " Version: " << V
.VerStr() << endl
;
265 cout
<< " File: " << V
.FileList().File().FileName() << endl
;
266 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; D
++)
267 cout
<< " Depends: " << D
.TargetPkg().Name() << ' ' << D
.TargetVer() << endl
;
271 for (pkgCache::PkgFileIterator
F(Cache
); F
.end() == false; F
++)
273 cout
<< "File: " << F
.FileName() << endl
;
274 cout
<< " Size: " << F
->Size
<< endl
;
275 cout
<< " ID: " << F
->ID
<< endl
;
276 cout
<< " Flags: " << F
->Flags
<< endl
;
277 cout
<< " Time: " << ctime(&F
->mtime
) << endl
;
283 // DumpAvail - Print out the available list /*{{{*/
284 // ---------------------------------------------------------------------
285 /* This is needed to make dpkg --merge happy */
286 bool DumpAvail(pkgCache
&Cache
)
288 unsigned char *Buffer
= new unsigned char[Cache
.HeaderP
->MaxVerFileSize
];
290 for (pkgCache::PkgFileIterator I
= Cache
.FileBegin(); I
.end() == false; I
++)
292 if ((I
->Flags
& pkgCache::Flag::NotSource
) != 0)
295 if (I
.IsOk() == false)
298 return _error
->Error("Package file %s is out of sync.",I
.FileName());
301 FileFd
PkgF(I
.FileName(),FileFd::ReadOnly
);
302 if (_error
->PendingError() == true)
308 /* Write all of the records from this package file, we search the entire
309 structure to find them */
310 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
312 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
314 if (V
->FileList
== 0)
316 if (V
.FileList().File() != I
)
319 // Read the record and then write it out again.
320 if (PkgF
.Seek(V
.FileList()->Offset
) == false ||
321 PkgF
.Read(Buffer
,V
.FileList()->Size
) == false ||
322 write(STDOUT_FILENO
,Buffer
,V
.FileList()->Size
) != V
.FileList()->Size
)
334 // DoAdd - Perform an adding operation /*{{{*/
335 // ---------------------------------------------------------------------
337 bool DoAdd(CommandLine
&CmdL
)
339 // Make sure there is at least one argument
340 if (CmdL
.FileSize() <= 1)
341 return _error
->Error("You must give at least one file name");
344 FileFd
CacheF(_config
->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny
);
345 if (_error
->PendingError() == true)
348 DynamicMMap
Map(CacheF
,MMap::Public
);
349 if (_error
->PendingError() == true)
352 OpTextProgress
Progress(*_config
);
353 pkgCacheGenerator
Gen(Map
,Progress
);
354 if (_error
->PendingError() == true)
357 unsigned long Length
= CmdL
.FileSize() - 1;
358 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
360 Progress
.OverallProgress(I
- CmdL
.FileList
,Length
,1,"Generating cache");
361 Progress
.SubProgress(Length
);
364 FileFd
TagF(*I
,FileFd::ReadOnly
);
365 debListParser
Parser(TagF
);
366 if (_error
->PendingError() == true)
367 return _error
->Error("Problem opening %s",*I
);
369 if (Gen
.SelectFile(*I
) == false)
370 return _error
->Error("Problem with SelectFile");
372 if (Gen
.MergeList(Parser
) == false)
373 return _error
->Error("Problem with MergeList");
377 Stats(Gen
.GetCache());
382 // GenCaches - Call the main cache generator /*{{{*/
383 // ---------------------------------------------------------------------
387 OpTextProgress
Progress(*_config
);
391 return pkgMakeStatusCache(List
,Progress
);
394 // ShowHelp - Show a help screen /*{{{*/
395 // ---------------------------------------------------------------------
399 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
400 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
402 cout
<< "Usage: apt-cache [options] command" << endl
;
403 cout
<< " apt-cache [options] add file1 [file1 ...]" << endl
;
404 cout
<< " apt-cache [options] showpkg pkg1 [pkg2 ...]" << endl
;
406 cout
<< "apt-cache is a low-level tool used to manipulate APT's binary" << endl
;
407 cout
<< "cache files stored in " << _config
->FindFile("Dir::Cache") << endl
;
408 cout
<< "It is not ment for ordinary use only as a debug aide." << endl
;
410 cout
<< "Commands:" << endl
;
411 cout
<< " add - Add an package file to the source cache" << endl
;
412 cout
<< " gencaches - Build both the package and source cache" << endl
;
413 cout
<< " showpkg - Show some general information for a single package" << endl
;
414 cout
<< " stats - Show some basic statistics" << endl
;
415 cout
<< " dump - Show the entire file in a terse form" << endl
;
416 cout
<< " dumpavail - Print an available file to stdout" << endl
;
417 cout
<< " unmet - Show unmet dependencies" << endl
;
418 cout
<< " check - Check the cache a bit" << endl
;
420 cout
<< "Options:" << endl
;
421 cout
<< " -h This help text." << endl
;
422 cout
<< " -p=? The package cache. [" << _config
->FindFile("Dir::Cache::pkgcache") << ']' << endl
;
423 cout
<< " -s=? The source cache. [" << _config
->FindFile("Dir::Cache::srcpkgcache") << ']' << endl
;
424 cout
<< " -q Disable progress indicator. " << endl
;
425 cout
<< " -c=? Read this configuration file" << endl
;
426 cout
<< " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl
;
427 cout
<< "See the apt-cache(8) and apt.conf(8) manual pages for more information." << endl
;
431 // CacheInitialize - Initialize things for apt-cache /*{{{*/
432 // ---------------------------------------------------------------------
434 void CacheInitialize()
436 _config
->Set("quiet",0);
437 _config
->Set("help",false);
441 int main(int argc
,const char *argv
[])
443 CommandLine::Args Args
[] = {
444 {'h',"help","help",0},
445 {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg
},
446 {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg
},
447 {'q',"quiet","quiet",CommandLine::IntLevel
},
448 {'i',"important","Important",0},
449 {'c',"config-file",0,CommandLine::ConfigFile
},
450 {'o',"option",0,CommandLine::ArbItem
},
455 // Parse the command line and initialize the package library
456 CommandLine
CmdL(Args
,_config
);
457 if (pkgInitialize(*_config
) == false ||
458 CmdL
.Parse(argc
,argv
) == false)
460 _error
->DumpErrors();
464 // See if the help should be shown
465 if (_config
->FindB("help") == true ||
466 CmdL
.FileSize() == 0)
471 if (strcmp(CmdL
.FileList
[0],"add") == 0)
477 if (strcmp(CmdL
.FileList
[0],"gencaches") == 0)
483 // Open the cache file
484 FileFd
CacheF(_config
->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly
);
485 if (_error
->PendingError() == true)
488 MMap
Map(CacheF
,MMap::Public
| MMap::ReadOnly
);
489 if (_error
->PendingError() == true)
493 if (_error
->PendingError() == true)
496 if (strcmp(CmdL
.FileList
[0],"showpkg") == 0)
498 DumpPackage(Cache
,CmdL
);
502 if (strcmp(CmdL
.FileList
[0],"stats") == 0)
508 if (strcmp(CmdL
.FileList
[0],"dump") == 0)
514 if (strcmp(CmdL
.FileList
[0],"dumpavail") == 0)
520 if (strcmp(CmdL
.FileList
[0],"unmet") == 0)
526 if (strcmp(CmdL
.FileList
[0],"check") == 0)
532 _error
->Error("Invalid operation %s", CmdL
.FileList
[0]);
536 // Print any errors or warnings found during parsing
537 if (_error
->empty() == false)
539 bool Errors
= _error
->PendingError();
540 _error
->DumpErrors();
541 return Errors
== true?100:0;