Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "sal/config.h"
30 : :
31 : : #include <cstring>
32 : :
33 : : #include "rtl/process.h"
34 : : #include "rtl/bootstrap.hxx"
35 : : #include "rtl/random.h"
36 : : #include "rtl/string.hxx"
37 : : #include "rtl/ustrbuf.hxx"
38 : : #include "rtl/uri.hxx"
39 : : #include "osl/diagnose.h"
40 : : #include "osl/file.hxx"
41 : : #include "osl/security.hxx"
42 : : #include "osl/thread.hxx"
43 : :
44 : : #include "cppuhelper/bootstrap.hxx"
45 : : #include "cppuhelper/findsofficepath.h"
46 : :
47 : : #include "com/sun/star/uno/XComponentContext.hpp"
48 : :
49 : : #include "com/sun/star/bridge/UnoUrlResolver.hpp"
50 : : #include "com/sun/star/bridge/XUnoUrlResolver.hpp"
51 : :
52 : : #include "macro_expander.hxx"
53 : :
54 : : #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
55 : : #define ARLEN(x) sizeof (x) / sizeof *(x)
56 : :
57 : :
58 : : using namespace ::rtl;
59 : : using namespace ::osl;
60 : : using namespace ::com::sun::star;
61 : : using namespace ::com::sun::star::uno;
62 : :
63 : : namespace cppu
64 : : {
65 : :
66 : 0 : BootstrapException::BootstrapException()
67 : : {
68 : 0 : }
69 : :
70 : 0 : BootstrapException::BootstrapException( const ::rtl::OUString & rMessage )
71 : 0 : :m_aMessage( rMessage )
72 : : {
73 : 0 : }
74 : :
75 : 0 : BootstrapException::BootstrapException( const BootstrapException & e )
76 : : {
77 : 0 : m_aMessage = e.m_aMessage;
78 : 0 : }
79 : :
80 : 0 : BootstrapException::~BootstrapException()
81 : : {
82 [ # # ]: 0 : }
83 : :
84 : 0 : BootstrapException & BootstrapException::operator=( const BootstrapException & e )
85 : : {
86 : 0 : m_aMessage = e.m_aMessage;
87 : 0 : return *this;
88 : : }
89 : :
90 : 0 : const ::rtl::OUString & BootstrapException::getMessage() const
91 : : {
92 : 0 : return m_aMessage;
93 : : }
94 : :
95 : 0 : Reference< XComponentContext > SAL_CALL bootstrap()
96 : : {
97 : 0 : Reference< XComponentContext > xRemoteContext;
98 : :
99 : : try
100 : : {
101 [ # # ]: 0 : char const * p1 = cppuhelper_detail_findSofficePath();
102 [ # # ]: 0 : if (p1 == NULL) {
103 : : throw BootstrapException(
104 [ # # ][ # # ]: 0 : OUSTR("no soffice installation found!"));
105 : : }
106 : 0 : rtl::OUString p2;
107 [ # # ]: 0 : if (!rtl_convertStringToUString(
108 [ # # ]: 0 : &p2.pData, p1, std::strlen(p1), osl_getThreadTextEncoding(),
109 : : (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
110 : : RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
111 : 0 : RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
112 : : {
113 : : throw BootstrapException(
114 [ # # ][ # # ]: 0 : OUSTR("bad characters in soffice installation path!"));
115 : : }
116 : 0 : OUString path;
117 [ # # ][ # # ]: 0 : if (osl::FileBase::getFileURLFromSystemPath(p2, path) !=
118 : : osl::FileBase::E_None)
119 : : {
120 : : throw BootstrapException(
121 [ # # ][ # # ]: 0 : OUSTR("cannot convert soffice installation path to URL!"));
122 : : }
123 [ # # ][ # # ]: 0 : if (!path.isEmpty() && path[path.getLength() - 1] != '/') {
[ # # ]
124 [ # # ]: 0 : path += OUSTR("/");
125 : : }
126 : :
127 : 0 : OUString uri;
128 [ # # ][ # # ]: 0 : if (!Bootstrap::get(OUSTR("URE_BOOTSTRAP"), uri)) {
129 : : Bootstrap::set(
130 : : OUSTR("URE_BOOTSTRAP"),
131 [ # # ][ # # ]: 0 : Bootstrap::encode(path + OUSTR(SAL_CONFIGFILE("fundamental"))));
132 : : }
133 : :
134 : : // create default local component context
135 : : Reference< XComponentContext > xLocalContext(
136 [ # # ]: 0 : defaultBootstrap_InitialComponentContext() );
137 [ # # ]: 0 : if ( !xLocalContext.is() )
138 [ # # ][ # # ]: 0 : throw BootstrapException( OUSTR( "no local component context!" ) );
139 : :
140 : : // create a random pipe name
141 : 0 : rtlRandomPool hPool = rtl_random_createPool();
142 [ # # ]: 0 : if ( hPool == 0 )
143 [ # # ][ # # ]: 0 : throw BootstrapException( OUSTR( "cannot create random pool!" ) );
144 : : sal_uInt8 bytes[ 16 ];
145 [ # # ]: 0 : if ( rtl_random_getBytes( hPool, bytes, ARLEN( bytes ) )
146 : : != rtl_Random_E_None )
147 [ # # ][ # # ]: 0 : throw BootstrapException( OUSTR( "random pool error!" ) );
148 : 0 : rtl_random_destroyPool( hPool );
149 : 0 : ::rtl::OUStringBuffer buf;
150 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno" ) );
151 [ # # ]: 0 : for ( sal_uInt32 i = 0; i < ARLEN( bytes ); ++i )
152 [ # # ]: 0 : buf.append( static_cast< sal_Int32 >( bytes[ i ] ) );
153 [ # # ]: 0 : OUString sPipeName( buf.makeStringAndClear() );
154 : :
155 : : // accept string
156 : : OSL_ASSERT( buf.getLength() == 0 );
157 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "--accept=pipe,name=" ) );
158 [ # # ]: 0 : buf.append( sPipeName );
159 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ";urp;" ) );
160 : :
161 : : // arguments
162 : : OUString args [] = {
163 : : OUSTR( "--nologo" ),
164 : : OUSTR( "--nodefault" ),
165 : : OUSTR( "--norestore" ),
166 : : OUSTR( "--nocrashreport" ),
167 : : OUSTR( "--nolockcheck" ),
168 : : buf.makeStringAndClear()
169 [ # # ][ # # ]: 0 : };
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
170 : : rtl_uString * ar_args [] = {
171 : : args[ 0 ].pData,
172 : : args[ 1 ].pData,
173 : : args[ 2 ].pData,
174 : : args[ 3 ].pData,
175 : : args[ 4 ].pData,
176 : : args[ 5 ].pData
177 : 0 : };
178 [ # # ]: 0 : ::osl::Security sec;
179 : :
180 : : // start office process
181 : 0 : oslProcess hProcess = 0;
182 : : oslProcessError rc = osl_executeProcess(
183 : : (path + OUSTR("soffice")).pData, ar_args, ARLEN( ar_args ),
184 : : osl_Process_DETACHED,
185 : : sec.getHandle(),
186 : : 0, // => current working dir
187 : : 0, 0, // => no env vars
188 [ # # ][ # # ]: 0 : &hProcess );
189 [ # # # # : 0 : switch ( rc )
# # ]
190 : : {
191 : : case osl_Process_E_None:
192 [ # # ]: 0 : osl_freeProcessHandle( hProcess );
193 : 0 : break;
194 : : case osl_Process_E_NotFound:
195 [ # # ][ # # ]: 0 : throw BootstrapException( OUSTR( "image not found!" ) );
196 : : case osl_Process_E_TimedOut:
197 [ # # ][ # # ]: 0 : throw BootstrapException( OUSTR( "timout occurred!" ) );
198 : : case osl_Process_E_NoPermission:
199 [ # # ][ # # ]: 0 : throw BootstrapException( OUSTR( "permission denied!" ) );
200 : : case osl_Process_E_Unknown:
201 [ # # ][ # # ]: 0 : throw BootstrapException( OUSTR( "unknown error!" ) );
202 : : case osl_Process_E_InvalidError:
203 : : default:
204 [ # # ][ # # ]: 0 : throw BootstrapException( OUSTR( "unmapped error!" ) );
205 : : }
206 : :
207 : : // create a URL resolver
208 : : Reference< bridge::XUnoUrlResolver > xUrlResolver(
209 [ # # ]: 0 : bridge::UnoUrlResolver::create( xLocalContext ) );
210 : :
211 : : // connection string
212 : : OSL_ASSERT( buf.getLength() == 0 );
213 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno:pipe,name=" ) );
214 [ # # ]: 0 : buf.append( sPipeName );
215 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
216 [ # # ]: 0 : ";urp;StarOffice.ComponentContext" ) );
217 [ # # ]: 0 : OUString sConnectString( buf.makeStringAndClear() );
218 : :
219 : : // wait until office is started
220 : 0 : for ( ; ; )
221 : : {
222 : : try
223 : : {
224 : : // try to connect to office
225 : : xRemoteContext.set(
226 [ # # ][ # # ]: 0 : xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW );
[ # # ]
227 : 0 : break;
228 : : }
229 [ # # # # ]: 0 : catch ( connection::NoConnectException & )
230 : : {
231 : : // wait 500 ms, then try to connect again
232 : 0 : TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ };
233 [ # # ]: 0 : ::osl::Thread::wait( tv );
234 : : }
235 [ # # ][ # # ]: 0 : }
[ # # ]
236 : : }
237 [ # # ]: 0 : catch ( Exception & e )
238 : : {
239 : : throw BootstrapException(
240 [ # # # # ]: 0 : OUSTR( "unexpected UNO exception caught: " ) + e.Message );
241 : : }
242 : :
243 : 0 : return xRemoteContext;
244 : : }
245 : :
246 : 20961 : OUString bootstrap_expandUri(OUString const & uri) {
247 : : static char const PREFIX[] = "vnd.sun.star.expand:";
248 : 20961 : return uri.matchAsciiL(RTL_CONSTASCII_STRINGPARAM(PREFIX))
249 : : ? cppuhelper::detail::expandMacros(
250 : : rtl::Uri::decode(
251 : : uri.copy(RTL_CONSTASCII_LENGTH(PREFIX)),
252 : : rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8))
253 [ + - ][ + + ]: 20961 : : uri;
[ + + ]
[ # # # # ]
[ + + ]
254 : : }
255 : :
256 : : } // namespace cppu
257 : :
258 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|