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 30*cdf0e10cSrcweir #include "dp_misc.h" 31*cdf0e10cSrcweir #include "unopkg_main.h" 32*cdf0e10cSrcweir #include "unopkg_shared.h" 33*cdf0e10cSrcweir #include "dp_identifier.hxx" 34*cdf0e10cSrcweir #include "sal/main.h" 35*cdf0e10cSrcweir #include "tools/extendapplicationenvironment.hxx" 36*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 37*cdf0e10cSrcweir #include "rtl/uri.hxx" 38*cdf0e10cSrcweir #include "rtl/bootstrap.hxx" 39*cdf0e10cSrcweir #include "osl/thread.h" 40*cdf0e10cSrcweir #include "osl/process.h" 41*cdf0e10cSrcweir #include "osl/conditn.hxx" 42*cdf0e10cSrcweir #include "osl/file.hxx" 43*cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx" 44*cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx" 45*cdf0e10cSrcweir #include "comphelper/anytostring.hxx" 46*cdf0e10cSrcweir #include "comphelper/sequence.hxx" 47*cdf0e10cSrcweir #include "com/sun/star/deployment/ExtensionManager.hpp" 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #include "com/sun/star/deployment/ui/PackageManagerDialog.hpp" 50*cdf0e10cSrcweir #include "com/sun/star/ui/dialogs/XExecutableDialog.hpp" 51*cdf0e10cSrcweir #include "com/sun/star/lang/DisposedException.hpp" 52*cdf0e10cSrcweir #include "boost/scoped_array.hpp" 53*cdf0e10cSrcweir #include "com/sun/star/ui/dialogs/XDialogClosedListener.hpp" 54*cdf0e10cSrcweir #include "com/sun/star/bridge/XBridgeFactory.hpp" 55*cdf0e10cSrcweir #include <stdio.h> 56*cdf0e10cSrcweir #include <vector> 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir using namespace ::com::sun::star; 60*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 61*cdf0e10cSrcweir using namespace ::unopkg; 62*cdf0e10cSrcweir using ::rtl::OUString; 63*cdf0e10cSrcweir namespace css = ::com::sun::star; 64*cdf0e10cSrcweir namespace { 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir struct ExtensionName 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir OUString m_str; 69*cdf0e10cSrcweir ExtensionName( OUString const & str ) : m_str( str ) {} 70*cdf0e10cSrcweir bool operator () ( Reference<deployment::XPackage> const & e ) const 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir if (m_str.equals(dp_misc::getIdentifier(e)) 73*cdf0e10cSrcweir || m_str.equals(e->getName())) 74*cdf0e10cSrcweir return true; 75*cdf0e10cSrcweir return false; 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir }; 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir //------------------------------------------------------------------------------ 80*cdf0e10cSrcweir const char s_usingText [] = 81*cdf0e10cSrcweir "\n" 82*cdf0e10cSrcweir "using: " APP_NAME " add <options> extension-path...\n" 83*cdf0e10cSrcweir " " APP_NAME " validate <options> extension-identifier...\n" 84*cdf0e10cSrcweir " " APP_NAME " remove <options> extension-identifier...\n" 85*cdf0e10cSrcweir " " APP_NAME " list <options> extension-identifier...\n" 86*cdf0e10cSrcweir " " APP_NAME " reinstall <options>\n" 87*cdf0e10cSrcweir " " APP_NAME " gui\n" 88*cdf0e10cSrcweir " " APP_NAME " -V\n" 89*cdf0e10cSrcweir " " APP_NAME " -h\n" 90*cdf0e10cSrcweir "\n" 91*cdf0e10cSrcweir "sub-commands:\n" 92*cdf0e10cSrcweir " add add extension\n" 93*cdf0e10cSrcweir " validate checks the prerequisites of an installed extension and" 94*cdf0e10cSrcweir " registers it if possible\n" 95*cdf0e10cSrcweir " remove remove extensions by identifier\n" 96*cdf0e10cSrcweir " reinstall expert feature: reinstall all deployed extensions\n" 97*cdf0e10cSrcweir " list list information about deployed extensions\n" 98*cdf0e10cSrcweir " gui raise Extension Manager Graphical User Interface (GUI)\n" 99*cdf0e10cSrcweir "\n" 100*cdf0e10cSrcweir "options:\n" 101*cdf0e10cSrcweir " -h, --help this help\n" 102*cdf0e10cSrcweir " -V, --version version information\n" 103*cdf0e10cSrcweir " -v, --verbose verbose output to stdout\n" 104*cdf0e10cSrcweir " -f, --force force overwriting existing extensions\n" 105*cdf0e10cSrcweir " -s, --suppress-license prevents showing the license provided that\n" 106*cdf0e10cSrcweir " the extension allows it\n" 107*cdf0e10cSrcweir " --log-file <file> custom log file; default: <cache-dir>/log.txt\n" 108*cdf0e10cSrcweir " --shared expert feature: operate on shared installation\n" 109*cdf0e10cSrcweir " deployment context;\n" 110*cdf0e10cSrcweir " run only when no concurrent Office\n" 111*cdf0e10cSrcweir " process(es) are running!\n" 112*cdf0e10cSrcweir " --bundled expert feature: operate on bundled extensions. Only\n" 113*cdf0e10cSrcweir " works with list, validate, reinstall;\n" 114*cdf0e10cSrcweir " --deployment-context expert feature: explicit deployment context\n" 115*cdf0e10cSrcweir " <context>\n" 116*cdf0e10cSrcweir "\n" 117*cdf0e10cSrcweir "To learn more about the Extension Manager and extensions, see:\n" 118*cdf0e10cSrcweir "http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Extensions/Extensions\n\n"; 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir //------------------------------------------------------------------------------ 121*cdf0e10cSrcweir const OptionInfo s_option_infos [] = { 122*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("help"), 'h', false }, 123*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("version"), 'V', false }, 124*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("verbose"), 'v', false }, 125*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("force"), 'f', false }, 126*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("log-file"), '\0', true }, 127*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("shared"), '\0', false }, 128*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("deployment-context"), '\0', true }, 129*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("bundled"), '\0', false}, 130*cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("suppress-license"), 's', false}, 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir { 0, 0, '\0', false } 133*cdf0e10cSrcweir }; 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir class DialogClosedListenerImpl : 136*cdf0e10cSrcweir public ::cppu::WeakImplHelper1< ui::dialogs::XDialogClosedListener > 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir osl::Condition & m_rDialogClosedCondition; 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir public: 141*cdf0e10cSrcweir DialogClosedListenerImpl( osl::Condition & rDialogClosedCondition ) 142*cdf0e10cSrcweir : m_rDialogClosedCondition( rDialogClosedCondition ) {} 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir // XEventListener (base of XDialogClosedListener) 145*cdf0e10cSrcweir virtual void SAL_CALL disposing( lang::EventObject const & Source ) 146*cdf0e10cSrcweir throw (RuntimeException); 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir // XDialogClosedListener 149*cdf0e10cSrcweir virtual void SAL_CALL dialogClosed( 150*cdf0e10cSrcweir ui::dialogs::DialogClosedEvent const & aEvent ) 151*cdf0e10cSrcweir throw (RuntimeException); 152*cdf0e10cSrcweir }; 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir // XEventListener (base of XDialogClosedListener) 155*cdf0e10cSrcweir void DialogClosedListenerImpl::disposing( lang::EventObject const & ) 156*cdf0e10cSrcweir throw (RuntimeException) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir // nothing to do 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir // XDialogClosedListener 162*cdf0e10cSrcweir void DialogClosedListenerImpl::dialogClosed( 163*cdf0e10cSrcweir ui::dialogs::DialogClosedEvent const & ) 164*cdf0e10cSrcweir throw (RuntimeException) 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir m_rDialogClosedCondition.set(); 167*cdf0e10cSrcweir } 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir // If a package had been installed with a pre OOo 2.2, it could not normally be 170*cdf0e10cSrcweir // found via its identifier; similarly (and for ease of use), a package 171*cdf0e10cSrcweir // installed with OOo 2.2 or later could not normally be found via its file 172*cdf0e10cSrcweir // name. 173*cdf0e10cSrcweir Reference<deployment::XPackage> findPackage( 174*cdf0e10cSrcweir OUString const & repository, 175*cdf0e10cSrcweir Reference<deployment::XExtensionManager> const & manager, 176*cdf0e10cSrcweir Reference<ucb::XCommandEnvironment > const & environment, 177*cdf0e10cSrcweir OUString const & idOrFileName ) 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > ps( 180*cdf0e10cSrcweir manager->getDeployedExtensions(repository, 181*cdf0e10cSrcweir Reference<task::XAbortChannel>(), environment ) ); 182*cdf0e10cSrcweir for ( sal_Int32 i = 0; i < ps.getLength(); ++i ) 183*cdf0e10cSrcweir if ( dp_misc::getIdentifier( ps[i] ) == idOrFileName ) 184*cdf0e10cSrcweir return ps[i]; 185*cdf0e10cSrcweir for ( sal_Int32 i = 0; i < ps.getLength(); ++i ) 186*cdf0e10cSrcweir if ( ps[i]->getName() == idOrFileName ) 187*cdf0e10cSrcweir return ps[i]; 188*cdf0e10cSrcweir return Reference<deployment::XPackage>(); 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir } // anon namespace 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir //workaround for some reason the bridge threads which communicate with the uno.exe 195*cdf0e10cSrcweir //process are not releases on time 196*cdf0e10cSrcweir void disposeBridges(Reference<css::uno::XComponentContext> ctx) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir if (!ctx.is()) 199*cdf0e10cSrcweir return; 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir Reference<css::bridge::XBridgeFactory> bridgeFac( 202*cdf0e10cSrcweir ctx->getServiceManager()->createInstanceWithContext( 203*cdf0e10cSrcweir OUSTR("com.sun.star.bridge.BridgeFactory"), ctx), 204*cdf0e10cSrcweir UNO_QUERY); 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir if (bridgeFac.is()) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges(); 209*cdf0e10cSrcweir for (sal_Int32 i = 0; i < seqBridges.getLength(); i++) 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY); 212*cdf0e10cSrcweir if (comp.is()) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir try { 215*cdf0e10cSrcweir comp->dispose(); 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir catch (css::lang::DisposedException& ) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir } 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir } 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir //############################################################################## 226*cdf0e10cSrcweir extern "C" int unopkg_main() 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir tools::extendApplicationEnvironment(); 229*cdf0e10cSrcweir DisposeGuard disposeGuard; 230*cdf0e10cSrcweir bool bNoOtherErrorMsg = false; 231*cdf0e10cSrcweir OUString subCommand; 232*cdf0e10cSrcweir bool option_shared = false; 233*cdf0e10cSrcweir bool option_force = false; 234*cdf0e10cSrcweir bool option_verbose = false; 235*cdf0e10cSrcweir bool option_bundled = false; 236*cdf0e10cSrcweir bool option_suppressLicense = false; 237*cdf0e10cSrcweir bool subcmd_add = false; 238*cdf0e10cSrcweir bool subcmd_gui = false; 239*cdf0e10cSrcweir OUString logFile; 240*cdf0e10cSrcweir OUString repository; 241*cdf0e10cSrcweir OUString cmdArg; 242*cdf0e10cSrcweir ::std::vector<OUString> cmdPackages; 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir OptionInfo const * info_shared = getOptionInfo( 245*cdf0e10cSrcweir s_option_infos, OUSTR("shared") ); 246*cdf0e10cSrcweir OptionInfo const * info_force = getOptionInfo( 247*cdf0e10cSrcweir s_option_infos, OUSTR("force") ); 248*cdf0e10cSrcweir OptionInfo const * info_verbose = getOptionInfo( 249*cdf0e10cSrcweir s_option_infos, OUSTR("verbose") ); 250*cdf0e10cSrcweir OptionInfo const * info_log = getOptionInfo( 251*cdf0e10cSrcweir s_option_infos, OUSTR("log-file") ); 252*cdf0e10cSrcweir OptionInfo const * info_context = getOptionInfo( 253*cdf0e10cSrcweir s_option_infos, OUSTR("deployment-context") ); 254*cdf0e10cSrcweir OptionInfo const * info_help = getOptionInfo( 255*cdf0e10cSrcweir s_option_infos, OUSTR("help") ); 256*cdf0e10cSrcweir OptionInfo const * info_version = getOptionInfo( 257*cdf0e10cSrcweir s_option_infos, OUSTR("version") ); 258*cdf0e10cSrcweir OptionInfo const * info_bundled = getOptionInfo( 259*cdf0e10cSrcweir s_option_infos, OUSTR("bundled") ); 260*cdf0e10cSrcweir OptionInfo const * info_suppressLicense = getOptionInfo( 261*cdf0e10cSrcweir s_option_infos, OUSTR("suppress-license") ); 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir Reference<XComponentContext> xComponentContext; 265*cdf0e10cSrcweir Reference<XComponentContext> xLocalComponentContext; 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir try { 268*cdf0e10cSrcweir sal_uInt32 nPos = 0; 269*cdf0e10cSrcweir sal_uInt32 nCount = osl_getCommandArgCount(); 270*cdf0e10cSrcweir if (nCount == 0 || isOption( info_help, &nPos )) 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir dp_misc::writeConsole(s_usingText); 273*cdf0e10cSrcweir return 0; 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir else if (isOption( info_version, &nPos )) { 276*cdf0e10cSrcweir dp_misc::writeConsole("\n"APP_NAME" Version 3.3\n"); 277*cdf0e10cSrcweir return 0; 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir //consume all bootstrap variables which may occur before the subcommannd 280*cdf0e10cSrcweir while(isBootstrapVariable(&nPos)); 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir if(nPos >= nCount) 283*cdf0e10cSrcweir return 0; 284*cdf0e10cSrcweir //get the sub command 285*cdf0e10cSrcweir osl_getCommandArg( nPos, &subCommand.pData ); 286*cdf0e10cSrcweir ++nPos; 287*cdf0e10cSrcweir subCommand = subCommand.trim(); 288*cdf0e10cSrcweir subcmd_add = subCommand.equalsAsciiL( 289*cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("add") ); 290*cdf0e10cSrcweir subcmd_gui = subCommand.equalsAsciiL( 291*cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("gui") ); 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir // sun-command options and packages: 294*cdf0e10cSrcweir while (nPos < nCount) 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir if (readArgument( &cmdArg, info_log, &nPos )) { 297*cdf0e10cSrcweir logFile = makeAbsoluteFileUrl( 298*cdf0e10cSrcweir cmdArg.trim(), getProcessWorkingDir() ); 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir else if (!readOption( &option_verbose, info_verbose, &nPos ) && 301*cdf0e10cSrcweir !readOption( &option_shared, info_shared, &nPos ) && 302*cdf0e10cSrcweir !readOption( &option_force, info_force, &nPos ) && 303*cdf0e10cSrcweir !readOption( &option_bundled, info_bundled, &nPos ) && 304*cdf0e10cSrcweir !readOption( &option_suppressLicense, info_suppressLicense, &nPos ) && 305*cdf0e10cSrcweir !readArgument( &repository, info_context, &nPos ) && 306*cdf0e10cSrcweir !isBootstrapVariable(&nPos)) 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir osl_getCommandArg( nPos, &cmdArg.pData ); 309*cdf0e10cSrcweir ++nPos; 310*cdf0e10cSrcweir cmdArg = cmdArg.trim(); 311*cdf0e10cSrcweir if (cmdArg.getLength() > 0) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir if (cmdArg[ 0 ] == '-') 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir // is option: 316*cdf0e10cSrcweir dp_misc::writeConsoleError( 317*cdf0e10cSrcweir OUSTR("\nERROR: unexpected option ") + 318*cdf0e10cSrcweir cmdArg + 319*cdf0e10cSrcweir OUSTR("!\n") + 320*cdf0e10cSrcweir OUSTR(" Use " APP_NAME " ") + 321*cdf0e10cSrcweir toString(info_help) + 322*cdf0e10cSrcweir OUSTR(" to print all options.\n")); 323*cdf0e10cSrcweir return 1; 324*cdf0e10cSrcweir } 325*cdf0e10cSrcweir else 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir // is package: 328*cdf0e10cSrcweir cmdPackages.push_back( 329*cdf0e10cSrcweir subcmd_add || subcmd_gui 330*cdf0e10cSrcweir ? makeAbsoluteFileUrl( 331*cdf0e10cSrcweir cmdArg, getProcessWorkingDir() ) 332*cdf0e10cSrcweir : cmdArg ); 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir if (repository.getLength() == 0) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir if (option_shared) 341*cdf0e10cSrcweir repository = OUSTR("shared"); 342*cdf0e10cSrcweir else if (option_bundled) 343*cdf0e10cSrcweir repository = OUSTR("bundled"); 344*cdf0e10cSrcweir else 345*cdf0e10cSrcweir repository = OUSTR("user"); 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir else 348*cdf0e10cSrcweir { 349*cdf0e10cSrcweir if (repository.equalsAsciiL( 350*cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("shared") )) { 351*cdf0e10cSrcweir option_shared = true; 352*cdf0e10cSrcweir } 353*cdf0e10cSrcweir else if (option_shared) { 354*cdf0e10cSrcweir dp_misc::writeConsoleError( 355*cdf0e10cSrcweir OUSTR("WARNING: explicit context given! ") + 356*cdf0e10cSrcweir OUSTR("Ignoring option ") + 357*cdf0e10cSrcweir toString( info_shared ) + 358*cdf0e10cSrcweir OUSTR("!\n") ); 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir } 361*cdf0e10cSrcweir 362*cdf0e10cSrcweir if (subCommand.equals(OUSTR("reinstall"))) 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir //We must prevent that services and types are loaded by UNO, 365*cdf0e10cSrcweir //otherwise we cannot delete the registry data folder. 366*cdf0e10cSrcweir OUString extensionUnorc; 367*cdf0e10cSrcweir if (repository.equals(OUSTR("user"))) 368*cdf0e10cSrcweir extensionUnorc = OUSTR("$UNO_USER_PACKAGES_CACHE/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc"); 369*cdf0e10cSrcweir else if (repository.equals(OUSTR("shared"))) 370*cdf0e10cSrcweir extensionUnorc = OUSTR("$SHARED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc"); 371*cdf0e10cSrcweir else if (repository.equals(OUSTR("bundled"))) 372*cdf0e10cSrcweir extensionUnorc = OUSTR("$BUNDLED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc"); 373*cdf0e10cSrcweir else 374*cdf0e10cSrcweir OSL_ASSERT(0); 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir ::rtl::Bootstrap::expandMacros(extensionUnorc); 377*cdf0e10cSrcweir oslFileError e = osl_removeFile(extensionUnorc.pData); 378*cdf0e10cSrcweir if (e != osl_File_E_None && e != osl_File_E_NOENT) 379*cdf0e10cSrcweir throw Exception(OUSTR("Could not delete ") + extensionUnorc, 0); 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir else if (subCommand.equals(OUSTR("sync"))) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir //sync is private!!!! Only to be called from setup!!! 384*cdf0e10cSrcweir //The UserInstallation is diverted to the prereg folder. But only 385*cdf0e10cSrcweir //the lock file is written! This requires that 386*cdf0e10cSrcweir //-env:UNO_JAVA_JFW_INSTALL_DATA is passed to javaldx and unopkg otherwise the 387*cdf0e10cSrcweir //javasettings file is written to the prereg folder. 388*cdf0e10cSrcweir // 389*cdf0e10cSrcweir //For performance reasons unopkg sync is called during the setup and 390*cdf0e10cSrcweir //creates the registration data for the repository of the bundled 391*cdf0e10cSrcweir //extensions. It is then copied to the user installation during 392*cdf0e10cSrcweir //startup of OOo (userdata/extensions/bundled). The registration 393*cdf0e10cSrcweir //data is in the brand installation and must be removed when 394*cdf0e10cSrcweir //uninstalling OOo. We do this here, before UNO is 395*cdf0e10cSrcweir //bootstrapped. Otherwies files could be locked by this process. 396*cdf0e10cSrcweir 397*cdf0e10cSrcweir //If there is no folder left in 398*cdf0e10cSrcweir //$BRAND_BASE_DIR/share/extensions 399*cdf0e10cSrcweir //then we can delete the registration data at 400*cdf0e10cSrcweir //$BUNDLED_EXTENSIONS_USER 401*cdf0e10cSrcweir if (hasNoFolder(OUSTR("$BRAND_BASE_DIR/share/extensions"))) 402*cdf0e10cSrcweir { 403*cdf0e10cSrcweir removeFolder(OUSTR("$BUNDLED_EXTENSIONS_PREREG")); 404*cdf0e10cSrcweir //return otherwise we create the registration data again 405*cdf0e10cSrcweir return 0; 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir //redirect the UserInstallation, so we do not create a 408*cdf0e10cSrcweir //user installation for the admin and we also do not need 409*cdf0e10cSrcweir //to call unopkg with -env:UserInstallation 410*cdf0e10cSrcweir ::rtl::Bootstrap::set(OUSTR("UserInstallation"), 411*cdf0e10cSrcweir OUSTR("$BUNDLED_EXTENSIONS_PREREG/..")); 412*cdf0e10cSrcweir //Setting UNO_JAVA_JFW_INSTALL_DATA causes the javasettings to be written 413*cdf0e10cSrcweir //in the office installation. We do not want to create the user data folder 414*cdf0e10cSrcweir //for the admin. The value must also be set in the unopkg script (Linux, etc.) 415*cdf0e10cSrcweir //when calling javaldx 416*cdf0e10cSrcweir ::rtl::Bootstrap::set(OUSTR("UNO_JAVA_JFW_INSTALL_DATA"), 417*cdf0e10cSrcweir OUSTR("$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml")); 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir } 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir xComponentContext = getUNO( 422*cdf0e10cSrcweir disposeGuard, option_verbose, option_shared, subcmd_gui, 423*cdf0e10cSrcweir xLocalComponentContext ); 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir Reference<deployment::XExtensionManager> xExtensionManager( 426*cdf0e10cSrcweir deployment::ExtensionManager::get( xComponentContext ) ); 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv( 429*cdf0e10cSrcweir createCmdEnv( xComponentContext, logFile, 430*cdf0e10cSrcweir option_force, option_verbose) ); 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir //synchronize bundled/shared extensions 433*cdf0e10cSrcweir //Do not synchronize when command is "reinstall". This could add types and services to UNO and 434*cdf0e10cSrcweir //prevent the deletion of the registry data folder 435*cdf0e10cSrcweir //synching is done in XExtensionManager.reinstall 436*cdf0e10cSrcweir if (!subcmd_gui && ! subCommand.equals(OUSTR("reinstall")) 437*cdf0e10cSrcweir && ! subCommand.equals(OUSTR("sync")) 438*cdf0e10cSrcweir && ! dp_misc::office_is_running()) 439*cdf0e10cSrcweir dp_misc::syncRepositories(xCmdEnv); 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir if (subcmd_add || 442*cdf0e10cSrcweir subCommand.equalsAsciiL( 443*cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("remove") )) 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos ) 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir OUString const & cmdPackage = cmdPackages[ pos ]; 448*cdf0e10cSrcweir if (subcmd_add) 449*cdf0e10cSrcweir { 450*cdf0e10cSrcweir beans::NamedValue nvSuppress( 451*cdf0e10cSrcweir OUSTR("SUPPRESS_LICENSE"), option_suppressLicense ? 452*cdf0e10cSrcweir makeAny(OUSTR("1")):makeAny(OUSTR("0"))); 453*cdf0e10cSrcweir xExtensionManager->addExtension( 454*cdf0e10cSrcweir cmdPackage, Sequence<beans::NamedValue>(&nvSuppress, 1), 455*cdf0e10cSrcweir repository, Reference<task::XAbortChannel>(), xCmdEnv); 456*cdf0e10cSrcweir } 457*cdf0e10cSrcweir else 458*cdf0e10cSrcweir { 459*cdf0e10cSrcweir try 460*cdf0e10cSrcweir { 461*cdf0e10cSrcweir xExtensionManager->removeExtension( 462*cdf0e10cSrcweir cmdPackage, cmdPackage, repository, 463*cdf0e10cSrcweir Reference<task::XAbortChannel>(), xCmdEnv ); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir catch (lang::IllegalArgumentException &) 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir Reference<deployment::XPackage> p( 468*cdf0e10cSrcweir findPackage(repository, 469*cdf0e10cSrcweir xExtensionManager, xCmdEnv, cmdPackage ) ); 470*cdf0e10cSrcweir if ( !p.is()) 471*cdf0e10cSrcweir throw; 472*cdf0e10cSrcweir else if (p.is()) 473*cdf0e10cSrcweir xExtensionManager->removeExtension( 474*cdf0e10cSrcweir ::dp_misc::getIdentifier(p), p->getName(), 475*cdf0e10cSrcweir repository, 476*cdf0e10cSrcweir Reference<task::XAbortChannel>(), xCmdEnv ); 477*cdf0e10cSrcweir } 478*cdf0e10cSrcweir } 479*cdf0e10cSrcweir } 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir else if (subCommand.equalsAsciiL( 482*cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("reinstall") )) 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir xExtensionManager->reinstallDeployedExtensions( 485*cdf0e10cSrcweir repository, Reference<task::XAbortChannel>(), xCmdEnv); 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("list") )) 488*cdf0e10cSrcweir { 489*cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted; 490*cdf0e10cSrcweir ::comphelper::sequenceToContainer(vecExtUnaccepted, 491*cdf0e10cSrcweir xExtensionManager->getExtensionsWithUnacceptedLicenses( 492*cdf0e10cSrcweir repository, xCmdEnv)); 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir //This vector tells what XPackage in allExtensions has an 495*cdf0e10cSrcweir //unaccepted license. 496*cdf0e10cSrcweir std::vector<bool> vecUnaccepted; 497*cdf0e10cSrcweir std::vector<Reference<deployment::XPackage> > allExtensions; 498*cdf0e10cSrcweir if (cmdPackages.empty()) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > 501*cdf0e10cSrcweir packages = xExtensionManager->getDeployedExtensions( 502*cdf0e10cSrcweir repository, Reference<task::XAbortChannel>(), xCmdEnv ); 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> > vec_packages; 505*cdf0e10cSrcweir ::comphelper::sequenceToContainer(vec_packages, packages); 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir //First copy the extensions with the unaccepted license 508*cdf0e10cSrcweir //to vector allExtensions. 509*cdf0e10cSrcweir allExtensions.resize(vecExtUnaccepted.size() + vec_packages.size()); 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> >::iterator i_all_ext = 512*cdf0e10cSrcweir ::std::copy(vecExtUnaccepted.begin(), vecExtUnaccepted.end(), 513*cdf0e10cSrcweir allExtensions.begin()); 514*cdf0e10cSrcweir //Now copy those we got from getDeployedExtensions 515*cdf0e10cSrcweir ::std::copy(vec_packages.begin(), vec_packages.end(), i_all_ext); 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir //Now prepare the vector which tells what extension has an 518*cdf0e10cSrcweir //unaccepted license 519*cdf0e10cSrcweir vecUnaccepted.resize(vecExtUnaccepted.size() + vec_packages.size()); 520*cdf0e10cSrcweir ::std::vector<bool>::iterator i_unaccepted = 521*cdf0e10cSrcweir ::std::fill_n(vecUnaccepted.begin(), 522*cdf0e10cSrcweir vecExtUnaccepted.size(), true); 523*cdf0e10cSrcweir ::std::fill_n(i_unaccepted, vec_packages.size(), false); 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir dp_misc::writeConsole( 526*cdf0e10cSrcweir OUSTR("All deployed ") + repository + OUSTR(" extensions:\n\n")); 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir else 529*cdf0e10cSrcweir { 530*cdf0e10cSrcweir //The user provided the names (ids or file names) of the extensions 531*cdf0e10cSrcweir //which shall be listed 532*cdf0e10cSrcweir for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos ) 533*cdf0e10cSrcweir { 534*cdf0e10cSrcweir Reference<deployment::XPackage> extension; 535*cdf0e10cSrcweir try 536*cdf0e10cSrcweir { 537*cdf0e10cSrcweir extension = xExtensionManager->getDeployedExtension( 538*cdf0e10cSrcweir repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv ); 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir catch (lang::IllegalArgumentException &) 541*cdf0e10cSrcweir { 542*cdf0e10cSrcweir extension = findPackage(repository, 543*cdf0e10cSrcweir xExtensionManager, xCmdEnv, cmdPackages[ pos ] ); 544*cdf0e10cSrcweir } 545*cdf0e10cSrcweir 546*cdf0e10cSrcweir //Now look if the requested extension has an unaccepted license 547*cdf0e10cSrcweir bool bUnacceptedLic = false; 548*cdf0e10cSrcweir if (!extension.is()) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> >::const_iterator 551*cdf0e10cSrcweir i = ::std::find_if( 552*cdf0e10cSrcweir vecExtUnaccepted.begin(), 553*cdf0e10cSrcweir vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos])); 554*cdf0e10cSrcweir if (i != vecExtUnaccepted.end()) 555*cdf0e10cSrcweir { 556*cdf0e10cSrcweir extension = *i; 557*cdf0e10cSrcweir bUnacceptedLic = true; 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir if (extension.is()) 562*cdf0e10cSrcweir { 563*cdf0e10cSrcweir allExtensions.push_back(extension); 564*cdf0e10cSrcweir vecUnaccepted.push_back(bUnacceptedLic); 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir else 568*cdf0e10cSrcweir throw lang::IllegalArgumentException( 569*cdf0e10cSrcweir OUSTR("There is no such extension deployed: ") + 570*cdf0e10cSrcweir cmdPackages[pos],0,-1); 571*cdf0e10cSrcweir } 572*cdf0e10cSrcweir 573*cdf0e10cSrcweir } 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir printf_packages(allExtensions, vecUnaccepted, xCmdEnv ); 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("validate") )) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted; 580*cdf0e10cSrcweir ::comphelper::sequenceToContainer( 581*cdf0e10cSrcweir vecExtUnaccepted, xExtensionManager->getExtensionsWithUnacceptedLicenses( 582*cdf0e10cSrcweir repository, xCmdEnv)); 583*cdf0e10cSrcweir 584*cdf0e10cSrcweir for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos ) 585*cdf0e10cSrcweir { 586*cdf0e10cSrcweir Reference<deployment::XPackage> extension; 587*cdf0e10cSrcweir try 588*cdf0e10cSrcweir { 589*cdf0e10cSrcweir extension = xExtensionManager->getDeployedExtension( 590*cdf0e10cSrcweir repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv ); 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir catch (lang::IllegalArgumentException &) 593*cdf0e10cSrcweir { 594*cdf0e10cSrcweir extension = findPackage( 595*cdf0e10cSrcweir repository, xExtensionManager, xCmdEnv, cmdPackages[ pos ] ); 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir if (!extension.is()) 599*cdf0e10cSrcweir { 600*cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> >::const_iterator 601*cdf0e10cSrcweir i = ::std::find_if( 602*cdf0e10cSrcweir vecExtUnaccepted.begin(), 603*cdf0e10cSrcweir vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos])); 604*cdf0e10cSrcweir if (i != vecExtUnaccepted.end()) 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir extension = *i; 607*cdf0e10cSrcweir } 608*cdf0e10cSrcweir } 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir if (extension.is()) 611*cdf0e10cSrcweir xExtensionManager->checkPrerequisitesAndEnable( 612*cdf0e10cSrcweir extension, Reference<task::XAbortChannel>(), xCmdEnv); 613*cdf0e10cSrcweir } 614*cdf0e10cSrcweir } 615*cdf0e10cSrcweir else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gui") )) 616*cdf0e10cSrcweir { 617*cdf0e10cSrcweir Reference<ui::dialogs::XAsynchronousExecutableDialog> xDialog( 618*cdf0e10cSrcweir deployment::ui::PackageManagerDialog::createAndInstall( 619*cdf0e10cSrcweir xComponentContext, 620*cdf0e10cSrcweir cmdPackages.size() > 0 ? cmdPackages[0] : OUString() )); 621*cdf0e10cSrcweir 622*cdf0e10cSrcweir osl::Condition dialogEnded; 623*cdf0e10cSrcweir dialogEnded.reset(); 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir Reference< ui::dialogs::XDialogClosedListener > xListener( 626*cdf0e10cSrcweir new DialogClosedListenerImpl( dialogEnded ) ); 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir xDialog->startExecuteModal(xListener); 629*cdf0e10cSrcweir dialogEnded.wait(); 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("sync"))) 632*cdf0e10cSrcweir { 633*cdf0e10cSrcweir if (! dp_misc::office_is_running()) 634*cdf0e10cSrcweir { 635*cdf0e10cSrcweir xExtensionManager->synchronizeBundledPrereg( 636*cdf0e10cSrcweir Reference<task::XAbortChannel>(), xCmdEnv); 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir else 639*cdf0e10cSrcweir { 640*cdf0e10cSrcweir dp_misc::writeConsoleError(OUSTR("\nError: office is running")); 641*cdf0e10cSrcweir } 642*cdf0e10cSrcweir } 643*cdf0e10cSrcweir else 644*cdf0e10cSrcweir { 645*cdf0e10cSrcweir dp_misc::writeConsoleError( 646*cdf0e10cSrcweir OUSTR("\nERROR: unknown sub-command ") + 647*cdf0e10cSrcweir subCommand + 648*cdf0e10cSrcweir OUSTR("!\n") + 649*cdf0e10cSrcweir OUSTR(" Use " APP_NAME " ") + 650*cdf0e10cSrcweir toString(info_help) + 651*cdf0e10cSrcweir OUSTR(" to print all options.\n")); 652*cdf0e10cSrcweir return 1; 653*cdf0e10cSrcweir } 654*cdf0e10cSrcweir 655*cdf0e10cSrcweir if (option_verbose) 656*cdf0e10cSrcweir dp_misc::writeConsole(OUSTR("\n"APP_NAME" done.\n")); 657*cdf0e10cSrcweir //Force to release all bridges which connect us to the child processes 658*cdf0e10cSrcweir disposeBridges(xLocalComponentContext); 659*cdf0e10cSrcweir return 0; 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir catch (ucb::CommandFailedException &e) 662*cdf0e10cSrcweir { 663*cdf0e10cSrcweir dp_misc::writeConsoleError(e.Message + OUSTR("\n")); 664*cdf0e10cSrcweir bNoOtherErrorMsg = true; 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir catch (ucb::CommandAbortedException &) 667*cdf0e10cSrcweir { 668*cdf0e10cSrcweir dp_misc::writeConsoleError("\n"APP_NAME" aborted!\n"); 669*cdf0e10cSrcweir } 670*cdf0e10cSrcweir catch (deployment::DeploymentException & exc) 671*cdf0e10cSrcweir { 672*cdf0e10cSrcweir OUString cause; 673*cdf0e10cSrcweir if (option_verbose) 674*cdf0e10cSrcweir { 675*cdf0e10cSrcweir cause = ::comphelper::anyToString(exc.Cause); 676*cdf0e10cSrcweir } 677*cdf0e10cSrcweir else 678*cdf0e10cSrcweir { 679*cdf0e10cSrcweir css::uno::Exception e; 680*cdf0e10cSrcweir if (exc.Cause >>= e) 681*cdf0e10cSrcweir cause = e.Message; 682*cdf0e10cSrcweir } 683*cdf0e10cSrcweir 684*cdf0e10cSrcweir dp_misc::writeConsoleError( 685*cdf0e10cSrcweir OUSTR("\nERROR: ") + exc.Message + OUSTR("\n")); 686*cdf0e10cSrcweir if (cause.getLength()) 687*cdf0e10cSrcweir dp_misc::writeConsoleError( 688*cdf0e10cSrcweir OUSTR(" Cause: ") + cause + OUSTR("\n")); 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir catch (LockFileException & e) 691*cdf0e10cSrcweir { 692*cdf0e10cSrcweir if (!subcmd_gui) 693*cdf0e10cSrcweir dp_misc::writeConsoleError(e.Message); 694*cdf0e10cSrcweir bNoOtherErrorMsg = true; 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir catch (::com::sun::star::uno::Exception & e ) { 697*cdf0e10cSrcweir Any exc( ::cppu::getCaughtException() ); 698*cdf0e10cSrcweir 699*cdf0e10cSrcweir dp_misc::writeConsoleError( 700*cdf0e10cSrcweir OUSTR("\nERROR: ") + 701*cdf0e10cSrcweir OUString(option_verbose ? e.Message + OUSTR("\nException details: \n") + 702*cdf0e10cSrcweir ::comphelper::anyToString(exc) : e.Message) + 703*cdf0e10cSrcweir OUSTR("\n")); 704*cdf0e10cSrcweir } 705*cdf0e10cSrcweir if (!bNoOtherErrorMsg) 706*cdf0e10cSrcweir dp_misc::writeConsoleError("\n"APP_NAME" failed.\n"); 707*cdf0e10cSrcweir disposeBridges(xLocalComponentContext); 708*cdf0e10cSrcweir return 1; 709*cdf0e10cSrcweir } 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir 712