|
|
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
|
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "cmConfigure.h" // IWYU pragma: keep
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <iosfwd>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#if defined(CMAKE_BOOTSTRAP)
|
|
|
|
# error "cmArchiveWrite not allowed during bootstrap build!"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
class cmArchiveWriteOptional
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
cmArchiveWriteOptional() { this->Clear(); }
|
|
|
|
explicit cmArchiveWriteOptional(T val) { this->Set(val); }
|
|
|
|
|
|
|
|
void Set(T val)
|
|
|
|
{
|
|
|
|
this->IsValueSet = true;
|
|
|
|
this->Value = val;
|
|
|
|
}
|
|
|
|
void Clear() { this->IsValueSet = false; }
|
|
|
|
bool IsSet() const { return this->IsValueSet; }
|
|
|
|
T Get() const { return this->Value; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
T Value;
|
|
|
|
bool IsValueSet;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** \class cmArchiveWrite
|
|
|
|
* \brief Wrapper around libarchive for writing.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class cmArchiveWrite
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/** Compression type. */
|
|
|
|
enum Compress
|
|
|
|
{
|
|
|
|
CompressNone,
|
|
|
|
CompressCompress,
|
|
|
|
CompressGZip,
|
|
|
|
CompressBZip2,
|
|
|
|
CompressLZMA,
|
|
|
|
CompressXZ,
|
|
|
|
CompressZstd
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Construct with output stream to which to write archive. */
|
|
|
|
cmArchiveWrite(std::ostream& os, Compress c = CompressNone,
|
|
|
|
std::string const& format = "paxr", int compressionLevel = 0,
|
|
|
|
int numThreads = 1);
|
|
|
|
|
|
|
|
~cmArchiveWrite();
|
|
|
|
|
|
|
|
cmArchiveWrite(const cmArchiveWrite&) = delete;
|
|
|
|
cmArchiveWrite& operator=(const cmArchiveWrite&) = delete;
|
|
|
|
|
|
|
|
bool Open();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a path (file or directory) to the archive. Directories are
|
|
|
|
* added recursively. The "path" must be readable on disk, either
|
|
|
|
* full path or relative to current working directory. The "skip"
|
|
|
|
* value indicates how many leading bytes from the input path to
|
|
|
|
* skip. The remaining part of the input path is appended to the
|
|
|
|
* "prefix" value to construct the final name in the archive.
|
|
|
|
*/
|
|
|
|
bool Add(std::string path, size_t skip = 0, const char* prefix = nullptr,
|
|
|
|
bool recursive = true);
|
|
|
|
|
|
|
|
/** Returns true if there has been no error. */
|
|
|
|
explicit operator bool() const { return this->Okay(); }
|
|
|
|
|
|
|
|
/** Returns true if there has been an error. */
|
|
|
|
bool operator!() const { return !this->Okay(); }
|
|
|
|
|
|
|
|
/** Return the error string; empty if none. */
|
|
|
|
std::string GetError() const { return this->Error; }
|
|
|
|
|
|
|
|
// TODO: More general callback instead of hard-coding calls to
|
|
|
|
// std::cout.
|
|
|
|
void SetVerbose(bool v) { this->Verbose = v; }
|
|
|
|
|
|
|
|
void SetMTime(std::string const& t) { this->MTime = t; }
|
|
|
|
|
|
|
|
//! Sets the permissions of the added files/folders
|
|
|
|
void SetPermissions(int permissions_)
|
|
|
|
{
|
|
|
|
this->Permissions.Set(permissions_);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Clears permissions - default is used instead
|
|
|
|
void ClearPermissions() { this->Permissions.Clear(); }
|
|
|
|
|
|
|
|
//! Sets the permissions mask of files/folders
|
|
|
|
//!
|
|
|
|
//! The permissions will be copied from the existing file
|
|
|
|
//! or folder. The mask will then be applied to unset
|
|
|
|
//! some of them
|
|
|
|
void SetPermissionsMask(int permissionsMask_)
|
|
|
|
{
|
|
|
|
this->PermissionsMask.Set(permissionsMask_);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Clears permissions mask - default is used instead
|
|
|
|
void ClearPermissionsMask() { this->PermissionsMask.Clear(); }
|
|
|
|
|
|
|
|
//! Sets UID and GID to be used in the tar file
|
|
|
|
void SetUIDAndGID(int uid_, int gid_)
|
|
|
|
{
|
|
|
|
this->Uid.Set(uid_);
|
|
|
|
this->Gid.Set(gid_);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Clears UID and GID to be used in the tar file - default is used instead
|
|
|
|
void ClearUIDAndGID()
|
|
|
|
{
|
|
|
|
this->Uid.Clear();
|
|
|
|
this->Gid.Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Sets UNAME and GNAME to be used in the tar file
|
|
|
|
void SetUNAMEAndGNAME(const std::string& uname_, const std::string& gname_)
|
|
|
|
{
|
|
|
|
this->Uname = uname_;
|
|
|
|
this->Gname = gname_;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Clears UNAME and GNAME to be used in the tar file
|
|
|
|
//! default is used instead
|
|
|
|
void ClearUNAMEAndGNAME()
|
|
|
|
{
|
|
|
|
this->Uname = "";
|
|
|
|
this->Gname = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool Okay() const { return this->Error.empty(); }
|
|
|
|
bool AddPath(const char* path, size_t skip, const char* prefix,
|
|
|
|
bool recursive = true);
|
|
|
|
bool AddFile(const char* file, size_t skip, const char* prefix);
|
|
|
|
bool AddData(const char* file, size_t size);
|
|
|
|
|
|
|
|
struct Callback;
|
|
|
|
friend struct Callback;
|
|
|
|
|
|
|
|
class Entry;
|
|
|
|
|
|
|
|
std::ostream& Stream;
|
|
|
|
struct archive* Archive;
|
|
|
|
struct archive* Disk;
|
|
|
|
bool Verbose;
|
|
|
|
std::string Format;
|
|
|
|
std::string Error;
|
|
|
|
std::string MTime;
|
|
|
|
|
|
|
|
//! UID of the user in the tar file
|
|
|
|
cmArchiveWriteOptional<int> Uid;
|
|
|
|
|
|
|
|
//! GUID of the user in the tar file
|
|
|
|
cmArchiveWriteOptional<int> Gid;
|
|
|
|
|
|
|
|
//! UNAME/GNAME of the user (does not override UID/GID)
|
|
|
|
//!@{
|
|
|
|
std::string Uname;
|
|
|
|
std::string Gname;
|
|
|
|
//!@}
|
|
|
|
|
|
|
|
//! Permissions on files/folders
|
|
|
|
cmArchiveWriteOptional<int> Permissions;
|
|
|
|
cmArchiveWriteOptional<int> PermissionsMask;
|
|
|
|
};
|