GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/sync_item_tar.cc Lines: 0 62 0.0 %
Date: 2019-02-03 02:48:13 Branches: 0 46 0.0 %

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 "platform.h"
13
#include "sync_union_tarball.h"
14
#include "util_concurrency.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
    : SyncItem(relative_parent_path, filename, union_engine, kItemUnknown),
24
      archive_(archive),
25
      archive_entry_(entry),
26
      obtained_tar_stat_(false),
27
      read_archive_signal_(read_archive_signal) {
28
  GetStatFromTar();
29
}
30
31
void SyncItemTar::StatScratch(const bool refresh) const {
32
  if (scratch_stat_.obtained && !refresh) return;
33
  scratch_stat_.stat = GetStatFromTar();
34
  scratch_stat_.error_code = 0;
35
  scratch_stat_.obtained = true;
36
}
37
38
SyncItemType SyncItemTar::GetScratchFiletype() const {
39
  assert(archive_entry_);
40
  switch (archive_entry_filetype(archive_entry_)) {
41
    case AE_IFREG: {
42
      return kItemFile;
43
      break;
44
    }
45
    case AE_IFLNK: {
46
      return kItemSymlink;
47
      break;
48
    }
49
    case AE_IFSOCK: {
50
      return kItemSocket;
51
      break;
52
    }
53
    case AE_IFCHR: {
54
      return kItemCharacterDevice;
55
      break;
56
    }
57
    case AE_IFBLK: {
58
      return kItemBlockDevice;
59
      break;
60
    }
61
    case AE_IFDIR: {
62
      return kItemDir;
63
      break;
64
    }
65
    case AE_IFIFO: {
66
      return kItemFifo;
67
      break;
68
    }
69
    default:
70
      return kItemUnknown;
71
      break;
72
  }
73
}
74
75
bool SyncItemTar::IsType(const SyncItemType expected_type) const {
76
  if (scratch_type_ == kItemUnknown) {
77
    scratch_type_ = GetScratchFiletype();
78
  }
79
  return scratch_type_ == expected_type;
80
}
81
82
platform_stat64 SyncItemTar::GetStatFromTar() const {
83
  assert(archive_entry_);
84
  if (obtained_tar_stat_) return tar_stat_;
85
86
  const struct stat *entry_stat = archive_entry_stat(archive_entry_);
87
  assert(NULL != entry_stat);
88
89
  tar_stat_.st_mode = entry_stat->st_mode;
90
  tar_stat_.st_uid = entry_stat->st_uid;
91
  tar_stat_.st_gid = entry_stat->st_gid;
92
  tar_stat_.st_size = entry_stat->st_size;
93
  tar_stat_.st_mtime = entry_stat->st_mtime;
94
  tar_stat_.st_nlink = entry_stat->st_nlink;
95
96
  if (IsDirectory()) {
97
    tar_stat_.st_size = 4096;
98
  }
99
100
  obtained_tar_stat_ = true;
101
102
  return tar_stat_;
103
}
104
105
catalog::DirectoryEntryBase SyncItemTar::CreateBasicCatalogDirent() const {
106
  assert(obtained_tar_stat_);
107
108
  catalog::DirectoryEntryBase dirent;
109
110
  // inode and parent inode is determined at runtime of client
111
  dirent.inode_ = catalog::DirectoryEntry::kInvalidInode;
112
113
  // tarfiles do not keep information about the linkcount, so it should always
114
  // appear as zero
115
  assert(this->tar_stat_.st_nlink == 0);
116
  dirent.linkcount_ = 1;
117
118
  dirent.mode_ = this->tar_stat_.st_mode;
119
  dirent.uid_ = this->tar_stat_.st_uid;
120
  dirent.gid_ = this->tar_stat_.st_gid;
121
  dirent.size_ = this->tar_stat_.st_size;
122
  dirent.mtime_ = this->tar_stat_.st_mtime;
123
  dirent.checksum_ = this->GetContentHash();
124
  dirent.is_external_file_ = this->IsExternalData();
125
  dirent.compression_algorithm_ = this->GetCompressionAlgorithm();
126
127
  dirent.name_.Assign(this->filename().data(), this->filename().length());
128
129
  if (this->IsSymlink()) {
130
    std::string symlink(archive_entry_symlink(archive_entry_));
131
    dirent.symlink_.Assign(symlink.c_str(), symlink.length());
132
  }
133
134
  if (this->IsCharacterDevice() || this->IsBlockDevice()) {
135
    dirent.size_ = makedev(GetRdevMajor(), GetRdevMinor());
136
  }
137
138
  assert(dirent.IsRegular() || dirent.IsDirectory() || dirent.IsLink() ||
139
         dirent.IsSpecial());
140
141
  return dirent;
142
}
143
144
IngestionSource *SyncItemTar::CreateIngestionSource() const {
145
  return new TarIngestionSource(GetUnionPath(), archive_, archive_entry_,
146
                                read_archive_signal_);
147
}
148
}  // namespace publish