You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

136 lines
3.6 KiB

  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 "aptmethod.h"
  15. #include <apt-pkg/aptconfiguration.h>
  16. #include <apt-pkg/error.h>
  17. #include <apt-pkg/fileutl.h>
  18. #include <apt-pkg/hashes.h>
  19. #include <apt-pkg/strutl.h>
  20. #include <string>
  21. #include <sys/stat.h>
  22. #include <apti18n.h>
  23. /*}}}*/
  24. class FileMethod : public aptMethod
  25. {
  26. virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE;
  27. public:
  28. FileMethod() : aptMethod("file", "1.0", SingleInstance | SendConfig | LocalOnly)
  29. {
  30. SeccompFlags = aptMethod::BASE;
  31. }
  32. };
  33. // FileMethod::Fetch - Fetch a file /*{{{*/
  34. // ---------------------------------------------------------------------
  35. /* */
  36. bool FileMethod::Fetch(FetchItem *Itm)
  37. {
  38. URI Get = Itm->Uri;
  39. std::string File = Get.Path;
  40. FetchResult Res;
  41. if (Get.Host.empty() == false)
  42. return _error->Error(_("Invalid URI, local URIS must not start with //"));
  43. struct stat Buf;
  44. // deal with destination files which might linger around
  45. if (lstat(Itm->DestFile.c_str(), &Buf) == 0)
  46. {
  47. if ((Buf.st_mode & S_IFREG) != 0)
  48. {
  49. if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
  50. {
  51. HashStringList const hsl = Itm->ExpectedHashes;
  52. if (Itm->ExpectedHashes.VerifyFile(File))
  53. {
  54. Res.Filename = Itm->DestFile;
  55. Res.IMSHit = true;
  56. }
  57. }
  58. }
  59. }
  60. if (Res.IMSHit != true)
  61. RemoveFile("file", Itm->DestFile);
  62. int olderrno = 0;
  63. // See if the file exists
  64. if (stat(File.c_str(),&Buf) == 0)
  65. {
  66. Res.Size = Buf.st_size;
  67. Res.Filename = File;
  68. Res.LastModified = Buf.st_mtime;
  69. Res.IMSHit = false;
  70. if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
  71. {
  72. unsigned long long const filesize = Itm->ExpectedHashes.FileSize();
  73. if (filesize != 0 && filesize == Res.Size)
  74. Res.IMSHit = true;
  75. }
  76. CalculateHashes(Itm, Res);
  77. }
  78. else
  79. olderrno = errno;
  80. if (Res.IMSHit == false)
  81. URIStart(Res);
  82. // See if the uncompressed file exists and reuse it
  83. FetchResult AltRes;
  84. AltRes.Filename.clear();
  85. std::vector<std::string> extensions = APT::Configuration::getCompressorExtensions();
  86. for (std::vector<std::string>::const_iterator ext = extensions.begin(); ext != extensions.end(); ++ext)
  87. {
  88. if (APT::String::Endswith(File, *ext) == true)
  89. {
  90. std::string const unfile = File.substr(0, File.length() - ext->length());
  91. if (stat(unfile.c_str(),&Buf) == 0)
  92. {
  93. AltRes.Size = Buf.st_size;
  94. AltRes.Filename = unfile;
  95. AltRes.LastModified = Buf.st_mtime;
  96. AltRes.IMSHit = false;
  97. if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
  98. AltRes.IMSHit = true;
  99. break;
  100. }
  101. // no break here as we could have situations similar to '.gz' vs '.tar.gz' here
  102. }
  103. }
  104. if (AltRes.Filename.empty() == false)
  105. URIDone(Res,&AltRes);
  106. else if (Res.Filename.empty() == false)
  107. URIDone(Res);
  108. else
  109. {
  110. errno = olderrno;
  111. return _error->Errno(File.c_str(), _("File not found"));
  112. }
  113. return true;
  114. }
  115. /*}}}*/
  116. int main()
  117. {
  118. return FileMethod().Run();
  119. }