diff options
Diffstat (limited to 'cmdline/apt-get.cc')
-rw-r--r-- | cmdline/apt-get.cc | 275 |
1 files changed, 149 insertions, 126 deletions
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 343226bc3..5ef5533e2 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1269,131 +1269,153 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords &SrcRecs,string &Src, pkgDepCache &Cache) { - string VerTag; - string DefRel = _config->Find("APT::Default-Release"); - string TmpSrc = Name; - const size_t found = TmpSrc.find_last_of("/="); - - // extract the version/release from the pkgname - if (found != string::npos) { - if (TmpSrc[found] == '/') - DefRel = TmpSrc.substr(found+1); - else - VerTag = TmpSrc.substr(found+1); - TmpSrc = TmpSrc.substr(0,found); - } - - /* 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. */ - bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); - const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); - if (MatchSrcOnly == false && Pkg.end() == false) { - if(VerTag.empty() == false || 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; - - // We match against a concrete version (or a part of this version) - if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0) - continue; - - // or we match against a release - if(VerTag.empty() == false || - (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || - (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) { - pkgRecords::Parser &Parse = Recs.Lookup(VF); - Src = Parse.SourcePkg(); - if (VerTag.empty() == true) - VerTag = Parse.SourceVer(); - break; - } - } - } - if (Src.empty() == true) { - if (VerTag.empty() == false) - _error->Warning(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); - else - _error->Warning(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str()); - VerTag.clear(); - DefRel.clear(); - } - } - if (VerTag.empty() == true && DefRel.empty() == true) { - // if we don't have a version or default release, use the CandidateVer to find the Source - pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); - if (Ver.end() == false) { - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - Src = Parse.SourcePkg(); - VerTag = Parse.SourceVer(); - } - } - } - - if (Src.empty() == true) - Src = TmpSrc; - else { - /* if we have a source pkg name, make sure to only search - for srcpkg names, otherwise apt gets confused if there - is a binary package "pkg1" and a source package "pkg1" - with the same name but that comes from different packages */ - MatchSrcOnly = true; - if (Src != TmpSrc) { - ioprintf(c1out, _("Picking '%s' as source package instead of '%s'\n"), Src.c_str(), TmpSrc.c_str()); - } - } - - // The best hit - pkgSrcRecords::Parser *Last = 0; - unsigned long Offset = 0; - string Version; - - /* Iterate over all of the hits, which includes the resulting - binary packages in the search */ - pkgSrcRecords::Parser *Parse; - while (true) { - SrcRecs.Restart(); - while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0) { - const string Ver = Parse->Version(); - - // Ignore all versions which doesn't fit - if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.c_str(), VerTag.size()) != 0) - continue; - - // Newer version or an exact match? Save the hit - if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0) { - Last = Parse; - Offset = Parse->Offset(); - Version = Ver; - } - - // was the version check above an exact match? If so, we don't need to look further - if (VerTag.empty() == false && VerTag.size() == Ver.size()) - break; - } - if (Last != 0 || VerTag.empty() == true) - break; - //if (VerTag.empty() == false && Last == 0) - _error->Warning(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); - VerTag.clear(); - } - - if (Last == 0 || Last->Jump(Offset) == false) - return 0; - - return Last; + string VerTag; + string DefRel = _config->Find("APT::Default-Release"); + string TmpSrc = Name; + + // extract the version/release from the pkgname + const size_t found = TmpSrc.find_last_of("/="); + if (found != string::npos) { + if (TmpSrc[found] == '/') + DefRel = TmpSrc.substr(found+1); + else + VerTag = TmpSrc.substr(found+1); + TmpSrc = TmpSrc.substr(0,found); + } + + /* 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. */ + bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); + const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); + if (MatchSrcOnly == false && Pkg.end() == false) + { + if(VerTag.empty() == false || 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; + + // We match against a concrete version (or a part of this version) + if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0) + continue; + + // or we match against a release + if(VerTag.empty() == false || + (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || + (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) + { + pkgRecords::Parser &Parse = Recs.Lookup(VF); + Src = Parse.SourcePkg(); + // no SourcePkg name, so it is the "binary" name + if (Src.empty() == true) + Src = TmpSrc; + // no Version, so we try the Version of the SourcePkg - + // and after that the version of the binary package + if (VerTag.empty() == true) + VerTag = Parse.SourceVer(); + if (VerTag.empty() == true) + VerTag = Ver.VerStr(); + break; + } + } + if (Src.empty() == false) + break; + } + if (Src.empty() == true) + { + // Sources files have no codename information + if (VerTag.empty() == true && DefRel.empty() == false) + _error->Warning(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str()); + DefRel.clear(); + } + } + if (Src.empty() == true) + { + // if we don't have found a fitting package yet so we will + // choose a good candidate and proceed with that. + // Maybe we will find a source later on with the right VerTag + pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); + if (Ver.end() == false) + { + pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); + Src = Parse.SourcePkg(); + if (VerTag.empty() == true) + VerTag = Parse.SourceVer(); + } + } + } + + if (Src.empty() == true) + Src = TmpSrc; + else + { + /* if we have a source pkg name, make sure to only search + for srcpkg names, otherwise apt gets confused if there + is a binary package "pkg1" and a source package "pkg1" + with the same name but that comes from different packages */ + MatchSrcOnly = true; + if (Src != TmpSrc) + { + ioprintf(c1out, _("Picking '%s' as source package instead of '%s'\n"), Src.c_str(), TmpSrc.c_str()); + } + } + + // The best hit + pkgSrcRecords::Parser *Last = 0; + unsigned long Offset = 0; + string Version; + + /* Iterate over all of the hits, which includes the resulting + binary packages in the search */ + pkgSrcRecords::Parser *Parse; + while (true) + { + SrcRecs.Restart(); + while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0) + { + const string Ver = Parse->Version(); + + // Ignore all versions which doesn't fit + if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.c_str(), VerTag.size()) != 0) + continue; + + // Newer version or an exact match? Save the hit + if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0) { + Last = Parse; + Offset = Parse->Offset(); + Version = Ver; + } + + // was the version check above an exact match? If so, we don't need to look further + if (VerTag.empty() == false && VerTag.size() == Ver.size()) + break; + } + if (Last != 0 || VerTag.empty() == true) + break; + //if (VerTag.empty() == false && Last == 0) + _error->Warning(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); + VerTag.clear(); + } + + if (Last == 0 || Last->Jump(Offset) == false) + return 0; + + return Last; } /*}}}*/ // DoUpdate - Update the package lists /*{{{*/ @@ -1776,7 +1798,8 @@ bool DoInstall(CommandLine &CmdL) if(!Remove && Cache[Pkg].Install() == false && (Cache[Pkg].Flags & pkgCache::Flag::Auto) && - _config->FindB("APT::Get::ReInstall",false) == false) + _config->FindB("APT::Get::ReInstall",false) == false && + _config->FindB("APT::Get::Download-Only",false) == false) { ioprintf(c1out,_("%s set to manually installed.\n"), Pkg.Name()); |