CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sync_item_tar.cc
Go to the documentation of this file.
1 
5 #include "sync_item_tar.h"
6 
7 #include <string>
8 
9 #include "directory_entry.h"
10 #include "duplex_libarchive.h"
12 #include "sync_union_tarball.h"
13 #include "util/concurrency.h"
14 #include "util/platform.h"
15 
16 namespace publish {
17 
18 SyncItemTar::SyncItemTar(const std::string &relative_parent_path,
19  const std::string &filename, struct archive *archive,
20  struct archive_entry *entry,
21  Signal *read_archive_signal,
22  const SyncUnion *union_engine, const uid_t uid,
23  const gid_t gid)
24  : SyncItem(relative_parent_path, filename, union_engine, kItemUnknown)
25  , archive_(archive)
26  , archive_entry_(entry)
27  , obtained_tar_stat_(false)
28  , read_archive_signal_(read_archive_signal)
29  , uid_(uid)
30  , gid_(gid) {
32 }
33 
34 SyncItemTar::SyncItemTar(const std::string &relative_parent_path,
35  const std::string &filename, struct archive *archive,
36  struct archive_entry *entry,
37  Signal *read_archive_signal,
38  const SyncUnion *union_engine)
39  : SyncItem(relative_parent_path, filename, union_engine, kItemUnknown)
40  , archive_(archive)
41  , archive_entry_(entry)
42  , obtained_tar_stat_(false)
43  , read_archive_signal_(read_archive_signal)
44  , uid_(-1u)
45  , gid_(-1u) {
47 }
48 
49 void SyncItemTar::StatScratch(const bool refresh) const {
50  if (scratch_stat_.obtained && !refresh)
51  return;
54  scratch_stat_.obtained = true;
55 }
56 
59  switch (archive_entry_filetype(archive_entry_)) {
60  case AE_IFREG: {
61  return kItemFile;
62  break;
63  }
64  case AE_IFLNK: {
65  return kItemSymlink;
66  break;
67  }
68  case AE_IFSOCK: {
69  return kItemSocket;
70  break;
71  }
72  case AE_IFCHR: {
73  return kItemCharacterDevice;
74  break;
75  }
76  case AE_IFBLK: {
77  return kItemBlockDevice;
78  break;
79  }
80  case AE_IFDIR: {
81  return kItemDir;
82  break;
83  }
84  case AE_IFIFO: {
85  return kItemFifo;
86  break;
87  }
88  default:
89  return kItemUnknown;
90  break;
91  }
92 }
93 
94 bool SyncItemTar::IsType(const SyncItemType expected_type) const {
95  if (scratch_type_ == kItemUnknown) {
97  }
98  return scratch_type_ == expected_type;
99 }
100 
103  if (obtained_tar_stat_)
104  return tar_stat_;
105 
106  const struct stat *entry_stat = archive_entry_stat(archive_entry_);
107  assert(NULL != entry_stat);
108 
109  tar_stat_.st_mode = entry_stat->st_mode;
110 
111  if (uid_ != -1u) {
112  tar_stat_.st_uid = uid_;
113  } else {
114  tar_stat_.st_uid = entry_stat->st_uid;
115  }
116  if (gid_ != -1u) {
117  tar_stat_.st_gid = gid_;
118  } else {
119  tar_stat_.st_gid = entry_stat->st_gid;
120  }
121 
122  tar_stat_.st_rdev = entry_stat->st_rdev;
123  tar_stat_.st_size = entry_stat->st_size;
124  tar_stat_.st_mtime = entry_stat->st_mtime;
125 #ifdef __APPLE__
126  tar_stat_.st_mtimespec.tv_nsec = entry_stat->st_mtimespec.tv_nsec;
127 #else
128  tar_stat_.st_mtim.tv_nsec = entry_stat->st_mtim.tv_nsec;
129 #endif
130  tar_stat_.st_nlink = entry_stat->st_nlink;
131 
132  if (IsDirectory()) {
133  tar_stat_.st_size = 4096;
134  }
135 
136  obtained_tar_stat_ = true;
137 
138  return tar_stat_;
139 }
140 
142  bool enable_mtime_ns) const {
144 
146 
147  // inode and parent inode is determined at runtime of client
149 
150  // tarfiles do not keep information about the linkcount, so it should always
151  // appear as zero
152  assert(this->tar_stat_.st_nlink == 0);
153  dirent.linkcount_ = 1;
154 
155  dirent.mode_ = this->tar_stat_.st_mode;
156  dirent.uid_ = this->tar_stat_.st_uid;
157  dirent.gid_ = this->tar_stat_.st_gid;
158  dirent.size_ = this->tar_stat_.st_size;
159  dirent.mtime_ = this->tar_stat_.st_mtime;
160  dirent.checksum_ = this->GetContentHash();
161  dirent.is_external_file_ = this->IsExternalData();
163 
164  dirent.name_.Assign(this->filename().data(), this->filename().length());
165 
166  if (this->IsSymlink()) {
167  std::string symlink(archive_entry_symlink(archive_entry_));
168  dirent.symlink_.Assign(symlink.c_str(), symlink.length());
169  }
170 
171  if (this->IsCharacterDevice() || this->IsBlockDevice()) {
172  dirent.size_ = makedev(major(tar_stat_.st_rdev), minor(tar_stat_.st_rdev));
173  }
174 
175  if (enable_mtime_ns) {
176 #ifdef __APPLE__
177  dirent.mtime_ns_ = static_cast<int32_t>(
178  this->tar_stat_.st_mtimespec.tv_nsec);
179 #else
180  dirent.mtime_ns_ = static_cast<int32_t>(this->tar_stat_.st_mtim.tv_nsec);
181 #endif
182  }
183 
184  assert(dirent.IsRegular() || dirent.IsDirectory() || dirent.IsLink()
185  || dirent.IsSpecial());
186 
187  return dirent;
188 }
189 
193 }
194 } // namespace publish
bool IsSpecial() const
struct stat64 platform_stat64
bool IsDirectory() const
shash::Any GetContentHash() const
Definition: sync_item.h:119
inode_t inode_
platform_stat64 GetStatFromTar() const
void Assign(const char *chars, const unsigned length)
Definition: shortstring.h:61
gid_t gid_
Definition: loader.cc:135
gid_t gid_
struct archive * archive_
Definition: sync_item_tar.h:43
bool IsBlockDevice() const
Definition: sync_item.h:77
bool IsDirectory() const
Definition: sync_item.h:64
bool IsCharacterDevice() const
Definition: sync_item.h:76
assert((mem||(size==0))&&"Out Of Memory")
virtual void StatScratch(const bool refresh) const
int32_t mtime_ns_
uint64_t size_
SyncItemType scratch_type_
Definition: sync_item.h:288
NameString name_
platform_stat64 stat
Definition: sync_item.h:271
zlib::Algorithms compression_algorithm_
bool IsLink() const
uid_t uid_
Definition: loader.cc:134
bool IsRegular() const
std::string GetUnionPath() const
Definition: sync_item.cc:259
uint32_t linkcount_
bool is_external_file_
zlib::Algorithms GetCompressionAlgorithm() const
Definition: sync_item.h:125
virtual catalog::DirectoryEntryBase CreateBasicCatalogDirent(bool enable_mtime_ns) const
time_t mtime_
static const inode_t kInvalidInode
virtual bool IsType(const SyncItemType expected_type) const
EntryStat scratch_stat_
Definition: sync_item.h:281
platform_stat64 tar_stat_
Definition: sync_item_tar.h:46
Signal * read_archive_signal_
Definition: sync_item_tar.h:48
unsigned int mode_
SyncItemType
Definition: sync_item.h:29
struct archive_entry * archive_entry_
Definition: sync_item_tar.h:44
shash::Any checksum_
bool IsSymlink() const
Definition: sync_item.h:68
std::string filename() const
Definition: sync_item.h:179
bool IsExternalData() const
Definition: sync_item.h:81
bool obtained
Definition: sync_item.h:269
virtual IngestionSource * CreateIngestionSource() const
LinkString symlink_
int error_code
Definition: sync_item.h:270
SyncItemTar(const std::string &relative_parent_path, const std::string &filename, struct archive *archive, struct archive_entry *entry, Signal *read_archive_signal, const SyncUnion *union_engine, const uid_t uid, const gid_t gid)
virtual SyncItemType GetScratchFiletype() const
uid_t uid_