1
// -*- mode: cpp; mode: fold -*-
3
// $Id: apt-cache.cc,v 1.1 1998/07/15 05:56:47 jgg Exp $
4
/* ######################################################################
6
apt-cache - Manages the cache file.
8
This program should eventually handle both low and high level
9
manipulation of the cache file. Depending how far things go it
10
might get quite a sophisticated UI.
12
Currently the command line is as follows:
13
apt-cache add cache file1:dist:ver file2:dist:ver ...
15
apt-cache add ./cache Pacakges:hamm:1.0
17
A usefull feature is 'upgradable' ie
18
apt-cache upgradable ./cache
19
will list .debs that should be installed to make all packages the latest
22
Returns 100 on failure, 0 on success.
24
##################################################################### */
26
// Include Files /*{{{*/
27
#include <apt-pkg/error.h>
28
#include <apt-pkg/pkgcachegen.h>
29
#include <apt-pkg/deblistparser.h>
38
// SplitArg - Split the triple /*{{{*/
39
// ---------------------------------------------------------------------
41
bool SplitArg(const char *Arg,string &File,string &Dist,string Ver)
43
const char *Start = Arg;
45
for (;*I != 0 && *I != ':'; I++);
47
return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
48
File = string(Start,I - Start);
52
for (;*I != 0 && *I != ':'; I++);
54
return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
55
Dist = string(Start,I - Start);
59
for (;*I != 0 && *I != ':'; I++);
61
return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
62
Ver = string(Start,I - Start);
67
// DoAdd - Perform an adding operation /*{{{*/
68
// ---------------------------------------------------------------------
70
bool DoAdd(int argc,char *argv[])
76
File CacheF(CacheFile,File::WriteEmpty);
77
if (_error->PendingError() == true)
80
DynamicMMap Map(CacheF,MMap::Public);
81
if (_error->PendingError() == true)
84
pkgCacheGenerator Gen(Map);
85
if (_error->PendingError() == true)
88
for (int I = 0; I != argc; I++)
90
if (SplitArg(argv[I],FileName,Dist,Ver) == false)
94
File TagF(FileName.c_str(),File::ReadOnly);
95
debListParser Parser(TagF);
96
if (_error->PendingError() == true)
98
if (Gen.SelectFile(FileName) == false)
101
if (Gen.MergeList(Parser) == false)
108
// DumpPackage - Show a dump of a package record /*{{{*/
109
// ---------------------------------------------------------------------
111
bool DumpPackage(int argc,char *argv[])
113
File CacheF(CacheFile,File::ReadOnly);
114
if (_error->PendingError() == true)
117
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
118
if (_error->PendingError() == true)
122
if (_error->PendingError() == true)
125
for (int I = 0; I != argc; I++)
127
pkgCache::PkgIterator Pkg = Cache.FindPkg(argv[I]);
128
if (Pkg.end() == true)
130
_error->Warning("Unable to locate package %s",argv[0]);
134
cout << "Package: " << Pkg.Name() << endl;
135
cout << "Versions: ";
136
for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
137
cout << Cur.VerStr() << ',';
140
cout << "Reverse Depends: " << endl;
141
for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++)
142
cout << " " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name() << endl;
144
cout << "Dependencies: " << endl;
145
for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
147
cout << Cur.VerStr() << " - ";
148
for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++)
149
cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << Dep.TargetVer() << ") ";
153
cout << "Provides: " << endl;
154
for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
156
cout << Cur.VerStr() << " - ";
157
for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++)
158
cout << Prv.ParentPkg().Name() << " ";
166
// Stats - Dump some nice statistics /*{{{*/
167
// ---------------------------------------------------------------------
169
bool Stats(const char *FileName)
171
File CacheF(FileName,File::ReadOnly);
172
if (_error->PendingError() == true)
175
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
176
if (_error->PendingError() == true)
180
if (_error->PendingError() == true)
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
// Dump - show everything /*{{{*/
234
// ---------------------------------------------------------------------
238
File CacheF(CacheFile,File::ReadOnly);
239
if (_error->PendingError() == true)
242
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
243
if (_error->PendingError() == true)
247
if (_error->PendingError() == true)
250
for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
252
cout << "Package: " << P.Name() << endl;
253
for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
255
cout << " Version: " << V.VerStr() << endl;
256
cout << " File: " << V.FileList().File().FileName() << endl;
257
for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
258
cout << " Depends: " << D.TargetPkg().Name() << ' ' << D.TargetVer() << endl;
262
for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++)
264
cout << "File: " << F.FileName() << endl;
265
cout << " Size: " << F->Size << endl;
266
cout << " ID: " << F->ID << endl;
267
cout << " Flags: " << F->Flags << endl;
268
cout << " Time: " << ctime(&F->mtime) << endl;
274
// DumpAvail - Print out the available list /*{{{*/
275
// ---------------------------------------------------------------------
276
/* This is needed to make dpkg --merge happy */
280
pkgCache Cache(CacheFile,true,true);
281
if (_error->PendingError() == true)
284
pkgControlCache CCache(Cache);
285
if (_error->PendingError() == true)
288
vector<string> Lines;
291
pkgCache::PkgIterator I = Cache.PkgBegin();
292
for (;I.end() != true; I++)
294
if (I->VersionList == 0)
297
pkgSPkgCtrlInfo Inf = CCache[I.VersionList()];
298
if (Inf.isNull() == true)
299
return _error->Error("Couldn't locate info record");
301
// Iterate over each element
302
pkgPkgCtrlInfo::const_iterator Elm = Inf->begin();
303
for (; Elm != Inf->end(); Elm++)
305
// Write the tag: value
306
cout << (*Elm)->Tag() << ": " << (*Elm)->Value() << endl;
308
// Write the multiline
309
(*Elm)->GetLines(Lines);
310
for (vector<string>::iterator j = Lines.begin(); j != Lines.end(); j++)
312
if ((*j).length() == 0)
313
cout << " ." << endl;
315
cout << " " << *j << endl;
318
Lines.erase(Lines.begin(),Lines.end());
328
int main(int argc, char *argv[])
333
cerr << "Usage is apt-cache add cache file1:dist:ver file2:dist:ver ..." << endl;
339
if (strcmp(argv[1],"add") == 0)
342
if (DoAdd(argc - 3,argv + 3) == true)
347
if (strcmp(argv[1],"showpkg") == 0)
350
DumpPackage(argc - 3,argv + 3);
354
if (strcmp(argv[1],"stats") == 0)
360
if (strcmp(argv[1],"dump") == 0)
367
if (strcmp(argv[1],"dumpavail") == 0)
374
_error->Error("Invalid operation %s", argv[1]);
378
// Print any errors or warnings found during parsing
379
if (_error->empty() == false)
381
_error->DumpErrors();