GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/sync_item_tar.cc
Date: 2024-04-28 02:33:07
Exec Total Coverage
Lines: 44 92 47.8%
Branches: 16 75 21.3%

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 "duplex_libarchive.h"
11 #include "ingestion/ingestion_source.h"
12 #include "sync_union_tarball.h"
13 #include "util/concurrency.h"
14 #include "util/platform.h"
15
16 namespace publish {
17
18 14 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 14 const uid_t uid, const gid_t gid)
24 : SyncItem(relative_parent_path, filename, union_engine, kItemUnknown),
25 14 archive_(archive),
26 14 archive_entry_(entry),
27 14 obtained_tar_stat_(false),
28 14 read_archive_signal_(read_archive_signal),
29 14 uid_(uid),
30 14 gid_(gid) {
31
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 GetStatFromTar();
32 14 }
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) {
46 GetStatFromTar();
47 }
48
49 void SyncItemTar::StatScratch(const bool refresh) const {
50 if (scratch_stat_.obtained && !refresh) return;
51 scratch_stat_.stat = GetStatFromTar();
52 scratch_stat_.error_code = 0;
53 scratch_stat_.obtained = true;
54 }
55
56 14 SyncItemType SyncItemTar::GetScratchFiletype() const {
57
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(archive_entry_);
58
3/8
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
14 switch (archive_entry_filetype(archive_entry_)) {
59 9 case AE_IFREG: {
60 9 return kItemFile;
61 break;
62 }
63 1 case AE_IFLNK: {
64 1 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 4 case AE_IFDIR: {
80 4 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 49 bool SyncItemTar::IsType(const SyncItemType expected_type) const {
94
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 35 times.
49 if (scratch_type_ == kItemUnknown) {
95 14 scratch_type_ = GetScratchFiletype();
96 }
97 49 return scratch_type_ == expected_type;
98 }
99
100 14 platform_stat64 SyncItemTar::GetStatFromTar() const {
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(archive_entry_);
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (obtained_tar_stat_) return tar_stat_;
103
104 14 const struct stat *entry_stat = archive_entry_stat(archive_entry_);
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(NULL != entry_stat);
106
107 14 tar_stat_.st_mode = entry_stat->st_mode;
108
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (uid_ != -1u) {
110 tar_stat_.st_uid = uid_;
111 } else {
112 14 tar_stat_.st_uid = entry_stat->st_uid;
113 }
114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (gid_ != -1u) {
115 tar_stat_.st_gid = gid_;
116 } else {
117 14 tar_stat_.st_gid = entry_stat->st_gid;
118 }
119
120 14 tar_stat_.st_rdev = entry_stat->st_rdev;
121 14 tar_stat_.st_size = entry_stat->st_size;
122 14 tar_stat_.st_mtime = entry_stat->st_mtime;
123 14 tar_stat_.st_nlink = entry_stat->st_nlink;
124
125
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 10 times.
14 if (IsDirectory()) {
126 4 tar_stat_.st_size = 4096;
127 }
128
129 14 obtained_tar_stat_ = true;
130
131 14 return tar_stat_;
132 }
133
134 catalog::DirectoryEntryBase SyncItemTar::CreateBasicCatalogDirent() const {
135 assert(obtained_tar_stat_);
136
137 catalog::DirectoryEntryBase dirent;
138
139 // inode and parent inode is determined at runtime of client
140 dirent.inode_ = catalog::DirectoryEntry::kInvalidInode;
141
142 // tarfiles do not keep information about the linkcount, so it should always
143 // appear as zero
144 assert(this->tar_stat_.st_nlink == 0);
145 dirent.linkcount_ = 1;
146
147 dirent.mode_ = this->tar_stat_.st_mode;
148 dirent.uid_ = this->tar_stat_.st_uid;
149 dirent.gid_ = this->tar_stat_.st_gid;
150 dirent.size_ = this->tar_stat_.st_size;
151 dirent.mtime_ = this->tar_stat_.st_mtime;
152 dirent.checksum_ = this->GetContentHash();
153 dirent.is_external_file_ = this->IsExternalData();
154 dirent.compression_algorithm_ = this->GetCompressionAlgorithm();
155
156 dirent.name_.Assign(this->filename().data(), this->filename().length());
157
158 if (this->IsSymlink()) {
159 std::string symlink(archive_entry_symlink(archive_entry_));
160 dirent.symlink_.Assign(symlink.c_str(), symlink.length());
161 }
162
163 if (this->IsCharacterDevice() || this->IsBlockDevice()) {
164 dirent.size_ = makedev(major(tar_stat_.st_rdev), minor(tar_stat_.st_rdev));
165 }
166
167 assert(dirent.IsRegular() || dirent.IsDirectory() || dirent.IsLink() ||
168 dirent.IsSpecial());
169
170 return dirent;
171 }
172
173 9 IngestionSource *SyncItemTar::CreateIngestionSource() const {
174 18 return new TarIngestionSource(GetUnionPath(), archive_, archive_entry_,
175
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
18 read_archive_signal_);
176 }
177 } // namespace publish
178