8 #define __STDC_FORMAT_MACROS
11 #include "cvmfs_config.h"
24 namespace swissknife {
29 static bool IsRemote(
const string &repository) {
30 return HasPrefix(repository,
"http://",
false) ||
37 bool CommandInfo::Exists(
const string &repository,
const string &file)
const {
39 const string url = repository +
"/" + file;
49 r.push_back(Parameter::Mandatory(
'r',
"repository directory / url"));
50 r.push_back(Parameter::Optional(
'u',
"repository mount point"));
51 r.push_back(Parameter::Optional(
'l',
"log level (0-4, default: 2)"));
52 r.push_back(Parameter::Optional(
'@',
"proxy url"));
53 r.push_back(Parameter::Switch(
'c',
"show root catalog hash"));
54 r.push_back(Parameter::Switch(
'C',
"show mounted root catalog hash"));
55 r.push_back(Parameter::Switch(
'n',
"show fully qualified repository name"));
56 r.push_back(Parameter::Switch(
't',
"show time stamp"));
57 r.push_back(Parameter::Switch(
'm',
58 "check if repository is marked as "
59 "replication master copy"));
60 r.push_back(Parameter::Switch(
'v',
"repository revision number"));
61 r.push_back(Parameter::Switch(
'g',
62 "check if repository is garbage "
64 r.push_back(Parameter::Switch(
'o',
65 "check if the repository maintains a "
66 "reference log file"));
67 r.push_back(Parameter::Switch(
'h',
"print results in human readable form"));
68 r.push_back(Parameter::Switch(
'L',
"follow HTTP redirects"));
69 r.push_back(Parameter::Switch(
'X',
70 "show whether external data is supported "
71 "in the root catalog."));
72 r.push_back(Parameter::Switch(
'M',
"print repository meta info."));
73 r.push_back(Parameter::Switch(
'R',
"print raw manifest."));
74 r.push_back(Parameter::Switch(
'e',
"check if the repository is empty"));
79 if (args.find(
'l') != args.end()) {
88 const string mount_point =
89 (args.find(
'u') != args.end()) ? *args.find(
'u')->second :
"";
93 if (args.count(
'C') > 0 && mount_point.empty()) {
99 const bool follow_redirects = args.count(
'L') > 0;
101 (args.find(
'@') != args.end()) ? *args.find(
'@')->second :
"";
102 if (!this->InitDownloadManager(follow_redirects, proxy)) {
108 const bool human_readable = (args.count(
'h') > 0);
110 if (args.count(
'e') > 0) {
111 string manifest_path =
IsRemote(repository)
113 : repository +
"/.cvmfspublished";
114 bool is_empty = !Exists(repository, manifest_path);
116 (human_readable) ?
"Empty Repository: " :
"",
118 if (is_empty)
return 0;
129 const string url = repository +
"/.cvmfspublished";
141 manifest_memsink.
pos());
143 if (chdir(repository.c_str()) != 0) {
157 const string certificate_path =
"data/" + manifest->certificate().MakePath();
158 if (!Exists(repository, certificate_path)) {
160 certificate_path.c_str());
165 if (args.count(
'C') > 0) {
166 assert(!mount_point.empty());
167 const std::string root_hash_xattr =
"user.root_hash";
168 std::string root_hash;
173 "failed to retrieve extended attribute "
174 " '%s' from '%s' (errno: %d)",
175 root_hash_xattr.c_str(), mount_point.c_str(), errno);
179 (human_readable) ?
"Mounted Root Hash: " :
"",
184 if (args.count(
'X') > 0) {
185 assert(!mount_point.empty());
186 const std::string external_data_xattr =
"user.external_data";
187 std::string external_data;
192 "failed to retrieve extended attribute "
193 " '%s' from '%s' (errno: %d)",
194 external_data_xattr.c_str(), mount_point.c_str(), errno);
198 (human_readable) ?
"External data enabled: " :
"",
199 external_data.c_str());
203 if (args.count(
'c') > 0) {
205 (human_readable) ?
"Root Catalog Hash: " :
"",
206 manifest->catalog_hash().ToString().c_str());
209 if (args.count(
'n') > 0) {
211 (human_readable) ?
"Fully Qualified Repository Name: " :
"",
212 manifest->repository_name().c_str());
215 if (args.count(
't') > 0) {
217 (human_readable) ?
"Time Stamp: " :
"",
218 manifest->publish_timestamp());
221 if (args.count(
'm') > 0) {
223 (human_readable) ?
"Replication Master Copy: " :
"",
224 (Exists(repository,
".cvmfs_master_replica")) ?
"true" :
"false");
227 if (args.count(
'v') > 0) {
229 (human_readable) ?
"Revision: " :
"",
233 if (args.count(
'g') > 0) {
235 (human_readable) ?
"Garbage Collectable: " :
"",
239 if (args.count(
'o') > 0) {
241 (human_readable) ?
"Maintains Reference Log: " :
"",
242 (Exists(repository,
".cvmfsreflog")) ?
"true" :
"false");
245 if (args.count(
'M') > 0) {
252 const string url = repository +
"/data/" +
meta_info.MakePath();
260 "failed to download meta info (%d - %s)", retval,
264 string info(reinterpret_cast<char*>(metainfo_memsink.
data()),
265 metainfo_memsink.
pos());
269 if (args.count(
'R') > 0) {
271 manifest->ExportString().c_str());
static bool IsRemote(const string &repository)
void SetLogVerbosity(const LogLevels max_level)
const manifest::Manifest * manifest() const
static Manifest * LoadMem(const unsigned char *buffer, const unsigned length)
std::vector< Parameter > ParameterList
assert((mem||(size==0))&&"Out Of Memory")
string StringifyBool(const bool value)
bool FileExists(const std::string &path)
const char * Code2Ascii(const Failures error)
string StringifyInt(const int64_t value)
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
uint64_t String2Uint64(const string &value)
std::map< char, SharedPtr< std::string > > ArgumentList
std::string meta_info() const
std::string MakeCanonicalPath(const std::string &path)
static Manifest * LoadFile(const std::string &path)
int Main(const ArgumentList &args)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)