1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "sal/config.h"
24 #include "rtl/process.h"
25 #include "rtl/bootstrap.hxx"
26 #include "rtl/random.h"
27 #include "rtl/string.hxx"
28 #include "rtl/ustrbuf.hxx"
29 #include "rtl/uri.hxx"
30 #include "osl/diagnose.h"
31 #include "osl/file.hxx"
32 #include "osl/security.hxx"
33 #include "osl/thread.hxx"
35 #include "cppuhelper/bootstrap.hxx"
36 #include "cppuhelper/findsofficepath.h"
38 #include "com/sun/star/uno/XComponentContext.hpp"
40 #include "com/sun/star/bridge/UnoUrlResolver.hpp"
41 #include "com/sun/star/bridge/XUnoUrlResolver.hpp"
43 #include "macro_expander.hxx"
45 #define ARLEN(x) sizeof (x) / sizeof *(x)
48 using namespace ::rtl
;
49 using namespace ::osl
;
50 using namespace ::com::sun::star
;
51 using namespace ::com::sun::star::uno
;
56 BootstrapException::BootstrapException()
60 BootstrapException::BootstrapException( const ::rtl::OUString
& rMessage
)
61 :m_aMessage( rMessage
)
65 BootstrapException::BootstrapException( const BootstrapException
& e
)
67 m_aMessage
= e
.m_aMessage
;
70 BootstrapException::~BootstrapException()
74 BootstrapException
& BootstrapException::operator=( const BootstrapException
& e
)
76 m_aMessage
= e
.m_aMessage
;
80 const ::rtl::OUString
& BootstrapException::getMessage() const
85 Reference
< XComponentContext
> SAL_CALL
bootstrap()
87 Reference
< XComponentContext
> xRemoteContext
;
91 char const * p1
= cppuhelper_detail_findSofficePath();
93 throw BootstrapException(
94 "no soffice installation found!");
97 if (!rtl_convertStringToUString(
98 &p2
.pData
, p1
, std::strlen(p1
), osl_getThreadTextEncoding(),
99 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
|
100 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
|
101 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR
)))
103 throw BootstrapException(
104 "bad characters in soffice installation path!");
107 if (osl::FileBase::getFileURLFromSystemPath(p2
, path
) !=
108 osl::FileBase::E_None
)
110 throw BootstrapException(
111 "cannot convert soffice installation path to URL!");
113 if (!path
.isEmpty() && path
[path
.getLength() - 1] != '/') {
118 if (!Bootstrap::get("URE_BOOTSTRAP", uri
)) {
121 Bootstrap::encode(path
+ SAL_CONFIGFILE("fundamental")));
124 // create default local component context
125 Reference
< XComponentContext
> xLocalContext(
126 defaultBootstrap_InitialComponentContext() );
127 if ( !xLocalContext
.is() )
128 throw BootstrapException( "no local component context!" );
130 // create a random pipe name
131 rtlRandomPool hPool
= rtl_random_createPool();
133 throw BootstrapException( "cannot create random pool!" );
134 sal_uInt8 bytes
[ 16 ];
135 if ( rtl_random_getBytes( hPool
, bytes
, ARLEN( bytes
) )
136 != rtl_Random_E_None
)
137 throw BootstrapException( "random pool error!" );
138 rtl_random_destroyPool( hPool
);
139 ::rtl::OUStringBuffer buf
;
140 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno" ) );
141 for ( sal_uInt32 i
= 0; i
< ARLEN( bytes
); ++i
)
142 buf
.append( static_cast< sal_Int32
>( bytes
[ i
] ) );
143 OUString
sPipeName( buf
.makeStringAndClear() );
146 OSL_ASSERT( buf
.isEmpty() );
147 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "--accept=pipe,name=" ) );
148 buf
.append( sPipeName
);
149 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( ";urp;" ) );
153 OUString("--nologo"),
154 OUString("--nodefault"),
155 OUString("--norestore"),
156 OUString("--nocrashreport"),
157 OUString("--nolockcheck"),
158 buf
.makeStringAndClear()
160 rtl_uString
* ar_args
[] = {
170 // start office process
171 oslProcess hProcess
= 0;
172 oslProcessError rc
= osl_executeProcess(
173 OUString(path
+ "soffice").pData
, ar_args
, ARLEN( ar_args
),
174 osl_Process_DETACHED
,
176 0, // => current working dir
177 0, 0, // => no env vars
181 case osl_Process_E_None
:
182 osl_freeProcessHandle( hProcess
);
184 case osl_Process_E_NotFound
:
185 throw BootstrapException( "image not found!" );
186 case osl_Process_E_TimedOut
:
187 throw BootstrapException( "timout occurred!" );
188 case osl_Process_E_NoPermission
:
189 throw BootstrapException( "permission denied!" );
190 case osl_Process_E_Unknown
:
191 throw BootstrapException( "unknown error!" );
192 case osl_Process_E_InvalidError
:
194 throw BootstrapException( "unmapped error!" );
197 // create a URL resolver
198 Reference
< bridge::XUnoUrlResolver
> xUrlResolver(
199 bridge::UnoUrlResolver::create( xLocalContext
) );
202 OSL_ASSERT( buf
.isEmpty() );
203 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno:pipe,name=" ) );
204 buf
.append( sPipeName
);
205 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(
206 ";urp;StarOffice.ComponentContext" ) );
207 OUString
sConnectString( buf
.makeStringAndClear() );
209 // wait until office is started
214 // try to connect to office
216 xUrlResolver
->resolve( sConnectString
), UNO_QUERY_THROW
);
219 catch ( connection::NoConnectException
& )
221 // wait 500 ms, then try to connect again
222 TimeValue tv
= { 0 /* secs */, 500000000 /* nanosecs */ };
223 ::osl::Thread::wait( tv
);
227 catch ( Exception
& e
)
229 throw BootstrapException(
230 "unexpected UNO exception caught: " + e
.Message
);
233 return xRemoteContext
;
236 OUString
bootstrap_expandUri(OUString
const & uri
) {
237 static char const PREFIX
[] = "vnd.sun.star.expand:";
238 return uri
.matchAsciiL(RTL_CONSTASCII_STRINGPARAM(PREFIX
))
239 ? cppuhelper::detail::expandMacros(
241 uri
.copy(RTL_CONSTASCII_LENGTH(PREFIX
)),
242 rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
))
248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */