]> git.saurik.com Git - apt.git/commitdiff
deal with partially downloaded changelogs
authorDavid Kalnischkies <david@kalnischkies.de>
Tue, 16 Feb 2016 14:35:36 +0000 (15:35 +0100)
committerDavid Kalnischkies <david@kalnischkies.de>
Sun, 6 Mar 2016 08:39:30 +0000 (09:39 +0100)
Changelogs are relatively small and we have no hashes for them, but we
had partial support for them before, so lets stick to it.

This also deletes the (partial) file before moving the downloaded file
into its place – rename(2) should be doing this by itself, but testing
on semaphoreci suggests that this isn't always the case (error is "Stale
file handle") and we don't need an atomic replace here, so be explicit.

Git-Dch: Ignore

apt-pkg/acquire-item.cc
test/integration/test-apt-get-changelog

index 4c1d93be1b9e38376f0d9c0e197eb7a5ea0a2000..62d9606336ba2750da86b738f7641bd6e78ef051 100644 (file)
@@ -3145,7 +3145,21 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi
 
    DestFile = flCombine(TemporaryDirectory, DestFileName);
    if (DestDir.empty() == false)
+   {
       d->FinalFile = flCombine(DestDir, DestFileName);
+      if (RealFileExists(d->FinalFile))
+      {
+        FileFd file1, file2;
+        if (file1.Open(DestFile, FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive) &&
+              file2.Open(d->FinalFile, FileFd::ReadOnly) && CopyFile(file2, file1))
+        {
+           struct timeval times[2];
+           times[0].tv_sec = times[1].tv_sec = file2.ModificationTime();
+           times[0].tv_usec = times[1].tv_usec = 0;
+           utimes(DestFile.c_str(), times);
+        }
+      }
+   }
 
    Desc.ShortDesc = "Changelog";
    strprintf(Desc.Description, "%s %s %s Changelog", URI::SiteOnly(Desc.URI).c_str(), SrcName.c_str(), SrcVersion.c_str());
@@ -3292,7 +3306,6 @@ void pkgAcqChangelog::Failed(string const &Message, pkgAcquire::MethodConfig con
       ErrorText = errText;
    else
       ErrorText = errText + " (" + ErrorText + ")";
-   return;
 }
                                                                        /*}}}*/
 // AcqChangelog::Done - Item downloaded OK                             /*{{{*/
@@ -3301,7 +3314,11 @@ void pkgAcqChangelog::Done(string const &Message,HashStringList const &CalcHashe
 {
    Item::Done(Message,CalcHashes,Cnf);
    if (d->FinalFile.empty() == false)
-      Rename(DestFile, d->FinalFile);
+   {
+      if (RemoveFile("pkgAcqChangelog::Done", d->FinalFile) == false ||
+           Rename(DestFile, d->FinalFile) == false)
+        Status = StatError;
+   }
 
    Complete = true;
 }
index d65c9530e081750e5c3c20bddac5330898b912f4..1815b99619ec6cf595b1476411cb2a0b021c53eb 100755 (executable)
@@ -94,9 +94,15 @@ 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
+touch -d 'now + 1 hour' 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)"
+echo -n 'bogus' > foo.changelog
+touch -d "$(stat -c%y aptarchive/pool/main/f/foo/foo_1.0/changelog)" foo.changelog
+testsuccess aptget changelog foo foo -d
+testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
+testequal 'bogus1.0) stable; urgency=low' head -n 1 foo.changelog
 rm -f foo.changelog
 
 # no @CHANGEPATH@ in the URI