From a4c404301df135bea81f23b944dc6e1967f9ca85 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 12:12:56 +0100 Subject: initial apt-get changelog implementation, not quite ready yet (need to get rid of tmpnam --- cmdline/apt-get.cc | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 8efcd0e2e..72c1ef0b0 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2733,6 +2733,104 @@ bool DoBuildDep(CommandLine &CmdL) return true; } /*}}}*/ +// DownloadChangelog - Download the changelog /*{{{*/ +// --------------------------------------------------------------------- +string DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerIterator V) +{ + string uri; + string srcpkg; + string prefix; + string descr; + string src_section; + string verstr; + + // data structures we need + pkgRecords Recs(CacheFile); + pkgCache::PkgIterator Pkg = V.ParentPkg(); + pkgRecords::Parser &rec=Recs.Lookup(V.FileList()); + + // build uri + srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); + strprintf(descr, _("Changelog for %s"), srcpkg.c_str()); + // FIXME: we actually need the source section here + src_section= Pkg.Section(); + if(src_section.find('/')!=src_section.npos) + src_section=string(src_section, 0, src_section.find('/')); + else + src_section="main"; + + prefix+=srcpkg[0]; + if(srcpkg.size()>3 && srcpkg[0]=='l' && srcpkg[1]=='i' && srcpkg[2]=='b') + prefix=std::string("lib")+srcpkg[3]; + + verstr = V.VerStr(); + if(verstr.find(':')!=verstr.npos) + verstr=string(verstr, verstr.find(':')+1); + + strprintf(uri, "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog", src_section.c_str(), prefix.c_str(), srcpkg.c_str(), srcpkg.c_str(), verstr.c_str()); + + AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); + Fetcher.Setup(&Stat); + + // temp file + string targetfile = tmpnam(strdup("apt-changelog-XXXXXX")); + new pkgAcqFile(&Fetcher, uri, "", 0, descr, srcpkg, "ignore", targetfile); + + // get it + int res = Fetcher.Run(); + if (FileExists(targetfile)) + return targetfile; + + // error + return ""; +} + /*}}}*/ +// DisplayFileInPager - Display File with pager /*{{{*/ +void DisplayFileInPager(string filename) +{ + pid_t Process = ExecFork(); + if (Process == 0) + { + const char *Args[3]; + Args[0] = "/usr/bin/sensible-pager"; + Args[1] = filename.c_str(); + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + // Wait for the subprocess + ExecWait(Process, "sensible-pager", false); +} + /*}}}*/ +// DoChangelog - Get changelog from the command line /*{{{*/ +// --------------------------------------------------------------------- +bool DoChangelog(CommandLine &CmdL) +{ + CacheFile Cache; + if (Cache.ReadOnlyOpen() == false) + return false; + + APT::CacheSetHelper helper(c0out); + APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache, + CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper); + pkgAcquire Fetcher; + + if (verset.empty() == true) + return false; + for (APT::VersionSet::const_iterator Ver = verset.begin(); + Ver != verset.end(); + ++Ver) + { + string changelogfile = DownloadChangelog(Cache, Fetcher, Ver); + if (changelogfile.size() > 0) + { + DisplayFileInPager(changelogfile); + unlink(changelogfile.c_str()); + } + } +} + /*}}}*/ // DoMoo - Never Ask, Never Tell /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -2923,6 +3021,7 @@ int main(int argc,const char *argv[]) /*{{{*/ {"autoclean",&DoAutoClean}, {"check",&DoCheck}, {"source",&DoSource}, + {"changelog",&DoChangelog}, {"moo",&DoMoo}, {"help",&ShowHelp}, {0,0}}; -- cgit v1.2.3-70-g09d2 From 4a6fe09cf2a7f18de2f80a1b79ea43e211302dbc Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 12:26:39 +0100 Subject: use mkdtemp() instead of tempnam, free mkdtemp() data afterwards, return true in DoChangelog handler --- cmdline/apt-get.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 72c1ef0b0..0d67585a7 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2773,11 +2773,18 @@ string DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::Ve Fetcher.Setup(&Stat); // temp file - string targetfile = tmpnam(strdup("apt-changelog-XXXXXX")); - new pkgAcqFile(&Fetcher, uri, "", 0, descr, srcpkg, "ignore", targetfile); + char *tmpdir = mkdtemp(strdup("apt-changelog-XXXXXX")); + if (tmpdir == NULL) { + _error->Errno("mkdtemp", "mkdtemp failed"); + return ""; + } + string targetfile = string(tmpdir) + "changelog"; // get it + new pkgAcqFile(&Fetcher, uri, "", 0, descr, srcpkg, tmpdir); int res = Fetcher.Run(); + free(tmpdir); + if (FileExists(targetfile)) return targetfile; @@ -2826,9 +2833,12 @@ bool DoChangelog(CommandLine &CmdL) if (changelogfile.size() > 0) { DisplayFileInPager(changelogfile); + // cleanup unlink(changelogfile.c_str()); + rmdir(flNotFile(changelogfile).c_str()); } } + return true; } /*}}}*/ // DoMoo - Never Ask, Never Tell /*{{{*/ -- cgit v1.2.3-70-g09d2 From 18ae8b296bf08b853c44fdd5c20689e45ae71bfc Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 12:53:52 +0100 Subject: support Apt::Changelog::Server, code cleanup --- cmdline/apt-get.cc | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 0d67585a7..a61bcc62b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2735,7 +2735,7 @@ bool DoBuildDep(CommandLine &CmdL) /*}}}*/ // DownloadChangelog - Download the changelog /*{{{*/ // --------------------------------------------------------------------- -string DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerIterator V) +bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerIterator V, string targetfile) { string uri; string srcpkg; @@ -2767,29 +2767,22 @@ string DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::Ve if(verstr.find(':')!=verstr.npos) verstr=string(verstr, verstr.find(':')+1); - strprintf(uri, "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog", src_section.c_str(), prefix.c_str(), srcpkg.c_str(), srcpkg.c_str(), verstr.c_str()); + string fmt = _config->Find("Apt::Changelogs::Server", + "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog"); + strprintf(uri, fmt.c_str(), src_section.c_str(), prefix.c_str(), srcpkg.c_str(), srcpkg.c_str(), verstr.c_str()); AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); Fetcher.Setup(&Stat); - // temp file - char *tmpdir = mkdtemp(strdup("apt-changelog-XXXXXX")); - if (tmpdir == NULL) { - _error->Errno("mkdtemp", "mkdtemp failed"); - return ""; - } - string targetfile = string(tmpdir) + "changelog"; - // get it - new pkgAcqFile(&Fetcher, uri, "", 0, descr, srcpkg, tmpdir); + new pkgAcqFile(&Fetcher, uri, "", 0, descr, srcpkg, "ignored", targetfile); int res = Fetcher.Run(); - free(tmpdir); if (FileExists(targetfile)) - return targetfile; + return true; // error - return ""; + return _error->Error("changelog download failed"); } /*}}}*/ // DisplayFileInPager - Display File with pager /*{{{*/ @@ -2825,19 +2818,24 @@ bool DoChangelog(CommandLine &CmdL) if (verset.empty() == true) return false; + char *tmpdir = mkdtemp(strdup("apt-changelog-XXXXXX")); + if (tmpdir == NULL) { + return _error->Errno("mkdtemp", "mkdtemp failed"); + } + for (APT::VersionSet::const_iterator Ver = verset.begin(); Ver != verset.end(); ++Ver) { - string changelogfile = DownloadChangelog(Cache, Fetcher, Ver); - if (changelogfile.size() > 0) - { + string changelogfile = string(tmpdir) + "changelog"; + if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile)) DisplayFileInPager(changelogfile); - // cleanup - unlink(changelogfile.c_str()); - rmdir(flNotFile(changelogfile).c_str()); - } + // cleanup temp file + unlink(changelogfile.c_str()); } + // clenaup tmp dir + rmdir(tmpdir); + free(tmpdir); return true; } /*}}}*/ -- cgit v1.2.3-70-g09d2 From c2991635eb1d2a6bc8a0910b4f84748415a3ac14 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 13:28:22 +0100 Subject: cmdline/apt-get.cc make only the server configurable, but not the format string (attack vector?) --- cmdline/apt-get.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a61bcc62b..a5e3ad454 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2737,12 +2737,13 @@ bool DoBuildDep(CommandLine &CmdL) // --------------------------------------------------------------------- bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerIterator V, string targetfile) { - string uri; string srcpkg; string prefix; string descr; string src_section; string verstr; + string server; + string path; // data structures we need pkgRecords Recs(CacheFile); @@ -2767,15 +2768,16 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerI if(verstr.find(':')!=verstr.npos) verstr=string(verstr, verstr.find(':')+1); - string fmt = _config->Find("Apt::Changelogs::Server", - "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog"); - strprintf(uri, fmt.c_str(), src_section.c_str(), prefix.c_str(), srcpkg.c_str(), srcpkg.c_str(), verstr.c_str()); - + // make the server configurable + server = _config->Find("Apt::Changelogs::Server", + "http://packages.debian.org/"); + // ... but not the format string to avoid all possible attacks + strprintf(path, "/changelogs/pool/%s/%s/%s/%s_%s/changelog", src_section.c_str(), prefix.c_str(), srcpkg.c_str(), srcpkg.c_str(), verstr.c_str()); AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); Fetcher.Setup(&Stat); // get it - new pkgAcqFile(&Fetcher, uri, "", 0, descr, srcpkg, "ignored", targetfile); + new pkgAcqFile(&Fetcher, server+path, "", 0, descr, srcpkg, "ignored", targetfile); int res = Fetcher.Run(); if (FileExists(targetfile)) -- cgit v1.2.3-70-g09d2 From 8cc74fb1f791935bea9afd767fddf78ecebd4740 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 13:34:36 +0100 Subject: cmdline/apt-get.cc: move Setup a level higher --- cmdline/apt-get.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a5e3ad454..cf4f1ab36 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2773,9 +2773,6 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerI "http://packages.debian.org/"); // ... but not the format string to avoid all possible attacks strprintf(path, "/changelogs/pool/%s/%s/%s/%s_%s/changelog", src_section.c_str(), prefix.c_str(), srcpkg.c_str(), srcpkg.c_str(), verstr.c_str()); - AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); - Fetcher.Setup(&Stat); - // get it new pkgAcqFile(&Fetcher, server+path, "", 0, descr, srcpkg, "ignored", targetfile); int res = Fetcher.Run(); @@ -2817,6 +2814,8 @@ bool DoChangelog(CommandLine &CmdL) APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache, CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper); pkgAcquire Fetcher; + AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); + Fetcher.Setup(&Stat); if (verset.empty() == true) return false; -- cgit v1.2.3-70-g09d2 From 64b4c03ee79d5df053df7dabd33e88e0ebef1f20 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 13:54:47 +0100 Subject: cmdline/apt-get.cc: create the mkdtemp dir in /tmp --- cmdline/apt-get.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index cf4f1ab36..53def383d 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2819,7 +2819,7 @@ bool DoChangelog(CommandLine &CmdL) if (verset.empty() == true) return false; - char *tmpdir = mkdtemp(strdup("apt-changelog-XXXXXX")); + char *tmpdir = mkdtemp(strdup("/tmp/apt-changelog-XXXXXX")); if (tmpdir == NULL) { return _error->Errno("mkdtemp", "mkdtemp failed"); } -- cgit v1.2.3-70-g09d2 From e58371283fff2f9bb6a7edb3868d7eb08d175175 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 14:19:00 +0100 Subject: test/integration/test-changelog: add regression test for changelog downloader --- test/integration/test-changelog | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100755 test/integration/test-changelog diff --git a/test/integration/test-changelog b/test/integration/test-changelog new file mode 100755 index 000000000..292df6e32 --- /dev/null +++ b/test/integration/test-changelog @@ -0,0 +1,34 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture "i386" + +# this will be valid until ubuntu lucid is EOL (04/2015) +pkgchangelogtest="Package: apt +Architecture: i386 +Version: 0.7.25.3ubuntu7 +Filename: pool/main/a/apt/apt_0.7.25.3ubuntu7_i386.deb +Section: admin +" +cat <<-EOF >aptarchive/Packages +$pkgchangelogtest +EOF + +setupaptarchive + +echo "Apt::Changelogs::Server \"http://changelogs.ubuntu.com/\";" >> ./aptconfig.conf +msgnmsg "apt-get changelog: " +aptget changelog apt -qq > downloaded-changelog +expected="apt (0.7.25.3ubuntu7) lucid; urgency=low" +got="$(head -n1 downloaded-changelog)" +if [ -s downloaded-changelog ] && [ "$got" = "$expected" ]; then + msgpass +else + msgfail + msgwarn "$got != $expected" +fi + -- cgit v1.2.3-70-g09d2 From ded9d4e22002ead2aa12bc5bc8b34c21f2d3b707 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 14:19:23 +0100 Subject: test/integration/framework: set methods dir --- test/integration/framework | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/framework b/test/integration/framework index 2422f0886..f78ae2ee1 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -117,6 +117,7 @@ setupenvironment() { echo "Debug::NoLocking \"true\";" >> aptconfig.conf echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf echo "Dir::Bin::dpkg \"fakeroot\";" >> aptconfig.conf + echo "Dir::Bin::methods \"${BUILDDIRECTORY}/methods\";" >> aptconfig.conf echo "DPKG::options:: \"dpkg\";" >> aptconfig.conf echo "DPKG::options:: \"--root=${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf echo "DPKG::options:: \"--force-not-root\";" >> aptconfig.conf -- cgit v1.2.3-70-g09d2 From c845d4ffaf1c2bedb43e1bcb16896d9722db735b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Nov 2010 14:25:29 +0100 Subject: doc/examples/configure-index: updated to include apt::changelogs::server --- doc/examples/configure-index | 97 ++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/doc/examples/configure-index b/doc/examples/configure-index index c4c2acb64..ef4cff8a1 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -114,54 +114,61 @@ APT // does a ExecFork) Keep-Fds {}; + Changelogs + { + // server the provides the changelogs, the code will automatically + // append "/changelogs/pool/%s/%s/%s/%s_%s/changelog" to the uri + Server "http://packages.debian.org/"; + }: + // control parameters for cron jobs by /etc/cron.daily/apt Periodic { - BackupArchiveInterval "0"; - // - Backup after n-days if archive contents changed.(0=disable) - - BackupLevel "3"; - // - Backup level.(0=disable), 1 is invalid. - - // APT::Archives::MaxAge "0"; (old, deprecated) - MaxAge "0"; // (new) - // - Set maximum allowed age of a cache package file. If a cache - // package file is older it is deleted (0=disable) - - // APT::Archives::MinAge "2"; (old, deprecated) - MinAge "2"; // (new) - // - Set minimum age of a package file. If a file is younger it - // will not be deleted (0=disable). Usefull to prevent races - // and to keep backups of the packages for emergency. - - // APT::Archives::MaxSize "0"; (old, deprecated) - MaxSize "0"; // (new) - // - Set maximum size of the cache in MB (0=disable). If the cache - // is bigger, cached package files are deleted until the size - // requirement is met (the biggest packages will be deleted - // first). - - Update-Package-Lists "0"; - // - Do "apt-get update" automatically every n-days (0=disable) - // - Download-Upgradeable-Packages "0"; - // - Do "apt-get upgrade --download-only" every n-days (0=disable) - // - Unattended-Upgrade "0"; - // - Run the "unattended-upgrade" security upgrade script - // every n-days (0=disabled) - // Requires the package "unattended-upgrades" and will write - // a log in /var/log/unattended-upgrades - // - AutocleanInterval "0"; - // - Do "apt-get autoclean" every n-days (0=disable) - - Verbose "0"; - // - Send report mail to root - // 0: no report (or null string) - // 1: progress report (actually any string) - // 2: + command outputs (remove -qq, remove 2>/dev/null, add -d) - // 3: + trace on + BackupArchiveInterval "0"; + // - Backup after n-days if archive contents changed.(0=disable) + + BackupLevel "3"; + // - Backup level.(0=disable), 1 is invalid. + + // APT::Archives::MaxAge "0"; (old, deprecated) + MaxAge "0"; // (new) + // - Set maximum allowed age of a cache package file. If a cache + // package file is older it is deleted (0=disable) + + // APT::Archives::MinAge "2"; (old, deprecated) + MinAge "2"; // (new) + // - Set minimum age of a package file. If a file is younger it + // will not be deleted (0=disable). Usefull to prevent races + // and to keep backups of the packages for emergency. + + // APT::Archives::MaxSize "0"; (old, deprecated) + MaxSize "0"; // (new) + // - Set maximum size of the cache in MB (0=disable). If the cache + // is bigger, cached package files are deleted until the size + // requirement is met (the biggest packages will be deleted + // first). + + Update-Package-Lists "0"; + // - Do "apt-get update" automatically every n-days (0=disable) + // + Download-Upgradeable-Packages "0"; + // - Do "apt-get upgrade --download-only" every n-days (0=disable) + // + Unattended-Upgrade "0"; + // - Run the "unattended-upgrade" security upgrade script + // every n-days (0=disabled) + // Requires the package "unattended-upgrades" and will write + // a log in /var/log/unattended-upgrades + // + AutocleanInterval "0"; + // - Do "apt-get autoclean" every n-days (0=disable) + + Verbose "0"; + // - Send report mail to root + // 0: no report (or null string) + // 1: progress report (actually any string) + // 2: + command outputs (remove -qq, remove 2>/dev/null, add -d) + // 3: + trace on }; }; -- cgit v1.2.3-70-g09d2 From cdb9307c701fd016325c83dc879351912fb35c9d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 16 Nov 2010 10:35:10 +0100 Subject: add support for third party changelogs --- apt-pkg/contrib/strutl.cc | 9 +++++++++ apt-pkg/contrib/strutl.h | 1 + cmdline/apt-get.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 987f4c3a4..c2b335ed7 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1174,6 +1174,15 @@ char *safe_snprintf(char *Buffer,char *End,const char *Format,...) return Buffer + Did; } /*}}}*/ +// StripEpoch - Remove the version "epoch" from a version string /*{{{*/ +// --------------------------------------------------------------------- +string StripEpoch(const string &VerStr) +{ + size_t i = VerStr.find(":"); + if (i == string::npos) + return VerStr; + return VerStr.substr(i+1); +} // tolower_ascii - tolower() function that ignores the locale /*{{{*/ // --------------------------------------------------------------------- diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index a457ff047..14cf5c943 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -61,6 +61,7 @@ void strprintf(string &out,const char *format,...) __like_printf(2); char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3); bool CheckDomainList(const string &Host, const string &List); int tolower_ascii(int const c) __attrib_const __hot; +string StripEpoch(const string &VerStr); #define APT_MKSTRCMP(name,func) \ inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \ diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 53def383d..35f37cc49 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2733,6 +2733,37 @@ bool DoBuildDep(CommandLine &CmdL) return true; } /*}}}*/ +// GuessThirdPartyChangelogUri - return url /*{{{*/ +// --------------------------------------------------------------------- +bool GuessThirdPartyChangelogUri(CacheFile &Cache, + pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver, + string &out_uri) +{ + pkgRecords Recs(Cache); + pkgSourceList *SrcList = Cache.GetSourceList(); + + // get the binary deb server path + pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList()); + string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); + // FIXME: deal with cases like gcc-defaults (srcver != binver) + string srcver = StripEpoch(Ver.VerStr()); + + pkgCache::VerFileIterator Vf = Ver.FileList(); + if (Vf.end() == true) + return false; + pkgCache::PkgFileIterator F = Vf.File(); + pkgIndexFile *index; + if(SrcList->FindIndex(F, index) == false) + return false; + // get archive uri for the binary deb + string deb_uri = index->ArchiveURI(rec.FileName()); + + // now strip away the filename and add srcpkg_srcver.changelog + out_uri = flNotFile(deb_uri); + out_uri += srcpkg + "_" + srcver + ".changelog"; + return true; +} // DownloadChangelog - Download the changelog /*{{{*/ // --------------------------------------------------------------------- bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerIterator V, string targetfile) @@ -2775,7 +2806,18 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerI strprintf(path, "/changelogs/pool/%s/%s/%s/%s_%s/changelog", src_section.c_str(), prefix.c_str(), srcpkg.c_str(), srcpkg.c_str(), verstr.c_str()); // get it new pkgAcqFile(&Fetcher, server+path, "", 0, descr, srcpkg, "ignored", targetfile); + // try downloading it, if that fails, they third-party-changelogs location + // FIXME: res is "Continue" even if I get a 404?!? int res = Fetcher.Run(); + if (!FileExists(targetfile)) + { + string third_party_uri; + if (GuessThirdPartyChangelogUri(CacheFile, Pkg, V, third_party_uri)) + { + new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, srcpkg, "ignored", targetfile); + res = Fetcher.Run(); + } + } if (FileExists(targetfile)) return true; -- cgit v1.2.3-70-g09d2 From d786352da27c6f05bc372a061f3a78237b69e6f4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 16 Nov 2010 10:40:36 +0100 Subject: cmdline/apt-get.cc: improve changelog description --- cmdline/apt-get.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 35f37cc49..8cb43be67 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2783,7 +2783,6 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerI // build uri srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); - strprintf(descr, _("Changelog for %s"), srcpkg.c_str()); // FIXME: we actually need the source section here src_section= Pkg.Section(); if(src_section.find('/')!=src_section.npos) @@ -2804,8 +2803,11 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerI "http://packages.debian.org/"); // ... but not the format string to avoid all possible attacks strprintf(path, "/changelogs/pool/%s/%s/%s/%s_%s/changelog", src_section.c_str(), prefix.c_str(), srcpkg.c_str(), srcpkg.c_str(), verstr.c_str()); - // get it - new pkgAcqFile(&Fetcher, server+path, "", 0, descr, srcpkg, "ignored", targetfile); + // queue it + string changelog_uri = server+path; + strprintf(descr, _("Changelog for %s (%s)"), srcpkg.c_str(), changelog_uri.c_str()); + new pkgAcqFile(&Fetcher, uri, "", 0, descr, srcpkg, "ignored", targetfile); + // try downloading it, if that fails, they third-party-changelogs location // FIXME: res is "Continue" even if I get a 404?!? int res = Fetcher.Run(); @@ -2814,6 +2816,7 @@ bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerI string third_party_uri; if (GuessThirdPartyChangelogUri(CacheFile, Pkg, V, third_party_uri)) { + strprintf(descr, _("Changelog for %s (%s)"), srcpkg.c_str(), third_party_uri.c_str()); new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, srcpkg, "ignored", targetfile); res = Fetcher.Run(); } -- cgit v1.2.3-70-g09d2