X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/93bf083d699c60f1ac40297bfa6783fb0cb800d8..62600666d21aacea63cece3b4ec64f0ffb40168b:/methods/file.cc diff --git a/methods/file.cc b/methods/file.cc index 64490749b..5cbf1924e 100644 --- a/methods/file.cc +++ b/methods/file.cc @@ -1,11 +1,11 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: file.cc,v 1.4 1998/10/30 07:53:52 jgg Exp $ +// $Id: file.cc,v 1.9.2.1 2004/01/16 18:58:50 mdz Exp $ /* ###################################################################### File URI method for APT - This simply checks that the file specified exists, if so the relevent + This simply checks that the file specified exists, if so the relevant information is returned. If a .gz filename is specified then the file name with .gz removed will also be checked and information about it will be returned in Alt-* @@ -13,72 +13,120 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include +#include + +#include #include +#include +#include +#include +#include "aptmethod.h" +#include #include -#include + +#include /*}}}*/ -class FileMethod : public pkgAcqMethod +class FileMethod : public aptMethod { - virtual bool Fetch(string Message,URI Get); - + virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE; + public: - - FileMethod() : pkgAcqMethod("1.0",SingleInstance) {}; + FileMethod() : aptMethod("file", "1.0", SingleInstance | SendConfig | LocalOnly) {}; }; // FileMethod::Fetch - Fetch a file /*{{{*/ // --------------------------------------------------------------------- /* */ -bool FileMethod::Fetch(string Message,URI Get) +bool FileMethod::Fetch(FetchItem *Itm) { - string File = Get.Path; + URI Get = Itm->Uri; + std::string File = Get.Path; FetchResult Res; - - // See if the file exists + if (Get.Host.empty() == false) + return _error->Error(_("Invalid URI, local URIS must not start with //")); + 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.Filename = Itm->DestFile; + Res.IMSHit = true; + } + } + } + } + if (Res.IMSHit != true) + RemoveFile("file", Itm->DestFile); + + int olderrno = 0; + // See if the file exists if (stat(File.c_str(),&Buf) == 0) { Res.Size = Buf.st_size; Res.Filename = File; Res.LastModified = Buf.st_mtime; Res.IMSHit = false; - if (LastModified == Buf.st_mtime) - Res.IMSHit = true; + if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0) + { + unsigned long long const filesize = Itm->ExpectedHashes.FileSize(); + if (filesize != 0 && filesize == Res.Size) + Res.IMSHit = true; + } + + CalculateHashes(Itm, Res); } - - // See if we can compute a file without a .gz exentsion - string::size_type Pos = File.rfind(".gz"); - if (Pos + 3 == File.length()) + else + olderrno = errno; + if (Res.IMSHit == false) + URIStart(Res); + + // See if the uncompressed file exists and reuse it + FetchResult AltRes; + AltRes.Filename.clear(); + std::vector extensions = APT::Configuration::getCompressorExtensions(); + for (std::vector::const_iterator ext = extensions.begin(); ext != extensions.end(); ++ext) { - File = string(File,0,Pos); - if (stat(File.c_str(),&Buf) == 0) + if (APT::String::Endswith(File, *ext) == true) { - FetchResult AltRes; - AltRes.Size = Buf.st_size; - AltRes.Filename = File; - AltRes.LastModified = Buf.st_mtime; - AltRes.IMSHit = false; - if (LastModified == Buf.st_mtime) - AltRes.IMSHit = true; - - URIDone(Res,&AltRes); - return true; - } + std::string const unfile = File.substr(0, File.length() - ext->length()); + if (stat(unfile.c_str(),&Buf) == 0) + { + 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; + break; + } + // no break here as we could have situations similar to '.gz' vs '.tar.gz' here + } } - - if (Res.Filename.empty() == true) - return _error->Error("File not found"); - - URIDone(Res); + + if (AltRes.Filename.empty() == false) + URIDone(Res,&AltRes); + else if (Res.Filename.empty() == false) + URIDone(Res); + else + { + errno = olderrno; + return _error->Errno(File.c_str(), _("File not found")); + } + return true; } /*}}}*/ int main() { - FileMethod Mth; - return Mth.Run(); + return FileMethod().Run(); }