8 #define __STDC_FORMAT_MACROS
23 namespace swissknife {
28 static bool IsRemote(
const string &repository) {
29 return HasPrefix(repository,
"http://",
false)
30 ||
HasPrefix(repository,
"https://",
false);
36 bool CommandInfo::Exists(
const string &repository,
const string &file)
const {
38 const string url = repository +
"/" + file;
48 r.push_back(Parameter::Mandatory(
'r',
"repository directory / url"));
49 r.push_back(Parameter::Optional(
'u',
"repository mount point"));
50 r.push_back(Parameter::Optional(
'l',
"log level (0-4, default: 2)"));
51 r.push_back(Parameter::Optional(
'@',
"proxy url"));
52 r.push_back(Parameter::Switch(
'c',
"show root catalog hash"));
53 r.push_back(Parameter::Switch(
'C',
"show mounted root catalog hash"));
54 r.push_back(Parameter::Switch(
'n',
"show fully qualified repository name"));
55 r.push_back(Parameter::Switch(
't',
"show time stamp"));
56 r.push_back(Parameter::Switch(
'm',
57 "check if repository is marked as "
58 "replication master copy"));
59 r.push_back(Parameter::Switch(
'v',
"repository revision number"));
60 r.push_back(Parameter::Switch(
'g',
61 "check if repository is garbage "
63 r.push_back(Parameter::Switch(
'o',
64 "check if the repository maintains a "
65 "reference log file"));
66 r.push_back(Parameter::Switch(
'h',
"print results in human readable form"));
67 r.push_back(Parameter::Switch(
'L',
"follow HTTP redirects"));
68 r.push_back(Parameter::Switch(
'X',
69 "show whether external data is supported "
70 "in the root catalog."));
71 r.push_back(Parameter::Switch(
'M',
"print repository meta info."));
72 r.push_back(Parameter::Switch(
'R',
"print raw manifest."));
73 r.push_back(Parameter::Switch(
'e',
"check if the repository is empty"));
78 if (args.find(
'l') != args.end()) {
87 const string mount_point = (args.find(
'u') != args.end())
88 ? *args.find(
'u')->second
93 if (args.count(
'C') > 0 && mount_point.empty()) {
99 const bool follow_redirects = args.count(
'L') > 0;
100 const string proxy = (args.find(
'@') != args.end())
101 ? *args.find(
'@')->second
103 if (!this->InitDownloadManager(follow_redirects, proxy)) {
109 const bool human_readable = (args.count(
'h') > 0);
111 if (args.count(
'e') > 0) {
112 const string manifest_path =
IsRemote(repository)
114 : repository +
"/.cvmfspublished";
115 const bool is_empty = !Exists(repository, manifest_path);
117 (human_readable) ?
"Empty Repository: " :
"",
131 const string url = repository +
"/.cvmfspublished";
136 download_manager()->Fetch(&download_manifest);
144 manifest_memsink.
pos());
146 if (chdir(repository.c_str()) != 0) {
160 const string certificate_path =
"data/" + manifest->certificate().MakePath();
161 if (!Exists(repository, certificate_path)) {
163 certificate_path.c_str());
168 if (args.count(
'C') > 0) {
169 assert(!mount_point.empty());
170 const std::string root_hash_xattr =
"user.root_hash";
171 std::string root_hash;
176 "failed to retrieve extended attribute "
177 " '%s' from '%s' (errno: %d)",
178 root_hash_xattr.c_str(), mount_point.c_str(), errno);
182 (human_readable) ?
"Mounted Root Hash: " :
"",
187 if (args.count(
'X') > 0) {
188 assert(!mount_point.empty());
189 const std::string external_data_xattr =
"user.external_data";
190 std::string external_data;
195 "failed to retrieve extended attribute "
196 " '%s' from '%s' (errno: %d)",
197 external_data_xattr.c_str(), mount_point.c_str(), errno);
201 (human_readable) ?
"External data enabled: " :
"",
202 external_data.c_str());
206 if (args.count(
'c') > 0) {
208 (human_readable) ?
"Root Catalog Hash: " :
"",
209 manifest->catalog_hash().ToString().c_str());
212 if (args.count(
'n') > 0) {
214 (human_readable) ?
"Fully Qualified Repository Name: " :
"",
215 manifest->repository_name().c_str());
218 if (args.count(
't') > 0) {
220 (human_readable) ?
"Time Stamp: " :
"",
221 manifest->publish_timestamp());
224 if (args.count(
'm') > 0) {
226 (human_readable) ?
"Replication Master Copy: " :
"",
227 (Exists(repository,
".cvmfs_master_replica")) ?
"true" :
"false");
230 if (args.count(
'v') > 0) {
232 (human_readable) ?
"Revision: " :
"",
236 if (args.count(
'g') > 0) {
238 (human_readable) ?
"Garbage Collectable: " :
"",
242 if (args.count(
'o') > 0) {
244 (human_readable) ?
"Maintains Reference Log: " :
"",
245 (Exists(repository,
".cvmfsreflog")) ?
"true" :
"false");
248 if (args.count(
'M') > 0) {
255 const string url = repository +
"/data/" +
meta_info.MakePath();
260 download_manager()->Fetch(&download_metainfo);
264 "failed to download meta info (%d - %s)", retval,
268 const string info(reinterpret_cast<char *>(metainfo_memsink.
data()),
269 metainfo_memsink.
pos());
273 if (args.count(
'R') > 0) {
275 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,...)