Bump version to 5.0-14
[LibreOffice.git] / cppuhelper / source / bootstrap.cxx
blob34dd060febfc4b2ebd82c27bd1aa0bd6566b48b4
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)
47 using namespace ::osl;
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::uno;
51 using rtl::Bootstrap;
52 using rtl::OUString;
54 namespace cppu
57 BootstrapException::BootstrapException()
61 BootstrapException::BootstrapException( const ::rtl::OUString & rMessage )
62 :m_aMessage( rMessage )
66 BootstrapException::BootstrapException( const BootstrapException & e )
68 m_aMessage = e.m_aMessage;
71 BootstrapException::~BootstrapException()
75 BootstrapException & BootstrapException::operator=( const BootstrapException & e )
77 m_aMessage = e.m_aMessage;
78 return *this;
81 const ::rtl::OUString & BootstrapException::getMessage() const
83 return m_aMessage;
86 Reference< XComponentContext > SAL_CALL bootstrap()
88 Reference< XComponentContext > xRemoteContext;
90 try
92 char const * p1 = cppuhelper_detail_findSofficePath();
93 if (p1 == NULL) {
94 throw BootstrapException(
95 "no soffice installation found!");
97 rtl::OUString p2;
98 if (!rtl_convertStringToUString(
99 &p2.pData, p1, std::strlen(p1), osl_getThreadTextEncoding(),
100 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
101 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
102 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
104 throw BootstrapException(
105 "bad characters in soffice installation path!");
107 OUString path;
108 if (osl::FileBase::getFileURLFromSystemPath(p2, path) !=
109 osl::FileBase::E_None)
111 throw BootstrapException(
112 "cannot convert soffice installation path to URL!");
114 if (!path.isEmpty() && !path.endsWith("/")) {
115 path += "/";
118 OUString uri;
119 if (!Bootstrap::get("URE_BOOTSTRAP", uri)) {
120 Bootstrap::set(
121 "URE_BOOTSTRAP",
122 Bootstrap::encode(
123 path +
124 #if defined MACOSX
125 "../Resources/"
126 #endif
127 SAL_CONFIGFILE("fundamental")));
130 // create default local component context
131 Reference< XComponentContext > xLocalContext(
132 defaultBootstrap_InitialComponentContext() );
133 if ( !xLocalContext.is() )
134 throw BootstrapException( "no local component context!" );
136 // create a random pipe name
137 rtlRandomPool hPool = rtl_random_createPool();
138 if ( hPool == 0 )
139 throw BootstrapException( "cannot create random pool!" );
140 sal_uInt8 bytes[ 16 ];
141 if ( rtl_random_getBytes( hPool, bytes, ARLEN( bytes ) )
142 != rtl_Random_E_None )
143 throw BootstrapException( "random pool error!" );
144 rtl_random_destroyPool( hPool );
145 ::rtl::OUStringBuffer buf("uno");
146 for ( sal_uInt32 i = 0; i < ARLEN( bytes ); ++i )
147 buf.append( static_cast< sal_Int32 >( bytes[ i ] ) );
148 OUString sPipeName( buf.makeStringAndClear() );
150 // arguments
151 OUString args [] = {
152 OUString("--nologo"),
153 OUString("--nodefault"),
154 OUString("--norestore"),
155 OUString("--nolockcheck"),
156 OUString("--accept=pipe,name=" + sPipeName + ";urp;")
158 rtl_uString * ar_args [] = {
159 args[ 0 ].pData,
160 args[ 1 ].pData,
161 args[ 2 ].pData,
162 args[ 3 ].pData,
163 args[ 4 ].pData
165 ::osl::Security sec;
167 // start office process
168 oslProcess hProcess = 0;
169 oslProcessError rc = osl_executeProcess(
170 OUString(path + "soffice").pData, ar_args, ARLEN( ar_args ),
171 osl_Process_DETACHED,
172 sec.getHandle(),
173 0, // => current working dir
174 0, 0, // => no env vars
175 &hProcess );
176 switch ( rc )
178 case osl_Process_E_None:
179 osl_freeProcessHandle( hProcess );
180 break;
181 case osl_Process_E_NotFound:
182 throw BootstrapException( "image not found!" );
183 case osl_Process_E_TimedOut:
184 throw BootstrapException( "timeout occurred!" );
185 case osl_Process_E_NoPermission:
186 throw BootstrapException( "permission denied!" );
187 case osl_Process_E_Unknown:
188 throw BootstrapException( "unknown error!" );
189 case osl_Process_E_InvalidError:
190 default:
191 throw BootstrapException( "unmapped error!" );
194 // create a URL resolver
195 Reference< bridge::XUnoUrlResolver > xUrlResolver(
196 bridge::UnoUrlResolver::create( xLocalContext ) );
198 // connection string
199 OUString sConnectString( "uno:pipe,name=" + sPipeName + ";urp;StarOffice.ComponentContext" );
201 // wait until office is started
202 for ( ; ; )
206 // try to connect to office
207 xRemoteContext.set(
208 xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW );
209 break;
211 catch ( connection::NoConnectException & )
213 // wait 500 ms, then try to connect again
214 TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ };
215 ::osl::Thread::wait( tv );
219 catch ( Exception & e )
221 throw BootstrapException(
222 "unexpected UNO exception caught: " + e.Message );
225 return xRemoteContext;
228 OUString bootstrap_expandUri(OUString const & uri) {
229 OUString rest;
230 return uri.startsWith("vnd.sun.star.expand:", &rest)
231 ? cppuhelper::detail::expandMacros(
232 rtl::Uri::decode(
233 rest, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8))
234 : uri;
237 } // namespace cppu
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */