GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/libcvmfs_legacy.cc
Date: 2025-09-14 02:35:40
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 637 static int set_option(char const *name, char const *value, bool *var) {
22
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 637 times.
637 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 637 *var = true;
28 637 return 0;
29 }
30
31
32 980 static int set_option(char const *name, char const *value, unsigned *var) {
33 980 unsigned v = 0;
34 980 int end = 0;
35 980 const int rc = sscanf(value, "%u%n", &v, &end);
36
2/4
✓ Branch 0 taken 980 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 980 times.
980 if (rc != 1 || value[end] != '\0') {
37 fprintf(stderr, "Invalid unsigned integer value for %s=%s\n", name, value);
38 return -1;
39 }
40 980 *var = v;
41 980 return 0;
42 }
43
44
45 539 static int set_option(char const *name, char const *value, int *var) {
46 539 int v = 0;
47 539 int end = 0;
48 539 const int rc = sscanf(value, "%d%n", &v, &end);
49
2/4
✓ Branch 0 taken 539 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
539 if (rc != 1 || value[end] != '\0') {
50 fprintf(stderr, "Invalid integer value for %s=%s\n", name, value);
51 return -1;
52 }
53 539 *var = v;
54 539 return 0;
55 }
56
57
58 980 static int set_option(char const *name, char const *value, string *var) {
59 980 *var = value;
60 980 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 490 cvmfs_repo_options()
102 490 : timeout(2)
103 490 , timeout_direct(2)
104
1/2
✓ Branch 2 taken 490 times.
✗ Branch 3 not taken.
490 , pubkey("/etc/cvmfs/keys/cern.ch.pub")
105
1/2
✓ Branch 2 taken 490 times.
✗ Branch 3 not taken.
490 , blacklist("")
106 1470 , 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 3185 int set_option(char const *name, char const *value) {
127
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 3136 times.
3185 CVMFS_OPT(alien_cache);
128
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 3087 times.
3136 CVMFS_OPT(alien_cachedir);
129
2/2
✓ Branch 0 taken 588 times.
✓ Branch 1 taken 2499 times.
3087 CVMFS_OPT(cache_directory);
130
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 2401 times.
2499 CVMFS_OPT(cachedir);
131
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2352 times.
2401 CVMFS_OPT(lock_directory);
132
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 2254 times.
2352 CVMFS_OPT(change_to_cache_directory);
133
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2205 times.
2254 CVMFS_OPT(logfile);
134
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2156 times.
2205 CVMFS_OPT(log_file);
135
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 2058 times.
2156 CVMFS_OPT(log_prefix);
136
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2009 times.
2058 CVMFS_OPT(log_syslog_level);
137
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 1960 times.
2009 CVMFS_OPT(syslog_level);
138
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 1666 times.
1960 CVMFS_OPT(max_open_files);
139
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 1519 times.
1666 CVMFS_OPT(nofiles);
140
2/2
✓ Branch 0 taken 490 times.
✓ Branch 1 taken 1029 times.
1519 CVMFS_OPT(quota_limit);
141
2/2
✓ Branch 0 taken 490 times.
✓ Branch 1 taken 539 times.
1029 CVMFS_OPT(quota_threshold);
142
2/2
✓ Branch 0 taken 490 times.
✓ Branch 1 taken 49 times.
539 CVMFS_OPT(rebuild_cachedb);
143
144 49 fprintf(stderr, "Unknown global option: %s\n", name);
145 49 return LIBCVMFS_FAIL_BADOPT;
146 }
147
148 637 int verify_sanity() {
149 // Alias handling
150
6/6
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 490 times.
✓ Branch 2 taken 98 times.
✓ Branch 3 taken 49 times.
✓ Branch 4 taken 49 times.
✓ Branch 5 taken 49 times.
637 if ((nofiles >= 0) && (max_open_files != 0) && (nofiles != max_open_files))
151 49 return LIBCVMFS_FAIL_BADOPT;
152
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 490 times.
588 if (nofiles >= 0)
153 98 max_open_files = nofiles;
154
155
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 539 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
588 if ((syslog_level >= 0) && (log_syslog_level != 0)
156
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 && (syslog_level != log_syslog_level)) {
157 49 return LIBCVMFS_FAIL_BADOPT;
158 }
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 539 times.
539 if (syslog_level >= 0)
160 log_syslog_level = syslog_level;
161
1/2
✓ Branch 0 taken 539 times.
✗ Branch 1 not taken.
539 if (log_syslog_level < 0)
162 539 log_syslog_level = 3;
163
164
6/8
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 490 times.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 49 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 49 times.
✓ Branch 10 taken 490 times.
539 if ((logfile != "") && (log_file != "") && (log_file != logfile))
165 49 return LIBCVMFS_FAIL_BADOPT;
166
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 490 times.
490 if (logfile != "")
167 log_file = logfile;
168
169
1/2
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
588 if ((cachedir != "") && (cache_directory != "")
170
6/6
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 392 times.
✓ Branch 3 taken 49 times.
✓ Branch 4 taken 49 times.
✓ Branch 5 taken 49 times.
✓ Branch 6 taken 441 times.
588 && (cache_directory != cachedir)) {
171 49 return LIBCVMFS_FAIL_BADOPT;
172 }
173
2/2
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 392 times.
441 if (cachedir != "")
174 49 cache_directory = cachedir;
175
176 441 return LIBCVMFS_FAIL_OK;
177 }
178
179 686 cvmfs_global_options()
180 1372 : change_to_cache_directory(false)
181 686 , alien_cache(false)
182 686 , syslog_level(-1)
183 686 , log_syslog_level(-1)
184 686 , nofiles(-1)
185 686 , max_open_files(0)
186 686 , quota_limit(0)
187 686 , quota_threshold(0)
188 686 , 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 6370 int set_option(char const *name, char const *value) {
219 6370 return DerivedT::set_option(name, value);
220 }
221
222 1372 int parse_options(char const *options) {
223
6/6
✓ Branch 1 taken 3136 times.
✓ Branch 2 taken 49 times.
✓ Branch 4 taken 3136 times.
✓ Branch 5 taken 49 times.
✓ Branch 6 taken 3185 times.
✓ Branch 7 taken 637 times.
14112 while (*options) {
224 6370 char const *next = options;
225 6370 string name;
226 6370 string value;
227
228 // get the option name
229
6/6
✓ Branch 0 taken 45913 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 45276 times.
✓ Branch 3 taken 637 times.
✓ Branch 4 taken 42777 times.
✓ Branch 5 taken 2499 times.
91924 for (next = options; *next && *next != ',' && *next != '='; next++) {
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42777 times.
85554 if (*next == '\\') {
231 next++;
232 if (*next == '\0')
233 break;
234 }
235
1/2
✓ Branch 1 taken 42777 times.
✗ Branch 2 not taken.
85554 name += *next;
236 }
237
238
2/2
✓ Branch 0 taken 2499 times.
✓ Branch 1 taken 686 times.
6370 if (*next == '=') {
239 4998 next++;
240 }
241
242 // get the option value
243
4/4
✓ Branch 0 taken 27930 times.
✓ Branch 1 taken 637 times.
✓ Branch 2 taken 25382 times.
✓ Branch 3 taken 2548 times.
57134 for (; *next && *next != ','; next++) {
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25382 times.
50764 if (*next == '\\') {
245 next++;
246 if (*next == '\0')
247 break;
248 }
249
1/2
✓ Branch 1 taken 25382 times.
✗ Branch 2 not taken.
50764 value += *next;
250 }
251
252
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 3185 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 3185 times.
✗ Branch 7 not taken.
6370 if (!name.empty() || !value.empty()) {
253
1/2
✓ Branch 3 taken 3185 times.
✗ Branch 4 not taken.
6370 const int result = set_option(name.c_str(), value.c_str());
254
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 3136 times.
6370 if (result != 0) {
255 98 return result;
256 }
257 }
258
259
2/2
✓ Branch 0 taken 2548 times.
✓ Branch 1 taken 588 times.
6272 if (*next == ',')
260 5096 next++;
261 6272 options = next;
262 }
263
264 1274 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 490 static void usage() {
275
1/2
✓ Branch 1 taken 490 times.
✗ Branch 2 not taken.
490 struct cvmfs_repo_options const defaults;
276 490 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 490 times.
✗ Branch 2 not taken.
490 CVMFS_VERSION, defaults.timeout, defaults.timeout_direct);
340 490 }
341
342
343 /**
344 * Translates from loader::Failure codes to legacy LIBCVMFS_FAIL_... constants.
345 */
346 441 static int TranslateReturnValue(loader::Failures code) {
347 441 const int unknown = -10;
348
349
3/14
✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 196 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 49 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.
441 switch (code) {
350 196 case loader::kFailOk:
351 196 return LIBCVMFS_FAIL_OK;
352 case loader::kFailUnknown:
353 return unknown; // missing constant
354 case loader::kFailOptions:
355 return LIBCVMFS_FAIL_BADOPT;
356 196 case loader::kFailPermission:
357 196 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 49 case loader::kFailCacheDir:
365 49 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 686 SimpleOptionsParser *cvmfs_options_init_legacy(char const *legacy_options) {
396 686 global_options global_opts;
397
1/2
✓ Branch 1 taken 686 times.
✗ Branch 2 not taken.
686 const int parse_result = global_opts.parse_options(legacy_options);
398
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 441 times.
686 if (parse_result != 0) {
399
1/2
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
245 fprintf(stderr, "Invalid CVMFS global options: %s.\n", legacy_options);
400
1/2
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
245 usage();
401 245 return NULL;
402 }
403
404
1/2
✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
441 SimpleOptionsParser *options_mgr = cvmfs_options_init();
405
2/4
✓ Branch 2 taken 441 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 441 times.
✗ Branch 6 not taken.
441 options_mgr->SetValue("CVMFS_CACHE_DIR", global_opts.cache_directory);
406
2/2
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 392 times.
441 if (!global_opts.lock_directory.empty()) {
407
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
49 options_mgr->SetValue("CVMFS_WORKSPACE", global_opts.lock_directory);
408 }
409
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 392 times.
441 if (global_opts.alien_cache) {
410
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
49 options_mgr->SetValue("CVMFS_ALIEN_CACHE", global_opts.cache_directory);
411 }
412
2/2
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 392 times.
441 if (!global_opts.alien_cachedir.empty()) {
413
2/4
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 49 times.
✗ Branch 6 not taken.
49 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 441 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 441 times.
✗ Branch 6 not taken.
441 options_mgr->SetValue("CVMFS_SYSLOG_LEVEL",
421
1/2
✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
882 StringifyInt(global_opts.log_syslog_level));
422
2/2
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 343 times.
441 if (!global_opts.log_prefix.empty()) {
423
2/4
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 98 times.
✗ Branch 6 not taken.
98 options_mgr->SetValue("CVMFS_SYSLOG_PREFIX", global_opts.log_prefix);
424 }
425
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 441 times.
441 if (!global_opts.log_file.empty()) {
426 options_mgr->SetValue("CVMFS_DEBUGLOG", global_opts.log_file);
427 }
428
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 147 times.
441 if (global_opts.max_open_files > 0) {
429
2/4
✓ Branch 2 taken 294 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 294 times.
✗ Branch 6 not taken.
294 options_mgr->SetValue("CVMFS_NFILES",
430
1/2
✓ Branch 1 taken 294 times.
✗ Branch 2 not taken.
588 StringifyInt(global_opts.max_open_files));
431 }
432
433 441 return options_mgr;
434 686 }
435
436
437 686 int cvmfs_init(char const *options) {
438 686 SimpleOptionsParser *options_mgr = cvmfs_options_init_legacy(options);
439
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 441 times.
686 if (options_mgr == NULL) {
440 245 fprintf(stderr, "Invalid CVMFS global options: %s.\n", options);
441 245 usage();
442 245 return LIBCVMFS_FAIL_BADOPT;
443 }
444
445 441 const loader::Failures result = LibGlobals::Initialize(options_mgr);
446 441 LibGlobals::GetInstance()->set_options_mgr(options_mgr);
447
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 196 times.
441 if (result != loader::kFailOk)
448 245 LibGlobals::CleanupInstance();
449 441 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