X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/4c36e0626ecaa9585a55f595db477b5e6e6f669c..7230ad48a5c7766281c824c7373ecc8900e25995:/cmdline/apt-get.cc diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 3ac21347f..54c464a37 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.152 2004/01/09 07:32:39 mdz Exp $ +// $Id: apt-get.cc,v 1.156 2004/08/28 01:05:16 mdz Exp $ /* ###################################################################### apt-get - Cover for dpkg @@ -58,6 +58,7 @@ #include #include #include +#include /*}}}*/ using namespace std; @@ -66,7 +67,7 @@ ostream c0out(0); ostream c1out(0); ostream c2out(0); ofstream devnull("/dev/null"); -unsigned int ScreenWidth = 80; +unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */ // class CacheFile - Cover class for some dependency cache functions /*{{{*/ // --------------------------------------------------------------------- @@ -111,7 +112,7 @@ class CacheFile : public pkgCacheFile // YnPrompt - Yes No Prompt. /*{{{*/ // --------------------------------------------------------------------- /* Returns true on a Yes.*/ -bool YnPrompt() +bool YnPrompt(bool Default=true) { if (_config->FindB("APT::Get::Assume-Yes",false) == true) { @@ -126,7 +127,7 @@ bool YnPrompt() return false; if (strlen(response) == 0) - return true; + return Default; regex_t Pattern; int Res; @@ -270,7 +271,7 @@ void ShowBroken(ostream &out,CacheFile &Cache,bool Now) // Compute a single dependency element (glob or) pkgCache::DepIterator Start; pkgCache::DepIterator End; - D.GlobOr(Start,End); + D.GlobOr(Start,End); // advances D if (Cache->IsImportantDep(End) == false) continue; @@ -541,9 +542,10 @@ bool ShowEssential(ostream &out,CacheFile &Cache) } delete [] Added; - return ShowList(out,_("WARNING: The following essential packages will be removed\n" + return ShowList(out,_("WARNING: The following essential packages will be removed.\n" "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList); } + /*}}}*/ // Stats - Show some statistics /*{{{*/ // --------------------------------------------------------------------- @@ -630,7 +632,7 @@ bool CacheFile::CheckDeps(bool AllowBroken) // Check that the system is OK if (DCache->DelCount() != 0 || DCache->InstCount() != 0) - return _error->Error("Internal Error, non-zero counts"); + return _error->Error("Internal error, non-zero counts"); // Apply corrections for half-installed packages if (pkgApplyStatus(*DCache) == false) @@ -666,6 +668,49 @@ bool CacheFile::CheckDeps(bool AllowBroken) return true; } + +static bool CheckAuth(pkgAcquire& Fetcher) +{ + string UntrustedList; + for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I) + { + if (!(*I)->IsTrusted()) + { + UntrustedList += string((*I)->ShortDesc()) + " "; + } + } + + if (UntrustedList == "") + { + return true; + } + + ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,""); + + if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true) + { + c2out << _("Authentication warning overridden.\n"); + return true; + } + + if (_config->FindI("quiet",0) < 2 + && _config->FindB("APT::Get::Assume-Yes",false) == false) + { + c2out << _("Install these packages without verification [y/N]? ") << flush; + if (!YnPrompt(false)) + return _error->Error(_("Some packages could not be authenticated")); + + return true; + } + else if (_config->FindB("APT::Get::Force-Yes",false) == true) + { + return true; + } + + return _error->Error(_("There are problems and -y was used without --force-yes")); +} + + /*}}}*/ // InstallPackages - Actually download and install the packages /*{{{*/ @@ -673,7 +718,7 @@ bool CacheFile::CheckDeps(bool AllowBroken) /* This displays the informative messages describing what is going to happen and then calls the download routines */ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, - bool Saftey = true) + bool Safety = true) { if (_config->FindB("APT::Get::Purge",false) == true) { @@ -701,12 +746,12 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, Essential = !ShowEssential(c1out,Cache); Fail |= Essential; Stats(c1out,Cache); - + // Sanity check if (Cache->BrokenCount() != 0) { ShowBroken(c1out,Cache,false); - return _error->Error("Internal Error, InstallPackages was called with broken packages!"); + return _error->Error(_("Internal error, InstallPackages was called with broken packages!")); } if (Cache->DelCount() == 0 && Cache->InstCount() == 0 && @@ -715,17 +760,18 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, // No remove flag if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false) - return _error->Error(_("Packages need to be removed but Remove is disabled.")); + return _error->Error(_("Packages need to be removed but remove is disabled.")); // Run the simulator .. if (_config->FindB("APT::Get::Simulate") == true) { pkgSimulate PM(Cache); - pkgPackageManager::OrderResult Res = PM.DoInstall(); + int status_fd = _config->FindI("APT::Status-Fd",-1); + pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd); if (Res == pkgPackageManager::Failed) return false; if (Res != pkgPackageManager::Completed) - return _error->Error("Internal Error, Ordering didn't finish"); + return _error->Error(_("Internal error, Ordering didn't finish")); return true; } @@ -766,7 +812,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, if (DebBytes != Cache->DebSize()) { c0out << DebBytes << ',' << Cache->DebSize() << endl; - c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl; + c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << endl; } // Number of bytes @@ -796,7 +842,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, struct statvfs Buf; string OutputDir = _config->FindDir("Dir::Cache::Archives"); if (statvfs(OutputDir.c_str(),&Buf) != 0) - return _error->Errno("statvfs","Couldn't determine free space in %s", + return _error->Errno("statvfs",_("Couldn't determine free space in %s"), OutputDir.c_str()); if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) return _error->Error(_("You don't have enough free space in %s."), @@ -811,14 +857,14 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, return _error->Error(_("There are problems and -y was used without --force-yes")); } - if (Essential == true && Saftey == true) + if (Essential == true && Safety == true) { if (_config->FindB("APT::Get::Trivial-Only",false) == true) return _error->Error(_("Trivial Only specified but this is not a trivial operation.")); const char *Prompt = _("Yes, do as I say!"); ioprintf(c2out, - _("You are about to do something potentially harmful\n" + _("You are about to do something potentially harmful.\n" "To continue type in the phrase '%s'\n" " ?] "),Prompt); c2out << flush; @@ -839,7 +885,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, if (_config->FindI("quiet",0) < 2 && _config->FindB("APT::Get::Assume-Yes",false) == false) { - c2out << _("Do you want to continue? [Y/n] ") << flush; + c2out << _("Do you want to continue [Y/n]? ") << flush; if (YnPrompt() == false) { @@ -860,6 +906,9 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, return true; } + if (!CheckAuth(Fetcher)) + return false; + /* Unlock the dpkg lock if we are not going to be doing an install after. */ if (_config->FindB("APT::Get::Download-Only",false) == true) @@ -943,11 +992,12 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, if (Failed == true && PM->FixMissing() == false) { cerr << _("Unable to correct missing packages.") << endl; - return _error->Error(_("Aborting Install.")); + return _error->Error(_("Aborting install.")); } - + _system->UnLock(); - pkgPackageManager::OrderResult Res = PM->DoInstall(); + int status_fd = _config->FindI("APT::Status-Fd",-1); + pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd); if (Res == pkgPackageManager::Failed || _error->PendingError() == true) return false; if (Res == pkgPackageManager::Completed) @@ -1141,24 +1191,54 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, string VerTag; string TmpSrc = Name; string::size_type Slash = TmpSrc.rfind('='); + + // honor default release + string DefRel = _config->Find("APT::Default-Release"); + pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); + if (Slash != string::npos) { VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end()); TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash); + } + else if(!Pkg.end() && DefRel.empty() == false) + { + // we have a default release, try to locate the pkg. we do it like + // this because GetCandidateVer() will not "downgrade", that means + // "apt-get source -t stable apt" won't work on a unstable system + for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; + Ver++) + { + for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; + VF++) + { + /* If this is the status file, and the current version is not the + version in the status file (ie it is not installed, or somesuch) + then it is not a candidate for installation, ever. This weeds + out bogus entries that may be due to config-file states, or + other. */ + if ((VF.File()->Flags & pkgCache::Flag::NotSource) == + pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver) + continue; + + //std::cout << VF.File().Archive() << std::endl; + if(VF.File().Archive() && (VF.File().Archive() == DefRel)) + { + VerTag = Ver.VerStr(); + break; + } + } + } } - + /* Lookup the version of the package we would install if we were to install a version and determine the source package name, then look - in the archive for a source package of the same name. In theory - we could stash the version string as well and match that too but - today there aren't multi source versions in the archive. */ - if (_config->FindB("APT::Get::Only-Source") == false && - VerTag.empty() == true) + in the archive for a source package of the same name. */ + if (_config->FindB("APT::Get::Only-Source") == false) { - pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); if (Pkg.end() == false) { - pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); + pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); if (Ver.end() == false) { pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); @@ -1216,10 +1296,7 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, } } - if (Last == 0) - return 0; - - if (Last->Jump(Offset) == false) + if (Last == 0 || Last->Jump(Offset) == false) return 0; return Last; @@ -1252,19 +1329,25 @@ bool DoUpdate(CommandLine &CmdL) AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); pkgAcquire Fetcher(&Stat); - // Populate it with the source selection - if (List.GetIndexes(&Fetcher) == false) - return false; // Just print out the uris an exit if the --print-uris flag was used if (_config->FindB("APT::Get::Print-URIs") == true) { + // Populate it with the source selection and get all Indexes + // (GetAll=true) + if (List.GetIndexes(&Fetcher,true) == false) + return false; + pkgAcquire::UriIterator I = Fetcher.UriBegin(); for (; I != Fetcher.UriEnd(); I++) cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl; return true; } + + // Populate it with the source selection + if (List.GetIndexes(&Fetcher) == false) + return false; // Run it if (Fetcher.Run() == pkgAcquire::Failed) @@ -1302,6 +1385,52 @@ bool DoUpdate(CommandLine &CmdL) return true; } /*}}}*/ +// DoAutomaticRemove - Remove all automatic unused packages /*{{{*/ +// --------------------------------------------------------------------- +/* Remove unused automatic packages */ +bool DoAutomaticRemove(CacheFile &Cache) +{ + if(_config->FindI("Debug::pkgAutoRemove",false)) + std::cout << "DoAutomaticRemove()" << std::endl; + + if (_config->FindB("APT::Get::Remove",true) == false) + return _error->Error(_("We are not supposed to delete stuff, can't " + "start AutoRemover")); + + { + pkgDepCache::ActionGroup group(*Cache); + + // look over the cache to see what can be removed + for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg) + { + if (Cache[Pkg].Garbage) + { + if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install()) + fprintf(stdout,"We could delete %s\n", Pkg.Name()); + + if(Pkg.CurrentVer() != 0 && Pkg->CurrentState != pkgCache::State::ConfigFiles) + Cache->MarkDelete(Pkg, _config->FindB("APT::Get::Purge", false)); + else + Cache->MarkKeep(Pkg, false, false); + } + } + } + + // Now see if we destroyed anything + if (Cache->BrokenCount() != 0) + { + c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n" + "shouldn't happen. Please file a bug report against apt.") << endl; + c1out << endl; + c1out << _("The following information may help to resolve the situation:") << endl; + c1out << endl; + ShowBroken(c1out,Cache,false); + + return _error->Error(_("Internal Error, AutoRemover broke stuff")); + } + return true; +} + // DoUpgrade - Upgrade all packages /*{{{*/ // --------------------------------------------------------------------- /* Upgrade all packages without installing new packages or erasing old @@ -1316,7 +1445,7 @@ bool DoUpgrade(CommandLine &CmdL) if (pkgAllUpgrade(Cache) == false) { ShowBroken(c1out,Cache,false); - return _error->Error(_("Internal Error, AllUpgrade broke stuff")); + return _error->Error(_("Internal error, AllUpgrade broke stuff")); } return InstallPackages(Cache,true); @@ -1327,6 +1456,15 @@ bool DoUpgrade(CommandLine &CmdL) /* Install named packages */ bool DoInstall(CommandLine &CmdL) { + // Lock the list directory + FileFd Lock; + if (_config->FindB("Debug::NoLocking",false) == false) + { + Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock")); + if (_error->PendingError() == true) + return _error->Error(_("Unable to lock the list directory")); + } + CacheFile Cache; if (Cache.OpenForInstall() == false || Cache.CheckDeps(CmdL.FileSize() != 1) == false) @@ -1344,6 +1482,11 @@ bool DoInstall(CommandLine &CmdL) bool DefRemove = false; if (strcasecmp(CmdL.FileList[0],"remove") == 0) DefRemove = true; + else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0) + { + _config->Set("APT::Get::AutomaticRemove", "true"); + DefRemove = true; + } for (const char **I = CmdL.FileList + 1; *I != 0; I++) { @@ -1493,6 +1636,11 @@ bool DoInstall(CommandLine &CmdL) return _error->Error(_("Broken packages")); } + if (_config->FindB("APT::Get::AutomaticRemove")) { + if (!DoAutomaticRemove(Cache)) + return false; + } + /* Print out a list of packages that are going to be installed extra to what the user asked */ if (Cache->InstCount() != ExpectedInst) @@ -1512,8 +1660,8 @@ bool DoInstall(CommandLine &CmdL) if (*J == 0) { List += string(I.Name()) + " "; - VersionsList += string(Cache[I].CandVersion) + "\n"; - } + VersionsList += string(Cache[I].CandVersion) + "\n"; + } } ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList); @@ -1532,32 +1680,36 @@ bool DoInstall(CommandLine &CmdL) continue; for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++) - { - for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++) - { + { + for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ) + { pkgCache::DepIterator Start; pkgCache::DepIterator End; - D.GlobOr(Start,End); + D.GlobOr(Start,End); // advances D /* * If this is a virtual package, we need to check the list of * packages that provide it and see if any of those are * installed */ - pkgCache::PrvIterator Prv = Start.TargetPkg().ProvidesList(); + bool providedBySomething = false; - for (; Prv.end() != true; Prv++) - if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) { + for (pkgCache::PrvIterator Prv = Start.TargetPkg().ProvidesList(); + Prv.end() != true; + Prv++) + if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) + { providedBySomething = true; break; } if (providedBySomething) continue; - do - { + for(;;) + { /* Skip if package is installed already, or is about to be */ string target = string(Start.TargetPkg().Name()) + " "; + if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install || Cache[Start.TargetPkg()].Install()) break; @@ -1575,12 +1727,13 @@ bool DoInstall(CommandLine &CmdL) RecommendsList += target; RecommendsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; } - if (Start == End) - break; - Start++; - } while (1); - } - } + + if (Start >= End) + break; + Start++; + } + } + } } ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions); ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions); @@ -1590,7 +1743,7 @@ bool DoInstall(CommandLine &CmdL) // See if we need to prompt if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0) return InstallPackages(Cache,false,false); - + return InstallPackages(Cache,false); } /*}}}*/ @@ -1603,7 +1756,7 @@ bool DoDistUpgrade(CommandLine &CmdL) if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false) return false; - c0out << _("Calculating Upgrade... ") << flush; + c0out << _("Calculating upgrade... ") << flush; if (pkgDistUpgrade(*Cache) == false) { c0out << _("Failed") << endl; @@ -1676,7 +1829,7 @@ bool DoDSelectUpgrade(CommandLine &CmdL) if (Fix.Resolve() == false) { ShowBroken(c1out,Cache,false); - return _error->Error("Internal Error, problem resolver broke stuff"); + return _error->Error(_("Internal error, problem resolver broke stuff")); } } @@ -1684,7 +1837,7 @@ bool DoDSelectUpgrade(CommandLine &CmdL) if (pkgAllUpgrade(Cache) == false) { ShowBroken(c1out,Cache,false); - return _error->Error("Internal Error, problem resolver broke stuff"); + return _error->Error(_("Internal error, problem resolver broke stuff")); } return InstallPackages(Cache,false); @@ -1855,7 +2008,7 @@ bool DoSource(CommandLine &CmdL) struct statvfs Buf; string OutputDir = "."; if (statvfs(OutputDir.c_str(),&Buf) != 0) - return _error->Errno("statvfs","Couldn't determine free space in %s", + return _error->Errno("statvfs",_("Couldn't determine free space in %s"), OutputDir.c_str()); if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) return _error->Error(_("You don't have enough free space in %s"), @@ -1872,7 +2025,7 @@ bool DoSource(CommandLine &CmdL) if (_config->FindB("APT::Get::Simulate",false) == true) { for (unsigned I = 0; I != J; I++) - ioprintf(cout,_("Fetch Source %s\n"),Dsc[I].Package.c_str()); + ioprintf(cout,_("Fetch source %s\n"),Dsc[I].Package.c_str()); return true; } @@ -1944,6 +2097,7 @@ bool DoSource(CommandLine &CmdL) if (system(S) != 0) { fprintf(stderr,_("Unpack command '%s' failed.\n"),S); + fprintf(stderr,_("Check if the 'dpkg-dev' package is installed.\n")); _exit(1); } } @@ -2257,7 +2411,7 @@ bool ShowHelp(CommandLine &CmdL) if (_config->FindB("version") == true) { - cout << _("Supported Modules:") << endl; + cout << _("Supported modules:") << endl; for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++) { @@ -2332,7 +2486,7 @@ bool ShowHelp(CommandLine &CmdL) " -b Build the source package after fetching it\n" " -V Show verbose version numbers\n" " -c=? Read this configuration file\n" - " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n" + " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n" "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n" "pages for more information and options.\n" " This APT has Super Cow Powers.\n"); @@ -2351,7 +2505,8 @@ void GetInitialize() _config->Set("APT::Get::Assume-Yes",false); _config->Set("APT::Get::Fix-Broken",false); _config->Set("APT::Get::Force-Yes",false); - _config->Set("APT::Get::APT::Get::No-List-Cleanup",true); + _config->Set("APT::Get::List-Cleanup",true); + _config->Set("APT::Get::AutomaticRemove",false); } /*}}}*/ // SigWinch - Window size change signal handler /*{{{*/ @@ -2407,6 +2562,8 @@ int main(int argc,const char *argv[]) {0,"remove","APT::Get::Remove",0}, {0,"only-source","APT::Get::Only-Source",0}, {0,"arch-only","APT::Get::Arch-Only",0}, + {0,"auto-remove","APT::Get::AutomaticRemove",0}, + {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}}; @@ -2414,6 +2571,7 @@ int main(int argc,const char *argv[]) {"upgrade",&DoUpgrade}, {"install",&DoInstall}, {"remove",&DoInstall}, + {"autoremove",&DoInstall}, {"dist-upgrade",&DoDistUpgrade}, {"dselect-upgrade",&DoDSelectUpgrade}, {"build-dep",&DoBuildDep},