]>
git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-cache.cc,v 1.8 1998/09/26 05:34:29 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
++)
47 cout
<< Cur
.VerStr() << ',';
50 cout
<< "Reverse Depends: " << endl
;
51 for (pkgCache::DepIterator D
= Pkg
.RevDependsList(); D
.end() != true; D
++)
52 cout
<< " " << D
.ParentPkg().Name() << ',' << D
.TargetPkg().Name() << endl
;
54 cout
<< "Dependencies: " << endl
;
55 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
57 cout
<< Cur
.VerStr() << " - ";
58 for (pkgCache::DepIterator Dep
= Cur
.DependsList(); Dep
.end() != true; Dep
++)
59 cout
<< Dep
.TargetPkg().Name() << " (" << (int)Dep
->CompareOp
<< " " << Dep
.TargetVer() << ") ";
63 cout
<< "Provides: " << endl
;
64 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
66 cout
<< Cur
.VerStr() << " - ";
67 for (pkgCache::PrvIterator Prv
= Cur
.ProvidesList(); Prv
.end() != true; Prv
++)
68 cout
<< Prv
.ParentPkg().Name() << " ";
71 cout
<< "Reverse Provides: " << endl
;
72 for (pkgCache::PrvIterator Prv
= Pkg
.ProvidesList(); Prv
.end() != true; Prv
++)
73 cout
<< Prv
.OwnerPkg().Name() << " " << Prv
.OwnerVer().VerStr();
80 // Stats - Dump some nice statistics /*{{{*/
81 // ---------------------------------------------------------------------
83 bool Stats(pkgCache
&Cache
)
85 cout
<< "Total Package Names : " << Cache
.Head().PackageCount
<< endl
;
86 pkgCache::PkgIterator I
= Cache
.PkgBegin();
93 for (;I
.end() != true; I
++)
95 if (I
->VersionList
!= 0 && I
->ProvidesList
== 0)
101 if (I
->VersionList
!= 0 && I
->ProvidesList
!= 0)
107 if (I
->VersionList
== 0 && I
->ProvidesList
!= 0)
110 if (I
.ProvidesList()->NextProvides
== 0)
118 if (I
->VersionList
== 0 && I
->ProvidesList
== 0)
124 cout
<< " Normal Packages: " << Normal
<< endl
;
125 cout
<< " Pure Virtual Packages: " << Virtual
<< endl
;
126 cout
<< " Single Virtual Packages: " << DVirt
<< endl
;
127 cout
<< " Mixed Virtual Packages: " << NVirt
<< endl
;
128 cout
<< " Missing: " << Missing
<< endl
;
130 cout
<< "Total Distinct Versions: " << Cache
.Head().VersionCount
<< endl
;
131 cout
<< "Total Dependencies: " << Cache
.Head().DependsCount
<< endl
;
135 // Dump - show everything /*{{{*/
136 // ---------------------------------------------------------------------
138 bool Dump(pkgCache
&Cache
)
140 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
142 cout
<< "Package: " << P
.Name() << endl
;
143 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
145 cout
<< " Version: " << V
.VerStr() << endl
;
146 cout
<< " File: " << V
.FileList().File().FileName() << endl
;
147 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; D
++)
148 cout
<< " Depends: " << D
.TargetPkg().Name() << ' ' << D
.TargetVer() << endl
;
152 for (pkgCache::PkgFileIterator
F(Cache
); F
.end() == false; F
++)
154 cout
<< "File: " << F
.FileName() << endl
;
155 cout
<< " Size: " << F
->Size
<< endl
;
156 cout
<< " ID: " << F
->ID
<< endl
;
157 cout
<< " Flags: " << F
->Flags
<< endl
;
158 cout
<< " Time: " << ctime(&F
->mtime
) << endl
;
164 // DumpAvail - Print out the available list /*{{{*/
165 // ---------------------------------------------------------------------
166 /* This is needed to make dpkg --merge happy */
167 bool DumpAvail(pkgCache
&Cache
)
169 unsigned char *Buffer
= new unsigned char[Cache
.HeaderP
->MaxVerFileSize
];
171 for (pkgCache::PkgFileIterator I
= Cache
.FileBegin(); I
.end() == false; I
++)
173 if ((I
->Flags
& pkgCache::Flag::NotSource
) != 0)
176 if (I
.IsOk() == false)
179 return _error
->Error("Package file %s is out of sync.",I
.FileName());
182 FileFd
PkgF(I
.FileName(),FileFd::ReadOnly
);
183 if (_error
->PendingError() == true)
189 /* Write all of the records from this package file, we search the entire
190 structure to find them */
191 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
193 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
195 if (V
->FileList
== 0)
197 if (V
.FileList().File() != I
)
200 // Read the record and then write it out again.
201 if (PkgF
.Seek(V
.FileList()->Offset
) == false ||
202 PkgF
.Read(Buffer
,V
.FileList()->Size
) == false ||
203 write(STDOUT_FILENO
,Buffer
,V
.FileList()->Size
) != V
.FileList()->Size
)
215 // DoAdd - Perform an adding operation /*{{{*/
216 // ---------------------------------------------------------------------
218 bool DoAdd(CommandLine
&CmdL
)
220 // Make sure there is at least one argument
221 if (CmdL
.FileSize() <= 1)
222 return _error
->Error("You must give at least one file name");
225 FileFd
CacheF(_config
->FindDir("Dir::Cache::srcpkgcache"),FileFd::ReadOnly
);
226 if (_error
->PendingError() == true)
229 DynamicMMap
Map(CacheF
,MMap::Public
);
230 if (_error
->PendingError() == true)
233 OpTextProgress Progress
;
234 pkgCacheGenerator
Gen(Map
,Progress
);
235 if (_error
->PendingError() == true)
238 unsigned long Length
= CmdL
.FileSize() - 1;
239 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++)
241 Progress
.OverallProgress(I
- CmdL
.FileList
,Length
,1,"Generating cache");
244 FileFd
TagF(*I
,FileFd::ReadOnly
);
245 debListParser
Parser(TagF
);
246 if (_error
->PendingError() == true)
247 return _error
->Error("Problem opening %s",*I
);
249 if (Gen
.SelectFile(*I
) == false)
250 return _error
->Error("Problem with SelectFile");
252 if (Gen
.MergeList(Parser
) == false)
253 return _error
->Error("Problem with MergeList");
257 Stats(Gen
.GetCache());
262 // GenCaches - Call the main cache generator /*{{{*/
263 // ---------------------------------------------------------------------
267 OpTextProgress Progress
;
270 return pkgMakeStatusCache(List
,Progress
);
273 // ShowHelp - Show a help screen /*{{{*/
274 // ---------------------------------------------------------------------
278 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
279 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
281 cout
<< "Usage: apt-cache [options] command" << endl
;
282 cout
<< " apt-cache [options] add file1 [file1 ...]" << endl
;
283 cout
<< " apt-cache [options] showpkg pkg2 [pkg2 ...]" << endl
;
285 cout
<< "apt-cache is a low-level tool used to manipulate APT's binary" << endl
;
286 cout
<< "cache files stored in " << _config
->FindDir("Dir::Cache") << endl
;
287 cout
<< "It is not ment for ordinary use only as a debug aide." << endl
;
289 cout
<< "Commands:" << endl
;
290 cout
<< " add - Add an package file to the source cache" << endl
;
291 cout
<< " gencaches - Build both the package and source cache" << endl
;
292 cout
<< " showpkg - Show some general information for a single package" << endl
;
293 cout
<< " stats - Show some basic statistics" << endl
;
294 cout
<< " dump - Show the entire file in a terse form" << endl
;
295 cout
<< " dumpavail - Print an available file to stdout" << endl
;
297 cout
<< "Options:" << endl
;
298 cout
<< " -h This help text." << endl
;
299 cout
<< " -p=? The package cache. [" << _config
->FindDir("Dir::Cache::pkgcache") << ']' << endl
;
300 cout
<< " -s=? The source cache. [" << _config
->FindDir("Dir::Cache::srcpkgcache") << ']' << endl
;
301 cout
<< " -q Disable progress indicator. " << endl
;
302 cout
<< " -c=? Read this configuration file" << endl
;
303 cout
<< " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl
;
304 cout
<< "See the apt-cache(8) and apt.conf(8) manual pages for more information." << endl
;
309 int main(int argc
,const char *argv
[])
311 CommandLine::Args Args
[] = {
312 {'h',"help","help",0},
313 {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg
},
314 {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg
},
315 {'q',"quiet","quiet",CommandLine::IntLevel
},
316 {'c',"config-file",0,CommandLine::ConfigFile
},
317 {'o',"option",0,CommandLine::ArbItem
},
320 // Parse the command line and initialize the package library
321 CommandLine
CmdL(Args
,_config
);
322 if (pkgInitialize(*_config
) == false ||
323 CmdL
.Parse(argc
,argv
) == false)
325 _error
->DumpErrors();
329 // See if the help should be shown
330 if (_config
->FindB("help") == true ||
331 CmdL
.FileSize() == 0)
336 if (strcmp(CmdL
.FileList
[0],"add") == 0)
342 if (strcmp(CmdL
.FileList
[0],"gencaches") == 0)
348 // Open the cache file
349 FileFd
CacheF(_config
->FindDir("Dir::Cache::pkgcache"),FileFd::ReadOnly
);
350 if (_error
->PendingError() == true)
353 MMap
Map(CacheF
,MMap::Public
| MMap::ReadOnly
);
354 if (_error
->PendingError() == true)
358 if (_error
->PendingError() == true)
361 if (strcmp(CmdL
.FileList
[0],"showpkg") == 0)
363 DumpPackage(Cache
,CmdL
);
367 if (strcmp(CmdL
.FileList
[0],"stats") == 0)
373 if (strcmp(CmdL
.FileList
[0],"dump") == 0)
379 if (strcmp(CmdL
.FileList
[0],"dumpavail") == 0)
385 _error
->Error("Invalid operation %s", CmdL
.FileList
[0]);
389 // Print any errors or warnings found during parsing
390 if (_error
->empty() == false)
392 _error
->DumpErrors();