file.cc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: file.cc,v 1.9.2.1 2004/01/16 18:58:50 mdz Exp $
  4. /* ######################################################################
  5. File URI method for APT
  6. This simply checks that the file specified exists, if so the relevant
  7. information is returned. If a .gz filename is specified then the file
  8. name with .gz removed will also be checked and information about it
  9. will be returned in Alt-*
  10. ##################################################################### */
  11. /*}}}*/
  12. // Include Files /*{{{*/
  13. #include <config.h>
  14. #include <apt-pkg/acquire-method.h>
  15. #include <apt-pkg/aptconfiguration.h>
  16. #include <apt-pkg/error.h>
  17. #include <apt-pkg/hashes.h>
  18. #include <apt-pkg/fileutl.h>
  19. #include <apt-pkg/strutl.h>
  20. #include <string>
  21. #include <sys/stat.h>
  22. #include <apti18n.h>
  23. /*}}}*/
  24. class FileMethod : public pkgAcqMethod
  25. {
  26. virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE;
  27. virtual bool Configuration(std::string Message) APT_OVERRIDE;
  28. public:
  29. FileMethod() : pkgAcqMethod("1.0",SingleInstance | SendConfig | LocalOnly) {};
  30. };
  31. bool FileMethod::Configuration(std::string Message)
  32. {
  33. if (pkgAcqMethod::Configuration(Message) == false)
  34. return false;
  35. DropPrivsOrDie();
  36. return true;
  37. }
  38. // FileMethod::Fetch - Fetch a file /*{{{*/
  39. // ---------------------------------------------------------------------
  40. /* */
  41. bool FileMethod::Fetch(FetchItem *Itm)
  42. {
  43. URI Get = Itm->Uri;
  44. std::string File = Get.Path;
  45. FetchResult Res;
  46. if (Get.Host.empty() == false)
  47. return _error->Error(_("Invalid URI, local URIS must not start with //"));
  48. struct stat Buf;
  49. // deal with destination files which might linger around
  50. if (lstat(Itm->DestFile.c_str(), &Buf) == 0)
  51. {
  52. if ((Buf.st_mode & S_IFREG) != 0)
  53. {
  54. if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
  55. {
  56. HashStringList const hsl = Itm->ExpectedHashes;
  57. if (Itm->ExpectedHashes.VerifyFile(File))
  58. {
  59. Res.Filename = Itm->DestFile;
  60. Res.IMSHit = true;
  61. }
  62. }
  63. }
  64. }
  65. if (Res.IMSHit != true)
  66. unlink(Itm->DestFile.c_str());
  67. // See if the file exists
  68. if (stat(File.c_str(),&Buf) == 0)
  69. {
  70. Res.Size = Buf.st_size;
  71. Res.Filename = File;
  72. Res.LastModified = Buf.st_mtime;
  73. Res.IMSHit = false;
  74. if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
  75. {
  76. unsigned long long const filesize = Itm->ExpectedHashes.FileSize();
  77. if (filesize != 0 && filesize == Res.Size)
  78. Res.IMSHit = true;
  79. }
  80. Hashes Hash(Itm->ExpectedHashes);
  81. FileFd Fd(File, FileFd::ReadOnly);
  82. Hash.AddFD(Fd);
  83. Res.TakeHashes(Hash);
  84. }
  85. if (Res.IMSHit == false)
  86. URIStart(Res);
  87. // See if the uncompressed file exists and reuse it
  88. FetchResult AltRes;
  89. AltRes.Filename.clear();
  90. std::vector<std::string> extensions = APT::Configuration::getCompressorExtensions();
  91. for (std::vector<std::string>::const_iterator ext = extensions.begin(); ext != extensions.end(); ++ext)
  92. {
  93. if (APT::String::Endswith(File, *ext) == true)
  94. {
  95. std::string const unfile = File.substr(0, File.length() - ext->length() - 1);
  96. if (stat(unfile.c_str(),&Buf) == 0)
  97. {
  98. AltRes.Size = Buf.st_size;
  99. AltRes.Filename = unfile;
  100. AltRes.LastModified = Buf.st_mtime;
  101. AltRes.IMSHit = false;
  102. if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
  103. AltRes.IMSHit = true;
  104. break;
  105. }
  106. // no break here as we could have situations similar to '.gz' vs '.tar.gz' here
  107. }
  108. }
  109. if (AltRes.Filename.empty() == false)
  110. URIDone(Res,&AltRes);
  111. else if (Res.Filename.empty() == false)
  112. URIDone(Res);
  113. else
  114. return _error->Error(_("File not found"));
  115. return true;
  116. }
  117. /*}}}*/
  118. int main()
  119. {
  120. setlocale(LC_ALL, "");
  121. FileMethod Mth;
  122. return Mth.Run();
  123. }