X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/a0f9b6bee8dae6eff15873db311f5a44cbb16fb3..3772dc74d3e7767980a011e01302dd688b3764fc:/cmdline/apt-get.cc?ds=inline diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 48b21a31f..64882e3e8 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,7 @@ #include "acqprogress.h" +#include #include #include #include @@ -1366,7 +1368,7 @@ bool DoUpdate(CommandLine &CmdL) } // Clean out any old list files - if (_config->FindB("APT::Get::List-Cleanup",true) == true) + if (!Failed && _config->FindB("APT::Get::List-Cleanup",true) == true) { if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false || Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false) @@ -1409,15 +1411,6 @@ 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) @@ -1616,68 +1609,86 @@ bool DoInstall(CommandLine &CmdL) string SuggestsVersions, RecommendsVersions; for (unsigned J = 0; J < Cache->Head().PackageCount; J++) { - pkgCache::PkgIterator I(Cache,Cache.List[J]); + pkgCache::PkgIterator Pkg(Cache,Cache.List[J]); /* Just look at the ones we want to install */ - if ((*Cache)[I].Install() == false) + if ((*Cache)[Pkg].Install() == false) continue; - for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++) - { - for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ) - { - pkgCache::DepIterator Start; - pkgCache::DepIterator 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 - */ - - bool providedBySomething = 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; - - 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; - - /* Skip if we already saw it */ - if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1) - break; - - if (Start->Type == pkgCache::Dep::Suggests) { - SuggestsList += target; - SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; - } - - if (Start->Type == pkgCache::Dep::Recommends) { - RecommendsList += target; - RecommendsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; - } - - if (Start >= End) - break; - Start++; - } - } - } + // get the recommends/suggests for the candidate ver + pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache); + for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; ) + { + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); // advances D + + // FIXME: we really should display a or-group as a or-group to the user + // the problem is that ShowList is incapable of doing this + string RecommendsOrList,RecommendsOrVersions; + string SuggestsOrList,SuggestsOrVersions; + bool foundInstalledInOrGroup = false; + 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()) + { + foundInstalledInOrGroup=true; + break; + } + + /* Skip if we already saw it */ + if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1) + { + foundInstalledInOrGroup=true; + break; + } + + // this is a dep on a virtual pkg, check if any package that provides it + // should be installed + if(Start.TargetPkg().ProvidesList() != 0) + { + pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList(); + for (; I.end() == false; I++) + { + pkgCache::PkgIterator Pkg = I.OwnerPkg(); + if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() && + Pkg.CurrentVer() != 0) + foundInstalledInOrGroup=true; + } + } + + if (Start->Type == pkgCache::Dep::Suggests) + { + SuggestsOrList += target; + SuggestsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; + } + + if (Start->Type == pkgCache::Dep::Recommends) + { + RecommendsOrList += target; + RecommendsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; + } + + if (Start >= End) + break; + Start++; + } + + if(foundInstalledInOrGroup == false) + { + RecommendsList += RecommendsOrList; + RecommendsVersions += RecommendsOrVersions; + SuggestsList += SuggestsOrList; + SuggestsVersions += SuggestsOrVersions; + } + + } } + ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions); ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions); @@ -1899,6 +1910,9 @@ bool DoSource(CommandLine &CmdL) DscFile *Dsc = new DscFile[CmdL.FileSize()]; + // insert all downloaded uris into this set to avoid downloading them + // twice + set queued; // Load the requestd sources into the fetcher unsigned J = 0; for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) @@ -1935,7 +1949,28 @@ bool DoSource(CommandLine &CmdL) if (_config->FindB("APT::Get::Tar-Only",false) == true && I->Type != "tar") continue; - + + // don't download the same uri twice (should this be moved to + // the fetcher interface itself?) + if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end()) + continue; + queued.insert(Last->Index().ArchiveURI(I->Path)); + + // check if we have a file with that md5 sum already localy + if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path))) + { + FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly); + MD5Summation sum; + sum.AddFD(Fd.Fd(), Fd.Size()); + Fd.Close(); + if((string)sum.Result() == I->MD5Hash) + { + ioprintf(c1out,_("Skipping already downloaded file '%s'\n"), + flNotDir(I->Path).c_str()); + continue; + } + } + new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path), I->MD5Hash,I->Size, Last->Index().SourceInfo(*Last,*I),Src);