| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- // -*- mode: cpp; mode: fold -*-
- // Description /*{{{*/
- // $Id: apt-cache.cc,v 1.6 1998/07/26 23:11:56 jgg Exp $
- /* ######################################################################
-
- apt-cache - Manages the cache file.
-
- This program should eventually handle both low and high level
- manipulation of the cache file. Depending how far things go it
- might get quite a sophisticated UI.
-
- Currently the command line is as follows:
- apt-cache add cache file1:dist:ver file2:dist:ver ...
- ie:
- apt-cache add ./cache Pacakges:hamm:1.0
- A usefull feature is 'upgradable' ie
- apt-cache upgradable ./cache
- will list .debs that should be installed to make all packages the latest
- version.
-
- Returns 100 on failure, 0 on success.
-
- ##################################################################### */
- /*}}}*/
- // Include Files /*{{{*/
- #include <apt-pkg/error.h>
- #include <apt-pkg/pkgcachegen.h>
- #include <apt-pkg/deblistparser.h>
- #include <apt-pkg/init.h>
- #include <apt-pkg/progress.h>
- #include <apt-pkg/sourcelist.h>
- #include <iostream.h>
- #include <fstream.h>
- /*}}}*/
- string CacheFile;
- // SplitArg - Split the triple /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool SplitArg(const char *Arg,string &File,string &Dist,string Ver)
- {
- const char *Start = Arg;
- const char *I = Arg;
- for (;*I != 0 && *I != ':'; I++);
- if (*I != ':')
- return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
- File = string(Start,I - Start);
- I++;
- Start = I;
- for (;*I != 0 && *I != ':'; I++);
- if (*I != ':')
- return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
- Dist = string(Start,I - Start);
-
- I++;
- Start = I;
- for (;*I != 0 && *I != ':'; I++);
- if (I == Start)
- return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
- Ver = string(Start,I - Start);
- return true;
- }
- /*}}}*/
- // DumpPackage - Show a dump of a package record /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool DumpPackage(pkgCache &Cache,int argc,char *argv[])
- {
- for (int I = 0; I != argc; I++)
- {
- pkgCache::PkgIterator Pkg = Cache.FindPkg(argv[I]);
- if (Pkg.end() == true)
- {
- _error->Warning("Unable to locate package %s",argv[0]);
- continue;
- }
- cout << "Package: " << Pkg.Name() << endl;
- cout << "Versions: ";
- for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
- cout << Cur.VerStr() << ',';
- cout << endl;
-
- cout << "Reverse Depends: " << endl;
- for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++)
- cout << " " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name() << endl;
- cout << "Dependencies: " << endl;
- for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
- {
- cout << Cur.VerStr() << " - ";
- for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++)
- cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << Dep.TargetVer() << ") ";
- cout << endl;
- }
- cout << "Provides: " << endl;
- for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
- {
- cout << Cur.VerStr() << " - ";
- for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++)
- cout << Prv.ParentPkg().Name() << " ";
- cout << endl;
- }
- cout << "Reverse Provides: " << endl;
- for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; Prv++)
- cout << Prv.OwnerPkg().Name() << " " << Prv.OwnerVer().VerStr();
- cout << endl;
- }
- return true;
- }
- /*}}}*/
- // Stats - Dump some nice statistics /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool Stats(pkgCache &Cache)
- {
- cout << "Total Package Names : " << Cache.Head().PackageCount << endl;
- pkgCache::PkgIterator I = Cache.PkgBegin();
-
- int Normal = 0;
- int Virtual = 0;
- int NVirt = 0;
- int DVirt = 0;
- int Missing = 0;
- for (;I.end() != true; I++)
- {
- if (I->VersionList != 0 && I->ProvidesList == 0)
- {
- Normal++;
- continue;
- }
- if (I->VersionList != 0 && I->ProvidesList != 0)
- {
- NVirt++;
- continue;
- }
-
- if (I->VersionList == 0 && I->ProvidesList != 0)
- {
- // Only 1 provides
- if (I.ProvidesList()->NextProvides == 0)
- {
- DVirt++;
- }
- else
- Virtual++;
- continue;
- }
- if (I->VersionList == 0 && I->ProvidesList == 0)
- {
- Missing++;
- continue;
- }
- }
- cout << " Normal Packages: " << Normal << endl;
- cout << " Pure Virtual Packages: " << Virtual << endl;
- cout << " Single Virtual Packages: " << DVirt << endl;
- cout << " Mixed Virtual Packages: " << NVirt << endl;
- cout << " Missing: " << Missing << endl;
-
- cout << "Total Distinct Versions: " << Cache.Head().VersionCount << endl;
- cout << "Total Dependencies: " << Cache.Head().DependsCount << endl;
- return true;
- }
- /*}}}*/
- // Dump - show everything /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool Dump(pkgCache &Cache)
- {
- for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
- {
- cout << "Package: " << P.Name() << endl;
- for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
- {
- cout << " Version: " << V.VerStr() << endl;
- cout << " File: " << V.FileList().File().FileName() << endl;
- for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
- cout << " Depends: " << D.TargetPkg().Name() << ' ' << D.TargetVer() << endl;
- }
- }
- for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++)
- {
- cout << "File: " << F.FileName() << endl;
- cout << " Size: " << F->Size << endl;
- cout << " ID: " << F->ID << endl;
- cout << " Flags: " << F->Flags << endl;
- cout << " Time: " << ctime(&F->mtime) << endl;
- }
- return true;
- }
- /*}}}*/
- // DumpAvail - Print out the available list /*{{{*/
- // ---------------------------------------------------------------------
- /* This is needed to make dpkg --merge happy */
- bool DumpAvail(pkgCache &Cache)
- {
- unsigned char *Buffer = new unsigned char[Cache.HeaderP->MaxVerFileSize];
- for (pkgCache::PkgFileIterator I = Cache.FileBegin(); I.end() == false; I++)
- {
- if ((I->Flags & pkgCache::Flag::NotSource) != 0)
- continue;
-
- if (I.IsOk() == false)
- {
- delete [] Buffer;
- return _error->Error("Package file %s is out of sync.",I.FileName());
- }
-
- FileFd PkgF(I.FileName(),FileFd::ReadOnly);
- if (_error->PendingError() == true)
- {
- delete [] Buffer;
- return false;
- }
- /* Write all of the records from this package file, we search the entire
- structure to find them */
- for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
- {
- for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
- {
- if (V->FileList == 0)
- continue;
- if (V.FileList().File() != I)
- continue;
-
- // Read the record and then write it out again.
- if (PkgF.Seek(V.FileList()->Offset) == false ||
- PkgF.Read(Buffer,V.FileList()->Size) == false ||
- write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size)
- {
- delete [] Buffer;
- return false;
- }
- }
- }
- }
-
- return true;
- }
- /*}}}*/
- // DoAdd - Perform an adding operation /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool DoAdd(int argc,char *argv[])
- {
- string FileName;
- string Dist;
- string Ver;
-
- // Open the cache
- FileFd CacheF(CacheFile,FileFd::WriteEmpty);
- if (_error->PendingError() == true)
- return false;
-
- DynamicMMap Map(CacheF,MMap::Public);
- if (_error->PendingError() == true)
- return false;
- OpTextProgress Progress;
- pkgCacheGenerator Gen(Map,Progress);
- if (_error->PendingError() == true)
- return false;
- for (int I = 0; I != argc; I++)
- {
- Progress.OverallProgress(I,argc,1,"Generating cache");
- if (SplitArg(argv[I],FileName,Dist,Ver) == false)
- return false;
-
- // Do the merge
- FileFd TagF(FileName.c_str(),FileFd::ReadOnly);
- debListParser Parser(TagF);
- if (_error->PendingError() == true)
- return _error->Error("Problem opening %s",FileName.c_str());
-
- if (Gen.SelectFile(FileName) == false)
- return _error->Error("Problem with SelectFile");
-
- if (Gen.MergeList(Parser) == false)
- return _error->Error("Problem with MergeList");
- }
- Progress.Done();
- Stats(Gen.GetCache());
-
- return true;
- }
- /*}}}*/
- // GenCaches - Call the main cache generator /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool GenCaches()
- {
- OpTextProgress Progress;
- pkgSourceList List;
- List.ReadMainList();
- return pkgMakeStatusCache(List,Progress);
- }
- /*}}}*/
- int main(int argc, char *argv[])
- {
- // Check arguments.
- if (argc < 3)
- {
- cerr << "Usage is apt-cache add cache file1:dist:ver file2:dist:ver ..." << endl;
- return 100;
- }
- pkgInitialize(*_config);
- while (1)
- {
- CacheFile = argv[2];
- if (strcmp(argv[1],"add") == 0)
- {
- DoAdd(argc - 3,argv + 3);
- break;
- }
- if (strcmp(argv[1],"gencaches") == 0)
- {
- GenCaches();
- break;
- }
- // Open the cache file
- FileFd CacheF(CacheFile,FileFd::ReadOnly);
- if (_error->PendingError() == true)
- break;
-
- MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
- if (_error->PendingError() == true)
- break;
-
- pkgCache Cache(Map);
- if (_error->PendingError() == true)
- break;
-
- if (strcmp(argv[1],"showpkg") == 0)
- {
- CacheFile = argv[2];
- DumpPackage(Cache,argc - 3,argv + 3);
- break;
- }
- if (strcmp(argv[1],"stats") == 0)
- {
- Stats(Cache);
- break;
- }
-
- if (strcmp(argv[1],"dump") == 0)
- {
- Dump(Cache);
- break;
- }
-
- if (strcmp(argv[1],"dumpavail") == 0)
- {
- DumpAvail(Cache);
- break;
- }
-
- _error->Error("Invalid operation %s", argv[1]);
- break;
- }
-
- // Print any errors or warnings found during parsing
- if (_error->empty() == false)
- {
- _error->DumpErrors();
- return 100;
- }
-
- return 0;
- }
|