cmArchiveWrite.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #pragma once
  4. #include "cmConfigure.h" // IWYU pragma: keep
  5. #include <cstddef>
  6. #include <iosfwd>
  7. #include <string>
  8. #if defined(CMAKE_BOOTSTRAP)
  9. # error "cmArchiveWrite not allowed during bootstrap build!"
  10. #endif
  11. template <typename T>
  12. class cmArchiveWriteOptional
  13. {
  14. public:
  15. cmArchiveWriteOptional() { this->Clear(); }
  16. explicit cmArchiveWriteOptional(T val) { this->Set(val); }
  17. void Set(T val)
  18. {
  19. this->IsValueSet = true;
  20. this->Value = val;
  21. }
  22. void Clear() { this->IsValueSet = false; }
  23. bool IsSet() const { return this->IsValueSet; }
  24. T Get() const { return this->Value; }
  25. private:
  26. T Value;
  27. bool IsValueSet;
  28. };
  29. /** \class cmArchiveWrite
  30. * \brief Wrapper around libarchive for writing.
  31. *
  32. */
  33. class cmArchiveWrite
  34. {
  35. public:
  36. /** Compression type. */
  37. enum Compress
  38. {
  39. CompressNone,
  40. CompressCompress,
  41. CompressGZip,
  42. CompressBZip2,
  43. CompressLZMA,
  44. CompressXZ,
  45. CompressZstd
  46. };
  47. /** Construct with output stream to which to write archive. */
  48. cmArchiveWrite(std::ostream& os, Compress c = CompressNone,
  49. std::string const& format = "paxr", int compressionLevel = 0);
  50. ~cmArchiveWrite();
  51. cmArchiveWrite(const cmArchiveWrite&) = delete;
  52. cmArchiveWrite& operator=(const cmArchiveWrite&) = delete;
  53. bool Open();
  54. /**
  55. * Add a path (file or directory) to the archive. Directories are
  56. * added recursively. The "path" must be readable on disk, either
  57. * full path or relative to current working directory. The "skip"
  58. * value indicates how many leading bytes from the input path to
  59. * skip. The remaining part of the input path is appended to the
  60. * "prefix" value to construct the final name in the archive.
  61. */
  62. bool Add(std::string path, size_t skip = 0, const char* prefix = nullptr,
  63. bool recursive = true);
  64. /** Returns true if there has been no error. */
  65. explicit operator bool() const { return this->Okay(); }
  66. /** Returns true if there has been an error. */
  67. bool operator!() const { return !this->Okay(); }
  68. /** Return the error string; empty if none. */
  69. std::string GetError() const { return this->Error; }
  70. // TODO: More general callback instead of hard-coding calls to
  71. // std::cout.
  72. void SetVerbose(bool v) { this->Verbose = v; }
  73. void SetMTime(std::string const& t) { this->MTime = t; }
  74. //! Sets the permissions of the added files/folders
  75. void SetPermissions(int permissions_)
  76. {
  77. this->Permissions.Set(permissions_);
  78. }
  79. //! Clears permissions - default is used instead
  80. void ClearPermissions() { this->Permissions.Clear(); }
  81. //! Sets the permissions mask of files/folders
  82. //!
  83. //! The permissions will be copied from the existing file
  84. //! or folder. The mask will then be applied to unset
  85. //! some of them
  86. void SetPermissionsMask(int permissionsMask_)
  87. {
  88. this->PermissionsMask.Set(permissionsMask_);
  89. }
  90. //! Clears permissions mask - default is used instead
  91. void ClearPermissionsMask() { this->PermissionsMask.Clear(); }
  92. //! Sets UID and GID to be used in the tar file
  93. void SetUIDAndGID(int uid_, int gid_)
  94. {
  95. this->Uid.Set(uid_);
  96. this->Gid.Set(gid_);
  97. }
  98. //! Clears UID and GID to be used in the tar file - default is used instead
  99. void ClearUIDAndGID()
  100. {
  101. this->Uid.Clear();
  102. this->Gid.Clear();
  103. }
  104. //! Sets UNAME and GNAME to be used in the tar file
  105. void SetUNAMEAndGNAME(const std::string& uname_, const std::string& gname_)
  106. {
  107. this->Uname = uname_;
  108. this->Gname = gname_;
  109. }
  110. //! Clears UNAME and GNAME to be used in the tar file
  111. //! default is used instead
  112. void ClearUNAMEAndGNAME()
  113. {
  114. this->Uname = "";
  115. this->Gname = "";
  116. }
  117. //! Set an option on a filter;
  118. bool SetFilterOption(const char* module, const char* key, const char* value);
  119. private:
  120. bool Okay() const { return this->Error.empty(); }
  121. bool AddPath(const char* path, size_t skip, const char* prefix,
  122. bool recursive = true);
  123. bool AddFile(const char* file, size_t skip, const char* prefix);
  124. bool AddData(const char* file, size_t size);
  125. struct Callback;
  126. friend struct Callback;
  127. class Entry;
  128. std::ostream& Stream;
  129. struct archive* Archive;
  130. struct archive* Disk;
  131. bool Verbose;
  132. std::string Format;
  133. std::string Error;
  134. std::string MTime;
  135. //! UID of the user in the tar file
  136. cmArchiveWriteOptional<int> Uid;
  137. //! GUID of the user in the tar file
  138. cmArchiveWriteOptional<int> Gid;
  139. //! UNAME/GNAME of the user (does not override UID/GID)
  140. //!@{
  141. std::string Uname;
  142. std::string Gname;
  143. //!@}
  144. //! Permissions on files/folders
  145. cmArchiveWriteOptional<int> Permissions;
  146. cmArchiveWriteOptional<int> PermissionsMask;
  147. };