]>
git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-cache.cc,v 1.9 1998/10/02 04:39:55 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::WriteAny
);
226 if (_error
->PendingError() == true)
229 DynamicMMap
Map(CacheF
,MMap::Public
);
230 if (_error
->PendingError() == true)
233 OpTextProgress
Progress(*_config
);
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(*_config
);
271 return pkgMakeStatusCache(List
,Progress
);
274 // ShowHelp - Show a help screen /*{{{*/
275 // ---------------------------------------------------------------------
279 cout
<< PACKAGE
<< ' ' << VERSION
<< " for " << ARCHITECTURE
<<
280 " compiled on " << __DATE__
<< " " << __TIME__
<< endl
;
282 cout
<< "Usage: apt-cache [options] command" << endl
;
283 cout
<< " apt-cache [options] add file1 [file1 ...]" << endl
;
284 cout
<< " apt-cache [options] showpkg pkg1 [pkg2 ...]" << endl
;
286 cout
<< "apt-cache is a low-level tool used to manipulate APT's binary" << endl
;
287 cout
<< "cache files stored in " << _config
->FindDir("Dir::Cache") << endl
;
288 cout
<< "It is not ment for ordinary use only as a debug aide." << endl
;
290 cout
<< "Commands:" << endl
;
291 cout
<< " add - Add an package file to the source cache" << endl
;
292 cout
<< " gencaches - Build both the package and source cache" << endl
;
293 cout
<< " showpkg - Show some general information for a single package" << endl
;
294 cout
<< " stats - Show some basic statistics" << endl
;
295 cout
<< " dump - Show the entire file in a terse form" << endl
;
296 cout
<< " dumpavail - Print an available file to stdout" << endl
;
298 cout
<< "Options:" << endl
;
299 cout
<< " -h This help text." << endl
;
300 cout
<< " -p=? The package cache. [" << _config
->FindDir("Dir::Cache::pkgcache") << ']' << endl
;
301 cout
<< " -s=? The source cache. [" << _config
->FindDir("Dir::Cache::srcpkgcache") << ']' << endl
;
302 cout
<< " -q Disable progress indicator. " << endl
;
303 cout
<< " -c=? Read this configuration file" << endl
;
304 cout
<< " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl
;
305 cout
<< "See the apt-cache(8) and apt.conf(8) manual pages for more information." << endl
;
309 // CacheInitialize - Initialize things for apt-cache /*{{{*/
310 // ---------------------------------------------------------------------
312 void CacheInitialize()
314 _config
->Set("quiet",0);
315 _config
->Set("help",false);
319 int main(int argc
,const char *argv
[])
321 CommandLine::Args Args
[] = {
322 {'h',"help","help",0},
323 {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg
},
324 {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg
},
325 {'q',"quiet","quiet",CommandLine::IntLevel
},
326 {'c',"config-file",0,CommandLine::ConfigFile
},
327 {'o',"option",0,CommandLine::ArbItem
},
332 // Parse the command line and initialize the package library
333 CommandLine
CmdL(Args
,_config
);
334 if (pkgInitialize(*_config
) == false ||
335 CmdL
.Parse(argc
,argv
) == false)
337 _error
->DumpErrors();
341 // See if the help should be shown
342 if (_config
->FindB("help") == true ||
343 CmdL
.FileSize() == 0)
348 if (strcmp(CmdL
.FileList
[0],"add") == 0)
354 if (strcmp(CmdL
.FileList
[0],"gencaches") == 0)
360 // Open the cache file
361 FileFd
CacheF(_config
->FindDir("Dir::Cache::pkgcache"),FileFd::ReadOnly
);
362 if (_error
->PendingError() == true)
365 MMap
Map(CacheF
,MMap::Public
| MMap::ReadOnly
);
366 if (_error
->PendingError() == true)
370 if (_error
->PendingError() == true)
373 if (strcmp(CmdL
.FileList
[0],"showpkg") == 0)
375 DumpPackage(Cache
,CmdL
);
379 if (strcmp(CmdL
.FileList
[0],"stats") == 0)
385 if (strcmp(CmdL
.FileList
[0],"dump") == 0)
391 if (strcmp(CmdL
.FileList
[0],"dumpavail") == 0)
397 _error
->Error("Invalid operation %s", CmdL
.FileList
[0]);
401 // Print any errors or warnings found during parsing
402 if (_error
->empty() == false)
404 bool Errors
= _error
->PendingError();
405 _error
->DumpErrors();
406 return Errors
== true?100:0;