]> git.saurik.com Git - apt.git/blame - cmdline/apt-cache.cc
Class File name change to FileFd
[apt.git] / cmdline / apt-cache.cc
CommitLineData
1164783d
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
8e06abb2 3// $Id: apt-cache.cc,v 1.4 1998/07/19 04:42:18 jgg Exp $
1164783d
AL
4/* ######################################################################
5
6 apt-cache - Manages the cache file.
7
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.
11
12 Currently the command line is as follows:
13 apt-cache add cache file1:dist:ver file2:dist:ver ...
14 ie:
15 apt-cache add ./cache Pacakges:hamm:1.0
16
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
20 version.
21
22 Returns 100 on failure, 0 on success.
23
24 ##################################################################### */
25 /*}}}*/
26// Include Files /*{{{*/
27#include <apt-pkg/error.h>
28#include <apt-pkg/pkgcachegen.h>
29#include <apt-pkg/deblistparser.h>
8efa2a3b 30#include <apt-pkg/init.h>
1164783d
AL
31
32#include <iostream.h>
33#include <fstream.h>
34
35 /*}}}*/
36
37string CacheFile;
38
39// SplitArg - Split the triple /*{{{*/
40// ---------------------------------------------------------------------
41/* */
42bool SplitArg(const char *Arg,string &File,string &Dist,string Ver)
43{
44 const char *Start = Arg;
45 const char *I = Arg;
46 for (;*I != 0 && *I != ':'; I++);
47 if (*I != ':')
48 return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
49 File = string(Start,I - Start);
50
51 I++;
52 Start = I;
53 for (;*I != 0 && *I != ':'; I++);
54 if (*I != ':')
55 return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
56 Dist = string(Start,I - Start);
57
58 I++;
59 Start = I;
60 for (;*I != 0 && *I != ':'; I++);
61 if (I == Start)
62 return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
63 Ver = string(Start,I - Start);
64
1164783d
AL
65 return true;
66}
67 /*}}}*/
68// DumpPackage - Show a dump of a package record /*{{{*/
69// ---------------------------------------------------------------------
70/* */
ad00ae81
AL
71bool DumpPackage(pkgCache &Cache,int argc,char *argv[])
72{
1164783d
AL
73 for (int I = 0; I != argc; I++)
74 {
75 pkgCache::PkgIterator Pkg = Cache.FindPkg(argv[I]);
76 if (Pkg.end() == true)
77 {
78 _error->Warning("Unable to locate package %s",argv[0]);
79 continue;
80 }
81
82 cout << "Package: " << Pkg.Name() << endl;
83 cout << "Versions: ";
84 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
85 cout << Cur.VerStr() << ',';
86 cout << endl;
87
88 cout << "Reverse Depends: " << endl;
89 for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++)
90 cout << " " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name() << endl;
91
92 cout << "Dependencies: " << endl;
93 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
94 {
95 cout << Cur.VerStr() << " - ";
96 for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++)
97 cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << Dep.TargetVer() << ") ";
98 cout << endl;
99 }
100
101 cout << "Provides: " << endl;
102 for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
103 {
104 cout << Cur.VerStr() << " - ";
105 for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++)
106 cout << Prv.ParentPkg().Name() << " ";
107 cout << endl;
8efa2a3b
AL
108 }
109 cout << "Reverse Provides: " << endl;
110 for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; Prv++)
111 cout << Prv.OwnerPkg().Name() << " " << Prv.OwnerVer().VerStr();
112 cout << endl;
1164783d
AL
113 }
114
115 return true;
116}
117 /*}}}*/
118// Stats - Dump some nice statistics /*{{{*/
119// ---------------------------------------------------------------------
120/* */
ad00ae81 121bool Stats(pkgCache &Cache)
1164783d 122{
1164783d
AL
123 cout << "Total Package Names : " << Cache.Head().PackageCount << endl;
124 pkgCache::PkgIterator I = Cache.PkgBegin();
125
126 int Normal = 0;
127 int Virtual = 0;
128 int NVirt = 0;
129 int DVirt = 0;
130 int Missing = 0;
131 for (;I.end() != true; I++)
132 {
133 if (I->VersionList != 0 && I->ProvidesList == 0)
134 {
135 Normal++;
136 continue;
137 }
138
139 if (I->VersionList != 0 && I->ProvidesList != 0)
140 {
141 NVirt++;
142 continue;
143 }
144
145 if (I->VersionList == 0 && I->ProvidesList != 0)
146 {
147 // Only 1 provides
148 if (I.ProvidesList()->NextProvides == 0)
149 {
150 DVirt++;
151 }
152 else
153 Virtual++;
154 continue;
155 }
156 if (I->VersionList == 0 && I->ProvidesList == 0)
157 {
158 Missing++;
159 continue;
160 }
161 }
162 cout << " Normal Packages: " << Normal << endl;
163 cout << " Pure Virtual Packages: " << Virtual << endl;
164 cout << " Single Virtual Packages: " << DVirt << endl;
165 cout << " Mixed Virtual Packages: " << NVirt << endl;
166 cout << " Missing: " << Missing << endl;
167
168 cout << "Total Distinct Versions: " << Cache.Head().VersionCount << endl;
169 cout << "Total Dependencies: " << Cache.Head().DependsCount << endl;
170 return true;
171}
172 /*}}}*/
173// Dump - show everything /*{{{*/
174// ---------------------------------------------------------------------
175/* */
ad00ae81 176bool Dump(pkgCache &Cache)
1164783d 177{
1164783d
AL
178 for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
179 {
180 cout << "Package: " << P.Name() << endl;
181 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
182 {
183 cout << " Version: " << V.VerStr() << endl;
184 cout << " File: " << V.FileList().File().FileName() << endl;
185 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
186 cout << " Depends: " << D.TargetPkg().Name() << ' ' << D.TargetVer() << endl;
187 }
188 }
189
190 for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++)
191 {
192 cout << "File: " << F.FileName() << endl;
193 cout << " Size: " << F->Size << endl;
194 cout << " ID: " << F->ID << endl;
195 cout << " Flags: " << F->Flags << endl;
196 cout << " Time: " << ctime(&F->mtime) << endl;
197 }
198
199 return true;
200}
201 /*}}}*/
202// DumpAvail - Print out the available list /*{{{*/
203// ---------------------------------------------------------------------
204/* This is needed to make dpkg --merge happy */
ad00ae81 205bool DumpAvail(pkgCache &Cache)
1164783d 206{
ad00ae81 207 unsigned char *Buffer = new unsigned char[Cache.HeaderP->MaxVerFileSize];
1164783d 208
ad00ae81 209 for (pkgCache::PkgFileIterator I = Cache.FileBegin(); I.end() == false; I++)
1164783d 210 {
ad00ae81 211 if ((I->Flags & pkgCache::Flag::NotSource) != 0)
1164783d
AL
212 continue;
213
ad00ae81
AL
214 if (I.IsOk() == false)
215 {
216 delete [] Buffer;
217 return _error->Error("Package file %s is out of sync.",I.FileName());
218 }
1164783d 219
8e06abb2 220 FileFd PkgF(I.FileName(),FileFd::ReadOnly);
ad00ae81 221 if (_error->PendingError() == true)
1164783d 222 {
ad00ae81
AL
223 delete [] Buffer;
224 return false;
225 }
226
227 /* Write all of the records from this package file, we search the entire
228 structure to find them */
229 for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
230 {
231 for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
1164783d 232 {
ad00ae81
AL
233 if (V->FileList == 0)
234 continue;
235 if (V.FileList().File() != I)
236 continue;
237
238 // Read the record and then write it out again.
239 if (PkgF.Seek(V.FileList()->Offset) == false ||
240 PkgF.Read(Buffer,V.FileList()->Size) == false ||
241 write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size)
242 {
243 delete [] Buffer;
244 return false;
245 }
1164783d 246 }
1164783d 247 }
ad00ae81
AL
248 }
249
250 return true;
251}
252 /*}}}*/
253// DoAdd - Perform an adding operation /*{{{*/
254// ---------------------------------------------------------------------
255/* */
256bool DoAdd(int argc,char *argv[])
257{
258 string FileName;
259 string Dist;
260 string Ver;
261
262 // Open the cache
8e06abb2 263 FileFd CacheF(CacheFile,FileFd::WriteEmpty);
ad00ae81
AL
264 if (_error->PendingError() == true)
265 return false;
266
267 DynamicMMap Map(CacheF,MMap::Public);
268 if (_error->PendingError() == true)
269 return false;
270
271 pkgCacheGenerator Gen(Map);
272 if (_error->PendingError() == true)
273 return false;
274
275 for (int I = 0; I != argc; I++)
276 {
277 if (SplitArg(argv[I],FileName,Dist,Ver) == false)
278 return false;
279 cout << FileName << endl;
1164783d 280
ad00ae81 281 // Do the merge
8e06abb2 282 FileFd TagF(FileName.c_str(),FileFd::ReadOnly);
ad00ae81
AL
283 debListParser Parser(TagF);
284 if (_error->PendingError() == true)
285 return _error->Error("Problem opening %s",FileName.c_str());
286
287 if (Gen.SelectFile(FileName) == false)
288 return _error->Error("Problem with SelectFile");
289
290 if (Gen.MergeList(Parser) == false)
291 return _error->Error("Problem with MergeList");
1164783d 292 }
ad00ae81
AL
293
294 Stats(Gen.GetCache());
295
1164783d
AL
296 return true;
297}
298 /*}}}*/
299
300int main(int argc, char *argv[])
301{
302 // Check arguments.
303 if (argc < 3)
304 {
305 cerr << "Usage is apt-cache add cache file1:dist:ver file2:dist:ver ..." << endl;
306 return 100;
307 }
8efa2a3b
AL
308
309 pkgInitialize(*_config);
1164783d
AL
310 while (1)
311 {
ad00ae81 312 CacheFile = argv[2];
1164783d
AL
313 if (strcmp(argv[1],"add") == 0)
314 {
ad00ae81 315 DoAdd(argc - 3,argv + 3);
1164783d
AL
316 break;
317 }
ad00ae81
AL
318
319 // Open the cache file
8e06abb2 320 FileFd CacheF(CacheFile,FileFd::ReadOnly);
ad00ae81
AL
321 if (_error->PendingError() == true)
322 break;
323
324 MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
325 if (_error->PendingError() == true)
326 break;
327
328 pkgCache Cache(Map);
329 if (_error->PendingError() == true)
330 break;
1164783d
AL
331
332 if (strcmp(argv[1],"showpkg") == 0)
333 {
334 CacheFile = argv[2];
ad00ae81 335 DumpPackage(Cache,argc - 3,argv + 3);
1164783d
AL
336 break;
337 }
338
339 if (strcmp(argv[1],"stats") == 0)
340 {
ad00ae81 341 Stats(Cache);
1164783d
AL
342 break;
343 }
344
345 if (strcmp(argv[1],"dump") == 0)
346 {
ad00ae81 347 Dump(Cache);
1164783d
AL
348 break;
349 }
350
351 if (strcmp(argv[1],"dumpavail") == 0)
352 {
ad00ae81 353 DumpAvail(Cache);
1164783d
AL
354 break;
355 }
356
357 _error->Error("Invalid operation %s", argv[1]);
358 break;
359 }
360
361 // Print any errors or warnings found during parsing
362 if (_error->empty() == false)
363 {
364 _error->DumpErrors();
365 return 100;
366 }
367
368 return 0;
369}