]>
git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-cache.cc,v 1.11 1998/11/13 04:24:01 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 // DumpPackage - Show a dump of a package record /*{{{*/
31 // ---------------------------------------------------------------------
33 bool DumpPackage(pkgCache
&Cache
,CommandLine
&CmdL
)
35 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
37 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(*I
);
38 if (Pkg
.end() == true)
40 _error
->Warning("Unable to locate package %s",*I
);
44 cout
<< "Package: " << Pkg
.Name() << endl
;
46 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
49 for (pkgCache::VerFileIterator Vf
= Cur
.FileList(); Vf
.end() == false; Vf
++)
50 cout
<< "(" << Vf
.File().FileName() << ")";
56 cout
<< "Reverse Depends: " << endl
;
57 for (pkgCache::DepIterator D
= Pkg
.RevDependsList(); D
.end() != true; D
++)
58 cout
<< " " << D
.ParentPkg().Name() << ',' << D
.TargetPkg().Name() << endl
;
60 cout
<< "Dependencies: " << endl
;
61 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
63 cout
<< Cur
.VerStr() << " - ";
64 for (pkgCache::DepIterator Dep
= Cur
.DependsList(); Dep
.end() != true; Dep
++)
65 cout
<< Dep
.TargetPkg().Name() << " (" << (int)Dep
->CompareOp
<< " " << Dep
.TargetVer() << ") ";
69 cout
<< "Provides: " << endl
;
70 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
72 cout
<< Cur
.VerStr() << " - ";
73 for (pkgCache::PrvIterator Prv
= Cur
.ProvidesList(); Prv
.end() != true; Prv
++)
74 cout
<< Prv
.ParentPkg().Name() << " ";
77 cout
<< "Reverse Provides: " << endl
;
78 for (pkgCache::PrvIterator Prv
= Pkg
.ProvidesList(); Prv
.end() != true; Prv
++)
79 cout
<< Prv
.OwnerPkg().Name() << " " << Prv
.OwnerVer().VerStr();
87 // Stats - Dump some nice statistics /*{{{*/
88 // ---------------------------------------------------------------------
90 bool Stats(pkgCache
&Cache
)
92 cout
<< "Total Package Names : " << Cache
.Head().PackageCount
<< endl
;
93 pkgCache::PkgIterator I
= Cache
.PkgBegin();
100 for (;I
.end() != true; I
++)
102 if (I
->VersionList
!= 0 && I
->ProvidesList
== 0)
108 if (I
->VersionList
!= 0 && I
->ProvidesList
!= 0)
114 if (I
->VersionList
== 0 && I
->ProvidesList
!= 0)
117 if (I
.ProvidesList()->NextProvides
== 0)
125 if (I
->VersionList
== 0 && I
->ProvidesList
== 0)
131 cout
<< " Normal Packages: " << Normal
<< endl
;
132 cout
<< " Pure Virtual Packages: " << Virtual
<< endl
;
133 cout
<< " Single Virtual Packages: " << DVirt
<< endl
;
134 cout
<< " Mixed Virtual Packages: " << NVirt
<< endl
;
135 cout
<< " Missing: " << Missing
<< endl
;
137 cout
<< "Total Distinct Versions: " << Cache
.Head().VersionCount
<< endl
;
138 cout
<< "Total Dependencies: " << Cache
.Head().DependsCount
<< endl
;
142 // Dump - show everything /*{{{*/
143 // ---------------------------------------------------------------------
145 bool Dump(pkgCache
&Cache
)
147 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
149 cout
<< "Package: " << P
.Name() << endl
;
150 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
152 cout
<< " Version: " << V
.VerStr() << endl
;
153 cout
<< " File: " << V
.FileList().File().FileName() << endl
;
154 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; D
++)
155 cout
<< " Depends: " << D
.TargetPkg().Name() << ' ' << D
.TargetVer() << endl
;
159 for (pkgCache::PkgFileIterator
F(Cache
); F
.end() == false; F
++)
161 cout
<< "File: " << F
.FileName() << endl
;
162 cout
<< " Size: " << F
->Size
<< endl
;
163 cout
<< " ID: " << F
->ID
<< endl
;
164 cout
<< " Flags: " << F
->Flags
<< endl
;
165 cout
<< " Time: " << ctime(&F
->mtime
) << endl
;
171 // DumpAvail - Print out the available list /*{{{*/
172 // ---------------------------------------------------------------------
173 /* This is needed to make dpkg --merge happy */
174 bool DumpAvail(pkgCache
&Cache
)
176 unsigned char *Buffer
= new unsigned char[Cache
.HeaderP
->MaxVerFileSize
];
178 for (pkgCache::PkgFileIterator I
= Cache
.FileBegin(); I
.end() == false; I
++)
180 if ((I
->Flags
& pkgCache::Flag::NotSource
) != 0)
183 if (I
.IsOk() == false)
186 return _error
->Error("Package file %s is out of sync.",I
.FileName());
189 FileFd
PkgF(I
.FileName(),FileFd::ReadOnly
);
190 if (_error
->PendingError() == true)
196 /* Write all of the records from this package file, we search the entire
197 structure to find them */
198 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
200 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
202 if (V
->FileList
== 0)
204 if (V
.FileList().File() != I
)
207 // Read the record and then write it out again.
208 if (PkgF
.Seek(V
.FileList()->Offset
) == false ||
209 PkgF
.Read(Buffer
,V
.FileList()->Size
) == false ||
210 write(STDOUT_FILENO
,Buffer
,V
.FileList()->Size
) != V
.FileList()->Size
)
222 // DoAdd - Perform an adding operation /*{{{*/
223 // ---------------------------------------------------------------------
225 bool DoAdd(CommandLine
&CmdL
)
227 // Make sure there is at least one argument
228 if (CmdL
.FileSize() <= 1)
229 return _error
->Error("You must give at least one file name");
232 FileFd
CacheF(_config
->FindFile("Dir::Cache::srcpkgcache"),FileFd::WriteAny
);
233 if (_error
->PendingError() == true)
236 DynamicMMap
Map(CacheF
,MMap::Public
);
237 if (_error
->PendingError() == true)
240 OpTextProgress
Progress(*_config
);
241 pkgCacheGenerator
Gen(Map
,Progress
);
242 if (_error
->PendingError() == true)
245 unsigned long Length
= CmdL
.FileSize() - 1;
246 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
248 Progress
.OverallProgress(I
- CmdL
.FileList
,Length
,1,"Generating cache");
251 FileFd
TagF(*I
,FileFd::ReadOnly
);
252 debListParser
Parser(TagF
);
253 if (_error
->PendingError() == true)
254 return _error
->Error("Problem opening %s",*I
);
256 if (Gen
.SelectFile(*I
) == false)
257 return _error
->Error("Problem with SelectFile");
259 if (Gen
.MergeList(Parser
) == false)
260 return _error
->Error("Problem with MergeList");
264 Stats(Gen
.GetCache());
269 // GenCaches - Call the main cache generator /*{{{*/
270 // ---------------------------------------------------------------------
274 OpTextProgress
Progress(*_config
);
278 return pkgMakeStatusCache(List
,Progress
);
281 // ShowHelp - Show a help screen /*{{{*/
282 // ---------------------------------------------------------------------
286 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
287 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
289 cout
<< "Usage: apt-cache [options] command" << endl
;
290 cout
<< " apt-cache [options] add file1 [file1 ...]" << endl
;
291 cout
<< " apt-cache [options] showpkg pkg1 [pkg2 ...]" << endl
;
293 cout
<< "apt-cache is a low-level tool used to manipulate APT's binary" << endl
;
294 cout
<< "cache files stored in " << _config
->FindFile("Dir::Cache") << endl
;
295 cout
<< "It is not ment for ordinary use only as a debug aide." << endl
;
297 cout
<< "Commands:" << endl
;
298 cout
<< " add - Add an package file to the source cache" << endl
;
299 cout
<< " gencaches - Build both the package and source cache" << endl
;
300 cout
<< " showpkg - Show some general information for a single package" << endl
;
301 cout
<< " stats - Show some basic statistics" << endl
;
302 cout
<< " dump - Show the entire file in a terse form" << endl
;
303 cout
<< " dumpavail - Print an available file to stdout" << endl
;
305 cout
<< "Options:" << endl
;
306 cout
<< " -h This help text." << endl
;
307 cout
<< " -p=? The package cache. [" << _config
->FindFile("Dir::Cache::pkgcache") << ']' << endl
;
308 cout
<< " -s=? The source cache. [" << _config
->FindFile("Dir::Cache::srcpkgcache") << ']' << endl
;
309 cout
<< " -q Disable progress indicator. " << endl
;
310 cout
<< " -c=? Read this configuration file" << endl
;
311 cout
<< " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl
;
312 cout
<< "See the apt-cache(8) and apt.conf(8) manual pages for more information." << endl
;
316 // CacheInitialize - Initialize things for apt-cache /*{{{*/
317 // ---------------------------------------------------------------------
319 void CacheInitialize()
321 _config
->Set("quiet",0);
322 _config
->Set("help",false);
326 int main(int argc
,const char *argv
[])
328 CommandLine::Args Args
[] = {
329 {'h',"help","help",0},
330 {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg
},
331 {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg
},
332 {'q',"quiet","quiet",CommandLine::IntLevel
},
333 {'c',"config-file",0,CommandLine::ConfigFile
},
334 {'o',"option",0,CommandLine::ArbItem
},
339 // Parse the command line and initialize the package library
340 CommandLine
CmdL(Args
,_config
);
341 if (pkgInitialize(*_config
) == false ||
342 CmdL
.Parse(argc
,argv
) == false)
344 _error
->DumpErrors();
348 // See if the help should be shown
349 if (_config
->FindB("help") == true ||
350 CmdL
.FileSize() == 0)
355 if (strcmp(CmdL
.FileList
[0],"add") == 0)
361 if (strcmp(CmdL
.FileList
[0],"gencaches") == 0)
367 // Open the cache file
368 FileFd
CacheF(_config
->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly
);
369 if (_error
->PendingError() == true)
372 MMap
Map(CacheF
,MMap::Public
| MMap::ReadOnly
);
373 if (_error
->PendingError() == true)
377 if (_error
->PendingError() == true)
380 if (strcmp(CmdL
.FileList
[0],"showpkg") == 0)
382 DumpPackage(Cache
,CmdL
);
386 if (strcmp(CmdL
.FileList
[0],"stats") == 0)
392 if (strcmp(CmdL
.FileList
[0],"dump") == 0)
398 if (strcmp(CmdL
.FileList
[0],"dumpavail") == 0)
404 _error
->Error("Invalid operation %s", CmdL
.FileList
[0]);
408 // Print any errors or warnings found during parsing
409 if (_error
->empty() == false)
411 bool Errors
= _error
->PendingError();
412 _error
->DumpErrors();
413 return Errors
== true?100:0;