CernVM-FS  2.12.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,
23  const uid_t uid, 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) return;
53  scratch_stat_.obtained = true;
54 }
55 
58  switch (archive_entry_filetype(archive_entry_)) {
59  case AE_IFREG: {
60  return kItemFile;
61  break;
62  }
63  case AE_IFLNK: {
64  return kItemSymlink;
65  break;
66  }
67  case AE_IFSOCK: {
68  return kItemSocket;
69  break;
70  }
71  case AE_IFCHR: {
72  return kItemCharacterDevice;
73  break;
74  }
75  case AE_IFBLK: {
76  return kItemBlockDevice;
77  break;
78  }
79  case AE_IFDIR: {
80  return kItemDir;
81  break;
82  }
83  case AE_IFIFO: {
84  return kItemFifo;
85  break;
86  }
87  default:
88  return kItemUnknown;
89  break;
90  }
91 }
92 
93 bool SyncItemTar::IsType(const SyncItemType expected_type) const {
94  if (scratch_type_ == kItemUnknown) {
96  }
97  return scratch_type_ == expected_type;
98 }
99 
102  if (obtained_tar_stat_) return tar_stat_;
103 
104  const struct stat *entry_stat = archive_entry_stat(archive_entry_);
105  assert(NULL != entry_stat);
106 
107  tar_stat_.st_mode = entry_stat->st_mode;
108 
109  if (uid_ != -1u) {
110  tar_stat_.st_uid = uid_;
111  } else {
112  tar_stat_.st_uid = entry_stat->st_uid;
113  }
114  if (gid_ != -1u) {
115  tar_stat_.st_gid = gid_;
116  } else {
117  tar_stat_.st_gid = entry_stat->st_gid;
118  }
119 
120  tar_stat_.st_rdev = entry_stat->st_rdev;
121  tar_stat_.st_size = entry_stat->st_size;
122  tar_stat_.st_mtime = entry_stat->st_mtime;
123 #ifdef __APPLE__
124  tar_stat_.st_mtimespec.tv_nsec = entry_stat->st_mtimespec.tv_nsec;
125 #else
126  tar_stat_.st_mtim.tv_nsec = entry_stat->st_mtim.tv_nsec;
127 #endif
128  tar_stat_.st_nlink = entry_stat->st_nlink;
129 
130  if (IsDirectory()) {
131  tar_stat_.st_size = 4096;
132  }
133 
134  obtained_tar_stat_ = true;
135 
136  return tar_stat_;
137 }
138 
140  bool enable_mtime_ns) const
141 {
143 
145 
146  // inode and parent inode is determined at runtime of client
148 
149  // tarfiles do not keep information about the linkcount, so it should always
150  // appear as zero
151  assert(this->tar_stat_.st_nlink == 0);
152  dirent.linkcount_ = 1;
153 
154  dirent.mode_ = this->tar_stat_.st_mode;
155  dirent.uid_ = this->tar_stat_.st_uid;
156  dirent.gid_ = this->tar_stat_.st_gid;
157  dirent.size_ = this->tar_stat_.st_size;
158  dirent.mtime_ = this->tar_stat_.st_mtime;
159  dirent.checksum_ = this->GetContentHash();
160  dirent.is_external_file_ = this->IsExternalData();
162 
163  dirent.name_.Assign(this->filename().data(), this->filename().length());
164 
165  if (this->IsSymlink()) {
166  std::string symlink(archive_entry_symlink(archive_entry_));
167  dirent.symlink_.Assign(symlink.c_str(), symlink.length());
168  }
169 
170  if (this->IsCharacterDevice() || this->IsBlockDevice()) {
171  dirent.size_ = makedev(major(tar_stat_.st_rdev), minor(tar_stat_.st_rdev));
172  }
173 
174  if (enable_mtime_ns) {
175 #ifdef __APPLE__
176  dirent.mtime_ns_ =
177  static_cast<int32_t>(this->tar_stat_.st_mtimespec.tv_nsec);
178 #else
179  dirent.mtime_ns_ = static_cast<int32_t>(this->tar_stat_.st_mtim.tv_nsec);
180 #endif
181  }
182 
183  assert(dirent.IsRegular() || dirent.IsDirectory() || dirent.IsLink() ||
184  dirent.IsSpecial());
185 
186  return dirent;
187 }
188 
192 }
193 } // namespace publish
bool IsSpecial() const
struct stat64 platform_stat64
bool IsDirectory() const
shash::Any GetContentHash() const
Definition: sync_item.h:121
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:133
gid_t gid_
struct archive * archive_
Definition: sync_item_tar.h:44
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:282
NameString name_
platform_stat64 stat
Definition: sync_item.h:265
zlib::Algorithms compression_algorithm_
bool IsLink() const
uid_t uid_
Definition: loader.cc:132
bool IsRegular() const
std::string GetUnionPath() const
Definition: sync_item.cc:261
uint32_t linkcount_
bool is_external_file_
zlib::Algorithms GetCompressionAlgorithm() const
Definition: sync_item.h:127
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:275
platform_stat64 tar_stat_
Definition: sync_item_tar.h:47
Signal * read_archive_signal_
Definition: sync_item_tar.h:49
unsigned int mode_
SyncItemType
Definition: sync_item.h:29
struct archive_entry * archive_entry_
Definition: sync_item_tar.h:45
shash::Any checksum_
bool IsSymlink() const
Definition: sync_item.h:68
std::string filename() const
Definition: sync_item.h:180
bool IsExternalData() const
Definition: sync_item.h:81
bool obtained
Definition: sync_item.h:263
virtual IngestionSource * CreateIngestionSource() const
LinkString symlink_
int error_code
Definition: sync_item.h:264
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_