1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_desktop.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "deployment.hrc"
32*cdf0e10cSrcweir #include "unopkg_shared.h"
33*cdf0e10cSrcweir #include "dp_identifier.hxx"
34*cdf0e10cSrcweir #include "../../deployment/gui/dp_gui.hrc"
35*cdf0e10cSrcweir #include "../../app/lockfile.hxx"
36*cdf0e10cSrcweir #include "vcl/svapp.hxx"
37*cdf0e10cSrcweir #include "vcl/msgbox.hxx"
38*cdf0e10cSrcweir #include "rtl/bootstrap.hxx"
39*cdf0e10cSrcweir #include "rtl/strbuf.hxx"
40*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
41*cdf0e10cSrcweir #include "osl/process.h"
42*cdf0e10cSrcweir #include "osl/file.hxx"
43*cdf0e10cSrcweir #include "osl/thread.hxx"
44*cdf0e10cSrcweir #include "tools/getprocessworkingdir.hxx"
45*cdf0e10cSrcweir #include "ucbhelper/contentbroker.hxx"
46*cdf0e10cSrcweir #include "ucbhelper/configurationkeys.hxx"
47*cdf0e10cSrcweir #include "unotools/processfactory.hxx"
48*cdf0e10cSrcweir #include "unotools/configmgr.hxx"
49*cdf0e10cSrcweir #include "com/sun/star/lang/XMultiServiceFactory.hpp"
50*cdf0e10cSrcweir #include "cppuhelper/bootstrap.hxx"
51*cdf0e10cSrcweir #include "comphelper/sequence.hxx"
52*cdf0e10cSrcweir #include <stdio.h>
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir using ::rtl::OUString;
55*cdf0e10cSrcweir using ::rtl::OString;
56*cdf0e10cSrcweir using namespace ::com::sun::star;
57*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
58*cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir namespace unopkg {
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir bool getLockFilePath(OUString & out);
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir ::rtl::OUString toString( OptionInfo const * info )
65*cdf0e10cSrcweir {
66*cdf0e10cSrcweir     OSL_ASSERT( info != 0 );
67*cdf0e10cSrcweir     ::rtl::OUStringBuffer buf;
68*cdf0e10cSrcweir     buf.appendAscii("--");
69*cdf0e10cSrcweir     buf.appendAscii(info->m_name);
70*cdf0e10cSrcweir     if (info->m_short_option != '\0')
71*cdf0e10cSrcweir     {
72*cdf0e10cSrcweir         buf.appendAscii(" (short -" );
73*cdf0e10cSrcweir         buf.append(info->m_short_option );
74*cdf0e10cSrcweir         buf.appendAscii(")");
75*cdf0e10cSrcweir     }
76*cdf0e10cSrcweir     if (info->m_has_argument)
77*cdf0e10cSrcweir         buf.appendAscii(" <argument>" );
78*cdf0e10cSrcweir     return buf.makeStringAndClear();
79*cdf0e10cSrcweir }
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir //==============================================================================
82*cdf0e10cSrcweir OptionInfo const * getOptionInfo(
83*cdf0e10cSrcweir     OptionInfo const * list,
84*cdf0e10cSrcweir     OUString const & opt, sal_Unicode copt )
85*cdf0e10cSrcweir {
86*cdf0e10cSrcweir     for ( ; list->m_name != 0; ++list )
87*cdf0e10cSrcweir     {
88*cdf0e10cSrcweir         OptionInfo const & option_info = *list;
89*cdf0e10cSrcweir         if (opt.getLength() > 0)
90*cdf0e10cSrcweir         {
91*cdf0e10cSrcweir             if (opt.equalsAsciiL(
92*cdf0e10cSrcweir                     option_info.m_name, option_info.m_name_length ) &&
93*cdf0e10cSrcweir                 (copt == '\0' || copt == option_info.m_short_option))
94*cdf0e10cSrcweir             {
95*cdf0e10cSrcweir                 return &option_info;
96*cdf0e10cSrcweir             }
97*cdf0e10cSrcweir         }
98*cdf0e10cSrcweir         else
99*cdf0e10cSrcweir         {
100*cdf0e10cSrcweir             OSL_ASSERT( copt != '\0' );
101*cdf0e10cSrcweir             if (copt == option_info.m_short_option)
102*cdf0e10cSrcweir             {
103*cdf0e10cSrcweir                 return &option_info;
104*cdf0e10cSrcweir             }
105*cdf0e10cSrcweir         }
106*cdf0e10cSrcweir     }
107*cdf0e10cSrcweir     OSL_ENSURE( 0, ::rtl::OUStringToOString(
108*cdf0e10cSrcweir                     opt, osl_getThreadTextEncoding() ).getStr() );
109*cdf0e10cSrcweir     return 0;
110*cdf0e10cSrcweir }
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir //==============================================================================
113*cdf0e10cSrcweir bool isOption( OptionInfo const * option_info, sal_uInt32 * pIndex )
114*cdf0e10cSrcweir {
115*cdf0e10cSrcweir     OSL_ASSERT( option_info != 0 );
116*cdf0e10cSrcweir     if (osl_getCommandArgCount() <= *pIndex)
117*cdf0e10cSrcweir         return false;
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir     OUString arg;
120*cdf0e10cSrcweir     osl_getCommandArg( *pIndex, &arg.pData );
121*cdf0e10cSrcweir     sal_Int32 len = arg.getLength();
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir     if (len < 2 || arg[ 0 ] != '-')
124*cdf0e10cSrcweir         return false;
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir     if (len == 2 && arg[ 1 ] == option_info->m_short_option)
127*cdf0e10cSrcweir     {
128*cdf0e10cSrcweir         ++(*pIndex);
129*cdf0e10cSrcweir         dp_misc::TRACE(OUSTR(__FILE__": identified option \'")
130*cdf0e10cSrcweir             + OUSTR("\'") + OUString( option_info->m_short_option ) + OUSTR("\n"));
131*cdf0e10cSrcweir         return true;
132*cdf0e10cSrcweir     }
133*cdf0e10cSrcweir     if (arg[ 1 ] == '-' && rtl_ustr_ascii_compare(
134*cdf0e10cSrcweir             arg.pData->buffer + 2, option_info->m_name ) == 0)
135*cdf0e10cSrcweir     {
136*cdf0e10cSrcweir         ++(*pIndex);
137*cdf0e10cSrcweir         dp_misc::TRACE(OUSTR( __FILE__": identified option \'")
138*cdf0e10cSrcweir             + OUString::createFromAscii(option_info->m_name) + OUSTR("\'\n"));
139*cdf0e10cSrcweir         return true;
140*cdf0e10cSrcweir     }
141*cdf0e10cSrcweir     return false;
142*cdf0e10cSrcweir }
143*cdf0e10cSrcweir //==============================================================================
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir bool isBootstrapVariable(sal_uInt32 * pIndex)
146*cdf0e10cSrcweir {
147*cdf0e10cSrcweir     OSL_ASSERT(osl_getCommandArgCount() >=  *pIndex);
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir     OUString arg;
150*cdf0e10cSrcweir     osl_getCommandArg(*pIndex, &arg.pData);
151*cdf0e10cSrcweir     if (arg.matchAsciiL("-env:", 5))
152*cdf0e10cSrcweir     {
153*cdf0e10cSrcweir         ++(*pIndex);
154*cdf0e10cSrcweir         return true;
155*cdf0e10cSrcweir     }
156*cdf0e10cSrcweir     return false;
157*cdf0e10cSrcweir }
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir //==============================================================================
160*cdf0e10cSrcweir bool readArgument(
161*cdf0e10cSrcweir     OUString * pValue, OptionInfo const * option_info, sal_uInt32 * pIndex )
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir     if (isOption( option_info, pIndex ))
164*cdf0e10cSrcweir     {
165*cdf0e10cSrcweir         if (*pIndex < osl_getCommandArgCount())
166*cdf0e10cSrcweir         {
167*cdf0e10cSrcweir             OSL_ASSERT( pValue != 0 );
168*cdf0e10cSrcweir             osl_getCommandArg( *pIndex, &pValue->pData );
169*cdf0e10cSrcweir             dp_misc::TRACE(OUSTR( __FILE__": argument value: ")
170*cdf0e10cSrcweir                 + *pValue + OUSTR("\n"));
171*cdf0e10cSrcweir             ++(*pIndex);
172*cdf0e10cSrcweir             return true;
173*cdf0e10cSrcweir         }
174*cdf0e10cSrcweir         --(*pIndex);
175*cdf0e10cSrcweir     }
176*cdf0e10cSrcweir     return false;
177*cdf0e10cSrcweir }
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir //##############################################################################
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir namespace {
182*cdf0e10cSrcweir struct ExecutableDir : public rtl::StaticWithInit<
183*cdf0e10cSrcweir     const OUString, ExecutableDir> {
184*cdf0e10cSrcweir     const OUString operator () () {
185*cdf0e10cSrcweir         OUString path;
186*cdf0e10cSrcweir         if (osl_getExecutableFile( &path.pData ) != osl_Process_E_None) {
187*cdf0e10cSrcweir             throw RuntimeException(
188*cdf0e10cSrcweir                 OUSTR("cannot locate executable directory!"),0  );
189*cdf0e10cSrcweir         }
190*cdf0e10cSrcweir         return path.copy( 0, path.lastIndexOf( '/' ) );
191*cdf0e10cSrcweir     }
192*cdf0e10cSrcweir };
193*cdf0e10cSrcweir struct ProcessWorkingDir : public rtl::StaticWithInit<
194*cdf0e10cSrcweir     const OUString, ProcessWorkingDir> {
195*cdf0e10cSrcweir     const OUString operator () () {
196*cdf0e10cSrcweir         OUString workingDir;
197*cdf0e10cSrcweir         tools::getProcessWorkingDir(&workingDir);
198*cdf0e10cSrcweir         return workingDir;
199*cdf0e10cSrcweir     }
200*cdf0e10cSrcweir };
201*cdf0e10cSrcweir } // anon namespace
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir //==============================================================================
204*cdf0e10cSrcweir OUString const & getExecutableDir()
205*cdf0e10cSrcweir {
206*cdf0e10cSrcweir     return ExecutableDir::get();
207*cdf0e10cSrcweir }
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir //==============================================================================
210*cdf0e10cSrcweir OUString const & getProcessWorkingDir()
211*cdf0e10cSrcweir {
212*cdf0e10cSrcweir     return ProcessWorkingDir::get();
213*cdf0e10cSrcweir }
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir //==============================================================================
216*cdf0e10cSrcweir OUString makeAbsoluteFileUrl(
217*cdf0e10cSrcweir     OUString const & sys_path, OUString const & base_url, bool throw_exc )
218*cdf0e10cSrcweir {
219*cdf0e10cSrcweir     // system path to file url
220*cdf0e10cSrcweir     OUString file_url;
221*cdf0e10cSrcweir     oslFileError rc = osl_getFileURLFromSystemPath( sys_path.pData, &file_url.pData );
222*cdf0e10cSrcweir     if ( rc != osl_File_E_None) {
223*cdf0e10cSrcweir         OUString tempPath;
224*cdf0e10cSrcweir         if ( osl_getSystemPathFromFileURL( sys_path.pData, &tempPath.pData) == osl_File_E_None )
225*cdf0e10cSrcweir         {
226*cdf0e10cSrcweir             file_url = sys_path;
227*cdf0e10cSrcweir         }
228*cdf0e10cSrcweir         else if (throw_exc)
229*cdf0e10cSrcweir         {
230*cdf0e10cSrcweir             throw RuntimeException(
231*cdf0e10cSrcweir                 OUSTR("cannot get file url from system path: ") +
232*cdf0e10cSrcweir                 sys_path, Reference< XInterface >() );
233*cdf0e10cSrcweir         }
234*cdf0e10cSrcweir     }
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir     OUString abs;
237*cdf0e10cSrcweir     if (osl_getAbsoluteFileURL(
238*cdf0e10cSrcweir             base_url.pData, file_url.pData, &abs.pData ) != osl_File_E_None)
239*cdf0e10cSrcweir     {
240*cdf0e10cSrcweir         if (throw_exc) {
241*cdf0e10cSrcweir             ::rtl::OUStringBuffer buf;
242*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
243*cdf0e10cSrcweir                                  "making absolute file url failed: \"") );
244*cdf0e10cSrcweir             buf.append( base_url );
245*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
246*cdf0e10cSrcweir                                  "\" (base-url) and \"") );
247*cdf0e10cSrcweir             buf.append( file_url );
248*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" (file-url)!") );
249*cdf0e10cSrcweir             throw RuntimeException(
250*cdf0e10cSrcweir                 buf.makeStringAndClear(), Reference< XInterface >() );
251*cdf0e10cSrcweir         }
252*cdf0e10cSrcweir         return OUString();
253*cdf0e10cSrcweir     }
254*cdf0e10cSrcweir     return abs[ abs.getLength() -1 ] == '/'
255*cdf0e10cSrcweir         ? abs.copy( 0, abs.getLength() -1 ) : abs;
256*cdf0e10cSrcweir }
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir //##############################################################################
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir namespace {
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir //------------------------------------------------------------------------------
263*cdf0e10cSrcweir inline void printf_space( sal_Int32 space )
264*cdf0e10cSrcweir {
265*cdf0e10cSrcweir     while (space--)
266*cdf0e10cSrcweir         dp_misc::writeConsole("  ");
267*cdf0e10cSrcweir }
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir //------------------------------------------------------------------------------
270*cdf0e10cSrcweir void printf_line(
271*cdf0e10cSrcweir     OUString const & name, OUString const & value, sal_Int32 level )
272*cdf0e10cSrcweir {
273*cdf0e10cSrcweir    printf_space( level );
274*cdf0e10cSrcweir     dp_misc::writeConsole(name + OUSTR(": ") + value + OUSTR("\n"));
275*cdf0e10cSrcweir }
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir //------------------------------------------------------------------------------
278*cdf0e10cSrcweir void printf_package(
279*cdf0e10cSrcweir     Reference<deployment::XPackage> const & xPackage,
280*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level )
281*cdf0e10cSrcweir {
282*cdf0e10cSrcweir     beans::Optional< OUString > id(
283*cdf0e10cSrcweir         level == 0
284*cdf0e10cSrcweir         ? beans::Optional< OUString >(
285*cdf0e10cSrcweir             true, dp_misc::getIdentifier( xPackage ) )
286*cdf0e10cSrcweir         : xPackage->getIdentifier() );
287*cdf0e10cSrcweir     if (id.IsPresent)
288*cdf0e10cSrcweir         printf_line( OUSTR("Identifier"), id.Value, level );
289*cdf0e10cSrcweir     OUString version(xPackage->getVersion());
290*cdf0e10cSrcweir     if (version.getLength() != 0)
291*cdf0e10cSrcweir         printf_line( OUSTR("Version"), version, level + 1 );
292*cdf0e10cSrcweir     printf_line( OUSTR("URL"), xPackage->getURL(), level + 1 );
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir     beans::Optional< beans::Ambiguous<sal_Bool> > option(
295*cdf0e10cSrcweir         xPackage->isRegistered( Reference<task::XAbortChannel>(), xCmdEnv ) );
296*cdf0e10cSrcweir     OUString value;
297*cdf0e10cSrcweir     if (option.IsPresent) {
298*cdf0e10cSrcweir         beans::Ambiguous<sal_Bool> const & reg = option.Value;
299*cdf0e10cSrcweir         if (reg.IsAmbiguous)
300*cdf0e10cSrcweir             value = OUSTR("unknown");
301*cdf0e10cSrcweir         else
302*cdf0e10cSrcweir             value = reg.Value ? OUSTR("yes") : OUSTR("no");
303*cdf0e10cSrcweir     }
304*cdf0e10cSrcweir     else
305*cdf0e10cSrcweir         value = OUSTR("n/a");
306*cdf0e10cSrcweir     printf_line( OUSTR("is registered"), value, level + 1 );
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir     const Reference<deployment::XPackageTypeInfo> xPackageType(
309*cdf0e10cSrcweir         xPackage->getPackageType() );
310*cdf0e10cSrcweir     OSL_ASSERT( xPackageType.is() );
311*cdf0e10cSrcweir     if (xPackageType.is()) {
312*cdf0e10cSrcweir         printf_line( OUSTR("Media-Type"),
313*cdf0e10cSrcweir                      xPackageType->getMediaType(), level + 1 );
314*cdf0e10cSrcweir     }
315*cdf0e10cSrcweir     printf_line( OUSTR("Description"), xPackage->getDescription(), level + 1 );
316*cdf0e10cSrcweir     if (xPackage->isBundle()) {
317*cdf0e10cSrcweir         Sequence< Reference<deployment::XPackage> > seq(
318*cdf0e10cSrcweir             xPackage->getBundle( Reference<task::XAbortChannel>(), xCmdEnv ) );
319*cdf0e10cSrcweir         printf_space( level + 1 );
320*cdf0e10cSrcweir         dp_misc::writeConsole("bundled Packages: {\n");
321*cdf0e10cSrcweir         ::std::vector<Reference<deployment::XPackage> >vec_bundle;
322*cdf0e10cSrcweir         ::comphelper::sequenceToContainer(vec_bundle, seq);
323*cdf0e10cSrcweir         printf_packages( vec_bundle, ::std::vector<bool>(vec_bundle.size()),
324*cdf0e10cSrcweir                          xCmdEnv, level + 2 );
325*cdf0e10cSrcweir         printf_space( level + 1 );
326*cdf0e10cSrcweir         dp_misc::writeConsole("}\n");
327*cdf0e10cSrcweir     }
328*cdf0e10cSrcweir }
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir } // anon namespace
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir void printf_unaccepted_licenses(
333*cdf0e10cSrcweir     Reference<deployment::XPackage> const & ext)
334*cdf0e10cSrcweir {
335*cdf0e10cSrcweir         OUString id(
336*cdf0e10cSrcweir             dp_misc::getIdentifier(ext) );
337*cdf0e10cSrcweir         printf_line( OUSTR("Identifier"), id, 0 );
338*cdf0e10cSrcweir         printf_space(1);
339*cdf0e10cSrcweir         dp_misc::writeConsole(OUSTR("License not accepted\n\n"));
340*cdf0e10cSrcweir }
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir //==============================================================================
343*cdf0e10cSrcweir void printf_packages(
344*cdf0e10cSrcweir     ::std::vector< Reference<deployment::XPackage> > const & allExtensions,
345*cdf0e10cSrcweir     ::std::vector<bool> const & vecUnaccepted,
346*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level )
347*cdf0e10cSrcweir {
348*cdf0e10cSrcweir     OSL_ASSERT(allExtensions.size() == vecUnaccepted.size());
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir     if (allExtensions.size() == 0)
351*cdf0e10cSrcweir     {
352*cdf0e10cSrcweir         printf_space( level );
353*cdf0e10cSrcweir         dp_misc::writeConsole("<none>\n");
354*cdf0e10cSrcweir     }
355*cdf0e10cSrcweir     else
356*cdf0e10cSrcweir     {
357*cdf0e10cSrcweir         typedef ::std::vector< Reference<deployment::XPackage> >::const_iterator I_EXT;
358*cdf0e10cSrcweir         int index = 0;
359*cdf0e10cSrcweir         for (I_EXT i = allExtensions.begin(); i != allExtensions.end(); i++, index++)
360*cdf0e10cSrcweir         {
361*cdf0e10cSrcweir             if (vecUnaccepted[index])
362*cdf0e10cSrcweir                 printf_unaccepted_licenses(*i);
363*cdf0e10cSrcweir             else
364*cdf0e10cSrcweir                 printf_package( *i, xCmdEnv, level );
365*cdf0e10cSrcweir             dp_misc::writeConsole(OUSTR("\n"));
366*cdf0e10cSrcweir         }
367*cdf0e10cSrcweir     }
368*cdf0e10cSrcweir }
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir //##############################################################################
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir namespace {
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir //------------------------------------------------------------------------------
376*cdf0e10cSrcweir Reference<XComponentContext> bootstrapStandAlone(
377*cdf0e10cSrcweir     DisposeGuard & disposeGuard, bool /*verbose */)
378*cdf0e10cSrcweir {
379*cdf0e10cSrcweir     Reference<XComponentContext> xContext =
380*cdf0e10cSrcweir         ::cppu::defaultBootstrap_InitialComponentContext();
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir     // assure disposing of local component context:
383*cdf0e10cSrcweir     disposeGuard.reset(
384*cdf0e10cSrcweir         Reference<lang::XComponent>( xContext, UNO_QUERY ) );
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir     Reference<lang::XMultiServiceFactory> xServiceManager(
387*cdf0e10cSrcweir         xContext->getServiceManager(), UNO_QUERY_THROW );
388*cdf0e10cSrcweir     // set global process service factory used by unotools config helpers
389*cdf0e10cSrcweir     ::utl::setProcessServiceFactory( xServiceManager );
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir     // initialize the ucbhelper ucb,
392*cdf0e10cSrcweir     // because the package implementation uses it
393*cdf0e10cSrcweir     Sequence<Any> ucb_args( 2 );
394*cdf0e10cSrcweir     ucb_args[ 0 ] <<= OUSTR(UCB_CONFIGURATION_KEY1_LOCAL);
395*cdf0e10cSrcweir     ucb_args[ 1 ] <<= OUSTR(UCB_CONFIGURATION_KEY2_OFFICE);
396*cdf0e10cSrcweir     if (! ::ucbhelper::ContentBroker::initialize( xServiceManager, ucb_args ))
397*cdf0e10cSrcweir         throw RuntimeException( OUSTR("cannot initialize UCB!"), 0 );
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir     disposeGuard.setDeinitUCB();
400*cdf0e10cSrcweir     return xContext;
401*cdf0e10cSrcweir }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir //------------------------------------------------------------------------------
404*cdf0e10cSrcweir Reference<XComponentContext> connectToOffice(
405*cdf0e10cSrcweir     Reference<XComponentContext> const & xLocalComponentContext,
406*cdf0e10cSrcweir     bool verbose )
407*cdf0e10cSrcweir {
408*cdf0e10cSrcweir     Sequence<OUString> args( 3 );
409*cdf0e10cSrcweir     args[ 0 ] = OUSTR("-nologo");
410*cdf0e10cSrcweir     args[ 1 ] = OUSTR("-nodefault");
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir     OUString pipeId( ::dp_misc::generateRandomPipeId() );
413*cdf0e10cSrcweir     ::rtl::OUStringBuffer buf;
414*cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("-accept=pipe,name=") );
415*cdf0e10cSrcweir     buf.append( pipeId );
416*cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(";urp;") );
417*cdf0e10cSrcweir     args[ 2 ] = buf.makeStringAndClear();
418*cdf0e10cSrcweir     OUString appURL( getExecutableDir() + OUSTR("/soffice") );
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir     if (verbose)
421*cdf0e10cSrcweir     {
422*cdf0e10cSrcweir         dp_misc::writeConsole(
423*cdf0e10cSrcweir             OUSTR("Raising process: ") +
424*cdf0e10cSrcweir             appURL +
425*cdf0e10cSrcweir             OUSTR("\nArguments: -nologo -nodefault ") +
426*cdf0e10cSrcweir             args[2] +
427*cdf0e10cSrcweir             OUSTR("\n"));
428*cdf0e10cSrcweir     }
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir     ::dp_misc::raiseProcess( appURL, args );
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir     if (verbose)
433*cdf0e10cSrcweir         dp_misc::writeConsole("Ok.  Connecting...");
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir     OSL_ASSERT( buf.getLength() == 0 );
436*cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") );
437*cdf0e10cSrcweir     buf.append( pipeId );
438*cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
439*cdf0e10cSrcweir                          ";urp;StarOffice.ComponentContext") );
440*cdf0e10cSrcweir     Reference<XComponentContext> xRet(
441*cdf0e10cSrcweir         ::dp_misc::resolveUnoURL(
442*cdf0e10cSrcweir             buf.makeStringAndClear(), xLocalComponentContext ),
443*cdf0e10cSrcweir         UNO_QUERY_THROW );
444*cdf0e10cSrcweir     if (verbose)
445*cdf0e10cSrcweir         dp_misc::writeConsole("Ok.\n");
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir     return xRet;
448*cdf0e10cSrcweir }
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir } // anon namespace
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir /** returns the path to the lock file used by unopkg.
453*cdf0e10cSrcweir     @return the path. An empty string signifies an error.
454*cdf0e10cSrcweir */
455*cdf0e10cSrcweir OUString getLockFilePath()
456*cdf0e10cSrcweir {
457*cdf0e10cSrcweir     OUString ret;
458*cdf0e10cSrcweir     OUString sBootstrap(RTL_CONSTASCII_USTRINGPARAM("${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}"));
459*cdf0e10cSrcweir     rtl::Bootstrap::expandMacros(sBootstrap);
460*cdf0e10cSrcweir     OUString sAbs;
461*cdf0e10cSrcweir     if (::osl::File::E_None ==  ::osl::File::getAbsoluteFileURL(
462*cdf0e10cSrcweir         sBootstrap, OUSTR(".lock"), sAbs))
463*cdf0e10cSrcweir     {
464*cdf0e10cSrcweir         if (::osl::File::E_None ==
465*cdf0e10cSrcweir             ::osl::File::getSystemPathFromFileURL(sAbs, sBootstrap))
466*cdf0e10cSrcweir         {
467*cdf0e10cSrcweir             ret = sBootstrap;
468*cdf0e10cSrcweir         }
469*cdf0e10cSrcweir     }
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir     return ret;
472*cdf0e10cSrcweir }
473*cdf0e10cSrcweir //==============================================================================
474*cdf0e10cSrcweir Reference<XComponentContext> getUNO(
475*cdf0e10cSrcweir     DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
476*cdf0e10cSrcweir     Reference<XComponentContext> & out_localContext)
477*cdf0e10cSrcweir {
478*cdf0e10cSrcweir     // do not create any user data (for the root user) in --shared mode:
479*cdf0e10cSrcweir     if (shared) {
480*cdf0e10cSrcweir         rtl::Bootstrap::set(
481*cdf0e10cSrcweir             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CFG_CacheUrl")),
482*cdf0e10cSrcweir             rtl::OUString());
483*cdf0e10cSrcweir     }
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir     // hold lock during process runtime:
486*cdf0e10cSrcweir     static ::desktop::Lockfile s_lockfile( false /* no IPC server */ );
487*cdf0e10cSrcweir     Reference<XComponentContext> xComponentContext(
488*cdf0e10cSrcweir         bootstrapStandAlone( disposeGuard, verbose ) );
489*cdf0e10cSrcweir     out_localContext = xComponentContext;
490*cdf0e10cSrcweir     if (::dp_misc::office_is_running()) {
491*cdf0e10cSrcweir         xComponentContext.set(
492*cdf0e10cSrcweir             connectToOffice( xComponentContext, verbose ) );
493*cdf0e10cSrcweir     }
494*cdf0e10cSrcweir     else
495*cdf0e10cSrcweir     {
496*cdf0e10cSrcweir         if (! s_lockfile.check( 0 ))
497*cdf0e10cSrcweir         {
498*cdf0e10cSrcweir             String sMsg(ResId(RID_STR_CONCURRENTINSTANCE, *DeploymentResMgr::get()));
499*cdf0e10cSrcweir             //Create this string before we call DeInitVCL, because this will kill
500*cdf0e10cSrcweir             //the ResMgr
501*cdf0e10cSrcweir             String sError(ResId(RID_STR_UNOPKG_ERROR, *DeploymentResMgr::get()));
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir             sMsg = sMsg + OUSTR("\n") + getLockFilePath();
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir             if (bGui)
506*cdf0e10cSrcweir             {
507*cdf0e10cSrcweir                 //We show a message box or print to the console that there
508*cdf0e10cSrcweir                 //is another instance already running
509*cdf0e10cSrcweir                 if ( ! InitVCL( Reference<lang::XMultiServiceFactory>(
510*cdf0e10cSrcweir                                     xComponentContext->getServiceManager(),
511*cdf0e10cSrcweir                                     UNO_QUERY_THROW ) ))
512*cdf0e10cSrcweir                     throw RuntimeException( OUSTR("Cannot initialize VCL!"),
513*cdf0e10cSrcweir                                             NULL );
514*cdf0e10cSrcweir                 {
515*cdf0e10cSrcweir                     WarningBox warn(NULL, WB_OK | WB_DEF_OK, sMsg);
516*cdf0e10cSrcweir                     warn.SetText(::utl::ConfigManager::GetDirectConfigProperty(
517*cdf0e10cSrcweir                                      ::utl::ConfigManager::PRODUCTNAME).get<OUString>());
518*cdf0e10cSrcweir                     warn.SetIcon(0);
519*cdf0e10cSrcweir                     warn.Execute();
520*cdf0e10cSrcweir                 }
521*cdf0e10cSrcweir                 DeInitVCL();
522*cdf0e10cSrcweir             }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir             throw LockFileException(
525*cdf0e10cSrcweir                 OUSTR("\n") + sError + sMsg + OUSTR("\n"));
526*cdf0e10cSrcweir         }
527*cdf0e10cSrcweir     }
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir     return xComponentContext;
530*cdf0e10cSrcweir }
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir //Determines if a folder does not contains a folder.
533*cdf0e10cSrcweir //Return false may also mean that the status could not be determined
534*cdf0e10cSrcweir //because some error occurred.
535*cdf0e10cSrcweir bool hasNoFolder(OUString const & folderUrl)
536*cdf0e10cSrcweir {
537*cdf0e10cSrcweir     bool ret = false;
538*cdf0e10cSrcweir     OUString url = folderUrl;
539*cdf0e10cSrcweir     ::rtl::Bootstrap::expandMacros(url);
540*cdf0e10cSrcweir     ::osl::Directory dir(url);
541*cdf0e10cSrcweir     osl::File::RC rc = dir.open();
542*cdf0e10cSrcweir     if (rc == osl::File::E_None)
543*cdf0e10cSrcweir     {
544*cdf0e10cSrcweir         bool bFolderExist = false;
545*cdf0e10cSrcweir         osl::DirectoryItem i;
546*cdf0e10cSrcweir         osl::File::RC rcNext = osl::File::E_None;
547*cdf0e10cSrcweir         while ( (rcNext = dir.getNextItem(i)) == osl::File::E_None)
548*cdf0e10cSrcweir         {
549*cdf0e10cSrcweir             osl::FileStatus stat(FileStatusMask_Type);
550*cdf0e10cSrcweir             if (i.getFileStatus(stat) == osl::File::E_None)
551*cdf0e10cSrcweir             {
552*cdf0e10cSrcweir                 if (stat.getFileType() == osl::FileStatus::Directory)
553*cdf0e10cSrcweir                 {
554*cdf0e10cSrcweir                     bFolderExist = true;
555*cdf0e10cSrcweir                     break;
556*cdf0e10cSrcweir                 }
557*cdf0e10cSrcweir             }
558*cdf0e10cSrcweir             else
559*cdf0e10cSrcweir             {
560*cdf0e10cSrcweir                 dp_misc::writeConsole(
561*cdf0e10cSrcweir                     OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n"));
562*cdf0e10cSrcweir                 break;
563*cdf0e10cSrcweir             }
564*cdf0e10cSrcweir             i = osl::DirectoryItem();
565*cdf0e10cSrcweir         }
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir         if (rcNext == osl::File::E_NOENT ||
568*cdf0e10cSrcweir             rcNext == osl::File::E_None)
569*cdf0e10cSrcweir         {
570*cdf0e10cSrcweir             if (!bFolderExist)
571*cdf0e10cSrcweir                 ret = true;
572*cdf0e10cSrcweir         }
573*cdf0e10cSrcweir         else
574*cdf0e10cSrcweir         {
575*cdf0e10cSrcweir             dp_misc::writeConsole(
576*cdf0e10cSrcweir                 OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n"));
577*cdf0e10cSrcweir         }
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir         dir.close();
580*cdf0e10cSrcweir     }
581*cdf0e10cSrcweir     else
582*cdf0e10cSrcweir     {
583*cdf0e10cSrcweir         dp_misc::writeConsole(
584*cdf0e10cSrcweir             OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n"));
585*cdf0e10cSrcweir     }
586*cdf0e10cSrcweir     return ret;
587*cdf0e10cSrcweir }
588*cdf0e10cSrcweir 
589*cdf0e10cSrcweir void removeFolder(OUString const & folderUrl)
590*cdf0e10cSrcweir {
591*cdf0e10cSrcweir     OUString url = folderUrl;
592*cdf0e10cSrcweir     ::rtl::Bootstrap::expandMacros(url);
593*cdf0e10cSrcweir     ::osl::Directory dir(url);
594*cdf0e10cSrcweir     ::osl::File::RC rc = dir.open();
595*cdf0e10cSrcweir     if (rc == osl::File::E_None)
596*cdf0e10cSrcweir     {
597*cdf0e10cSrcweir         ::osl::DirectoryItem i;
598*cdf0e10cSrcweir         ::osl::File::RC rcNext = ::osl::File::E_None;
599*cdf0e10cSrcweir         while ( (rcNext = dir.getNextItem(i)) == ::osl::File::E_None)
600*cdf0e10cSrcweir         {
601*cdf0e10cSrcweir             ::osl::FileStatus stat(FileStatusMask_Type | FileStatusMask_FileURL);
602*cdf0e10cSrcweir             if (i.getFileStatus(stat) == ::osl::File::E_None)
603*cdf0e10cSrcweir             {
604*cdf0e10cSrcweir                 ::osl::FileStatus::Type t = stat.getFileType();
605*cdf0e10cSrcweir                 if (t == ::osl::FileStatus::Directory)
606*cdf0e10cSrcweir                 {
607*cdf0e10cSrcweir                     //remove folder
608*cdf0e10cSrcweir                     removeFolder(stat.getFileURL());
609*cdf0e10cSrcweir                 }
610*cdf0e10cSrcweir                 else if (t == ::osl::FileStatus::Regular)
611*cdf0e10cSrcweir                 {
612*cdf0e10cSrcweir                     //remove file
613*cdf0e10cSrcweir                     ::osl::File::remove(stat.getFileURL());
614*cdf0e10cSrcweir                 }
615*cdf0e10cSrcweir                 else
616*cdf0e10cSrcweir                 {
617*cdf0e10cSrcweir                     OSL_ASSERT(0);
618*cdf0e10cSrcweir                 }
619*cdf0e10cSrcweir             }
620*cdf0e10cSrcweir             else
621*cdf0e10cSrcweir             {
622*cdf0e10cSrcweir                 dp_misc::writeConsole(
623*cdf0e10cSrcweir                     OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n"));
624*cdf0e10cSrcweir                 break;
625*cdf0e10cSrcweir             }
626*cdf0e10cSrcweir             i = ::osl::DirectoryItem();
627*cdf0e10cSrcweir         }
628*cdf0e10cSrcweir         dir.close();
629*cdf0e10cSrcweir         ::osl::Directory::remove(url);
630*cdf0e10cSrcweir     }
631*cdf0e10cSrcweir     else if (rc != osl::File::E_NOENT)
632*cdf0e10cSrcweir     {
633*cdf0e10cSrcweir         dp_misc::writeConsole(
634*cdf0e10cSrcweir             OUSTR("unopkg: Error while removing ") + url + OUSTR("\n"));
635*cdf0e10cSrcweir     }
636*cdf0e10cSrcweir }
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir }
639