]>
git.saurik.com Git - apt.git/blob - cmdline/apt-cache.cc
85405941e5621697b08cce3b4139160d5e69e030
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-cache.cc,v 1.7 1998/09/22 05:30:30 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>
30 #include <apt-pkg/init.h>
31 #include <apt-pkg/progress.h>
32 #include <apt-pkg/sourcelist.h>
33 #include <apt-pkg/cmndline.h>
42 // SplitArg - Split the triple /*{{{*/
43 // ---------------------------------------------------------------------
45 bool SplitArg(const char *Arg
,string
&File
,string
&Dist
,string Ver
)
47 const char *Start
= Arg
;
49 for (;*I
!= 0 && *I
!= ':'; I
++);
51 return _error
->Error("Malformed argument %s, must be in file:dist:rev form",Arg
);
52 File
= string(Start
,I
- Start
);
56 for (;*I
!= 0 && *I
!= ':'; I
++);
58 return _error
->Error("Malformed argument %s, must be in file:dist:rev form",Arg
);
59 Dist
= string(Start
,I
- Start
);
63 for (;*I
!= 0 && *I
!= ':'; I
++);
65 return _error
->Error("Malformed argument %s, must be in file:dist:rev form",Arg
);
66 Ver
= string(Start
,I
- Start
);
71 // DumpPackage - Show a dump of a package record /*{{{*/
72 // ---------------------------------------------------------------------
74 bool DumpPackage(pkgCache
&Cache
,int argc
,const char *argv
[])
76 for (int I
= 0; I
!= argc
; I
++)
78 pkgCache::PkgIterator Pkg
= Cache
.FindPkg(argv
[I
]);
79 if (Pkg
.end() == true)
81 _error
->Warning("Unable to locate package %s",argv
[0]);
85 cout
<< "Package: " << Pkg
.Name() << endl
;
87 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
88 cout
<< Cur
.VerStr() << ',';
91 cout
<< "Reverse Depends: " << endl
;
92 for (pkgCache::DepIterator D
= Pkg
.RevDependsList(); D
.end() != true; D
++)
93 cout
<< " " << D
.ParentPkg().Name() << ',' << D
.TargetPkg().Name() << endl
;
95 cout
<< "Dependencies: " << endl
;
96 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
98 cout
<< Cur
.VerStr() << " - ";
99 for (pkgCache::DepIterator Dep
= Cur
.DependsList(); Dep
.end() != true; Dep
++)
100 cout
<< Dep
.TargetPkg().Name() << " (" << (int)Dep
->CompareOp
<< " " << Dep
.TargetVer() << ") ";
104 cout
<< "Provides: " << endl
;
105 for (pkgCache::VerIterator Cur
= Pkg
.VersionList(); Cur
.end() != true; Cur
++)
107 cout
<< Cur
.VerStr() << " - ";
108 for (pkgCache::PrvIterator Prv
= Cur
.ProvidesList(); Prv
.end() != true; Prv
++)
109 cout
<< Prv
.ParentPkg().Name() << " ";
112 cout
<< "Reverse Provides: " << endl
;
113 for (pkgCache::PrvIterator Prv
= Pkg
.ProvidesList(); Prv
.end() != true; Prv
++)
114 cout
<< Prv
.OwnerPkg().Name() << " " << Prv
.OwnerVer().VerStr();
121 // Stats - Dump some nice statistics /*{{{*/
122 // ---------------------------------------------------------------------
124 bool Stats(pkgCache
&Cache
)
126 cout
<< "Total Package Names : " << Cache
.Head().PackageCount
<< endl
;
127 pkgCache::PkgIterator I
= Cache
.PkgBegin();
134 for (;I
.end() != true; I
++)
136 if (I
->VersionList
!= 0 && I
->ProvidesList
== 0)
142 if (I
->VersionList
!= 0 && I
->ProvidesList
!= 0)
148 if (I
->VersionList
== 0 && I
->ProvidesList
!= 0)
151 if (I
.ProvidesList()->NextProvides
== 0)
159 if (I
->VersionList
== 0 && I
->ProvidesList
== 0)
165 cout
<< " Normal Packages: " << Normal
<< endl
;
166 cout
<< " Pure Virtual Packages: " << Virtual
<< endl
;
167 cout
<< " Single Virtual Packages: " << DVirt
<< endl
;
168 cout
<< " Mixed Virtual Packages: " << NVirt
<< endl
;
169 cout
<< " Missing: " << Missing
<< endl
;
171 cout
<< "Total Distinct Versions: " << Cache
.Head().VersionCount
<< endl
;
172 cout
<< "Total Dependencies: " << Cache
.Head().DependsCount
<< endl
;
176 // Dump - show everything /*{{{*/
177 // ---------------------------------------------------------------------
179 bool Dump(pkgCache
&Cache
)
181 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
183 cout
<< "Package: " << P
.Name() << endl
;
184 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
186 cout
<< " Version: " << V
.VerStr() << endl
;
187 cout
<< " File: " << V
.FileList().File().FileName() << endl
;
188 for (pkgCache::DepIterator D
= V
.DependsList(); D
.end() == false; D
++)
189 cout
<< " Depends: " << D
.TargetPkg().Name() << ' ' << D
.TargetVer() << endl
;
193 for (pkgCache::PkgFileIterator
F(Cache
); F
.end() == false; F
++)
195 cout
<< "File: " << F
.FileName() << endl
;
196 cout
<< " Size: " << F
->Size
<< endl
;
197 cout
<< " ID: " << F
->ID
<< endl
;
198 cout
<< " Flags: " << F
->Flags
<< endl
;
199 cout
<< " Time: " << ctime(&F
->mtime
) << endl
;
205 // DumpAvail - Print out the available list /*{{{*/
206 // ---------------------------------------------------------------------
207 /* This is needed to make dpkg --merge happy */
208 bool DumpAvail(pkgCache
&Cache
)
210 unsigned char *Buffer
= new unsigned char[Cache
.HeaderP
->MaxVerFileSize
];
212 for (pkgCache::PkgFileIterator I
= Cache
.FileBegin(); I
.end() == false; I
++)
214 if ((I
->Flags
& pkgCache::Flag::NotSource
) != 0)
217 if (I
.IsOk() == false)
220 return _error
->Error("Package file %s is out of sync.",I
.FileName());
223 FileFd
PkgF(I
.FileName(),FileFd::ReadOnly
);
224 if (_error
->PendingError() == true)
230 /* Write all of the records from this package file, we search the entire
231 structure to find them */
232 for (pkgCache::PkgIterator P
= Cache
.PkgBegin(); P
.end() == false; P
++)
234 for (pkgCache::VerIterator V
= P
.VersionList(); V
.end() == false; V
++)
236 if (V
->FileList
== 0)
238 if (V
.FileList().File() != I
)
241 // Read the record and then write it out again.
242 if (PkgF
.Seek(V
.FileList()->Offset
) == false ||
243 PkgF
.Read(Buffer
,V
.FileList()->Size
) == false ||
244 write(STDOUT_FILENO
,Buffer
,V
.FileList()->Size
) != V
.FileList()->Size
)
256 // DoAdd - Perform an adding operation /*{{{*/
257 // ---------------------------------------------------------------------
259 bool DoAdd(int argc
,const char *argv
[])
266 FileFd
CacheF(CacheFile
,FileFd::WriteEmpty
);
267 if (_error
->PendingError() == true)
270 DynamicMMap
Map(CacheF
,MMap::Public
);
271 if (_error
->PendingError() == true)
274 OpTextProgress Progress
;
275 pkgCacheGenerator
Gen(Map
,Progress
);
276 if (_error
->PendingError() == true)
279 for (int I
= 0; I
!= argc
; I
++)
281 Progress
.OverallProgress(I
,argc
,1,"Generating cache");
282 if (SplitArg(argv
[I
],FileName
,Dist
,Ver
) == false)
286 FileFd
TagF(FileName
.c_str(),FileFd::ReadOnly
);
287 debListParser
Parser(TagF
);
288 if (_error
->PendingError() == true)
289 return _error
->Error("Problem opening %s",FileName
.c_str());
291 if (Gen
.SelectFile(FileName
) == false)
292 return _error
->Error("Problem with SelectFile");
294 if (Gen
.MergeList(Parser
) == false)
295 return _error
->Error("Problem with MergeList");
299 Stats(Gen
.GetCache());
304 // GenCaches - Call the main cache generator /*{{{*/
305 // ---------------------------------------------------------------------
309 OpTextProgress Progress
;
312 return pkgMakeStatusCache(List
,Progress
);
316 int main(int argc
,const char *argv
[])
318 CommandLine::Args Args
[] = {
319 {'h',"help","help",0},
322 CommandLine
Cmds(Args
,_config
);
323 if (pkgInitialize(*_config
) == false ||
324 Cmds
.Parse(argc
,argv
) == false)
326 _error
->DumpErrors();
329 cout
<< _config
->Find("help") << endl
;
334 cerr
<< "Usage is apt-cache add cache file1:dist:ver file2:dist:ver ..." << endl
;
341 if (strcmp(argv
[1],"add") == 0)
343 DoAdd(argc
- 3,argv
+ 3);
347 if (strcmp(argv
[1],"gencaches") == 0)
353 // Open the cache file
354 FileFd
CacheF(CacheFile
,FileFd::ReadOnly
);
355 if (_error
->PendingError() == true)
358 MMap
Map(CacheF
,MMap::Public
| MMap::ReadOnly
);
359 if (_error
->PendingError() == true)
363 if (_error
->PendingError() == true)
366 if (strcmp(argv
[1],"showpkg") == 0)
369 DumpPackage(Cache
,argc
- 3,argv
+ 3);
373 if (strcmp(argv
[1],"stats") == 0)
379 if (strcmp(argv
[1],"dump") == 0)
385 if (strcmp(argv
[1],"dumpavail") == 0)
391 _error
->Error("Invalid operation %s", argv
[1]);
395 // Print any errors or warnings found during parsing
396 if (_error
->empty() == false)
398 _error
->DumpErrors();