summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2016-02-11 22:54:49 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2016-02-11 23:13:47 +0100
commit6fd4b4c0b693b52cb8b593b76e5b60f77e500454 (patch)
treec5513fb604ff2da8826109b1ba0f74014ff94ac3
parentb5aba9096e371a5f8612aff05384aca54ccc5acd (diff)
always download changelogs into /tmp first
pkgAcqChangelog has the default behaviour of downloading a changelog to a temporary directory (inside /tmp, not /tmp directly), which is cleaned up on shutdown, but this can be overridden to store the changelog more permanently – but that caries a permission problem. For changelog we can 'easily' solve this by always downloading to a temporary directory and only move it out of there on done.
-rw-r--r--apt-pkg/acquire-item.cc56
-rw-r--r--apt-pkg/acquire-item.h3
-rw-r--r--apt-pkg/acquire.cc2
-rwxr-xr-xtest/integration/test-apt-get-changelog32
4 files changed, 50 insertions, 43 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 2057b7287..03baa9751 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -3076,9 +3076,14 @@ std::string pkgAcqArchive::ShortDesc() const /*{{{*/
pkgAcqArchive::~pkgAcqArchive() {}
// AcqChangelog::pkgAcqChangelog - Constructors /*{{{*/
+class pkgAcqChangelog::Private
+{
+ public:
+ std::string FinalFile;
+};
pkgAcqChangelog::pkgAcqChangelog(pkgAcquire * const Owner, pkgCache::VerIterator const &Ver,
std::string const &DestDir, std::string const &DestFilename) :
- pkgAcquire::Item(Owner), d(NULL), SrcName(Ver.SourcePkgName()), SrcVersion(Ver.SourceVerStr())
+ pkgAcquire::Item(Owner), d(new pkgAcqChangelog::Private()), SrcName(Ver.SourcePkgName()), SrcVersion(Ver.SourceVerStr())
{
Desc.URI = URI(Ver);
Init(DestDir, DestFilename);
@@ -3087,7 +3092,7 @@ pkgAcqChangelog::pkgAcqChangelog(pkgAcquire * const Owner, pkgCache::VerIterator
pkgAcqChangelog::pkgAcqChangelog(pkgAcquire * const Owner, pkgCache::RlsFileIterator const &RlsFile,
char const * const Component, char const * const SrcName, char const * const SrcVersion,
const string &DestDir, const string &DestFilename) :
- pkgAcquire::Item(Owner), d(NULL), SrcName(SrcName), SrcVersion(SrcVersion)
+ pkgAcquire::Item(Owner), d(new pkgAcqChangelog::Private()), SrcName(SrcName), SrcVersion(SrcVersion)
{
Desc.URI = URI(RlsFile, Component, SrcName, SrcVersion);
Init(DestDir, DestFilename);
@@ -3095,7 +3100,7 @@ pkgAcqChangelog::pkgAcqChangelog(pkgAcquire * const Owner, pkgCache::RlsFileIter
pkgAcqChangelog::pkgAcqChangelog(pkgAcquire * const Owner,
std::string const &URI, char const * const SrcName, char const * const SrcVersion,
const string &DestDir, const string &DestFilename) :
- pkgAcquire::Item(Owner), d(NULL), SrcName(SrcName), SrcVersion(SrcVersion)
+ pkgAcquire::Item(Owner), d(new pkgAcqChangelog::Private()), SrcName(SrcName), SrcVersion(SrcVersion)
{
Desc.URI = URI;
Init(DestDir, DestFilename);
@@ -3116,30 +3121,30 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi
return;
}
- if (DestDir.empty())
- {
- std::string const SandboxUser = _config->Find("APT::Sandbox::User");
- std::string const systemTemp = GetTempDir(SandboxUser);
- char tmpname[100];
- snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", systemTemp.c_str());
- if (NULL == mkdtemp(tmpname))
- {
- _error->Errno("mkdtemp", "mkdtemp failed in changelog acquire of %s %s", SrcName.c_str(), SrcVersion.c_str());
- Status = StatError;
- return;
- }
- DestFile = TemporaryDirectory = tmpname;
+ std::string DestFileName;
+ if (DestFilename.empty())
+ DestFileName = flCombine(DestFile, SrcName + ".changelog");
+ else
+ DestFileName = flCombine(DestFile, DestFilename);
- ChangeOwnerAndPermissionOfFile("Item::QueueURI", DestFile.c_str(),
- SandboxUser.c_str(), "root", 0700);
+ std::string const SandboxUser = _config->Find("APT::Sandbox::User");
+ std::string const systemTemp = GetTempDir(SandboxUser);
+ char tmpname[1000];
+ snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", systemTemp.c_str());
+ if (NULL == mkdtemp(tmpname))
+ {
+ _error->Errno("mkdtemp", "mkdtemp failed in changelog acquire of %s %s", SrcName.c_str(), SrcVersion.c_str());
+ Status = StatError;
+ return;
}
- else
- DestFile = DestDir;
+ TemporaryDirectory = tmpname;
- if (DestFilename.empty())
- DestFile = flCombine(DestFile, SrcName + ".changelog");
- else
- DestFile = flCombine(DestFile, DestFilename);
+ ChangeOwnerAndPermissionOfFile("Item::QueueURI", TemporaryDirectory.c_str(),
+ SandboxUser.c_str(), "root", 0700);
+
+ DestFile = flCombine(TemporaryDirectory, DestFileName);
+ if (DestDir.empty() == false)
+ d->FinalFile = flCombine(DestDir, DestFileName);
Desc.ShortDesc = "Changelog";
strprintf(Desc.Description, "%s %s %s Changelog", URI::SiteOnly(Desc.URI).c_str(), SrcName.c_str(), SrcVersion.c_str());
@@ -3294,6 +3299,8 @@ void pkgAcqChangelog::Done(string const &Message,HashStringList const &CalcHashe
pkgAcquire::MethodConfig const * const Cnf)
{
Item::Done(Message,CalcHashes,Cnf);
+ if (d->FinalFile.empty() == false)
+ Rename(DestFile, d->FinalFile);
Complete = true;
}
@@ -3305,6 +3312,7 @@ pkgAcqChangelog::~pkgAcqChangelog() /*{{{*/
RemoveFile("~pkgAcqChangelog", DestFile);
rmdir(TemporaryDirectory.c_str());
}
+ delete d;
}
/*}}}*/
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index 306b1772a..61f64c3a9 100644
--- a/apt-pkg/acquire-item.h
+++ b/apt-pkg/acquire-item.h
@@ -1055,7 +1055,8 @@ class pkgAcqArchive : public pkgAcquire::Item
*/
class pkgAcqChangelog : public pkgAcquire::Item
{
- void * const d;
+ class Private;
+ Private * const d;
std::string TemporaryDirectory;
std::string const SrcName;
std::string const SrcVersion;
diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc
index e515255ae..17ee691d7 100644
--- a/apt-pkg/acquire.cc
+++ b/apt-pkg/acquire.cc
@@ -559,7 +559,7 @@ static void CheckDropPrivsMustBeDisabled(pkgAcquire const &Fetcher)
I != Fetcher.ItemsEnd(); ++I)
{
// no need to drop privileges for a complete file
- if ((*I)->Complete == true)
+ if ((*I)->Complete == true || (*I)->Status != pkgAcquire::Item::StatIdle)
continue;
// if destination file is inaccessible all hope is lost for privilege dropping
diff --git a/test/integration/test-apt-get-changelog b/test/integration/test-apt-get-changelog
index 3de1c5c5c..d65c9530e 100755
--- a/test/integration/test-apt-get-changelog
+++ b/test/integration/test-apt-get-changelog
@@ -48,12 +48,7 @@ testsuccessequal "'http://localhost:${APTHTTPPORT}/main/f/foo/foo_1.0.changelog'
'http://localhost:${APTHTTPPORT}/main/libb/libbar/libbar_1.0.changelog' libbar.changelog" aptget changelog foo libbar --print-uris -o Acquire::Changelogs::URI::Override::Label::Debian="http://localhost:${APTHTTPPORT}/@CHANGEPATH@.changelog"
releasechanger 'Changelogs' 'no'
-if [ "$(id -u)" = '0' ]; then
- testfailuremsg "W: Can't drop privileges for downloading as file 'foo.changelog' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
-E: Failed to fetch changelog:/foo.changelog Changelog unavailable for foo=1.0" aptget changelog foo -d
-else
- testfailuremsg 'E: Failed to fetch changelog:/foo.changelog Changelog unavailable for foo=1.0' aptget changelog foo -d
-fi
+testfailuremsg 'E: Failed to fetch changelog:/foo.changelog Changelog unavailable for foo=1.0' aptget changelog foo -d
sed -i '/^Changelogs: / d' $(find rootdir/var/lib/apt/lists -name '*Release')
releasechanger 'Label' 'Testcases'
@@ -73,29 +68,35 @@ testsuccess aptget changelog foo libbar -qq
testfileequal 'rootdir/tmp/testsuccess.output' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)
$(cat aptarchive/pool/main/libb/libbar/libbar_1.0/changelog)"
-cd downloaded
-
testsuccess aptget changelog foo -d
testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
-testfileequal 'foo.changelog' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)"
+testfileequal 'foo.changelog' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)"
rm -f foo.changelog
testsuccess aptget changelog libbar foo -d
testfilestats 'libbar.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
-testfileequal 'libbar.changelog' "$(cat ../aptarchive/pool/main/libb/libbar/libbar_1.0/changelog)"
-testfileequal 'foo.changelog' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)"
+testfileequal 'libbar.changelog' "$(cat aptarchive/pool/main/libb/libbar/libbar_1.0/changelog)"
+testfileequal 'foo.changelog' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)"
rm -f libbar.changelog foo.changelog
# as such bogus, but can happen with multiple binaries from the same source
testsuccessequal "'http://localhost:${APTHTTPPORT}/pool/main/f/foo/foo_1.0/changelog' foo.changelog
'http://localhost:${APTHTTPPORT}/pool/main/f/foo/foo_1.0/changelog' foo.changelog" aptget changelog foo foo --print-uris
testsuccess aptget changelog foo foo -qq
-testfileequal '../rootdir/tmp/testsuccess.output' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)
-$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)"
+testfileequal 'rootdir/tmp/testsuccess.output' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)
+$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)"
+testsuccess aptget changelog foo foo -d
+testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
+testfileequal 'foo.changelog' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)"
+# we have the file already, confused?
+testsuccess aptget changelog foo foo -d
+testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
+testfileequal 'foo.changelog' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)"
+echo 'bogus' > foo.changelog
testsuccess aptget changelog foo foo -d
testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
-testfileequal 'foo.changelog' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)"
+testfileequal 'foo.changelog' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)"
rm -f foo.changelog
# no @CHANGEPATH@ in the URI
@@ -106,7 +107,6 @@ testfailure test -e foo.changelog
testequal "E: Failed to fetch http://localhost:${APTHTTPPORT}/does/not/exist/main/f/foo/foo_1.0/change.txt Changelog unavailable for foo=1.0 (404 Not Found)
" aptget changelog foo -qq -d -o Acquire::Changelogs::URI::Label::Testcases="http://localhost:${APTHTTPPORT}/does/not/exist/@CHANGEPATH@/change.txt"
testfailure test -e foo.changelog
-cd ..
testdpkgnotinstalled 'foo'
testsuccessequal "'http://localhost:${APTHTTPPORT}/pool/main/f/foo/foo_1.0/changelog' foo.changelog" apt changelog foo --print-uris -o Acquire::Changelogs::AlwaysOnline=false
@@ -121,10 +121,8 @@ testsuccessequal "'http://localhost:${APTHTTPPORT}/pool/main/d/dpkg/dpkg_42/chan
testsuccessequal "'http://localhost:${APTHTTPPORT}/pool/main/d/dpkg/dpkg_42/changelog' dpkg.changelog" apt changelog dpkg --print-uris -o Acquire::Changelogs::AlwaysOnline=false -o Acquire::Changelogs::AlwaysOnline::Origin::Ubuntu=true
testsuccessequal "'gzip:///usr/share/doc/dpkg/changelog.Debian.gz' dpkg.changelog" apt changelog dpkg --print-uris -o Acquire::Changelogs::AlwaysOnline=false -o Acquire::Changelogs::AlwaysOnline::Origin::Debian=true
-cd downloaded
testsuccess apt changelog dpkg -d
testfilestats 'dpkg.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
head -n 3 dpkg.changelog > dpkg.change
testfileequal 'dpkg.change' "$(apthelper cat-file '/usr/share/doc/dpkg/changelog.Debian.gz' | head -n 3)"
rm -f dpkg.change dpkg.changelog
-cd ..