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