Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <config_folders.h>
21 :
22 : #include <stdio.h>
23 :
24 : #include <unotools/bootstrap.hxx>
25 :
26 : #include <rtl/ustring.hxx>
27 : #include <rtl/ustrbuf.hxx>
28 : #include <sal/log.hxx>
29 : #include <osl/file.hxx>
30 : #include <osl/mutex.hxx>
31 : #include <osl/diagnose.h>
32 :
33 : #include <rtl/bootstrap.hxx>
34 : #include <rtl/instance.hxx>
35 : #include <osl/process.h>
36 : #include <tools/getprocessworkingdir.hxx>
37 :
38 : // #define this to true, if remembering defaults is not supported properly
39 : #define RTL_BOOTSTRAP_DEFAULTS_BROKEN true
40 :
41 : #define BOOTSTRAP_ITEM_PRODUCT_KEY "ProductKey"
42 : #define BOOTSTRAP_ITEM_VERSIONFILE "Location"
43 : #define BOOTSTRAP_ITEM_BUILDID "buildid"
44 : #define BOOTSTRAP_ITEM_BUILDVERSION "BuildVersion"
45 :
46 : #define BOOTSTRAP_ITEM_BASEINSTALLATION "BRAND_BASE_DIR"
47 : #define BOOTSTRAP_ITEM_USERINSTALLATION "UserInstallation"
48 :
49 : #define BOOTSTRAP_ITEM_USERDIR "UserDataDir"
50 :
51 : #define BOOTSTRAP_DEFAULT_BASEINSTALL "$SYSBINDIR/.."
52 :
53 : #define BOOTSTRAP_DIRNAME_USERDIR "user"
54 :
55 : typedef char const * AsciiString;
56 :
57 : namespace utl
58 : {
59 :
60 : // Implementation class: Bootstrap::Impl
61 :
62 : namespace
63 : {
64 210 : OUString makeImplName()
65 : {
66 210 : OUString uri;
67 210 : rtl::Bootstrap::get( OUString("BRAND_BASE_DIR"), uri);
68 210 : return uri + "/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap");
69 : }
70 : }
71 :
72 210 : class Bootstrap::Impl
73 : {
74 : const OUString m_aImplName;
75 : public: // struct to cache the result of a path lookup
76 840 : struct PathData
77 : {
78 : OUString path;
79 : PathStatus status;
80 :
81 840 : PathData()
82 : : path()
83 840 : , status(DATA_UNKNOWN)
84 840 : {}
85 : };
86 : public: // data members
87 : // base install data
88 : PathData aBaseInstall_;
89 :
90 : // user install data
91 : PathData aUserInstall_;
92 :
93 : // INI files
94 : PathData aBootstrapINI_;
95 : PathData aVersionINI_;
96 :
97 : // overall status
98 : Status status_;
99 :
100 : public: // construction and initialization
101 210 : Impl() : m_aImplName(makeImplName())
102 : {
103 210 : initialize();
104 210 : }
105 :
106 : void initialize();
107 :
108 : // access helper
109 : OUString getBootstrapValue(OUString const& _sName, OUString const& _sDefault) const;
110 : static bool getVersionValue(OUString const& _sName, OUString& _rValue, OUString const& _sDefault);
111 :
112 210 : OUString getImplName() const { return m_aImplName; }
113 :
114 : private: // implementation
115 : bool initBaseInstallationData(rtl::Bootstrap& _rData);
116 : bool initUserInstallationData(rtl::Bootstrap& _rData);
117 : };
118 :
119 : namespace
120 : {
121 : class theImpl : public rtl::Static<Bootstrap::Impl, theImpl> {};
122 : }
123 :
124 921 : const Bootstrap::Impl& Bootstrap::data()
125 : {
126 921 : return theImpl::get();
127 : }
128 :
129 116 : void Bootstrap::reloadData()
130 : {
131 116 : theImpl::get().initialize();
132 116 : }
133 :
134 : // helper
135 :
136 : typedef Bootstrap::PathStatus PathStatus;
137 :
138 : sal_Unicode const cURLSeparator = '/';
139 :
140 : // path status utility function
141 : static
142 1187 : PathStatus implCheckStatusOfURL(OUString const& _sURL, osl::DirectoryItem& aDirItem)
143 : {
144 : using namespace osl;
145 :
146 1187 : PathStatus eStatus = Bootstrap::DATA_UNKNOWN;
147 :
148 1187 : if (!_sURL.isEmpty())
149 : {
150 1187 : switch( DirectoryItem::get(_sURL, aDirItem) )
151 : {
152 : case DirectoryItem::E_None: // Success
153 1174 : eStatus = Bootstrap::PATH_EXISTS;
154 1174 : break;
155 :
156 : case DirectoryItem::E_NOENT: // No such file or directory<br>
157 13 : eStatus = Bootstrap::PATH_VALID;
158 13 : break;
159 :
160 : case DirectoryItem::E_INVAL: // the format of the parameters was not valid<br>
161 : case DirectoryItem::E_NAMETOOLONG: // File name too long<br>
162 : case DirectoryItem::E_NOTDIR: // A component of the path prefix of path is not a directory<p>
163 0 : eStatus = Bootstrap::DATA_INVALID;
164 0 : break;
165 :
166 : // how to handle these ?
167 : case DirectoryItem::E_LOOP: // Too many symbolic links encountered<br>
168 : case DirectoryItem::E_ACCES: // permission denied<br>
169 : // any other error - what to do ?
170 : default:
171 0 : eStatus = Bootstrap::DATA_UNKNOWN;
172 0 : break;
173 : }
174 : }
175 : else
176 0 : eStatus = Bootstrap::DATA_MISSING;
177 :
178 1187 : return eStatus;
179 : }
180 :
181 : static
182 1174 : bool implNormalizeURL(OUString & _sURL, osl::DirectoryItem& aDirItem)
183 : {
184 : using namespace osl;
185 :
186 : OSL_PRECOND(aDirItem.is(), "Opened DirItem required");
187 :
188 : static const sal_uInt32 cosl_FileStatus_Mask = osl_FileStatus_Mask_FileURL;
189 :
190 1174 : FileStatus aFileStatus(cosl_FileStatus_Mask);
191 :
192 1174 : if (aDirItem.getFileStatus(aFileStatus) != DirectoryItem::E_None)
193 0 : return false;
194 :
195 2348 : OUString aNormalizedURL = aFileStatus.getFileURL();
196 :
197 1174 : if (aNormalizedURL.isEmpty())
198 0 : return false;
199 :
200 : // #109863# sal/osl returns final slash for file URLs contradicting
201 : // the URL/URI RFCs.
202 1174 : if ( !aNormalizedURL.endsWith(OUString(cURLSeparator)) )
203 1174 : _sURL = aNormalizedURL;
204 : else
205 0 : _sURL = aNormalizedURL.copy( 0, aNormalizedURL.getLength()-1 );
206 :
207 2348 : return true;
208 : }
209 :
210 : static
211 1187 : bool implEnsureAbsolute(OUString & _rsURL) // also strips embedded dots !!
212 : {
213 : using osl::File;
214 :
215 1187 : OUString sBasePath;
216 1187 : OSL_VERIFY(tools::getProcessWorkingDir(sBasePath));
217 :
218 2374 : OUString sAbsolute;
219 1187 : if ( File::E_None == File::getAbsoluteFileURL(sBasePath, _rsURL, sAbsolute))
220 : {
221 1187 : _rsURL = sAbsolute;
222 1187 : return true;
223 : }
224 : else
225 : {
226 : OSL_FAIL("Could not get absolute file URL for URL");
227 0 : return false;
228 1187 : }
229 : }
230 :
231 : static
232 1187 : bool implMakeAbsoluteURL(OUString & _rsPathOrURL)
233 : {
234 : using namespace osl;
235 :
236 : bool bURL;
237 :
238 1187 : OUString sOther;
239 : // check if it already was normalized
240 1187 : if ( File::E_None == File::getSystemPathFromFileURL(_rsPathOrURL, sOther) )
241 : {
242 1187 : bURL = true;
243 : }
244 :
245 0 : else if ( File::E_None == File::getFileURLFromSystemPath(_rsPathOrURL, sOther) )
246 : {
247 0 : _rsPathOrURL = sOther;
248 0 : bURL = true;
249 : }
250 : else
251 0 : bURL = false;
252 :
253 1187 : return bURL && implEnsureAbsolute(_rsPathOrURL);
254 : }
255 :
256 : #if OSL_DEBUG_LEVEL > 0
257 : static
258 : PathStatus dbgCheckStatusOfURL(OUString const& _sURL)
259 : {
260 : using namespace osl;
261 :
262 : DirectoryItem aDirItem;
263 :
264 : return implCheckStatusOfURL(_sURL,aDirItem);
265 : }
266 :
267 : #endif
268 :
269 : static
270 1513 : PathStatus checkStatusAndNormalizeURL(OUString & _sURL)
271 : {
272 : using namespace osl;
273 :
274 1513 : PathStatus eStatus = Bootstrap::DATA_UNKNOWN;
275 :
276 1513 : if (_sURL.isEmpty())
277 326 : eStatus = Bootstrap::DATA_MISSING;
278 :
279 1187 : else if ( !implMakeAbsoluteURL(_sURL) )
280 0 : eStatus = Bootstrap::DATA_INVALID;
281 :
282 : else
283 : {
284 1187 : DirectoryItem aDirItem;
285 :
286 1187 : eStatus = implCheckStatusOfURL(_sURL,aDirItem);
287 :
288 1187 : if (eStatus == Bootstrap::PATH_EXISTS)
289 : {
290 1174 : if (!implNormalizeURL(_sURL,aDirItem))
291 : OSL_FAIL("Unexpected failure getting actual URL for existing object");
292 1187 : }
293 : }
294 1513 : return eStatus;
295 : }
296 :
297 : // helpers to build and check a nested URL
298 : static
299 210 : PathStatus getDerivedPath(
300 : OUString& _rURL,
301 : OUString const& _aBaseURL, PathStatus _aBaseStatus,
302 : OUString const& _sRelativeURL,
303 : rtl::Bootstrap& _rData, OUString const& _sBootstrapParameter
304 : )
305 : {
306 210 : OUString sDerivedURL;
307 : OSL_PRECOND(!_rData.getFrom(_sBootstrapParameter,sDerivedURL),"Setting for derived path is already defined");
308 : OSL_PRECOND(!_sRelativeURL.isEmpty() && _sRelativeURL[0] != cURLSeparator,"Invalid Relative URL");
309 :
310 210 : PathStatus aStatus = _aBaseStatus;
311 :
312 : // do we have a base path ?
313 210 : if (!_aBaseURL.isEmpty())
314 : {
315 : OSL_PRECOND(!_aBaseURL.endsWith(OUString(cURLSeparator)), "Unexpected: base URL ends in slash");
316 :
317 210 : sDerivedURL = OUStringBuffer(_aBaseURL).append(cURLSeparator).append(_sRelativeURL).makeStringAndClear();
318 :
319 : // a derived (nested) URL can only exist or have a lesser status, if the parent exists
320 210 : if (aStatus == Bootstrap::PATH_EXISTS)
321 209 : aStatus = checkStatusAndNormalizeURL(sDerivedURL);
322 :
323 : else // the relative appendix must be valid
324 : OSL_ASSERT(aStatus != Bootstrap::PATH_VALID || dbgCheckStatusOfURL(sDerivedURL) == Bootstrap::PATH_VALID);
325 :
326 210 : _rData.getFrom(_sBootstrapParameter, _rURL, sDerivedURL);
327 :
328 : OSL_ENSURE(sDerivedURL == _rURL,"Could not set derived URL via Bootstrap default parameter");
329 : SAL_WARN_IF( !(RTL_BOOTSTRAP_DEFAULTS_BROKEN || (_rData.getFrom(_sBootstrapParameter,sDerivedURL) && sDerivedURL==_rURL)),
330 : "unotools.config",
331 : "Use of default did not affect bootstrap value");
332 : }
333 : else
334 : {
335 : // clear the result
336 0 : _rURL = _aBaseURL;
337 :
338 : // if we have no data it can't be a valid path
339 : OSL_ASSERT( aStatus > Bootstrap::PATH_VALID );
340 : }
341 :
342 210 : return aStatus;
343 : }
344 :
345 : static
346 : inline
347 210 : PathStatus getDerivedPath(
348 : OUString& _rURL,
349 : Bootstrap::Impl::PathData const& _aBaseData,
350 : OUString const& _sRelativeURL,
351 : rtl::Bootstrap& _rData, OUString const& _sBootstrapParameter
352 : )
353 : {
354 210 : return getDerivedPath(_rURL,_aBaseData.path,_aBaseData.status,_sRelativeURL,_rData,_sBootstrapParameter);
355 : }
356 :
357 : static
358 0 : OUString getExecutableBaseName()
359 : {
360 0 : OUString sExecutable;
361 :
362 0 : if (osl_Process_E_None == osl_getExecutableFile(&sExecutable.pData))
363 : {
364 : // split the executable name
365 0 : sal_Int32 nSepIndex = sExecutable.lastIndexOf(cURLSeparator);
366 :
367 0 : sExecutable = sExecutable.copy(nSepIndex + 1);
368 :
369 : // ... and get the basename (strip the extension)
370 0 : sal_Unicode const cExtensionSep = '.';
371 :
372 0 : sal_Int32 const nExtIndex = sExecutable.lastIndexOf(cExtensionSep);
373 0 : sal_Int32 const nExtLength = sExecutable.getLength() - nExtIndex - 1;
374 0 : if (0 < nExtIndex && nExtLength < 4)
375 0 : sExecutable = sExecutable.copy(0,nExtIndex);
376 : }
377 : else
378 : OSL_TRACE("Cannot get executable name: osl_getExecutableFile failed");
379 :
380 0 : return sExecutable;
381 : }
382 :
383 : static
384 : inline
385 1304 : Bootstrap::PathStatus updateStatus(Bootstrap::Impl::PathData & _rResult)
386 : {
387 1304 : return _rResult.status = checkStatusAndNormalizeURL(_rResult.path);
388 : }
389 :
390 : static
391 326 : Bootstrap::PathStatus implGetBootstrapFile(rtl::Bootstrap& _rData, Bootstrap::Impl::PathData & _rBootstrapFile)
392 : {
393 326 : _rData.getIniName(_rBootstrapFile.path);
394 :
395 326 : return updateStatus(_rBootstrapFile);
396 : }
397 :
398 : static
399 326 : Bootstrap::PathStatus implGetVersionFile(rtl::Bootstrap& _rData, Bootstrap::Impl::PathData & _rVersionFile)
400 : {
401 326 : OUString const csVersionFileItem(BOOTSTRAP_ITEM_VERSIONFILE);
402 :
403 326 : _rData.getFrom(csVersionFileItem,_rVersionFile.path);
404 :
405 326 : return updateStatus(_rVersionFile);
406 : }
407 :
408 : // Error reporting
409 :
410 : static char const IS_MISSING[] = "is missing";
411 : static char const IS_INVALID[] = "is corrupt";
412 : static char const PERIOD[] = ". ";
413 :
414 0 : static void addFileError(OUStringBuffer& _rBuf, OUString const& _aPath, AsciiString _sWhat)
415 : {
416 0 : OUString sSimpleFileName = _aPath.copy(1 +_aPath.lastIndexOf(cURLSeparator));
417 :
418 0 : _rBuf.appendAscii("The configuration file");
419 0 : _rBuf.appendAscii(" '").append(sSimpleFileName).appendAscii("' ");
420 0 : _rBuf.appendAscii(_sWhat).appendAscii(PERIOD);
421 0 : }
422 :
423 0 : static void addMissingDirectoryError(OUStringBuffer& _rBuf, OUString const& _aPath)
424 : {
425 0 : _rBuf.appendAscii("The configuration directory");
426 0 : _rBuf.appendAscii(" '").append(_aPath).appendAscii("' ");
427 0 : _rBuf.appendAscii(IS_MISSING).appendAscii(PERIOD);
428 0 : }
429 :
430 0 : static void addUnexpectedError(OUStringBuffer& _rBuf, AsciiString _sExtraInfo = NULL)
431 : {
432 0 : if (NULL == _sExtraInfo)
433 0 : _sExtraInfo = "An internal failure occurred";
434 :
435 0 : _rBuf.appendAscii(_sExtraInfo).appendAscii(PERIOD);
436 0 : }
437 :
438 0 : static Bootstrap::FailureCode describeError(OUStringBuffer& _rBuf, Bootstrap::Impl const& _rData)
439 : {
440 0 : Bootstrap::FailureCode eErrCode = Bootstrap::INVALID_BOOTSTRAP_DATA;
441 :
442 0 : _rBuf.appendAscii("The program cannot be started. ");
443 :
444 0 : switch (_rData.aUserInstall_.status)
445 : {
446 : case Bootstrap::PATH_EXISTS:
447 0 : switch (_rData.aBaseInstall_.status)
448 : {
449 : case Bootstrap::PATH_VALID:
450 0 : addMissingDirectoryError(_rBuf, _rData.aBaseInstall_.path);
451 0 : eErrCode = Bootstrap::MISSING_INSTALL_DIRECTORY;
452 0 : break;
453 :
454 : case Bootstrap::DATA_INVALID:
455 0 : addUnexpectedError(_rBuf,"The installation path is invalid");
456 0 : break;
457 :
458 : case Bootstrap::DATA_MISSING:
459 0 : addUnexpectedError(_rBuf,"The installation path is not available");
460 0 : break;
461 :
462 : case Bootstrap::PATH_EXISTS: // seems to be all fine (?)
463 0 : addUnexpectedError(_rBuf,"");
464 0 : break;
465 :
466 : default: OSL_ASSERT(false);
467 0 : addUnexpectedError(_rBuf);
468 0 : break;
469 : }
470 0 : break;
471 :
472 : case Bootstrap::PATH_VALID:
473 0 : addMissingDirectoryError(_rBuf, _rData.aUserInstall_.path);
474 0 : eErrCode = Bootstrap::MISSING_USER_DIRECTORY;
475 0 : break;
476 :
477 : // else fall through
478 : case Bootstrap::DATA_INVALID:
479 0 : if (_rData.aVersionINI_.status == Bootstrap::PATH_EXISTS)
480 : {
481 0 : addFileError(_rBuf, _rData.aVersionINI_.path, IS_INVALID);
482 0 : eErrCode = Bootstrap::INVALID_VERSION_FILE_ENTRY;
483 0 : break;
484 : }
485 : // else fall through
486 :
487 : case Bootstrap::DATA_MISSING:
488 0 : switch (_rData.aVersionINI_.status)
489 : {
490 : case Bootstrap::PATH_EXISTS:
491 0 : addFileError(_rBuf, _rData.aVersionINI_.path, "does not support the current version");
492 0 : eErrCode = Bootstrap::MISSING_VERSION_FILE_ENTRY;
493 0 : break;
494 :
495 : case Bootstrap::PATH_VALID:
496 0 : addFileError(_rBuf, _rData.aVersionINI_.path, IS_MISSING);
497 0 : eErrCode = Bootstrap::MISSING_VERSION_FILE;
498 0 : break;
499 :
500 : default:
501 0 : switch (_rData.aBootstrapINI_.status)
502 : {
503 : case Bootstrap::PATH_EXISTS:
504 0 : addFileError(_rBuf, _rData.aBootstrapINI_.path, IS_INVALID);
505 :
506 0 : if (_rData.aVersionINI_.status == Bootstrap::DATA_MISSING)
507 0 : eErrCode = Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY;
508 : else
509 0 : eErrCode = Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY;
510 0 : break;
511 :
512 : case Bootstrap::DATA_INVALID: OSL_ASSERT(false);
513 : case Bootstrap::PATH_VALID:
514 0 : addFileError(_rBuf, _rData.aBootstrapINI_.path, IS_MISSING);
515 0 : eErrCode = Bootstrap::MISSING_BOOTSTRAP_FILE;
516 0 : break;
517 :
518 : default:
519 0 : addUnexpectedError(_rBuf);
520 0 : break;
521 : }
522 0 : break;
523 : }
524 0 : break;
525 :
526 : default: OSL_ASSERT(false);
527 0 : addUnexpectedError(_rBuf);
528 0 : break;
529 : }
530 :
531 0 : return eErrCode;
532 : }
533 :
534 : // class Bootstrap
535 :
536 0 : OUString Bootstrap::getProductKey()
537 : {
538 0 : OUString const csProductKeyItem(BOOTSTRAP_ITEM_PRODUCT_KEY);
539 :
540 0 : OUString const sDefaultProductKey = getExecutableBaseName();
541 :
542 0 : return data().getBootstrapValue( csProductKeyItem, sDefaultProductKey );
543 : }
544 :
545 0 : OUString Bootstrap::getProductKey(OUString const& _sDefault)
546 : {
547 0 : OUString const csProductKeyItem(BOOTSTRAP_ITEM_PRODUCT_KEY);
548 :
549 0 : return data().getBootstrapValue( csProductKeyItem, _sDefault );
550 : }
551 :
552 0 : OUString Bootstrap::getBuildVersion(OUString const& _sDefault)
553 : {
554 0 : OUString const csBuildVersionItem(BOOTSTRAP_ITEM_BUILDVERSION);
555 :
556 0 : OUString sBuildVersion;
557 : // read BuildVersion from version.ini (versionrc)
558 0 : utl::Bootstrap::Impl::getVersionValue( csBuildVersionItem, sBuildVersion, _sDefault );
559 0 : return sBuildVersion;
560 : }
561 :
562 2558 : OUString Bootstrap::getBuildIdData(OUString const& _sDefault)
563 : {
564 2558 : OUString const csBuildIdItem(BOOTSTRAP_ITEM_BUILDID);
565 :
566 2558 : OUString sBuildId;
567 : // read buildid from version.ini (versionrc), if it doesn't exist or buildid is empty
568 5116 : if ( !utl::Bootstrap::Impl::getVersionValue( csBuildIdItem, sBuildId, _sDefault ) ||
569 2558 : sBuildId.isEmpty() )
570 : // read buildid from bootstrap.ini (bootstraprc)
571 0 : sBuildId = data().getBootstrapValue( csBuildIdItem, _sDefault );
572 2558 : return sBuildId;
573 : }
574 :
575 91 : Bootstrap::PathStatus Bootstrap::locateBaseInstallation(OUString& _rURL)
576 : {
577 91 : Impl::PathData const& aPathData = data().aBaseInstall_;
578 :
579 91 : _rURL = aPathData.path;
580 91 : return aPathData.status;
581 : }
582 :
583 410 : PathStatus Bootstrap::locateUserInstallation(OUString& _rURL)
584 : {
585 410 : Impl::PathData const& aPathData = data().aUserInstall_;
586 :
587 410 : _rURL = aPathData.path;
588 410 : return aPathData.status;
589 : }
590 :
591 210 : PathStatus Bootstrap::locateUserData(OUString& _rURL)
592 : {
593 210 : OUString const csUserDirItem(BOOTSTRAP_ITEM_USERDIR);
594 :
595 420 : rtl::Bootstrap aData( data().getImplName() );
596 :
597 210 : if ( aData.getFrom(csUserDirItem, _rURL) )
598 : {
599 0 : return checkStatusAndNormalizeURL(_rURL);
600 : }
601 : else
602 : {
603 210 : OUString const csUserDir(BOOTSTRAP_DIRNAME_USERDIR);
604 210 : return getDerivedPath(_rURL, data().aUserInstall_ ,csUserDir, aData, csUserDirItem);
605 210 : }
606 : }
607 :
608 0 : PathStatus Bootstrap::locateBootstrapFile(OUString& _rURL)
609 : {
610 0 : Impl::PathData const& aPathData = data().aBootstrapINI_;
611 :
612 0 : _rURL = aPathData.path;
613 0 : return aPathData.status;
614 : }
615 :
616 0 : PathStatus Bootstrap::locateVersionFile(OUString& _rURL)
617 : {
618 0 : Impl::PathData const& aPathData = data().aVersionINI_;
619 :
620 0 : _rURL = aPathData.path;
621 0 : return aPathData.status;
622 : }
623 :
624 0 : Bootstrap::Status Bootstrap::checkBootstrapStatus(OUString& _rDiagnosticMessage, FailureCode& _rErrCode)
625 : {
626 0 : Impl const& aData = data();
627 :
628 0 : Status result = aData.status_;
629 :
630 : // maybe do further checks here
631 :
632 0 : OUStringBuffer sErrorBuffer;
633 0 : if (result != DATA_OK)
634 0 : _rErrCode = describeError(sErrorBuffer,aData);
635 :
636 : else
637 0 : _rErrCode = NO_FAILURE;
638 :
639 0 : _rDiagnosticMessage = sErrorBuffer.makeStringAndClear();
640 :
641 0 : return result;
642 : }
643 :
644 : // class Bootstrap::Impl
645 :
646 326 : bool Bootstrap::Impl::initBaseInstallationData(rtl::Bootstrap& _rData)
647 : {
648 326 : OUString const csBaseInstallItem( BOOTSTRAP_ITEM_BASEINSTALLATION );
649 652 : OUString const csBaseInstallDefault( BOOTSTRAP_DEFAULT_BASEINSTALL );
650 :
651 326 : _rData.getFrom(csBaseInstallItem, aBaseInstall_.path, csBaseInstallDefault);
652 :
653 326 : bool bResult = (PATH_EXISTS == updateStatus(aBaseInstall_));
654 :
655 326 : implGetBootstrapFile(_rData, aBootstrapINI_);
656 :
657 652 : return bResult;
658 : }
659 :
660 326 : bool Bootstrap::Impl::initUserInstallationData(rtl::Bootstrap& _rData)
661 : {
662 326 : OUString const csUserInstallItem( BOOTSTRAP_ITEM_USERINSTALLATION );
663 :
664 326 : if (_rData.getFrom(csUserInstallItem, aUserInstall_.path))
665 : {
666 326 : updateStatus(aUserInstall_);
667 : }
668 : else
669 : {
670 : // should we do just this
671 0 : aUserInstall_.status = DATA_MISSING;
672 :
673 : // ... or this - look for a single-user user directory ?
674 0 : OUString const csUserDirItem(BOOTSTRAP_ITEM_USERDIR);
675 0 : OUString sDummy;
676 : // look for $BASEINSTALLATION/user only if default UserDir setting is used
677 0 : if (! _rData.getFrom(csUserDirItem, sDummy))
678 : {
679 0 : OUString const csUserDir(BOOTSTRAP_DIRNAME_USERDIR);
680 :
681 0 : if ( PATH_EXISTS == getDerivedPath(sDummy, aBaseInstall_, csUserDir, _rData, csUserDirItem) )
682 0 : aUserInstall_ = aBaseInstall_;
683 0 : }
684 : }
685 :
686 326 : bool bResult = (PATH_EXISTS == aUserInstall_.status);
687 :
688 326 : implGetVersionFile(_rData, aVersionINI_);
689 :
690 326 : return bResult;
691 : }
692 :
693 326 : void Bootstrap::Impl::initialize()
694 : {
695 326 : rtl::Bootstrap aData( m_aImplName );
696 :
697 326 : if (!initBaseInstallationData(aData))
698 : {
699 0 : status_ = INVALID_BASE_INSTALL;
700 : }
701 326 : else if (!initUserInstallationData(aData))
702 : {
703 1 : status_ = INVALID_USER_INSTALL;
704 :
705 1 : if (aUserInstall_.status >= DATA_MISSING)
706 : {
707 0 : switch (aVersionINI_.status)
708 : {
709 : case PATH_EXISTS:
710 : case PATH_VALID:
711 0 : status_ = MISSING_USER_INSTALL;
712 0 : break;
713 :
714 : case DATA_INVALID:
715 : case DATA_MISSING:
716 0 : status_ = INVALID_BASE_INSTALL;
717 0 : break;
718 : default:
719 0 : break;
720 : }
721 : }
722 : }
723 : else
724 : {
725 325 : status_ = DATA_OK;
726 326 : }
727 326 : }
728 :
729 0 : OUString Bootstrap::Impl::getBootstrapValue(OUString const& _sName, OUString const& _sDefault) const
730 : {
731 0 : rtl::Bootstrap aData( m_aImplName );
732 :
733 0 : OUString sResult;
734 0 : aData.getFrom(_sName,sResult,_sDefault);
735 0 : return sResult;
736 : }
737 :
738 2558 : bool Bootstrap::Impl::getVersionValue(OUString const& _sName, OUString& _rValue, OUString const& _sDefault)
739 : {
740 : // try to open version.ini (versionrc)
741 2558 : OUString uri;
742 2558 : rtl::Bootstrap::get( OUString("BRAND_BASE_DIR"), uri);
743 5116 : rtl::Bootstrap aData( uri + "/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") );
744 2558 : if ( aData.getHandle() == NULL )
745 : // version.ini (versionrc) doesn't exist
746 0 : return false;
747 :
748 : // read value
749 2558 : aData.getFrom(_sName,_rValue,_sDefault);
750 5116 : return true;
751 : }
752 :
753 : } // namespace utl
754 :
755 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|