GCC Code Coverage Report


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