update credits
[LibreOffice.git] / cppuhelper / source / bootstrap.cxx
blob2de4b5643211d4ad256340cab2df65d8b64e507f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
22 #include <cstring>
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;
53 namespace cppu
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;
77 return *this;
80 const ::rtl::OUString & BootstrapException::getMessage() const
82 return m_aMessage;
85 Reference< XComponentContext > SAL_CALL bootstrap()
87 Reference< XComponentContext > xRemoteContext;
89 try
91 char const * p1 = cppuhelper_detail_findSofficePath();
92 if (p1 == NULL) {
93 throw BootstrapException(
94 "no soffice installation found!");
96 rtl::OUString p2;
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!");
106 OUString 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] != '/') {
114 path += "/";
117 OUString uri;
118 if (!Bootstrap::get("URE_BOOTSTRAP", uri)) {
119 Bootstrap::set(
120 "URE_BOOTSTRAP",
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();
132 if ( hPool == 0 )
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() );
145 // accept string
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;" ) );
151 // arguments
152 OUString args [] = {
153 OUString("--nologo"),
154 OUString("--nodefault"),
155 OUString("--norestore"),
156 OUString("--nocrashreport"),
157 OUString("--nolockcheck"),
158 buf.makeStringAndClear()
160 rtl_uString * ar_args [] = {
161 args[ 0 ].pData,
162 args[ 1 ].pData,
163 args[ 2 ].pData,
164 args[ 3 ].pData,
165 args[ 4 ].pData,
166 args[ 5 ].pData
168 ::osl::Security sec;
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,
175 sec.getHandle(),
176 0, // => current working dir
177 0, 0, // => no env vars
178 &hProcess );
179 switch ( rc )
181 case osl_Process_E_None:
182 osl_freeProcessHandle( hProcess );
183 break;
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:
193 default:
194 throw BootstrapException( "unmapped error!" );
197 // create a URL resolver
198 Reference< bridge::XUnoUrlResolver > xUrlResolver(
199 bridge::UnoUrlResolver::create( xLocalContext ) );
201 // connection string
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
210 for ( ; ; )
214 // try to connect to office
215 xRemoteContext.set(
216 xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW );
217 break;
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(
240 rtl::Uri::decode(
241 uri.copy(RTL_CONSTASCII_LENGTH(PREFIX)),
242 rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8))
243 : uri;
246 } // namespace cppu
248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */