GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/libcvmfs_legacy.cc
Date: 2024-04-28 02:33:07
Exec Total Coverage
Lines: 148 252 58.7%
Branches: 140 360 38.9%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 *
4 * Translates cvmfs_init and cvmfs_repo_attach calls into their contemporary
5 * counterparts.
6 */
7
8 #include "cvmfs_config.h"
9 #include "libcvmfs.h"
10
11 #include <cstdio>
12 #include <cstring>
13 #include <string>
14
15 #include "libcvmfs_int.h"
16 #include "loader.h"
17 #include "options.h"
18 #include "util/string.h"
19
20 using namespace std; // NOLINT
21
22 16 static int set_option(char const *name, char const *value, bool *var) {
23
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (*value != '\0') {
24 fprintf(stderr, "Option %s=%s contains a value when none was expected.\n",
25 name, value);
26 return -1;
27 }
28 16 *var = true;
29 16 return 0;
30 }
31
32
33 20 static int set_option(char const *name, char const *value, unsigned *var) {
34 20 unsigned v = 0;
35 20 int end = 0;
36 20 int rc = sscanf(value, "%u%n", &v, &end);
37
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
20 if (rc != 1 || value[end] != '\0') {
38 fprintf(stderr, "Invalid unsigned integer value for %s=%s\n", name, value);
39 return -1;
40 }
41 20 *var = v;
42 20 return 0;
43 }
44
45
46 13 static int set_option(char const *name, char const *value, int *var) {
47 13 int v = 0;
48 13 int end = 0;
49 13 int rc = sscanf(value, "%d%n", &v, &end);
50
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 if (rc != 1 || value[end] != '\0') {
51 fprintf(stderr, "Invalid integer value for %s=%s\n", name, value);
52 return -1;
53 }
54 13 *var = v;
55 13 return 0;
56 }
57
58
59 26 static int set_option(char const *name, char const *value, string *var) {
60 26 *var = value;
61 26 return 0;
62 }
63
64
65 #define CVMFS_OPT(var) if (strcmp(name, #var) == 0) \
66 return ::set_option(name, value, &var)
67
68
69 struct cvmfs_repo_options {
70 int set_option(char const *name, char const *value) {
71 CVMFS_OPT(allow_unsigned);
72 CVMFS_OPT(blacklist);
73 CVMFS_OPT(deep_mount); // deprecated
74 CVMFS_OPT(fallback_proxies);
75 CVMFS_OPT(mountpoint);
76 CVMFS_OPT(proxies);
77 CVMFS_OPT(pubkey);
78 CVMFS_OPT(repo_name);
79 CVMFS_OPT(timeout);
80 CVMFS_OPT(timeout_direct);
81 CVMFS_OPT(tracefile);
82 CVMFS_OPT(url);
83
84 fprintf(stderr, "Unknown repo option: %s\n", name);
85 return -1;
86 }
87
88 int verify_sanity() {
89 if (mountpoint.empty() && !repo_name.empty()) {
90 mountpoint = "/cvmfs/";
91 mountpoint += repo_name;
92 }
93 while (mountpoint.length() > 0 && mountpoint[mountpoint.length()-1] == '/')
94 {
95 mountpoint.resize(mountpoint.length()-1);
96 }
97
98 return LIBCVMFS_FAIL_OK;
99 }
100
101 10 cvmfs_repo_options() :
102 10 timeout(2),
103 10 timeout_direct(2),
104
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 pubkey("/etc/cvmfs/keys/cern.ch.pub"),
105
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 blacklist(""),
106 30 allow_unsigned(false) {}
107
108 unsigned timeout;
109 unsigned timeout_direct;
110 std::string url;
111 std::string external_url;
112 std::string proxies;
113 std::string fallback_proxies;
114 std::string tracefile; // unused
115 std::string pubkey;
116 std::string deep_mount;
117 std::string blacklist;
118 std::string repo_name;
119 std::string root_hash;
120 std::string mountpoint;
121 bool allow_unsigned;
122 };
123
124
125 struct cvmfs_global_options {
126 76 int set_option(char const *name, char const *value) {
127
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 74 times.
76 CVMFS_OPT(alien_cache);
128
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 72 times.
74 CVMFS_OPT(alien_cachedir);
129
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 58 times.
72 CVMFS_OPT(cache_directory);
130
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 56 times.
58 CVMFS_OPT(cachedir);
131
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 54 times.
56 CVMFS_OPT(lock_directory);
132
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 50 times.
54 CVMFS_OPT(change_to_cache_directory);
133
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 49 times.
50 CVMFS_OPT(logfile);
134
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 48 times.
49 CVMFS_OPT(log_file);
135
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 44 times.
48 CVMFS_OPT(log_prefix);
136
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 43 times.
44 CVMFS_OPT(log_syslog_level);
137
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 42 times.
43 CVMFS_OPT(syslog_level);
138
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 34 times.
42 CVMFS_OPT(max_open_files);
139
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 31 times.
34 CVMFS_OPT(nofiles);
140
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 21 times.
31 CVMFS_OPT(quota_limit);
141
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 11 times.
21 CVMFS_OPT(quota_threshold);
142
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
11 CVMFS_OPT(rebuild_cachedb);
143
144 1 fprintf(stderr, "Unknown global option: %s\n", name);
145 1 return LIBCVMFS_FAIL_BADOPT;
146 }
147
148 15 int verify_sanity() {
149 // Alias handling
150
6/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
15 if ((nofiles >= 0) && (max_open_files != 0) && (nofiles != max_open_files))
151 1 return LIBCVMFS_FAIL_BADOPT;
152
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
14 if (nofiles >= 0)
153 2 max_open_files = nofiles;
154
155
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
14 if ((syslog_level >= 0) && (log_syslog_level != 0) &&
156
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 (syslog_level != log_syslog_level))
157 {
158 1 return LIBCVMFS_FAIL_BADOPT;
159 }
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (syslog_level >= 0)
161 log_syslog_level = syslog_level;
162
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (log_syslog_level < 0)
163 13 log_syslog_level = 3;
164
165
6/8
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 12 times.
13 if ((logfile != "") && (log_file != "") && (log_file != logfile))
166 1 return LIBCVMFS_FAIL_BADOPT;
167
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 if (logfile != "")
168 log_file = logfile;
169
170
7/8
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 10 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 11 times.
14 if ((cachedir != "") && (cache_directory != "") &&
171 2 (cache_directory != cachedir))
172 {
173 1 return LIBCVMFS_FAIL_BADOPT;
174 }
175
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
11 if (cachedir != "")
176 1 cache_directory = cachedir;
177
178 11 return LIBCVMFS_FAIL_OK;
179 }
180
181 16 cvmfs_global_options()
182 32 : change_to_cache_directory(false)
183 16 , alien_cache(false)
184 16 , syslog_level(-1)
185 16 , log_syslog_level(-1)
186 16 , nofiles(-1)
187 16 , max_open_files(0)
188 16 , quota_limit(0)
189 16 , quota_threshold(0)
190 16 , rebuild_cachedb(0)
191 16 { }
192
193 std::string cache_directory;
194 std::string cachedir; // Alias of cache_directory
195 std::string alien_cachedir;
196 std::string lock_directory;
197 bool change_to_cache_directory;
198 bool alien_cache;
199
200 int syslog_level;
201 int log_syslog_level;
202 std::string log_prefix;
203 std::string logfile;
204 std::string log_file;
205
206 int nofiles;
207 int max_open_files; // Alias of nofiles
208
209 // Currently ignored
210 unsigned quota_limit;
211 unsigned quota_threshold;
212 bool rebuild_cachedb;
213 };
214
215
216 /**
217 * Structure to parse the file system options.
218 */
219 template <class DerivedT>
220 struct cvmfs_options : public DerivedT {
221 152 int set_option(char const *name, char const *value) {
222 152 return DerivedT::set_option(name, value);
223 }
224
225 32 int parse_options(char const *options)
226 {
227
6/6
✓ Branch 1 taken 75 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 75 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 76 times.
✓ Branch 7 taken 15 times.
336 while (*options) {
228 152 char const *next = options;
229 152 string name;
230 152 string value;
231
232 // get the option name
233
6/6
✓ Branch 0 taken 1115 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1099 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 1040 times.
✓ Branch 5 taken 59 times.
2232 for (next=options; *next && *next != ',' && *next != '='; next++) {
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1040 times.
2080 if (*next == '\\') {
235 next++;
236 if (*next == '\0') break;
237 }
238
1/2
✓ Branch 1 taken 1040 times.
✗ Branch 2 not taken.
2080 name += *next;
239 }
240
241
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 17 times.
152 if (*next == '=') {
242 118 next++;
243 }
244
245 // get the option value
246
4/4
✓ Branch 0 taken 723 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 662 times.
✓ Branch 3 taken 61 times.
1476 for (; *next && *next != ','; next++) {
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 662 times.
1324 if (*next == '\\') {
248 next++;
249 if (*next == '\0') break;
250 }
251
1/2
✓ Branch 1 taken 662 times.
✗ Branch 2 not taken.
1324 value += *next;
252 }
253
254
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 76 times.
✗ Branch 7 not taken.
152 if (!name.empty() || !value.empty()) {
255
1/2
✓ Branch 3 taken 76 times.
✗ Branch 4 not taken.
152 int result = set_option(name.c_str(), value.c_str());
256
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 75 times.
152 if (result != 0) {
257 2 return result;
258 }
259 }
260
261
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 14 times.
150 if (*next == ',') next++;
262 150 options = next;
263 }
264
265 30 return DerivedT::verify_sanity();
266 }
267 };
268
269 typedef cvmfs_options<cvmfs_repo_options> repo_options;
270 typedef cvmfs_options<cvmfs_global_options> global_options;
271
272 /**
273 * Display the usage message.
274 */
275 10 static void usage() {
276
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 struct cvmfs_repo_options defaults;
277
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 fprintf(stderr,
278 "CernVM-FS version %s\n"
279 "Copyright (c) 2009- CERN\n"
280 "All rights reserved\n\n"
281 "Please visit http://cernvm.cern.ch/project/info for license details "
282 "and author list.\n\n"
283
284 "libcvmfs options are expected in the form: option1,option2,option3,...\n"
285 "Within an option, the characters , and \\ must be preceded by \\.\n\n"
286
287 "There are two types of options (global and repository specifics)\n"
288 " cvmfs_init() expects global options\n"
289 " cvmfs_attach_repo() expects repository specific options\n"
290
291 "global options are:\n"
292 " cache_directory/cachedir=DIR Where to store disk cache\n"
293 " change_to_cache_directory Performs a cd to the cache directory "
294 "(performance tweak)\n"
295 " alien_cache Treat cache directory as alien cache\n"
296 " alien_cachedir=DIR Explicitly set an alien cache directory\n"
297 " lock_directory=DIR Directory for per instance lock files.\n"
298 " Needs to be on a file system with POSIX locks.\n"
299 " Should be different from alien cache directory."
300 " \nDefaults to cache_directory.\n"
301 " (log_)syslog_level=LEVEL Sets the level used for syslog to "
302 "DEBUG (1), INFO (2), or NOTICE (3).\n"
303 " Default is NOTICE.\n"
304 " log_prefix String to use as a log prefix in syslog\n"
305 " log_file/logfile Logs all messages to FILE instead of "
306 "stderr and daemonizes.\n"
307 " Makes only sense for the debug version\n"
308 " nofiles/max_open_files Set the maximum number of open files "
309 "for CernVM-FS process (soft limit)\n\n"
310
311 "repository specific options are:"
312 " repo_name=REPO_NAME Unique name of the mounted repository, "
313 "e.g. atlas.cern.ch\n"
314 " url=REPOSITORY_URL The URL of the CernVM-FS server(s): "
315 "'url1;url2;...'\n"
316 " timeout=SECONDS Timeout for network operations (default is %d)\n"
317 " timeout_direct=SECONDS Timeout for network operations without proxy "
318 "(default is %d)\n"
319 " proxies=HTTP_PROXIES Set the HTTP proxy list, such as "
320 "'proxy1|proxy2;DIRECT'\n"
321 " fallback_proxies=PROXIES Set the fallback proxy list, such as "
322 "'proxy1;proxy2'\n"
323 " tracefile=FILE Trace FUSE opaerations into FILE\n"
324 " pubkey=PEMFILE Public RSA key that is used to verify the "
325 "whitelist signature.\n"
326 " allow_unsigned Accept unsigned catalogs "
327 "(allows man-in-the-middle attacks)\n"
328 " deep_mount=PREFIX Path prefix if a repository is mounted on a "
329 "nested catalog,\n"
330 " i.e. deep_mount=/software/15.0.1\n"
331 " mountpoint=PATH Path to root of repository, "
332 "e.g. /cvmfs/atlas.cern.ch\n"
333 " blacklist=FILE Local blacklist for invalid certificates. "
334 "Has precedence over the whitelist.\n",
335 PACKAGE_VERSION, defaults.timeout, defaults.timeout_direct);
336 10 }
337
338
339 /**
340 * Translates from loader::Failure codes to legacy LIBCVMFS_FAIL_... constants.
341 */
342 11 static int TranslateReturnValue(loader::Failures code) {
343 11 const int unknown = -10;
344
345
3/14
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
11 switch (code) {
346 6 case loader::kFailOk:
347 6 return LIBCVMFS_FAIL_OK;
348 case loader::kFailUnknown:
349 return unknown; // missing constant
350 case loader::kFailOptions:
351 return LIBCVMFS_FAIL_BADOPT;
352 4 case loader::kFailPermission:
353 4 return LIBCVMFS_FAIL_NOFILES;
354 case loader::kFailMount:
355 case loader::kFailLoaderTalk:
356 case loader::kFailFuseLoop:
357 case loader::kFailLoadLibrary:
358 case loader::kFailIncompatibleVersions:
359 return unknown;
360 1 case loader::kFailCacheDir:
361 1 return LIBCVMFS_FAIL_MKCACHE;
362 case loader::kFailPeers:
363 case loader::kFailNfsMaps:
364 return unknown;
365 case loader::kFailQuota:
366 return LIBCVMFS_FAIL_INITQUOTA;
367 case loader::kFailMonitor:
368 case loader::kFailTalk:
369 return unknown;
370 case loader::kFailSignature:
371 case loader::kFailCatalog:
372 return LIBCVMFS_FAIL_INITCACHE;
373 case loader::kFailMaintenanceMode:
374 case loader::kFailSaveState:
375 case loader::kFailRestoreState:
376 case loader::kFailOtherMount:
377 case loader::kFailDoubleMount:
378 case loader::kFailHistory:
379 case loader::kFailRevisionBlacklisted:
380 return unknown;
381 case loader::kFailWpad:
382 return LIBCVMFS_FAIL_INITCACHE;
383 case loader::kFailLockWorkspace:
384 return LIBCVMFS_FAIL_LOCKFILE;
385 default:
386 return unknown;
387 }
388 }
389
390
391 16 SimpleOptionsParser *cvmfs_options_init_legacy(char const *legacy_options) {
392 16 global_options global_opts;
393
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 int parse_result = global_opts.parse_options(legacy_options);
394
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 11 times.
16 if (parse_result != 0) {
395
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 fprintf(stderr, "Invalid CVMFS global options: %s.\n", legacy_options);
396
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 usage();
397 5 return NULL;
398 }
399
400
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 SimpleOptionsParser *options_mgr = cvmfs_options_init();
401
2/4
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
11 options_mgr->SetValue("CVMFS_CACHE_DIR", global_opts.cache_directory);
402
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 9 times.
11 if (!global_opts.lock_directory.empty()) {
403
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 options_mgr->SetValue("CVMFS_WORKSPACE", global_opts.lock_directory);
404 }
405
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9 times.
11 if (global_opts.alien_cache) {
406
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 options_mgr->SetValue("CVMFS_ALIEN_CACHE", global_opts.cache_directory);
407 }
408
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 9 times.
11 if (!global_opts.alien_cachedir.empty()) {
409
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 options_mgr->SetValue("CVMFS_ALIEN_CACHE", global_opts.alien_cachedir);
410 }
411 // Note: as of version 2.4 CVMFS_CWD_CACHE support was dropped due to
412 // disproportional large complexity in the FileSystem class
413 // if (global_opts.change_to_cache_directory) {
414 // options_mgr->SetValue("CVMFS_CWD_CACHE", "on");
415 // }
416
2/4
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
11 options_mgr->SetValue("CVMFS_SYSLOG_LEVEL",
417
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
22 StringifyInt(global_opts.log_syslog_level));
418
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 7 times.
11 if (!global_opts.log_prefix.empty()) {
419
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 options_mgr->SetValue("CVMFS_SYSLOG_PREFIX", global_opts.log_prefix);
420 }
421
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if (!global_opts.log_file.empty()) {
422 options_mgr->SetValue("CVMFS_DEBUGLOG", global_opts.log_file);
423 }
424
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 if (global_opts.max_open_files > 0) {
425
2/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
8 options_mgr->SetValue("CVMFS_NFILES",
426
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 StringifyInt(global_opts.max_open_files));
427 }
428
429 11 return options_mgr;
430 16 }
431
432
433 16 int cvmfs_init(char const *options) {
434 16 SimpleOptionsParser *options_mgr = cvmfs_options_init_legacy(options);
435
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 11 times.
16 if (options_mgr == NULL) {
436 5 fprintf(stderr, "Invalid CVMFS global options: %s.\n", options);
437 5 usage();
438 5 return LIBCVMFS_FAIL_BADOPT;
439 }
440
441 11 loader::Failures result = LibGlobals::Initialize(options_mgr);
442 11 LibGlobals::GetInstance()->set_options_mgr(options_mgr);
443
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
11 if (result != loader::kFailOk)
444 5 LibGlobals::CleanupInstance();
445 11 return TranslateReturnValue(result);
446 }
447
448
449 SimpleOptionsParser *cvmfs_options_clone_legacy(
450 SimpleOptionsParser *opts,
451 const char *legacy_options)
452 {
453 // Parse options
454 repo_options repo_opts;
455 int parse_result = repo_opts.parse_options(legacy_options);
456 if ((parse_result != 0) || repo_opts.url.empty()) {
457 return NULL;
458 }
459
460 SimpleOptionsParser *options_mgr = cvmfs_options_clone(opts);
461 options_mgr->SwitchTemplateManager(
462 new DefaultOptionsTemplateManager(repo_opts.repo_name));
463 options_mgr->SetValue("CVMFS_FQRN", repo_opts.repo_name);
464 options_mgr->SetValue("CVMFS_TIMEOUT", StringifyInt(repo_opts.timeout));
465 options_mgr->SetValue("CVMFS_TIMEOUT_DIRECT",
466 StringifyInt(repo_opts.timeout_direct));
467 options_mgr->SetValue("CVMFS_SERVER_URL", repo_opts.url);
468 if (!repo_opts.external_url.empty()) {
469 options_mgr->SetValue("CVMFS_EXTERNAL_URL", repo_opts.external_url);
470 }
471 if (repo_opts.proxies.empty()) {
472 if (!options_mgr->IsDefined("CVMFS_HTTP_PROXY"))
473 options_mgr->SetValue("CVMFS_HTTP_PROXY", "DIRECT");
474 } else {
475 options_mgr->SetValue("CVMFS_HTTP_PROXY", repo_opts.proxies);
476 }
477 options_mgr->SetValue("CVMFS_FALLBACK_PROXY", repo_opts.fallback_proxies);
478 options_mgr->SetValue("CVMFS_PUBLIC_KEY", repo_opts.pubkey);
479 if (!repo_opts.blacklist.empty()) {
480 options_mgr->SetValue("CVMFS_BLACKLIST", repo_opts.blacklist);
481 }
482 if (!repo_opts.root_hash.empty()) {
483 options_mgr->SetValue("CVMFS_ROOT_HASH", repo_opts.root_hash);
484 }
485
486 return options_mgr;
487 }
488
489
490 LibContext* cvmfs_attach_repo(char const *options)
491 {
492 SimpleOptionsParser *options_mgr_base = cvmfs_options_init();
493 SimpleOptionsParser *options_mgr =
494 cvmfs_options_clone_legacy(options_mgr_base, options);
495 cvmfs_options_fini(options_mgr_base);
496 if (options_mgr == NULL) {
497 fprintf(stderr, "Invalid CVMFS options: %s.\n", options);
498 usage();
499 return NULL;
500 }
501
502 string repo_name;
503 bool retval = options_mgr->GetValue("CVMFS_FQRN", &repo_name);
504 assert(retval);
505 LibContext *ctx = LibContext::Create(repo_name, options_mgr);
506 assert(ctx != NULL);
507 if (ctx->mount_point()->boot_status() != loader::kFailOk) {
508 LogCvmfs(kLogCvmfs, kLogDebug, "failed attaching %s, %s (%d)",
509 repo_name.c_str(), ctx->mount_point()->boot_error().c_str(),
510 ctx->mount_point()->boot_status());
511 delete ctx;
512 return NULL;
513 }
514 ctx->set_options_mgr(options_mgr);
515 return ctx;
516 }
517