X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/0a8e3465cb644e380ab0fc6d66f6d1f17363b34e..43981212ff994ce2d51bf3038b8057ab1b417619:/cmdline/apt-cache.cc diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index c4a6c7a42..26d96c860 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: apt-cache.cc,v 1.9 1998/10/02 04:39:55 jgg Exp $ +// $Id: apt-cache.cc,v 1.24 1999/02/08 07:54:58 jgg Exp $ /* ###################################################################### apt-cache - Manages the cache files @@ -22,16 +22,113 @@ #include #include #include +#include +#include #include -#include +#include /*}}}*/ +pkgCache *GCache = 0; + +// UnMet - Show unmet dependencies /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool UnMet(CommandLine &CmdL) +{ + pkgCache &Cache = *GCache; + bool Important = _config->FindB("APT::Cache::Important",false); + + for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + { + for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++) + { + bool Header = false; + for (pkgCache::DepIterator D = V.DependsList(); D.end() == false;) + { + // Collect or groups + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); + +/* cout << "s: Check " << Start.TargetPkg().Name() << ',' << + End.TargetPkg().Name() << endl;*/ + + // Skip conflicts and replaces + if (End->Type != pkgCache::Dep::PreDepends && + End->Type != pkgCache::Dep::Depends && + End->Type != pkgCache::Dep::Suggests && + End->Type != pkgCache::Dep::Recommends) + continue; + + // Important deps only + if (Important == true) + if (End->Type != pkgCache::Dep::PreDepends && + End->Type != pkgCache::Dep::Depends) + continue; + + // Verify the or group + bool OK = false; + pkgCache::DepIterator RealStart = Start; + do + { + // See if this dep is Ok + pkgCache::Version **VList = Start.AllTargets(); + if (*VList != 0) + { + OK = true; + delete [] VList; + break; + } + delete [] VList; + + if (Start == End) + break; + Start++; + } + while (1); + + // The group is OK + if (OK == true) + continue; + + // Oops, it failed.. + if (Header == false) + cout << "Package " << P.Name() << " version " << + V.VerStr() << " has an unmet dep:" << endl; + Header = true; + + // Print out the dep type + cout << " " << End.DepType() << ": "; + + // Show the group + Start = RealStart; + do + { + cout << Start.TargetPkg().Name(); + if (Start.TargetVer() != 0) + cout << " (" << Start.CompType() << " " << Start.TargetVer() << + ")"; + if (Start == End) + break; + cout << " | "; + Start++; + } + while (1); + + cout << endl; + } + } + } + return true; +} + /*}}}*/ // DumpPackage - Show a dump of a package record /*{{{*/ // --------------------------------------------------------------------- /* */ -bool DumpPackage(pkgCache &Cache,CommandLine &CmdL) +bool DumpPackage(CommandLine &CmdL) { + pkgCache &Cache = *GCache; for (const char **I = CmdL.FileList + 1; *I != 0; I++) { pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); @@ -44,7 +141,13 @@ bool DumpPackage(pkgCache &Cache,CommandLine &CmdL) cout << "Package: " << Pkg.Name() << endl; cout << "Versions: "; for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++) - cout << Cur.VerStr() << ','; + { + cout << Cur.VerStr(); + for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; Vf++) + cout << "(" << Vf.File().FileName() << ")"; + cout << ','; + } + cout << endl; cout << "Reverse Depends: " << endl; @@ -72,6 +175,7 @@ bool DumpPackage(pkgCache &Cache,CommandLine &CmdL) for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; Prv++) cout << Prv.OwnerPkg().Name() << " " << Prv.OwnerVer().VerStr(); cout << endl; + } return true; @@ -80,9 +184,11 @@ bool DumpPackage(pkgCache &Cache,CommandLine &CmdL) // Stats - Dump some nice statistics /*{{{*/ // --------------------------------------------------------------------- /* */ -bool Stats(pkgCache &Cache) +bool Stats(CommandLine &Cmd) { - cout << "Total Package Names : " << Cache.Head().PackageCount << endl; + pkgCache &Cache = *GCache; + cout << "Total Package Names : " << Cache.Head().PackageCount << " (" << + SizeToStr(Cache.Head().PackageCount*Cache.Head().PackageSz) << ')' << endl; pkgCache::PkgIterator I = Cache.PkgBegin(); int Normal = 0; @@ -127,16 +233,71 @@ bool Stats(pkgCache &Cache) 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; + cout << "Total Distinct Versions: " << Cache.Head().VersionCount << " (" << + SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl; + cout << "Total Dependencies: " << Cache.Head().DependsCount << " (" << + SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl; + + cout << "Total Ver/File relations: " << Cache.Head().VerFileCount << " (" << + SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl; + cout << "Total Provides Mappings: " << Cache.Head().ProvidesCount << " (" << + SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl; + + // String list stats + unsigned long Size = 0; + unsigned long Count = 0; + for (pkgCache::StringItem *I = Cache.StringItemP + Cache.Head().StringList; + I!= Cache.StringItemP; I = Cache.StringItemP + I->NextItem) + { + Count++; + Size += strlen(Cache.StrP + I->String); + } + cout << "Total Globbed Strings: " << Count << " (" << SizeToStr(Size) << ')' << endl; + + unsigned long Slack = 0; + for (int I = 0; I != 7; I++) + Slack += Cache.Head().Pools[I].ItemSize*Cache.Head().Pools[I].Count; + cout << "Total Slack space: " << SizeToStr(Slack) << endl; + + unsigned long Total = 0; + Total = Slack + Size + Cache.Head().DependsCount*Cache.Head().DependencySz + + Cache.Head().VersionCount*Cache.Head().VersionSz + + Cache.Head().PackageCount*Cache.Head().PackageSz + + Cache.Head().VerFileCount*Cache.Head().VerFileSz + + Cache.Head().ProvidesCount*Cache.Head().ProvidesSz; + cout << "Total Space Accounted for: " << SizeToStr(Total) << endl; + + return true; +} + /*}}}*/ +// Check - Check some things about the cache /*{{{*/ +// --------------------------------------------------------------------- +/* Debug aide mostly */ +bool Check(CommandLine &Cmd) +{ + pkgCache &Cache = *GCache; + pkgCache::PkgIterator Pkg = Cache.PkgBegin(); + for (;Pkg.end() != true; Pkg++) + { + if (Pkg.Section() == 0 && Pkg->VersionList != 0) + cout << "Bad section " << Pkg.Name() << endl; + + for (pkgCache::VerIterator Cur = Pkg.VersionList(); + Cur.end() != true; Cur++) + { + if (Cur->Priority < 1 || Cur->Priority > 5) + cout << "Bad prio " << Pkg.Name() << ',' << Cur.VerStr() << " == " << (int)Cur->Priority << endl; + } + } return true; } /*}}}*/ // Dump - show everything /*{{{*/ // --------------------------------------------------------------------- /* */ -bool Dump(pkgCache &Cache) +bool Dump(CommandLine &Cmd) { + pkgCache &Cache = *GCache; for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) { cout << "Package: " << P.Name() << endl; @@ -155,7 +316,13 @@ bool Dump(pkgCache &Cache) cout << " Size: " << F->Size << endl; cout << " ID: " << F->ID << endl; cout << " Flags: " << F->Flags << endl; - cout << " Time: " << ctime(&F->mtime) << endl; + cout << " Time: " << TimeRFC1123(F->mtime) << endl; + cout << " Archive: " << F.Archive() << endl; + cout << " Component: " << F.Component() << endl; + cout << " Version: " << F.Version() << endl; + cout << " Origin: " << F.Origin() << endl; + cout << " Label: " << F.Label() << endl; + cout << " Architecture: " << F.Architecture() << endl; } return true; @@ -164,8 +331,9 @@ bool Dump(pkgCache &Cache) // DumpAvail - Print out the available list /*{{{*/ // --------------------------------------------------------------------- /* This is needed to make dpkg --merge happy */ -bool DumpAvail(pkgCache &Cache) +bool DumpAvail(CommandLine &Cmd) { + pkgCache &Cache = *GCache; unsigned char *Buffer = new unsigned char[Cache.HeaderP->MaxVerFileSize]; for (pkgCache::PkgFileIterator I = Cache.FileBegin(); I.end() == false; I++) @@ -222,7 +390,7 @@ bool DoAdd(CommandLine &CmdL) return _error->Error("You must give at least one file name"); // Open the cache - FileFd CacheF(_config->FindDir("Dir::Cache::srcpkgcache"),FileFd::WriteAny); + FileFd CacheF(_config->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny); if (_error->PendingError() == true) return false; @@ -239,7 +407,8 @@ bool DoAdd(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++) { Progress.OverallProgress(I - CmdL.FileList,Length,1,"Generating cache"); - + Progress.SubProgress(Length); + // Do the merge FileFd TagF(*I,FileFd::ReadOnly); debListParser Parser(TagF); @@ -254,7 +423,8 @@ bool DoAdd(CommandLine &CmdL) } Progress.Done(); - Stats(Gen.GetCache()); + GCache = &Gen.GetCache(); + Stats(CmdL); return true; } @@ -262,7 +432,7 @@ bool DoAdd(CommandLine &CmdL) // GenCaches - Call the main cache generator /*{{{*/ // --------------------------------------------------------------------- /* */ -bool GenCaches() +bool GenCaches(CommandLine &Cmd) { OpTextProgress Progress(*_config); @@ -274,17 +444,19 @@ bool GenCaches() // ShowHelp - Show a help screen /*{{{*/ // --------------------------------------------------------------------- /* */ -int ShowHelp() +bool ShowHelp(CommandLine &Cmd) { cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE << " compiled on " << __DATE__ << " " << __TIME__ << endl; + if (_config->FindB("version") == true) + return 100; cout << "Usage: apt-cache [options] command" << endl; cout << " apt-cache [options] add file1 [file1 ...]" << endl; cout << " apt-cache [options] showpkg pkg1 [pkg2 ...]" << endl; cout << endl; cout << "apt-cache is a low-level tool used to manipulate APT's binary" << endl; - cout << "cache files stored in " << _config->FindDir("Dir::Cache") << endl; + cout << "cache files stored in " << _config->FindFile("Dir::Cache") << endl; cout << "It is not ment for ordinary use only as a debug aide." << endl; cout << endl; cout << "Commands:" << endl; @@ -294,15 +466,18 @@ int ShowHelp() cout << " stats - Show some basic statistics" << endl; cout << " dump - Show the entire file in a terse form" << endl; cout << " dumpavail - Print an available file to stdout" << endl; + cout << " unmet - Show unmet dependencies" << endl; + cout << " check - Check the cache a bit" << endl; cout << endl; cout << "Options:" << endl; cout << " -h This help text." << endl; - cout << " -p=? The package cache. [" << _config->FindDir("Dir::Cache::pkgcache") << ']' << endl; - cout << " -s=? The source cache. [" << _config->FindDir("Dir::Cache::srcpkgcache") << ']' << endl; - cout << " -q Disable progress indicator. " << endl; + cout << " -p=? The package cache. [" << _config->FindFile("Dir::Cache::pkgcache") << ']' << endl; + cout << " -s=? The source cache. [" << _config->FindFile("Dir::Cache::srcpkgcache") << ']' << endl; + cout << " -q Disable progress indicator." << endl; + cout << " -i Show only important deps for the unmet command." << endl; cout << " -c=? Read this configuration file" << endl; cout << " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl; - cout << "See the apt-cache(8) and apt.conf(8) manual pages for more information." << endl; + cout << "See the apt-cache(8) and apt.conf(5) manual pages for more information." << endl; return 100; } /*}}}*/ @@ -320,12 +495,25 @@ int main(int argc,const char *argv[]) { CommandLine::Args Args[] = { {'h',"help","help",0}, + {'v',"version","version",0}, {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg}, {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg}, {'q',"quiet","quiet",CommandLine::IntLevel}, + {'i',"important","APT::Cache::Important",0}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}}; + CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp}, + {"add",&DoAdd}, + {"gencaches",&GenCaches}, + {0,0}}; + CommandLine::Dispatch CmdsB[] = {{"showpkg",&DumpPackage}, + {"stats",&Stats}, + {"dump",&Dump}, + {"dumpavail",&DumpAvail}, + {"unmet",&UnMet}, + {"check",&Check}, + {0,0}}; CacheInitialize(); @@ -341,61 +529,20 @@ int main(int argc,const char *argv[]) // See if the help should be shown if (_config->FindB("help") == true || CmdL.FileSize() == 0) - return ShowHelp(); - - while (1) - { - if (strcmp(CmdL.FileList[0],"add") == 0) - { - DoAdd(CmdL); - break; - } - - if (strcmp(CmdL.FileList[0],"gencaches") == 0) - { - GenCaches(); - break; - } + return ShowHelp(CmdL); + if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false) + { // Open the cache file - FileFd CacheF(_config->FindDir("Dir::Cache::pkgcache"),FileFd::ReadOnly); - if (_error->PendingError() == true) - break; - + FileFd CacheF(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); MMap Map(CacheF,MMap::Public | MMap::ReadOnly); - if (_error->PendingError() == true) - break; - - pkgCache Cache(Map); - if (_error->PendingError() == true) - break; - - if (strcmp(CmdL.FileList[0],"showpkg") == 0) - { - DumpPackage(Cache,CmdL); - break; - } - - if (strcmp(CmdL.FileList[0],"stats") == 0) + if (_error->PendingError() == false) { - Stats(Cache); - break; - } - - if (strcmp(CmdL.FileList[0],"dump") == 0) - { - Dump(Cache); - break; - } - - if (strcmp(CmdL.FileList[0],"dumpavail") == 0) - { - DumpAvail(Cache); - break; - } - - _error->Error("Invalid operation %s", CmdL.FileList[0]); - break; + pkgCache Cache(Map); + GCache = &Cache; + if (_error->PendingError() == false) + CmdL.DispatchArg(CmdsB); + } } // Print any errors or warnings found during parsing