GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/sync_item_tar.cc
Date: 2026-04-19 02:41:37
Exec Total Coverage
Lines: 45 97 46.4%
Branches: 16 77 20.8%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System
3 */
4
5 #include "sync_item_tar.h"
6
7 #include <string>
8
9 #include "directory_entry.h"
10 #include "ingestion/ingestion_source.h"
11 #include "util/concurrency.h"
12
13 namespace publish {
14
15 462 SyncItemTar::SyncItemTar(const std::string &relative_parent_path,
16 const std::string &filename, struct archive *archive,
17 struct archive_entry *entry,
18 Signal *read_archive_signal,
19 const SyncUnion *union_engine, const uid_t uid,
20 462 const gid_t gid)
21 : SyncItem(relative_parent_path, filename, union_engine, kItemUnknown)
22 462 , archive_(archive)
23 462 , archive_entry_(entry)
24 462 , obtained_tar_stat_(false)
25 462 , read_archive_signal_(read_archive_signal)
26 462 , uid_(uid)
27 462 , gid_(gid) {
28
1/2
✓ Branch 1 taken 462 times.
✗ Branch 2 not taken.
462 GetStatFromTar();
29 462 }
30
31 SyncItemTar::SyncItemTar(const std::string &relative_parent_path,
32 const std::string &filename, struct archive *archive,
33 struct archive_entry *entry,
34 Signal *read_archive_signal,
35 const SyncUnion *union_engine)
36 : SyncItem(relative_parent_path, filename, union_engine, kItemUnknown)
37 , archive_(archive)
38 , archive_entry_(entry)
39 , obtained_tar_stat_(false)
40 , read_archive_signal_(read_archive_signal)
41 , uid_(-1u)
42 , gid_(-1u) {
43 GetStatFromTar();
44 }
45
46 void SyncItemTar::StatScratch(const bool refresh) const {
47 if (scratch_stat_.obtained && !refresh)
48 return;
49 scratch_stat_.stat = GetStatFromTar();
50 scratch_stat_.error_code = 0;
51 scratch_stat_.obtained = true;
52 }
53
54 462 SyncItemType SyncItemTar::GetScratchFiletype() const {
55
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 462 times.
462 assert(archive_entry_);
56
3/8
✓ Branch 1 taken 297 times.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 132 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
462 switch (archive_entry_filetype(archive_entry_)) {
57 297 case AE_IFREG: {
58 297 return kItemFile;
59 break;
60 }
61 33 case AE_IFLNK: {
62 33 return kItemSymlink;
63 break;
64 }
65 case AE_IFSOCK: {
66 return kItemSocket;
67 break;
68 }
69 case AE_IFCHR: {
70 return kItemCharacterDevice;
71 break;
72 }
73 case AE_IFBLK: {
74 return kItemBlockDevice;
75 break;
76 }
77 132 case AE_IFDIR: {
78 132 return kItemDir;
79 break;
80 }
81 case AE_IFIFO: {
82 return kItemFifo;
83 break;
84 }
85 default:
86 return kItemUnknown;
87 break;
88 }
89 }
90
91 1617 bool SyncItemTar::IsType(const SyncItemType expected_type) const {
92
2/2
✓ Branch 0 taken 462 times.
✓ Branch 1 taken 1155 times.
1617 if (scratch_type_ == kItemUnknown) {
93 462 scratch_type_ = GetScratchFiletype();
94 }
95 1617 return scratch_type_ == expected_type;
96 }
97
98 462 platform_stat64 SyncItemTar::GetStatFromTar() const {
99
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 462 times.
462 assert(archive_entry_);
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 462 times.
462 if (obtained_tar_stat_)
101 return tar_stat_;
102
103 462 const struct stat *entry_stat = archive_entry_stat(archive_entry_);
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 462 times.
462 assert(NULL != entry_stat);
105
106 462 tar_stat_.st_mode = entry_stat->st_mode;
107
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 462 times.
462 if (uid_ != -1u) {
109 tar_stat_.st_uid = uid_;
110 } else {
111 462 tar_stat_.st_uid = entry_stat->st_uid;
112 }
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 462 times.
462 if (gid_ != -1u) {
114 tar_stat_.st_gid = gid_;
115 } else {
116 462 tar_stat_.st_gid = entry_stat->st_gid;
117 }
118
119 462 tar_stat_.st_rdev = entry_stat->st_rdev;
120 462 tar_stat_.st_size = entry_stat->st_size;
121 462 tar_stat_.st_mtime = entry_stat->st_mtime;
122 #ifdef __APPLE__
123 tar_stat_.st_mtimespec.tv_nsec = entry_stat->st_mtimespec.tv_nsec;
124 #else
125 462 tar_stat_.st_mtim.tv_nsec = entry_stat->st_mtim.tv_nsec;
126 #endif
127 462 tar_stat_.st_nlink = entry_stat->st_nlink;
128
129
2/2
✓ Branch 1 taken 132 times.
✓ Branch 2 taken 330 times.
462 if (IsDirectory()) {
130 132 tar_stat_.st_size = 4096;
131 }
132
133 462 obtained_tar_stat_ = true;
134
135 462 return tar_stat_;
136 }
137
138 catalog::DirectoryEntryBase SyncItemTar::CreateBasicCatalogDirent(
139 bool enable_mtime_ns) const {
140 assert(obtained_tar_stat_);
141
142 catalog::DirectoryEntryBase dirent;
143
144 // inode and parent inode is determined at runtime of client
145 dirent.inode_ = catalog::DirectoryEntry::kInvalidInode;
146
147 // tarfiles do not keep information about the linkcount, so it should always
148 // appear as zero
149 assert(this->tar_stat_.st_nlink == 0);
150 dirent.linkcount_ = 1;
151
152 dirent.mode_ = this->tar_stat_.st_mode;
153 dirent.uid_ = this->tar_stat_.st_uid;
154 dirent.gid_ = this->tar_stat_.st_gid;
155 dirent.size_ = this->tar_stat_.st_size;
156 dirent.mtime_ = this->tar_stat_.st_mtime;
157 dirent.checksum_ = this->GetContentHash();
158 dirent.is_external_file_ = this->IsExternalData();
159 dirent.compression_algorithm_ = this->GetCompressionAlgorithm();
160
161 dirent.name_.Assign(this->filename().data(), this->filename().length());
162
163 if (this->IsSymlink()) {
164 const std::string symlink(archive_entry_symlink(archive_entry_));
165 dirent.symlink_.Assign(symlink.c_str(), symlink.length());
166 }
167
168 if (this->IsCharacterDevice() || this->IsBlockDevice()) {
169 dirent.size_ = makedev(major(tar_stat_.st_rdev), minor(tar_stat_.st_rdev));
170 }
171
172 if (enable_mtime_ns) {
173 #ifdef __APPLE__
174 dirent.mtime_ns_ = static_cast<int32_t>(
175 this->tar_stat_.st_mtimespec.tv_nsec);
176 #else
177 dirent.mtime_ns_ = static_cast<int32_t>(this->tar_stat_.st_mtim.tv_nsec);
178 #endif
179 }
180
181 assert(dirent.IsRegular() || dirent.IsDirectory() || dirent.IsLink()
182 || dirent.IsSpecial());
183
184 return dirent;
185 }
186
187 297 IngestionSource *SyncItemTar::CreateIngestionSource() const {
188 594 return new TarIngestionSource(GetUnionPath(), archive_, archive_entry_,
189
2/4
✓ Branch 1 taken 297 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 297 times.
✗ Branch 5 not taken.
594 read_archive_signal_);
190 }
191 } // namespace publish
192