X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/f292686be49d32fdfecc8e386a3d5b4865b2f913..1b6d659c38ff5fd44aa4bc22f28cfeae43e8f8f5:/cmdline/apt-get.cc diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index b56b441c4..d7727c7d3 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: apt-get.cc,v 1.73 1999/09/05 20:27:37 jgg Exp $ +// $Id: apt-get.cc,v 1.84 1999/10/24 06:03:48 jgg Exp $ /* ###################################################################### apt-get - Cover for dpkg @@ -52,6 +52,7 @@ #include #include #include +#include #include /*}}}*/ @@ -154,7 +155,7 @@ bool ShowList(ostream &out,string Title,string List) /* This prints out the names of all the packages that are broken along with the name of each each broken dependency and a quite version description. */ -void ShowBroken(ostream &out,CacheFile &Cache) +void ShowBroken(ostream &out,CacheFile &Cache,bool Now) { out << "Sorry, but the following packages have unmet dependencies:" << endl; for (unsigned J = 0; J < Cache->Head().PackageCount; J++) @@ -166,7 +167,7 @@ void ShowBroken(ostream &out,CacheFile &Cache) // Print out each package and the failed dependencies out <<" " << I.Name() << ":"; - int Indent = strlen(I.Name()) + 3; + unsigned Indent = strlen(I.Name()) + 3; bool First = true; if (Cache[I].InstVerIter(Cache).end() == true) { @@ -184,44 +185,62 @@ void ShowBroken(ostream &out,CacheFile &Cache) if (Cache->IsImportantDep(End) == false || (Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) continue; - - if (First == false) - for (int J = 0; J != Indent; J++) - out << ' '; - First = false; - out << ' ' << End.DepType() << ": " << End.TargetPkg().Name(); - - // Show a quick summary of the version requirements - if (End.TargetVer() != 0) - out << " (" << End.CompType() << " " << End.TargetVer() << - ")"; - - /* Show a summary of the target package if possible. In the case - of virtual packages we show nothing */ - - pkgCache::PkgIterator Targ = End.TargetPkg(); - if (Targ->ProvidesList == 0) + bool FirstOr = true; + while (1) { - out << " but "; - pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache); - if (Ver.end() == false) - out << Ver.VerStr() << " is installed"; + if (First == false) + for (unsigned J = 0; J != Indent; J++) + out << ' '; + First = false; + + if (FirstOr == false) + { + for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++) + out << ' '; + } else + out << ' ' << End.DepType() << ": "; + FirstOr = false; + + out << Start.TargetPkg().Name(); + + // Show a quick summary of the version requirements + if (Start.TargetVer() != 0) + out << " (" << Start.CompType() << " " << Start.TargetVer() << + ")"; + + /* Show a summary of the target package if possible. In the case + of virtual packages we show nothing */ + pkgCache::PkgIterator Targ = Start.TargetPkg(); + if (Targ->ProvidesList == 0) { - if (Cache[Targ].CandidateVerIter(Cache).end() == true) + out << " but "; + pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache); + if (Ver.end() == false) + out << Ver.VerStr() << (Now?" is installed":" is to be installed"); + else { - if (Targ->ProvidesList == 0) - out << "it is not installable"; + if (Cache[Targ].CandidateVerIter(Cache).end() == true) + { + if (Targ->ProvidesList == 0) + out << "it is not installable"; + else + out << "it is a virtual package"; + } else - out << "it is a virtual package"; - } - else - out << "it is not installed"; - } - } - - out << endl; + out << (Now?"it is not installed":"it is not going to be installed"); + } + } + + if (Start != End) + cout << " or"; + out << endl; + + if (Start == End) + break; + Start++; + } } } } @@ -389,6 +408,7 @@ void Stats(ostream &out,pkgDepCache &Dep) { unsigned long Upgrade = 0; unsigned long Install = 0; + unsigned long ReInstall = 0; for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++) { if (Dep[I].NewInstall() == true) @@ -396,11 +416,15 @@ void Stats(ostream &out,pkgDepCache &Dep) else if (Dep[I].Upgrade() == true) Upgrade++; + if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall) + ReInstall++; } out << Upgrade << " packages upgraded, " << - Install << " newly installed, " << - Dep.DelCount() << " to remove and " << + Install << " newly installed, "; + if (ReInstall != 0) + out << ReInstall << " reinstalled, "; + out << Dep.DelCount() << " to remove and " << Dep.KeepCount() << " not upgraded." << endl; if (Dep.BadCount() != 0) @@ -467,7 +491,7 @@ bool CacheFile::CheckDeps(bool AllowBroken) if (pkgFixBroken(*Cache) == false || Cache->BrokenCount() != 0) { c1out << " failed." << endl; - ShowBroken(c1out,*this); + ShowBroken(c1out,*this,true); return _error->Error("Unable to correct dependencies"); } @@ -479,7 +503,7 @@ bool CacheFile::CheckDeps(bool AllowBroken) else { c1out << "You might want to run `apt-get -f install' to correct these." << endl; - ShowBroken(c1out,*this); + ShowBroken(c1out,*this,true); return _error->Error("Unmet dependencies. Try using -f."); } @@ -522,11 +546,11 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = // Sanity check if (Cache->BrokenCount() != 0) { - ShowBroken(c1out,Cache); + ShowBroken(c1out,Cache,false); return _error->Error("Internal Error, InstallPackages was called with broken packages!"); } - if (Cache->DelCount() == 0 && Cache->InstCount() == 0 && + if (Cache->DelCount() == 0 && Cache->InstCount() == 0 && Cache->BadCount() == 0) return true; @@ -580,16 +604,6 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = c0out << DebBytes << ',' << Cache->DebSize() << endl; c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl; } - - // Check for enough free space - struct statfs Buf; - string OutputDir = _config->FindDir("Dir::Cache::Archives"); - if (statfs(OutputDir.c_str(),&Buf) != 0) - return _error->Errno("statfs","Couldn't determine free space in %s", - OutputDir.c_str()); - if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) - return _error->Error("Sorry, you don't have enough free space in %s", - OutputDir.c_str()); // Number of bytes c1out << "Need to get "; @@ -599,6 +613,16 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = c1out << SizeToStr(DebBytes) << 'B'; c1out << " of archives. After unpacking "; + + // Check for enough free space + struct statfs Buf; + string OutputDir = _config->FindDir("Dir::Cache::Archives"); + if (statfs(OutputDir.c_str(),&Buf) != 0) + return _error->Errno("statfs","Couldn't determine free space in %s", + OutputDir.c_str()); + if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) + return _error->Error("Sorry, you don't have enough free space in %s to hold all the .debs.", + OutputDir.c_str()); // Size delta if (Cache->UsrSize() >= 0) @@ -661,7 +685,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = while (1) { if (_config->FindB("APT::Get::No-Download",false) == false) - if( Fetcher.Run() == pkgAcquire::Failed) + if (Fetcher.Run() == pkgAcquire::Failed) return false; // Print out errors @@ -673,8 +697,6 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = (*I)->Complete == true) continue; - (*I)->Finished(); - if ((*I)->Status == pkgAcquire::Item::StatIdle) { Transient = true; @@ -686,6 +708,16 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = cerr << " " << (*I)->ErrorText << endl; Failed = true; } + + /* If we are in no download mode and missing files then there were + 'failures' then the user must specify -m. Furthermore, there + is no such thing as a transient error in no-download mode! */ + if (Transient == true && + _config->FindB("APT::Get::No-Download",false) == true) + { + Transient = false; + Failed = true; + } if (_config->FindB("APT::Get::Download-Only",false) == true) { @@ -696,12 +728,6 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false) { - /*if (Transient == true) - { - c2out << "Upgrading with disk swapping is not supported in this version." << endl; - c2out << "Try running multiple times with --fix-missing" << endl; - }*/ - return _error->Error("Unable to fetch some archives, maybe try with --fix-missing?"); } @@ -729,6 +755,115 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = } } /*}}}*/ +// TryToInstall - Try to install a single package /*{{{*/ +// --------------------------------------------------------------------- +/* This used to be inlined in DoInstall, but with the advent of regex package + name matching it was split out.. */ +bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, + pkgProblemResolver &Fix,bool Remove,bool BrokenFix, + unsigned int &ExpectedInst,bool AllowFail = true) +{ + /* This is a pure virtual package and there is a single available + provides */ + if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 && + Pkg.ProvidesList()->NextProvides == 0) + { + pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg(); + c1out << "Note, installing " << Tmp.Name() << " instead of " << Pkg.Name() << endl; + Pkg = Tmp; + } + + // Handle the no-upgrade case + if (_config->FindB("APT::Get::no-upgrade",false) == true && + Pkg->CurrentVer != 0) + { + if (AllowFail == true) + c1out << "Skipping " << Pkg.Name() << ", it is already installed and no-upgrade is set." << endl; + return true; + } + + // Check if there is something at all to install + pkgDepCache::StateCache &State = Cache[Pkg]; + if (State.CandidateVer == 0) + { + if (AllowFail == false) + return false; + + if (Pkg->ProvidesList != 0) + { + c1out << "Package " << Pkg.Name() << " is a virtual package provided by:" << endl; + + pkgCache::PrvIterator I = Pkg.ProvidesList(); + for (; I.end() == false; I++) + { + pkgCache::PkgIterator Pkg = I.OwnerPkg(); + + if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) + { + if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false) + c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << + " [Installed]"<< endl; + else + c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl; + } + } + c1out << "You should explicitly select one to install." << endl; + } + else + { + c1out << "Package " << Pkg.Name() << " has no available version, but exists in the database." << endl; + c1out << "This typically means that the package was mentioned in a dependency and " << endl; + c1out << "never uploaded, or that it is an obsolete package." << endl; + + string List; + pkgCache::DepIterator Dep = Pkg.RevDependsList(); + for (; Dep.end() == false; Dep++) + { + if (Dep->Type != pkgCache::Dep::Replaces) + continue; + List += string(Dep.ParentPkg().Name()) + " "; + } + ShowList(c1out,"However the following packages replace it:",List); + } + + _error->Error("Package %s has no installation candidate",Pkg.Name()); + return false; + } + + Fix.Protect(Pkg); + if (Remove == true) + { + Fix.Remove(Pkg); + Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false)); + return true; + } + + // Install it + Cache.MarkInstall(Pkg,false); + if (State.Install() == false) + { + if (_config->FindB("APT::Get::ReInstall",false) == true) + { + if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false) + c1out << "Sorry, re-installation of " << Pkg.Name() << " is not possible, it cannot be downloaded" << endl; + else + Cache.SetReInstall(Pkg,true); + } + else + { + if (AllowFail == true) + c1out << "Sorry, " << Pkg.Name() << " is already the newest version" << endl; + } + } + else + ExpectedInst++; + + // Install it with autoinstalling enabled. + if (State.InstBroken() == true && BrokenFix == false) + Cache.MarkInstall(Pkg,true); + return true; +} + /*}}}*/ // DoUpdate - Update the package lists /*{{{*/ // --------------------------------------------------------------------- @@ -774,6 +909,8 @@ bool DoUpdate(CommandLine &) (*I)->Finished(); + cerr << "Failed to fetch " << (*I)->DescURI() << endl; + cerr << " " << (*I)->ErrorText << endl; Failed = true; } @@ -808,7 +945,7 @@ bool DoUpgrade(CommandLine &CmdL) // Do the upgrade if (pkgAllUpgrade(Cache) == false) { - ShowBroken(c1out,Cache); + ShowBroken(c1out,Cache,false); return _error->Error("Internal Error, AllUpgrade broke stuff"); } @@ -871,78 +1008,44 @@ bool DoInstall(CommandLine &CmdL) pkgCache::PkgIterator Pkg = Cache->FindPkg(S); Packages++; if (Pkg.end() == true) - return _error->Error("Couldn't find package %s",S); - - // Handle the no-upgrade case - if (_config->FindB("APT::Get::no-upgrade",false) == true && - Pkg->CurrentVer != 0) { - c1out << "Skipping " << Pkg.Name() << ", it is already installed and no-upgrade is set." << endl; - continue; - } - - // Check if there is something new to install - pkgDepCache::StateCache &State = (*Cache)[Pkg]; - if (State.CandidateVer == 0) - { - if (Pkg->ProvidesList != 0) - { - c1out << "Package " << S << " is a virtual package provided by:" << endl; - - pkgCache::PrvIterator I = Pkg.ProvidesList(); - for (; I.end() == false; I++) - { - pkgCache::PkgIterator Pkg = I.OwnerPkg(); - - if ((*Cache)[Pkg].CandidateVerIter(*Cache) == I.OwnerVer()) - { - if ((*Cache)[Pkg].Install() == true && (*Cache)[Pkg].NewInstall() == false) - c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << - " [Installed]"<< endl; - else - c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl; - } - } - c1out << "You should explicly select one to install." << endl; - } - else + // Check if the name is a regex + const char *I; + for (I = S; *I != 0; I++) + if (*I == '.' || *I == '?' || *I == '*') + break; + if (*I == 0) + return _error->Error("Couldn't find package %s",S); + + // Regexs must always be confirmed + ExpectedInst += 1000; + + // Compile the regex pattern + regex_t Pattern; + if (regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE | + REG_NOSUB) != 0) + return _error->Error("Regex compilation error"); + + // Run over the matches + bool Hit = false; + for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) { - c1out << "Package " << S << " has no available version, but exists in the database." << endl; - c1out << "This typically means that the package was mentioned in a dependency and " << endl; - c1out << "never uploaded, or that it is an obsolete package." << endl; + if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0) + continue; - string List; - pkgCache::DepIterator Dep = Pkg.RevDependsList(); - for (; Dep.end() == false; Dep++) - { - if (Dep->Type != pkgCache::Dep::Replaces) - continue; - List += string(Dep.ParentPkg().Name()) + " "; - } - ShowList(c1out,"However the following packages replace it:",List); + Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix, + ExpectedInst,false); } + regfree(&Pattern); - return _error->Error("Package %s has no installation candidate",S); + if (Hit == false) + return _error->Error("Couldn't find package %s",S); } - - Fix.Protect(Pkg); - if (Remove == true) - { - Fix.Remove(Pkg); - Cache->MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false)); - continue; - } - - // Install it - Cache->MarkInstall(Pkg,false); - if (State.Install() == false) - c1out << "Sorry, " << S << " is already the newest version" << endl; else - ExpectedInst++; - - // Install it with autoinstalling enabled. - if (State.InstBroken() == true && BrokenFix == false) - Cache->MarkInstall(Pkg,true); + { + if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false) + return false; + } } /* If we are in the Broken fixing mode we do not attempt to fix the @@ -951,7 +1054,7 @@ bool DoInstall(CommandLine &CmdL) if (BrokenFix == true && Cache->BrokenCount() != 0) { c1out << "You might want to run `apt-get -f install' to correct these:" << endl; - ShowBroken(c1out,Cache); + ShowBroken(c1out,Cache,false); return _error->Error("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."); } @@ -978,7 +1081,7 @@ bool DoInstall(CommandLine &CmdL) c1out << "The following information may help to resolve the situation:" << endl; c1out << endl; - ShowBroken(c1out,Cache); + ShowBroken(c1out,Cache,false); return _error->Error("Sorry, broken packages"); } @@ -1025,7 +1128,7 @@ bool DoDistUpgrade(CommandLine &CmdL) if (pkgDistUpgrade(*Cache) == false) { c0out << "Failed" << endl; - ShowBroken(c1out,Cache); + ShowBroken(c1out,Cache,false); return false; } @@ -1093,7 +1196,7 @@ bool DoDSelectUpgrade(CommandLine &CmdL) if (Fix.Resolve() == false) { - ShowBroken(c1out,Cache); + ShowBroken(c1out,Cache,false); return _error->Error("Internal Error, problem resolver broke stuff"); } } @@ -1101,7 +1204,7 @@ bool DoDSelectUpgrade(CommandLine &CmdL) // Now upgrade everything if (pkgAllUpgrade(Cache) == false) { - ShowBroken(c1out,Cache); + ShowBroken(c1out,Cache,false); return _error->Error("Internal Error, problem resolver broke stuff"); } @@ -1113,6 +1216,15 @@ bool DoDSelectUpgrade(CommandLine &CmdL) /* */ bool DoClean(CommandLine &CmdL) { + // Lock the archive directory + FileFd Lock; + if (_config->FindB("Debug::NoLocking",false) == false) + { + Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); + if (_error->PendingError() == true) + return _error->Error("Unable to lock the download directory"); + } + pkgAcquire Fetcher; Fetcher.Clean(_config->FindDir("Dir::Cache::archives")); Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/"); @@ -1137,6 +1249,15 @@ class LogCleaner : public pkgArchiveCleaner bool DoAutoClean(CommandLine &CmdL) { + // Lock the archive directory + FileFd Lock; + if (_config->FindB("Debug::NoLocking",false) == false) + { + Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); + if (_error->PendingError() == true) + return _error->Error("Unable to lock the download directory"); + } + CacheFile Cache; if (Cache.Open() == false) return false; @@ -1277,6 +1398,16 @@ bool DoSource(CommandLine &CmdL) if (I->Path.find(".diff.gz") != string::npos) Comp = "diff"; + // Diff only mode only fetches .diff files + if (_config->FindB("APT::Get::Diff-Only",false) == true && + Comp != "diff") + continue; + + // Tar only mode only fetches .tar files + if (_config->FindB("APT::Get::Tar-Only",false) == true && + Comp != "tar") + continue; + new pkgAcqFile(&Fetcher,Last->Source()->ArchiveURI(I->Path), I->MD5Hash,I->Size,Last->Source()->SourceInfo(Src, Last->Version(),Comp),Src); @@ -1354,6 +1485,11 @@ bool DoSource(CommandLine &CmdL) { string Dir = Dsc[I].Package + '-' + pkgBaseVersion(Dsc[I].Version.c_str()); + // Diff only mode only fetches .diff files + if (_config->FindB("APT::Get::Diff-Only",false) == true || + _config->FindB("APT::Get::Tar-Only",false) == true) + continue; + // See if the package is already unpacked struct stat Stat; if (stat(Dir.c_str(),&Stat) == 0 && @@ -1514,8 +1650,11 @@ int main(int argc,const char *argv[]) {0,"no-upgrade","APT::Get::no-upgrade",0}, {0,"force-yes","APT::Get::force-yes",0}, {0,"print-uris","APT::Get::Print-URIs",0}, + {0,"diff-only","APT::Get::Diff-Only",0}, + {0,"tar-only","APT::Get::tar-Only",0}, {0,"purge","APT::Get::Purge",0}, {0,"list-cleanup","APT::Get::List-Cleanup",0}, + {0,"reinstall","APT::Get::ReInstall",0}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}};