GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/swissknife_lsrepo.cc
Date: 2025-07-06 02:35:01
Exec Total Coverage
Lines: 0 71 0.0%
Branches: 0 54 0.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5
6 #include "swissknife_lsrepo.h"
7
8 #include <string>
9
10 #include "util/logging.h"
11 #include "util/posix.h"
12 #include "util/string.h"
13
14 namespace swissknife {
15
16 CommandListCatalogs::CommandListCatalogs()
17 : print_tree_(false)
18 , print_hash_(false)
19 , print_size_(false)
20 , print_entries_(false) { }
21
22
23 ParameterList CommandListCatalogs::GetParams() const {
24 ParameterList r;
25 r.push_back(Parameter::Mandatory(
26 'r', "repository URL (absolute local path or remote URL)"));
27 r.push_back(Parameter::Optional('n', "fully qualified repository name"));
28 r.push_back(Parameter::Optional('k', "repository master key(s) / dir"));
29 r.push_back(Parameter::Optional('l', "temporary directory"));
30 r.push_back(Parameter::Optional('h', "root hash (other than trunk)"));
31 r.push_back(Parameter::Optional('@', "proxy url"));
32 r.push_back(Parameter::Switch('t', "print tree structure of catalogs"));
33 r.push_back(Parameter::Switch('d', "print digest for each catalog"));
34 r.push_back(Parameter::Switch('s', "print catalog file sizes"));
35 r.push_back(Parameter::Switch('e', "print number of catalog entries"));
36 return r;
37 }
38
39
40 int CommandListCatalogs::Main(const ArgumentList &args) {
41 print_tree_ = (args.count('t') > 0);
42 print_hash_ = (args.count('d') > 0);
43 print_size_ = (args.count('s') > 0);
44 print_entries_ = (args.count('e') > 0);
45
46 shash::Any manual_root_hash;
47 const std::string &repo_url = *args.find('r')->second;
48 const std::string &repo_name = (args.count('n') > 0) ? *args.find('n')->second
49 : "";
50 std::string repo_keys = (args.count('k') > 0) ? *args.find('k')->second : "";
51 if (DirectoryExists(repo_keys))
52 repo_keys = JoinStrings(FindFilesBySuffix(repo_keys, ".pub"), ":");
53 const std::string &tmp_dir = (args.count('l') > 0) ? *args.find('l')->second
54 : "/tmp";
55 if (args.count('h') > 0) {
56 manual_root_hash = shash::MkFromHexPtr(
57 shash::HexPtr(*args.find('h')->second), shash::kSuffixCatalog);
58 }
59
60 bool success = false;
61 if (IsHttpUrl(repo_url)) {
62 const bool follow_redirects = false;
63 const std::string proxy = ((args.count('@') > 0) ? *args.find('@')->second
64 : "");
65 if (!this->InitDownloadManager(follow_redirects, proxy)
66 || !this->InitSignatureManager(repo_keys)) {
67 LogCvmfs(kLogCatalog, kLogStderr, "Failed to init remote connection");
68 return 1;
69 }
70
71 HttpObjectFetcher<catalog::Catalog, history::SqliteHistory> fetcher(
72 repo_name, repo_url, tmp_dir, download_manager(), signature_manager());
73 success = Run(manual_root_hash, &fetcher);
74 } else {
75 LocalObjectFetcher<> fetcher(repo_url, tmp_dir);
76 success = Run(manual_root_hash, &fetcher);
77 }
78
79 return (success) ? 0 : 1;
80 }
81
82
83 void CommandListCatalogs::CatalogCallback(
84 const CatalogTraversalData<catalog::Catalog> &data) {
85 std::string tree_indent;
86 std::string hash_string;
87 std::string clg_size;
88 std::string clg_entries;
89 std::string path;
90
91 if (print_tree_) {
92 for (unsigned int i = 1; i < data.tree_level; ++i) {
93 tree_indent += "\u2502 ";
94 }
95
96 if (data.tree_level > 0)
97 tree_indent += "\u251C\u2500 ";
98 }
99
100 if (print_hash_) {
101 hash_string = data.catalog_hash.ToString() + " ";
102 }
103
104 if (print_size_) {
105 clg_size = StringifyInt(data.file_size) + "B ";
106 }
107
108 if (print_entries_) {
109 clg_entries = StringifyInt(data.catalog->GetNumEntries()) + " ";
110 }
111
112 path = data.catalog->mountpoint().ToString();
113 if (path.empty())
114 path = "/";
115
116 LogCvmfs(kLogCatalog, kLogStdout, "%s%s%s%s%s", tree_indent.c_str(),
117 hash_string.c_str(), clg_size.c_str(), clg_entries.c_str(),
118 path.c_str());
119 }
120
121 } // namespace swissknife
122