GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/swissknife_main.cc
Date: 2025-06-22 02:36:02
Exec Total Coverage
Lines: 0 113 0.0%
Branches: 0 56 0.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include <cassert>
6 #include <string>
7
8 #include "statistics_database.h"
9 #include "swissknife.h"
10 #include "swissknife_check.h"
11 #include "swissknife_filestats.h"
12 #include "swissknife_gc.h"
13 #include "swissknife_graft.h"
14 #include "swissknife_history.h"
15 #include "swissknife_info.h"
16 #include "swissknife_ingest.h"
17 #include "swissknife_lease.h"
18 #include "swissknife_letter.h"
19 #include "swissknife_list_reflog.h"
20 #include "swissknife_lsrepo.h"
21 #include "swissknife_migrate.h"
22 #include "swissknife_notify.h"
23 #include "swissknife_pull.h"
24 #include "swissknife_reflog.h"
25 #include "swissknife_scrub.h"
26 #include "swissknife_sign.h"
27 #include "swissknife_sync.h"
28 #include "swissknife_zpipe.h"
29 #include "util/logging.h"
30 #include "util/posix.h"
31 #include "util/string.h"
32
33 using namespace std; // NOLINT
34
35 typedef vector<swissknife::Command *> Commands;
36 Commands command_list;
37
38 void Usage() {
39 LogCvmfs(kLogCvmfs, kLogStdout,
40 "CernVM-FS repository storage management commands\n"
41 "Version %s\n"
42 "Usage (normally called from cvmfs_server):\n"
43 " cvmfs_swissknife <command> [options]\n",
44 CVMFS_VERSION);
45
46 for (unsigned i = 0; i < command_list.size(); ++i) {
47 LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak,
48 "\n"
49 "Command %s\n"
50 "--------",
51 command_list[i]->GetName().c_str());
52 for (unsigned j = 0; j < command_list[i]->GetName().length(); ++j) {
53 LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "-");
54 }
55 LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n");
56 LogCvmfs(kLogCvmfs, kLogStdout, "%s",
57 command_list[i]->GetDescription().c_str());
58 swissknife::ParameterList params = command_list[i]->GetParams();
59 if (!params.empty()) {
60 LogCvmfs(kLogCvmfs, kLogStdout, "Options:");
61 for (unsigned j = 0; j < params.size(); ++j) {
62 LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, " -%c %s",
63 params[j].key(), params[j].description().c_str());
64 if (params[j].optional())
65 LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, " (optional)");
66 LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n");
67 }
68 } // Parameter list
69 } // Command list
70
71 LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n");
72 }
73
74
75 int main(int argc, char **argv) {
76 // Set default logging facilities
77 DefaultLogging::Set(kLogStdout, kLogStderr);
78
79 command_list.push_back(new swissknife::CommandCreate());
80 command_list.push_back(new swissknife::CommandUpload());
81 command_list.push_back(new swissknife::CommandRemove());
82 command_list.push_back(new swissknife::CommandPeek());
83 command_list.push_back(new swissknife::CommandSync());
84 command_list.push_back(new swissknife::CommandApplyDirtab());
85 command_list.push_back(new swissknife::CommandEditTag());
86 command_list.push_back(new swissknife::CommandListTags());
87 command_list.push_back(new swissknife::CommandInfoTag());
88 command_list.push_back(new swissknife::CommandRollbackTag());
89 command_list.push_back(new swissknife::CommandEmptyRecycleBin());
90 command_list.push_back(new swissknife::CommandSign());
91 command_list.push_back(new swissknife::CommandLetter());
92 command_list.push_back(new swissknife::CommandCheck());
93 command_list.push_back(new swissknife::CommandListCatalogs());
94 command_list.push_back(new swissknife::CommandPull());
95 command_list.push_back(new swissknife::CommandZpipe());
96 command_list.push_back(new swissknife::CommandGraft());
97 command_list.push_back(new swissknife::CommandInfo());
98 command_list.push_back(new swissknife::CommandVersion());
99 command_list.push_back(new swissknife::CommandMigrate());
100 command_list.push_back(new swissknife::CommandScrub());
101 command_list.push_back(new swissknife::CommandGc());
102 command_list.push_back(new swissknife::CommandListReflog());
103 command_list.push_back(new swissknife::CommandReconstructReflog());
104 command_list.push_back(new swissknife::CommandLease());
105 command_list.push_back(new swissknife::Ingest());
106 command_list.push_back(new swissknife::CommandNotify());
107 command_list.push_back(new swissknife::CommandFileStats());
108
109 if (argc < 2) {
110 Usage();
111 return 1;
112 }
113 if ((string(argv[1]) == "--help")) {
114 Usage();
115 return 0;
116 }
117 if ((string(argv[1]) == "--version")) {
118 swissknife::CommandVersion().Main(swissknife::ArgumentList());
119 return 0;
120 }
121
122 // find the command to be run
123 swissknife::Command *command = NULL;
124 for (unsigned i = 0; i < command_list.size(); ++i) {
125 if (command_list[i]->GetName() == string(argv[1])) {
126 command = command_list[i];
127 break;
128 }
129 }
130
131 if (NULL == command) {
132 Usage();
133 return 1;
134 }
135
136 bool display_statistics = false;
137
138 // parse the command line arguments for the Command
139 swissknife::ArgumentList args;
140 optind = 1;
141 string option_string = "";
142 swissknife::ParameterList params = command->GetParams();
143 for (unsigned j = 0; j < params.size(); ++j) {
144 option_string.push_back(params[j].key());
145 if (!params[j].switch_only())
146 option_string.push_back(':');
147 }
148 // Now adding the generic -+ extra option command
149 option_string.push_back(swissknife::Command::kGenericParam);
150 option_string.push_back(':');
151 int c;
152 while ((c = getopt(argc, argv, option_string.c_str())) != -1) {
153 bool valid_option = false;
154 for (unsigned j = 0; j < params.size(); ++j) {
155 if (c == params[j].key()) {
156 assert(c != swissknife::Command::kGenericParam);
157 valid_option = true;
158 args[c].Reset();
159 if (!params[j].switch_only()) {
160 args[c].Reset(new string(optarg));
161 }
162 break;
163 }
164 }
165 if (c == swissknife::Command::kGenericParam) {
166 valid_option = true;
167 vector<string> flags = SplitString(
168 optarg, swissknife::Command::kGenericParamSeparator);
169 for (unsigned i = 0; i < flags.size(); ++i) {
170 if (flags[i] == "stats") {
171 display_statistics = true;
172 }
173 }
174 }
175 if (!valid_option) {
176 Usage();
177 return 1;
178 }
179 }
180 for (unsigned j = 0; j < params.size(); ++j) {
181 if (!params[j].optional()) {
182 if (args.find(params[j].key()) == args.end()) {
183 LogCvmfs(kLogCvmfs, kLogStderr, "parameter -%c missing",
184 params[j].key());
185 return 1;
186 }
187 }
188 }
189
190 // run the command
191 const string start_time = GetGMTimestamp();
192 const int retval = command->Main(args);
193 const string finish_time = GetGMTimestamp();
194
195 if (display_statistics) {
196 LogCvmfs(kLogCvmfs, kLogStdout, "Command statistics");
197 LogCvmfs(kLogCvmfs, kLogStdout, "%s",
198 command->statistics()
199 ->PrintList(perf::Statistics::kPrintHeader)
200 .c_str());
201 }
202
203 // delete the command list
204 Commands::const_iterator i = command_list.begin();
205 const Commands::const_iterator iend = command_list.end();
206 for (; i != iend; ++i) {
207 delete *i;
208 }
209 command_list.clear();
210
211 return retval;
212 }
213