From 9c876fe428588d155533b40f95265beaee03fc88 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 19 Oct 2009 21:10:09 +0200 Subject: rewrite FindSrc() in cmdline/apt-get.cc to fix some bugs, including: * cmdline/apt-get.cc: - source should displays his final pkg pick (Closes: #249383, #550952) - source doesn't need the complete version for match (Closes: #245250) - source ignores versions/releases if not available (Closes: #377424) --- cmdline/apt-get.cc | 256 ++++++++++++++++++++++++++--------------------------- debian/changelog | 4 + po/apt-all.pot | 131 ++++++++++++++------------- 3 files changed, 200 insertions(+), 191 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index c32d67226..ca14f4c2b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1243,137 +1243,131 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords &SrcRecs,string &Src, pkgDepCache &Cache) { - // We want to pull the version off the package specification.. - string VerTag; - string DefRel; - string TmpSrc = Name; - const size_t found = TmpSrc.find_last_of("/="); - - // honor default release - if (found != string::npos && TmpSrc[found] == '/') - { - DefRel = TmpSrc.substr(found+1); - TmpSrc = TmpSrc.substr(0,found); - } - else - DefRel = _config->Find("APT::Default-Release"); - - pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); - - if (found != string::npos && TmpSrc[found] == '=') - { - VerTag = TmpSrc.substr(found+1); - TmpSrc = TmpSrc.substr(0,found); - } - 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; - - if((VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || - (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) - { - pkgRecords::Parser &Parse = Recs.Lookup(VF); - VerTag = Parse.SourceVer(); - if (VerTag.empty()) - 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. */ - bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); - if (MatchSrcOnly == false) - { - if (Pkg.end() == false) - { - pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); - if (Ver.end() == false) - { - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - Src = Parse.SourcePkg(); - } - } - } - - // The best hit - pkgSrcRecords::Parser *Last = 0; - unsigned long Offset = 0; - string Version; - bool IsMatch = false; - - // No source package name.. - 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 we are matching by version then we need exact matches to be happy - if (VerTag.empty() == false) - IsMatch = true; - - /* Iterate over all of the hits, which includes the resulting - binary packages in the search */ - pkgSrcRecords::Parser *Parse; - SrcRecs.Restart(); - while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0) - { - string Ver = Parse->Version(); - - // show name mismatches - if (IsMatch == true && Parse->Package() != Src) - ioprintf(c1out, _("No source package '%s' picking '%s' instead\n"), Src.c_str(), Parse->Package().c_str()); - - if (VerTag.empty() == false) - { - /* Don't want to fall through because we are doing exact version - matching. */ - if (Cache.VS().CmpVersion(VerTag,Ver) != 0) - continue; - - Last = Parse; - Offset = Parse->Offset(); - break; - } - - // Newer version or an exact match - if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 || - (Parse->Package() == Src && IsMatch == false)) - { - IsMatch = Parse->Package() == Src; - Last = Parse; - Offset = Parse->Offset(); - Version = Ver; - } - } - - if (Last == 0 || Last->Jump(Offset) == false) - return 0; - - return Last; + 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; } /*}}}*/ // DoUpdate - Update the package lists /*{{{*/ diff --git a/debian/changelog b/debian/changelog index 4b2719e50..82b08619d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -24,6 +24,10 @@ apt (0.7.25) UNRELEASED; urgency=low - add note about additional apt-transport-methods * doc/apt-mark.8.xml: - correct showauto synopsis, thanks Andrew Schulman (Closes: #551440) + * cmdline/apt-get.cc: + - source should displays his final pkg pick (Closes: #249383, #550952) + - source doesn't need the complete version for match (Closes: #245250) + - source ignores versions/releases if not available (Closes: #377424) [ Julian Andres Klode ] * doc/apt.conf.5.xml: diff --git a/po/apt-all.pot b/po/apt-all.pot index f894f121e..f464ef198 100644 --- a/po/apt-all.pot +++ b/po/apt-all.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-30 18:47+0200\n" +"POT-Creation-Date: 2009-10-19 21:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -151,7 +151,7 @@ msgstr "" #: cmdline/apt-cache.cc:1718 cmdline/apt-cdrom.cc:134 cmdline/apt-config.cc:70 #: cmdline/apt-extracttemplates.cc:225 ftparchive/apt-ftparchive.cc:547 -#: cmdline/apt-get.cc:2651 cmdline/apt-sortpkgs.cc:144 +#: cmdline/apt-get.cc:2645 cmdline/apt-sortpkgs.cc:144 #, c-format msgid "%s %s for %s compiled on %s %s\n" msgstr "" @@ -549,7 +549,7 @@ msgstr "" msgid "Y" msgstr "" -#: cmdline/apt-get.cc:149 cmdline/apt-get.cc:1720 +#: cmdline/apt-get.cc:149 cmdline/apt-get.cc:1714 #, c-format msgid "Regex compilation error - %s" msgstr "" @@ -708,11 +708,11 @@ msgstr "" msgid "Internal error, Ordering didn't finish" msgstr "" -#: cmdline/apt-get.cc:811 cmdline/apt-get.cc:2062 cmdline/apt-get.cc:2095 +#: cmdline/apt-get.cc:811 cmdline/apt-get.cc:2056 cmdline/apt-get.cc:2089 msgid "Unable to lock the download directory" msgstr "" -#: cmdline/apt-get.cc:821 cmdline/apt-get.cc:2143 cmdline/apt-get.cc:2392 +#: cmdline/apt-get.cc:821 cmdline/apt-get.cc:2137 cmdline/apt-get.cc:2386 #: apt-pkg/cachefile.cc:65 msgid "The list of sources could not be read." msgstr "" @@ -741,7 +741,7 @@ msgstr "" msgid "After this operation, %sB disk space will be freed.\n" msgstr "" -#: cmdline/apt-get.cc:866 cmdline/apt-get.cc:2238 +#: cmdline/apt-get.cc:866 cmdline/apt-get.cc:2232 #, c-format msgid "Couldn't determine free space in %s" msgstr "" @@ -775,7 +775,7 @@ msgstr "" msgid "Do you want to continue [Y/n]? " msgstr "" -#: cmdline/apt-get.cc:989 cmdline/apt-get.cc:2289 apt-pkg/algorithms.cc:1389 +#: cmdline/apt-get.cc:989 cmdline/apt-get.cc:2283 apt-pkg/algorithms.cc:1389 #, c-format msgid "Failed to fetch %s %s\n" msgstr "" @@ -784,7 +784,7 @@ msgstr "" msgid "Some files failed to download" msgstr "" -#: cmdline/apt-get.cc:1008 cmdline/apt-get.cc:2298 +#: cmdline/apt-get.cc:1008 cmdline/apt-get.cc:2292 msgid "Download complete and in download only mode" msgstr "" @@ -876,39 +876,50 @@ msgstr "" msgid "Selected version %s (%s) for %s\n" msgstr "" -#: cmdline/apt-get.cc:1348 +#. if (VerTag.empty() == false && Last == 0) +#: cmdline/apt-get.cc:1301 cmdline/apt-get.cc:1363 #, c-format -msgid "No source package '%s' picking '%s' instead\n" +msgid "Ignore unavailable version '%s' of package '%s'" msgstr "" -#: cmdline/apt-get.cc:1385 +#: cmdline/apt-get.cc:1303 +#, c-format +msgid "Ignore unavailable target release '%s' of package '%s'" +msgstr "" + +#: cmdline/apt-get.cc:1328 +#, c-format +msgid "Picking '%s' as source package instead of '%s'\n" +msgstr "" + +#: cmdline/apt-get.cc:1379 msgid "The update command takes no arguments" msgstr "" -#: cmdline/apt-get.cc:1398 +#: cmdline/apt-get.cc:1392 msgid "Unable to lock the list directory" msgstr "" -#: cmdline/apt-get.cc:1454 +#: cmdline/apt-get.cc:1448 msgid "We are not supposed to delete stuff, can't start AutoRemover" msgstr "" -#: cmdline/apt-get.cc:1503 +#: cmdline/apt-get.cc:1497 msgid "" "The following packages were automatically installed and are no longer " "required:" msgstr "" -#: cmdline/apt-get.cc:1505 +#: cmdline/apt-get.cc:1499 #, c-format msgid "%lu packages were automatically installed and are no longer required.\n" msgstr "" -#: cmdline/apt-get.cc:1506 +#: cmdline/apt-get.cc:1500 msgid "Use 'apt-get autoremove' to remove them." msgstr "" -#: cmdline/apt-get.cc:1511 +#: cmdline/apt-get.cc:1505 msgid "" "Hmm, seems like the AutoRemover destroyed something which really\n" "shouldn't happen. Please file a bug report against apt." @@ -924,49 +935,49 @@ msgstr "" #. "that package should be filed.") << endl; #. } #. -#: cmdline/apt-get.cc:1514 cmdline/apt-get.cc:1804 +#: cmdline/apt-get.cc:1508 cmdline/apt-get.cc:1798 msgid "The following information may help to resolve the situation:" msgstr "" -#: cmdline/apt-get.cc:1518 +#: cmdline/apt-get.cc:1512 msgid "Internal Error, AutoRemover broke stuff" msgstr "" -#: cmdline/apt-get.cc:1537 +#: cmdline/apt-get.cc:1531 msgid "Internal error, AllUpgrade broke stuff" msgstr "" -#: cmdline/apt-get.cc:1592 +#: cmdline/apt-get.cc:1586 #, c-format msgid "Couldn't find task %s" msgstr "" -#: cmdline/apt-get.cc:1707 cmdline/apt-get.cc:1743 +#: cmdline/apt-get.cc:1701 cmdline/apt-get.cc:1737 #, c-format msgid "Couldn't find package %s" msgstr "" -#: cmdline/apt-get.cc:1730 +#: cmdline/apt-get.cc:1724 #, c-format msgid "Note, selecting %s for regex '%s'\n" msgstr "" -#: cmdline/apt-get.cc:1761 +#: cmdline/apt-get.cc:1755 #, c-format msgid "%s set to manually installed.\n" msgstr "" -#: cmdline/apt-get.cc:1774 +#: cmdline/apt-get.cc:1768 msgid "You might want to run `apt-get -f install' to correct these:" msgstr "" -#: cmdline/apt-get.cc:1777 +#: cmdline/apt-get.cc:1771 msgid "" "Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a " "solution)." msgstr "" -#: cmdline/apt-get.cc:1789 +#: cmdline/apt-get.cc:1783 msgid "" "Some packages could not be installed. This may mean that you have\n" "requested an impossible situation or if you are using the unstable\n" @@ -974,152 +985,152 @@ msgid "" "or been moved out of Incoming." msgstr "" -#: cmdline/apt-get.cc:1807 +#: cmdline/apt-get.cc:1801 msgid "Broken packages" msgstr "" -#: cmdline/apt-get.cc:1836 +#: cmdline/apt-get.cc:1830 msgid "The following extra packages will be installed:" msgstr "" -#: cmdline/apt-get.cc:1925 +#: cmdline/apt-get.cc:1919 msgid "Suggested packages:" msgstr "" -#: cmdline/apt-get.cc:1926 +#: cmdline/apt-get.cc:1920 msgid "Recommended packages:" msgstr "" -#: cmdline/apt-get.cc:1955 +#: cmdline/apt-get.cc:1949 msgid "Calculating upgrade... " msgstr "" -#: cmdline/apt-get.cc:1958 methods/ftp.cc:707 methods/connect.cc:112 +#: cmdline/apt-get.cc:1952 methods/ftp.cc:707 methods/connect.cc:112 msgid "Failed" msgstr "" -#: cmdline/apt-get.cc:1963 +#: cmdline/apt-get.cc:1957 msgid "Done" msgstr "" -#: cmdline/apt-get.cc:2030 cmdline/apt-get.cc:2038 +#: cmdline/apt-get.cc:2024 cmdline/apt-get.cc:2032 msgid "Internal error, problem resolver broke stuff" msgstr "" -#: cmdline/apt-get.cc:2138 +#: cmdline/apt-get.cc:2132 msgid "Must specify at least one package to fetch source for" msgstr "" -#: cmdline/apt-get.cc:2168 cmdline/apt-get.cc:2410 +#: cmdline/apt-get.cc:2162 cmdline/apt-get.cc:2404 #, c-format msgid "Unable to find a source package for %s" msgstr "" -#: cmdline/apt-get.cc:2217 +#: cmdline/apt-get.cc:2211 #, c-format msgid "Skipping already downloaded file '%s'\n" msgstr "" -#: cmdline/apt-get.cc:2248 +#: cmdline/apt-get.cc:2242 #, c-format msgid "You don't have enough free space in %s" msgstr "" -#: cmdline/apt-get.cc:2254 +#: cmdline/apt-get.cc:2248 #, c-format msgid "Need to get %sB/%sB of source archives.\n" msgstr "" -#: cmdline/apt-get.cc:2257 +#: cmdline/apt-get.cc:2251 #, c-format msgid "Need to get %sB of source archives.\n" msgstr "" -#: cmdline/apt-get.cc:2263 +#: cmdline/apt-get.cc:2257 #, c-format msgid "Fetch source %s\n" msgstr "" -#: cmdline/apt-get.cc:2294 +#: cmdline/apt-get.cc:2288 msgid "Failed to fetch some archives." msgstr "" -#: cmdline/apt-get.cc:2322 +#: cmdline/apt-get.cc:2316 #, c-format msgid "Skipping unpack of already unpacked source in %s\n" msgstr "" -#: cmdline/apt-get.cc:2334 +#: cmdline/apt-get.cc:2328 #, c-format msgid "Unpack command '%s' failed.\n" msgstr "" -#: cmdline/apt-get.cc:2335 +#: cmdline/apt-get.cc:2329 #, c-format msgid "Check if the 'dpkg-dev' package is installed.\n" msgstr "" -#: cmdline/apt-get.cc:2352 +#: cmdline/apt-get.cc:2346 #, c-format msgid "Build command '%s' failed.\n" msgstr "" -#: cmdline/apt-get.cc:2371 +#: cmdline/apt-get.cc:2365 msgid "Child process failed" msgstr "" -#: cmdline/apt-get.cc:2387 +#: cmdline/apt-get.cc:2381 msgid "Must specify at least one package to check builddeps for" msgstr "" -#: cmdline/apt-get.cc:2415 +#: cmdline/apt-get.cc:2409 #, c-format msgid "Unable to get build-dependency information for %s" msgstr "" -#: cmdline/apt-get.cc:2435 +#: cmdline/apt-get.cc:2429 #, c-format msgid "%s has no build depends.\n" msgstr "" -#: cmdline/apt-get.cc:2487 +#: cmdline/apt-get.cc:2481 #, c-format msgid "" "%s dependency for %s cannot be satisfied because the package %s cannot be " "found" msgstr "" -#: cmdline/apt-get.cc:2540 +#: cmdline/apt-get.cc:2534 #, c-format msgid "" "%s dependency for %s cannot be satisfied because no available versions of " "package %s can satisfy version requirements" msgstr "" -#: cmdline/apt-get.cc:2576 +#: cmdline/apt-get.cc:2570 #, c-format msgid "Failed to satisfy %s dependency for %s: Installed package %s is too new" msgstr "" -#: cmdline/apt-get.cc:2603 +#: cmdline/apt-get.cc:2597 #, c-format msgid "Failed to satisfy %s dependency for %s: %s" msgstr "" -#: cmdline/apt-get.cc:2619 +#: cmdline/apt-get.cc:2613 #, c-format msgid "Build-dependencies for %s could not be satisfied." msgstr "" -#: cmdline/apt-get.cc:2624 +#: cmdline/apt-get.cc:2618 msgid "Failed to process build dependencies" msgstr "" -#: cmdline/apt-get.cc:2656 +#: cmdline/apt-get.cc:2650 msgid "Supported modules:" msgstr "" -#: cmdline/apt-get.cc:2697 +#: cmdline/apt-get.cc:2691 msgid "" "Usage: apt-get [options] command\n" " apt-get [options] install|remove pkg1 [pkg2 ...]\n" @@ -1163,7 +1174,7 @@ msgid "" " This APT has Super Cow Powers.\n" msgstr "" -#: cmdline/apt-get.cc:2864 +#: cmdline/apt-get.cc:2858 msgid "" "NOTE: This is only a simulation!\n" " apt-get needs root privileges for real execution.\n" -- cgit v1.2.3