summaryrefslogtreecommitdiff
path: root/methods/file.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-06-15 12:51:22 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-06-15 14:39:37 +0200
commit9f697f69cf1adaced476598cfe08ab03c76c5d18 (patch)
treee0032a72715eed96aff0ad096a8b27693a1b3627 /methods/file.cc
parentd56e2917f27a722b54685de13aeb1bb7592fc61b (diff)
ensure valid or remove destination file in file method
'file' isn't using the destination file per-se, but returns another name via "Filename" header. It still should deal with destination files as they could exist (pkgAcqFile e.g. creates links in that location) and are potentially bogus.
Diffstat (limited to 'methods/file.cc')
-rw-r--r--methods/file.cc44
1 files changed, 33 insertions, 11 deletions
diff --git a/methods/file.cc b/methods/file.cc
index 353e54bd5..5d5fffa67 100644
--- a/methods/file.cc
+++ b/methods/file.cc
@@ -48,8 +48,24 @@ bool FileMethod::Fetch(FetchItem *Itm)
if (Get.Host.empty() == false)
return _error->Error(_("Invalid URI, local URIS must not start with //"));
- // See if the file exists
struct stat Buf;
+ // deal with destination files which might linger around
+ if (lstat(Itm->DestFile.c_str(), &Buf) == 0)
+ {
+ if ((Buf.st_mode & S_IFREG) != 0)
+ {
+ if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
+ {
+ HashStringList const hsl = Itm->ExpectedHashes;
+ if (Itm->ExpectedHashes.VerifyFile(File))
+ Res.IMSHit = true;
+ }
+ }
+ }
+ if (Res.IMSHit != true)
+ unlink(Itm->DestFile.c_str());
+
+ // See if the file exists
if (stat(File.c_str(),&Buf) == 0)
{
Res.Size = Buf.st_size;
@@ -65,6 +81,8 @@ bool FileMethod::Fetch(FetchItem *Itm)
}
// See if the uncompressed file exists and reuse it
+ FetchResult AltRes;
+ AltRes.Filename.clear();
std::vector<std::string> extensions = APT::Configuration::getCompressorExtensions();
for (std::vector<std::string>::const_iterator ext = extensions.begin(); ext != extensions.end(); ++ext)
{
@@ -73,29 +91,33 @@ bool FileMethod::Fetch(FetchItem *Itm)
std::string const unfile = File.substr(0, File.length() - ext->length() - 1);
if (stat(unfile.c_str(),&Buf) == 0)
{
- FetchResult AltRes;
AltRes.Size = Buf.st_size;
AltRes.Filename = unfile;
AltRes.LastModified = Buf.st_mtime;
AltRes.IMSHit = false;
if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
AltRes.IMSHit = true;
-
- URIDone(Res,&AltRes);
- return true;
+ break;
}
// no break here as we could have situations similar to '.gz' vs '.tar.gz' here
}
}
- if (Res.Filename.empty() == true)
+ if (Res.Filename.empty() == false)
+ {
+ Hashes Hash(Itm->ExpectedHashes);
+ FileFd Fd(Res.Filename, FileFd::ReadOnly);
+ Hash.AddFD(Fd);
+ Res.TakeHashes(Hash);
+ }
+
+ if (AltRes.Filename.empty() == false)
+ URIDone(Res,&AltRes);
+ else if (Res.Filename.empty() == false)
+ URIDone(Res);
+ else
return _error->Error(_("File not found"));
- Hashes Hash(Itm->ExpectedHashes);
- FileFd Fd(Res.Filename, FileFd::ReadOnly);
- Hash.AddFD(Fd);
- Res.TakeHashes(Hash);
- URIDone(Res);
return true;
}
/*}}}*/