summaryrefslogtreecommitdiff
path: root/desktop/source/pkgchk
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source/pkgchk')
-rw-r--r--desktop/source/pkgchk/unopkg/makefile.mk106
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_app.cxx512
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx445
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_main.c39
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_main.h46
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_misc.cxx509
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_shared.h186
-rw-r--r--desktop/source/pkgchk/unopkg/version.map38
8 files changed, 1881 insertions, 0 deletions
diff --git a/desktop/source/pkgchk/unopkg/makefile.mk b/desktop/source/pkgchk/unopkg/makefile.mk
new file mode 100644
index 000000000000..3562fad961d9
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/makefile.mk
@@ -0,0 +1,106 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.17 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = unopkg
+.IF "$(GUI)" == "OS2"
+TARGETTYPE = CUI
+.ELSE
+TARGETTYPE = GUI
+.ENDIF
+ENABLE_EXCEPTIONS = TRUE
+LIBTARGET=NO
+
+PRJINC += ..$/..$/deployment ..$/..
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+APP1TARGET = so$/unopkg
+APP1OBJS = $(OBJFILES)
+APP1STDLIBS = $(SALLIB) $(UNOPKGAPPLIB)
+APP1DEPN = $(SHL1TARGETN)
+APP1NOSAL = TRUE
+APP1RPATH = BRAND
+.IF "$(OS)" == "WNT"
+APP1ICON = $(SOLARRESDIR)$/icons/so9_main_app.ico
+APP1LINKRES = $(MISC)$/$(TARGET)1.res
+.ENDIF
+
+APP2TARGET = unopkg
+APP2OBJS = $(OBJFILES)
+APP2STDLIBS = $(SALLIB) $(UNOPKGAPPLIB)
+APP2DEPN = $(SHL1TARGETN)
+APP2NOSAL = TRUE
+APP2RPATH = BRAND
+.IF "$(OS)" == "WNT"
+APP2ICON = $(SOLARRESDIR)$/icons/ooo3_main_app.ico
+APP2LINKRES = $(MISC)$/$(TARGET)2.res
+.ENDIF
+
+SHL1TARGET = unopkgapp
+SHL1OBJS = $(SLOFILES) $(SLO)$/lockfile.obj
+SHL1STDLIBS = \
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(VCLLIB) \
+ $(DEPLOYMENTMISCLIB)
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = \
+ $(SLO)$/unopkg_app.obj \
+ $(SLO)$/unopkg_cmdenv.obj \
+ $(SLO)$/unopkg_misc.obj
+
+OBJFILES = $(OBJ)$/unopkg_main.obj
+
+.INCLUDE : target.mk
+
+.IF "$(APP1TARGETN)" != "" # not set during depend=x
+$(APP1TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP1TARGETN)"!=""
+
+$(MISC)$/binso_created.flg:
+ @@-$(MKDIRHIER) $(BIN)$/so && $(TOUCH) $@
+ @@-$(MKDIRHIER) $(MISC)$/so && $(TOUCH) $@
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
new file mode 100644
index 000000000000..5fc4136a9501
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
@@ -0,0 +1,512 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unopkg_app.cxx,v $
+ * $Revision: 1.14.58.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "dp_misc.h"
+#include "unopkg_main.h"
+#include "unopkg_shared.h"
+#include "dp_identifier.hxx"
+#include "sal/main.h"
+#include "tools/extendapplicationenvironment.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "osl/thread.h"
+#include "osl/process.h"
+#include "osl/conditn.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/anytostring.hxx"
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+#include "com/sun/star/deployment/ui/PackageManagerDialog.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "boost/scoped_array.hpp"
+#include "com/sun/star/ui/dialogs/XDialogClosedListener.hpp"
+#include "com/sun/star/bridge/XBridgeFactory.hpp"
+#include <stdio.h>
+#include <vector>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::unopkg;
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+namespace {
+
+//------------------------------------------------------------------------------
+const char s_usingText [] =
+"\n"
+"using: " APP_NAME " add <options> extension-path...\n"
+" " APP_NAME " remove <options> extension-identifier...\n"
+" " APP_NAME " list <options> extension-identifier...\n"
+" " APP_NAME " reinstall <options>\n"
+" " APP_NAME " gui\n"
+" " APP_NAME " -V\n"
+" " APP_NAME " -h\n"
+"\n"
+"sub-commands:\n"
+" add add extension\n"
+" remove remove extensions by identifier\n"
+" reinstall expert feature: reinstall all deployed extensions\n"
+" list list information about deployed extensions\n"
+" gui raise Extension Manager Graphical User Interface (GUI)\n"
+"\n"
+"options:\n"
+" -h, --help this help\n"
+" -V, --version version information\n"
+" -v, --verbose verbose output to stdout\n"
+" -f, --force force overwriting existing extensions\n"
+" --log-file <file> custom log file; default: <cache-dir>/log.txt\n"
+" --shared expert feature: operate on shared installation\n"
+" deployment context;\n"
+" run only when no concurrent Office\n"
+" process(es) are running!\n"
+" --deployment-context expert feature: explicit deployment context\n"
+" <context>\n"
+"\n"
+"To learn more about the Extension Manager and extensions, see:\n"
+"http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Extensions/Extensions\n\n";
+
+//------------------------------------------------------------------------------
+const OptionInfo s_option_infos [] = {
+ { RTL_CONSTASCII_STRINGPARAM("help"), 'h', false },
+ { RTL_CONSTASCII_STRINGPARAM("version"), 'V', false },
+ { RTL_CONSTASCII_STRINGPARAM("verbose"), 'v', false },
+ { RTL_CONSTASCII_STRINGPARAM("force"), 'f', false },
+ { RTL_CONSTASCII_STRINGPARAM("log-file"), '\0', true },
+ { RTL_CONSTASCII_STRINGPARAM("shared"), '\0', false },
+ { RTL_CONSTASCII_STRINGPARAM("deployment-context"), '\0', true },
+ { RTL_CONSTASCII_STRINGPARAM("bundled"), '\0', false},
+
+ { 0, 0, '\0', false }
+};
+
+class DialogClosedListenerImpl :
+ public ::cppu::WeakImplHelper1< ui::dialogs::XDialogClosedListener >
+{
+ osl::Condition & m_rDialogClosedCondition;
+
+public:
+ DialogClosedListenerImpl( osl::Condition & rDialogClosedCondition )
+ : m_rDialogClosedCondition( rDialogClosedCondition ) {}
+
+ // XEventListener (base of XDialogClosedListener)
+ virtual void SAL_CALL disposing( lang::EventObject const & Source )
+ throw (RuntimeException);
+
+ // XDialogClosedListener
+ virtual void SAL_CALL dialogClosed(
+ ui::dialogs::DialogClosedEvent const & aEvent )
+ throw (RuntimeException);
+};
+
+// XEventListener (base of XDialogClosedListener)
+void DialogClosedListenerImpl::disposing( lang::EventObject const & )
+ throw (RuntimeException)
+{
+ // nothing to do
+}
+
+// XDialogClosedListener
+void DialogClosedListenerImpl::dialogClosed(
+ ui::dialogs::DialogClosedEvent const & )
+ throw (RuntimeException)
+{
+ m_rDialogClosedCondition.set();
+}
+
+// If a package had been installed with a pre OOo 2.2, it could not normally be
+// found via its identifier; similarly (and for ease of use), a package
+// installed with OOo 2.2 or later could not normally be found via its file
+// name.
+Reference<deployment::XPackage> findPackage(
+ Reference<deployment::XPackageManager> const & manager,
+ Reference<ucb::XCommandEnvironment > const & environment,
+ OUString const & idOrFileName )
+{
+ Sequence< Reference<deployment::XPackage> > ps(
+ manager->getDeployedPackages(
+ Reference<task::XAbortChannel>(), environment ) );
+ for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
+ if ( dp_misc::getIdentifier( ps[i] ) == idOrFileName )
+ return ps[i];
+ for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
+ if ( ps[i]->getName() == idOrFileName )
+ return ps[i];
+ return Reference<deployment::XPackage>();
+}
+
+} // anon namespace
+
+
+//workaround for some reason the bridge threads which communicate with the uno.exe
+//process are not releases on time
+void disposeBridges(Reference<css::uno::XComponentContext> ctx)
+{
+ if (!ctx.is())
+ return;
+
+ Reference<css::bridge::XBridgeFactory> bridgeFac(
+ ctx->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.bridge.BridgeFactory"), ctx),
+ UNO_QUERY);
+
+ if (bridgeFac.is())
+ {
+ const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges();
+ for (sal_Int32 i = 0; i < seqBridges.getLength(); i++)
+ {
+ Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY);
+ if (comp.is())
+ {
+ try {
+ comp->dispose();
+ }
+ catch (css::lang::DisposedException& )
+ {
+ }
+ }
+ }
+ }
+}
+
+//##############################################################################
+extern "C" int unopkg_main()
+{
+ tools::extendApplicationEnvironment();
+ DisposeGuard disposeGuard;
+ bool bNoOtherErrorMsg = false;
+ OUString subCommand;
+ bool option_shared = false;
+ bool option_force = false;
+ bool option_verbose = false;
+ bool option_bundled = false;
+ bool subcmd_add = false;
+ bool subcmd_gui = false;
+ OUString logFile;
+ OUString deploymentContext;
+ OUString cmdArg;
+ ::std::vector<OUString> cmdPackages;
+
+ OptionInfo const * info_shared = getOptionInfo(
+ s_option_infos, OUSTR("shared") );
+ OptionInfo const * info_force = getOptionInfo(
+ s_option_infos, OUSTR("force") );
+ OptionInfo const * info_verbose = getOptionInfo(
+ s_option_infos, OUSTR("verbose") );
+ OptionInfo const * info_log = getOptionInfo(
+ s_option_infos, OUSTR("log-file") );
+ OptionInfo const * info_context = getOptionInfo(
+ s_option_infos, OUSTR("deployment-context") );
+ OptionInfo const * info_help = getOptionInfo(
+ s_option_infos, OUSTR("help") );
+ OptionInfo const * info_version = getOptionInfo(
+ s_option_infos, OUSTR("version") );
+ OptionInfo const * info_bundled = getOptionInfo(
+ s_option_infos, OUSTR("bundled") );
+
+ Reference<XComponentContext> xComponentContext;
+ Reference<XComponentContext> xLocalComponentContext;
+
+ try {
+ sal_uInt32 nPos = 0;
+ sal_uInt32 nCount = osl_getCommandArgCount();
+ if (nCount == 0 || isOption( info_help, &nPos ))
+ {
+ dp_misc::writeConsole(s_usingText);
+ return 0;
+ }
+ else if (isOption( info_version, &nPos )) {
+ dp_misc::writeConsole("\n"APP_NAME" Version 3.0\n");
+ return 0;
+ }
+ //consume all bootstrap variables which may occur before the subcommannd
+ while(isBootstrapVariable(&nPos));
+
+ if(nPos >= nCount)
+ return 0;
+ //get the sub command
+ osl_getCommandArg( nPos, &subCommand.pData );
+ ++nPos;
+ subCommand = subCommand.trim();
+ subcmd_add = subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("add") );
+ subcmd_gui = subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("gui") );
+
+ // sun-command options and packages:
+ while (nPos < nCount)
+ {
+ if (readArgument( &cmdArg, info_log, &nPos )) {
+ logFile = makeAbsoluteFileUrl(
+ cmdArg.trim(), getProcessWorkingDir() );
+ }
+ else if (!readOption( &option_verbose, info_verbose, &nPos ) &&
+ !readOption( &option_shared, info_shared, &nPos ) &&
+ !readOption( &option_force, info_force, &nPos ) &&
+ !readOption( &option_bundled, info_bundled, &nPos ) &&
+ !readArgument( &deploymentContext, info_context, &nPos ) &&
+ !isBootstrapVariable(&nPos))
+ {
+ osl_getCommandArg( nPos, &cmdArg.pData );
+ ++nPos;
+ cmdArg = cmdArg.trim();
+ if (cmdArg.getLength() > 0)
+ {
+ if (cmdArg[ 0 ] == '-')
+ {
+ // is option:
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: unexpected option ") +
+ cmdArg +
+ OUSTR("!\n") +
+ OUSTR(" Use " APP_NAME " ") +
+ toString(info_help) +
+ OUSTR(" to print all options.\n"));
+ return 1;
+ }
+ else
+ {
+ // is package:
+ cmdPackages.push_back(
+ subcmd_add || subcmd_gui
+ ? makeAbsoluteFileUrl(
+ cmdArg, getProcessWorkingDir() )
+ : cmdArg );
+ }
+ }
+ }
+ }
+
+ //make sure the bundled option was provided together with shared
+ if (option_bundled && !option_shared)
+ {
+ dp_misc::writeConsoleError(
+ "\nERROR: option --bundled can only be used together with --shared!");
+ return 1;
+ }
+
+
+ xComponentContext = getUNO(
+ disposeGuard, option_verbose, option_shared, subcmd_gui,
+ xLocalComponentContext );
+
+ if (deploymentContext.getLength() == 0) {
+ deploymentContext = option_shared ? OUSTR("shared") : OUSTR("user");
+ }
+ else
+ {
+ if (deploymentContext.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("shared") )) {
+ option_shared = true;
+ }
+ else if (option_shared) {
+ dp_misc::writeConsoleError(
+ OUSTR("WARNING: explicit context given! ") +
+ OUSTR("Ignoring option ") +
+ toString( info_shared ) +
+ OUSTR("!\n") );
+ }
+ }
+
+ Reference<deployment::XPackageManagerFactory> xPackageManagerFactory(
+ deployment::thePackageManagerFactory::get( xComponentContext ) );
+ Reference<deployment::XPackageManager> xPackageManager(
+ xPackageManagerFactory->getPackageManager( deploymentContext ) );
+
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv(
+ createCmdEnv( xComponentContext, logFile,
+ option_force, option_verbose, option_bundled) );
+
+ if (subcmd_add ||
+ subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("remove") ))
+ {
+ for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
+ {
+ OUString const & cmdPackage = cmdPackages[ pos ];
+ if (subcmd_add)
+ {
+ Reference<deployment::XPackage> xPackage(
+ xPackageManager->addPackage(
+ cmdPackage, OUString() /* to be detected */,
+ Reference<task::XAbortChannel>(), xCmdEnv ) );
+ OSL_ASSERT( xPackage.is() );
+ }
+ else
+ {
+ try
+ {
+ xPackageManager->removePackage(
+ cmdPackage, cmdPackage,
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ Reference<deployment::XPackage> p(
+ findPackage(
+ xPackageManager, xCmdEnv, cmdPackage ) );
+ //Todo. temporary preventing exception in bundled case.
+ //In case of a bundled extension, remove would be called as a result of
+ //uninstalling a rpm. Then we do not want to show an error when the
+ //extension does not exist, because the package will be uninstalled anyway
+ //and the error would only confuse people.
+ if ( !p.is() && !option_bundled)
+ throw;
+ else if (p.is())
+ xPackageManager->removePackage(
+ ::dp_misc::getIdentifier(p), p->getName(),
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ }
+ }
+ }
+ else if (subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("reinstall") ))
+ {
+ xPackageManager->reinstallDeployedPackages(
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("list") ))
+ {
+ Sequence< Reference<deployment::XPackage> > packages;
+ if (cmdPackages.empty())
+ {
+ packages = xPackageManager->getDeployedPackages(
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ dp_misc::writeConsole(
+ OUSTR("all deployed ") + deploymentContext + OUSTR(" packages:\n"));
+ }
+ else
+ {
+ packages.realloc( cmdPackages.size() );
+ for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
+ try
+ {
+ packages[ pos ] = xPackageManager->getDeployedPackage(
+ cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ packages[ pos ] = findPackage(
+ xPackageManager, xCmdEnv, cmdPackages[ pos ] );
+ if ( !packages[ pos ].is() )
+ throw;
+ }
+ }
+ printf_packages( packages, xCmdEnv );
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gui") ))
+ {
+ Reference<ui::dialogs::XAsynchronousExecutableDialog> xDialog(
+ deployment::ui::PackageManagerDialog::createAndInstall(
+ xComponentContext,
+ cmdPackages.size() > 0 ? cmdPackages[0] : OUString() ));
+
+ osl::Condition dialogEnded;
+ dialogEnded.reset();
+
+ Reference< ui::dialogs::XDialogClosedListener > xListener(
+ new DialogClosedListenerImpl( dialogEnded ) );
+
+ xDialog->startExecuteModal(xListener);
+ dialogEnded.wait();
+ }
+ else
+ {
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: unknown sub-command ") +
+ subCommand +
+ OUSTR("!\n") +
+ OUSTR(" Use " APP_NAME " ") +
+ toString(info_help) +
+ OUSTR(" to print all options.\n"));
+ return 1;
+ }
+
+ if (option_verbose)
+ dp_misc::writeConsole(OUSTR("\n"APP_NAME" done.\n"));
+ //Force to release all bridges which connect us to the child processes
+ disposeBridges(xLocalComponentContext);
+ return 0;
+ }
+ catch (ucb::CommandFailedException &e)
+ {
+ dp_misc::writeConsoleError(e.Message + OUSTR("\n"));
+ bNoOtherErrorMsg = true;
+ }
+ catch (ucb::CommandAbortedException &)
+ {
+ dp_misc::writeConsoleError("\n"APP_NAME" aborted!\n");
+ }
+ catch (deployment::DeploymentException & exc)
+ {
+ OUString cause;
+ if (option_verbose)
+ {
+ cause = ::comphelper::anyToString(exc.Cause);
+ }
+ else
+ {
+ css::uno::Exception e;
+ if (exc.Cause >>= e)
+ cause = e.Message;
+ }
+
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") + exc.Message + OUSTR("\n"));
+ if (cause.getLength())
+ dp_misc::writeConsoleError(
+ OUSTR(" Cause: ") + cause + OUSTR("\n"));
+ }
+ catch (LockFileException & e)
+ {
+ if (!subcmd_gui)
+ dp_misc::writeConsoleError(e.Message);
+ bNoOtherErrorMsg = true;
+ }
+ catch (::com::sun::star::uno::Exception & e ) {
+ Any exc( ::cppu::getCaughtException() );
+
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") +
+ OUString(option_verbose ? e.Message + OUSTR("\nException details: \n") +
+ ::comphelper::anyToString(exc) : e.Message) +
+ OUSTR("\n"));
+ }
+ if (!bNoOtherErrorMsg)
+ dp_misc::writeConsoleError("\n"APP_NAME" failed.\n");
+ disposeBridges(xLocalComponentContext);
+ return 1;
+}
+
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
new file mode 100644
index 000000000000..ea0659c63874
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
@@ -0,0 +1,445 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unopkg_cmdenv.cxx,v $
+ * $Revision: 1.12.8.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "../../deployment/gui/dp_gui.hrc"
+#include "../../deployment/gui/dp_gui_shared.hxx"
+#include "unopkg_shared.h"
+#include "osl/thread.h"
+#include "rtl/memory.h"
+#include "tools/string.hxx"
+#include "tools/resmgr.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/anytostring.hxx"
+#include "unotools/configmgr.hxx"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/container/ElementExistException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
+#include "com/sun/star/i18n/XCollator.hpp"
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+#include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp"
+#include <stdio.h>
+#include "deployment.hrc"
+#include "dp_version.hxx"
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::unopkg;
+using ::rtl::OUString;
+
+
+namespace {
+
+//==============================================================================
+struct OfficeLocale :
+ public rtl::StaticWithInit<const lang::Locale, OfficeLocale> {
+ const lang::Locale operator () () {
+ OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw RuntimeException( OUSTR("Cannot determine language!"), 0 );
+ return toLocale(slang);
+ }
+};
+
+//==============================================================================
+class CommandEnvironmentImpl
+ : public ::cppu::WeakImplHelper3< XCommandEnvironment,
+ task::XInteractionHandler,
+ XProgressHandler >
+{
+ sal_Int32 m_logLevel;
+ bool m_option_force_overwrite;
+ bool m_option_verbose;
+ bool m_option_bundled;
+ Reference< XComponentContext > m_xComponentContext;
+ Reference< XProgressHandler > m_xLogFile;
+
+ void update_( Any const & Status ) throw (RuntimeException);
+ void printLicense(const OUString& sLicense, bool & accept, bool & decline);
+
+public:
+ virtual ~CommandEnvironmentImpl();
+ CommandEnvironmentImpl(
+ Reference<XComponentContext> const & xComponentContext,
+ OUString const & log_file,
+ bool option_force_overwrite,
+ bool option_verbose,
+ bool option_bundled);
+
+ // XCommandEnvironment
+ virtual Reference< task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (RuntimeException);
+ virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
+ throw (RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ Reference< task::XInteractionRequest > const & xRequest )
+ throw (RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException);
+ virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException);
+ virtual void SAL_CALL pop() throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+CommandEnvironmentImpl::CommandEnvironmentImpl(
+ Reference<XComponentContext> const & xComponentContext,
+ OUString const & log_file,
+ bool option_force_overwrite,
+ bool option_verbose,
+ bool option_bundled)
+ : m_logLevel(0),
+ m_option_force_overwrite( option_force_overwrite ),
+ m_option_verbose( option_verbose ),
+ m_option_bundled( option_bundled),
+ m_xComponentContext(xComponentContext)
+{
+ if (log_file.getLength() > 0) {
+ const Any logfile(log_file);
+ m_xLogFile.set(
+ xComponentContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.comp.deployment.ProgressLog"),
+ Sequence<Any>( &logfile, 1 ), xComponentContext ),
+ UNO_QUERY_THROW );
+ }
+}
+
+//______________________________________________________________________________
+CommandEnvironmentImpl::~CommandEnvironmentImpl()
+{
+ try {
+ Reference< lang::XComponent > xComp( m_xLogFile, UNO_QUERY );
+ if (xComp.is())
+ xComp->dispose();
+ }
+ catch (RuntimeException & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, osl_getThreadTextEncoding() ).getStr() );
+ }
+}
+
+//May throw exceptions
+void CommandEnvironmentImpl::printLicense(const OUString& sLicense, bool & accept, bool &decline)
+{
+ ResMgr * pResMgr = DeploymentResMgr::get();
+ OUString s1 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_1, *pResMgr));
+ OUString s2 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_2, *pResMgr));
+ OUString s3 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_3, *pResMgr));
+ OUString s4 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_4, *pResMgr));
+ OUString sYES = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_YES, *pResMgr));
+ OUString sY = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_Y, *pResMgr));
+ OUString sNO = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_NO, *pResMgr));
+ OUString sN = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_N, *pResMgr));
+
+ OUString sNewLine(RTL_CONSTASCII_USTRINGPARAM("\n"));
+
+ dp_misc::writeConsole(sNewLine + sNewLine + s1 + sNewLine + sNewLine);
+ dp_misc::writeConsole(sLicense + sNewLine + sNewLine);
+ dp_misc::writeConsole(s2 + sNewLine);
+ dp_misc::writeConsole(s3);
+
+ //the user may enter "yes" or "no", we compare in a case insensitive way
+ Reference< css::i18n::XCollator > xCollator(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.i18n.Collator"),m_xComponentContext),
+ UNO_QUERY_THROW );
+ xCollator->loadDefaultCollator(OfficeLocale::get(),
+ css::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE);
+
+ do
+ {
+ OUString sAnswer = dp_misc::readConsole();
+ if (xCollator->compareString(sAnswer, sYES) == 0
+ || xCollator->compareString(sAnswer, sY) == 0)
+ {
+ accept = true;
+ break;
+ }
+ else if(xCollator->compareString(sAnswer, sNO) == 0
+ || xCollator->compareString(sAnswer, sN) == 0)
+ {
+ decline = true;
+ break;
+ }
+ else
+ {
+ dp_misc::writeConsole(sNewLine + sNewLine + s4 + sNewLine);
+ }
+ }
+ while(true);
+}
+
+// XCommandEnvironment
+//______________________________________________________________________________
+Reference< task::XInteractionHandler >
+CommandEnvironmentImpl::getInteractionHandler() throw (RuntimeException)
+{
+ return this;
+}
+
+//______________________________________________________________________________
+Reference< XProgressHandler > CommandEnvironmentImpl::getProgressHandler()
+ throw (RuntimeException)
+{
+ return this;
+}
+
+// XInteractionHandler
+//______________________________________________________________________________
+void CommandEnvironmentImpl::handle(
+ Reference<task::XInteractionRequest> const & xRequest )
+ throw (RuntimeException)
+{
+ Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == TypeClass_EXCEPTION );
+ dp_misc::TRACE(OUSTR("[unopkg_cmdenv.cxx] incoming request:\n")
+ + ::comphelper::anyToString(request) + OUSTR("\n\n"));
+
+ // selections:
+ bool approve = false;
+ bool abort = false;
+
+ lang::WrappedTargetException wtExc;
+ deployment::LicenseException licExc;
+ deployment::InstallException instExc;
+ deployment::LicenseIndividualAgreementException licAgreementExc;
+ deployment::PlatformException platExc;
+ deployment::VersionException verExc;
+
+
+ bool bLicenseException = false;
+ if (request >>= wtExc) {
+ // ignore intermediate errors of legacy packages, i.e.
+ // former pkgchk behaviour:
+ const Reference<deployment::XPackage> xPackage(
+ wtExc.Context, UNO_QUERY );
+ OSL_ASSERT( xPackage.is() );
+ if (xPackage.is()) {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is()) {
+ approve = (xPackage->isBundle() &&
+ xPackageType->getMediaType().matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/"
+ "vnd.sun.star.legacy-package-bundle") ));
+ }
+ }
+ abort = !approve;
+ if (abort) {
+ // notify cause as error:
+ request = wtExc.TargetException;
+ }
+ else {
+ // handable deployment error signalled, e.g.
+ // bundle item registration failed, notify as warning:
+ update_( wtExc.TargetException );
+ }
+ }
+ else if (request >>= licAgreementExc)
+ {
+ String sResMsg( ResId( RID_STR_UNOPKG_NO_SHARED_ALLOWED, *DeploymentResMgr::get() ) );
+ sResMsg.SearchAndReplaceAllAscii( "%NAME", licAgreementExc.ExtensionName );
+ dp_misc::writeConsole(OUSTR("\n") + sResMsg + OUSTR("\n\n"));
+ abort = true;
+ }
+ else if (request >>= licExc)
+ {
+ bLicenseException = true;
+ printLicense(licExc.Text, approve, abort);
+ }
+ else if (request >>= instExc)
+ {
+ //Only if the unopgk was started with gui + extension then we user is asked.
+ //In console mode there is no asking.
+ approve = true;
+ }
+ else if (request >>= platExc)
+ {
+ String sMsg(ResId(RID_STR_UNSUPPORTED_PLATFORM, *dp_gui::DeploymentGuiResMgr::get()));
+ sMsg.SearchAndReplaceAllAscii("%Name", platExc.package->getDisplayName());
+ dp_misc::writeConsole(OUSTR("\n") + sMsg + OUSTR("\n\n"));
+ approve = true;
+ }
+ else {
+ deployment::VersionException nc_exc;
+ if (request >>= nc_exc) {
+ approve = m_option_force_overwrite ||
+ (::dp_misc::comparePackageVersions(nc_exc.New, nc_exc.Deployed)
+ == ::dp_misc::GREATER);
+ abort = !approve;
+ }
+ else
+ return; // unknown request => no selection at all
+ }
+
+ //In case of a user declining a license abort is true but this is intended,
+ //therefore no logging
+ if (abort && m_option_verbose && !bLicenseException)
+ {
+ OUString msg = ::comphelper::anyToString(request);
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") + msg + OUSTR("\n"));
+ }
+
+ // select:
+ Sequence< Reference<task::XInteractionContinuation> > conts(
+ xRequest->getContinuations() );
+ Reference<task::XInteractionContinuation> const * pConts =
+ conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ Reference<task::XInteractionApprove> xInteractionApprove(
+ pConts[ pos ], UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ break;
+ }
+ }
+ else if (abort) {
+ Reference<task::XInteractionAbort> xInteractionAbort(
+ pConts[ pos ], UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ break;
+ }
+ }
+ }
+}
+
+// XProgressHandler
+//______________________________________________________________________________
+void CommandEnvironmentImpl::push( Any const & Status )
+ throw (RuntimeException)
+{
+ update_( Status );
+ OSL_ASSERT( m_logLevel >= 0 );
+ ++m_logLevel;
+ if (m_xLogFile.is())
+ m_xLogFile->push( Status );
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::update_( Any const & Status )
+ throw (RuntimeException)
+{
+ if (! Status.hasValue())
+ return;
+ bool bUseErr = false;
+ OUString msg;
+ if (Status >>= msg) {
+ if (! m_option_verbose)
+ return;
+ }
+ else {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("WARNING: ") );
+ deployment::DeploymentException dp_exc;
+ if (Status >>= dp_exc) {
+ buf.append( dp_exc.Message );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", Cause: ") );
+ buf.append( ::comphelper::anyToString(dp_exc.Cause) );
+ }
+ else {
+ buf.append( ::comphelper::anyToString(Status) );
+ }
+ msg = buf.makeStringAndClear();
+ bUseErr = true;
+ }
+ OSL_ASSERT( m_logLevel >= 0 );
+ for ( sal_Int32 n = 0; n < m_logLevel; ++n )
+ {
+ if (bUseErr)
+ dp_misc::writeConsoleError(" ");
+ else
+ dp_misc::writeConsole(" ");
+ }
+
+ if (bUseErr)
+ dp_misc::writeConsoleError(msg + OUSTR("\n"));
+ else
+ dp_misc::writeConsole(msg + OUSTR("\n"));
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::update( Any const & Status )
+ throw (RuntimeException)
+{
+ update_( Status );
+ if (m_xLogFile.is())
+ m_xLogFile->update( Status );
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::pop() throw (RuntimeException)
+{
+ OSL_ASSERT( m_logLevel > 0 );
+ --m_logLevel;
+ if (m_xLogFile.is())
+ m_xLogFile->pop();
+}
+
+} // anon namespace
+
+namespace unopkg {
+
+//==============================================================================
+Reference< XCommandEnvironment > createCmdEnv(
+ Reference< XComponentContext > const & xContext,
+ OUString const & logFile,
+ bool option_force_overwrite,
+ bool option_verbose,
+ bool option_bundled)
+{
+ return new CommandEnvironmentImpl(
+ xContext, logFile, option_force_overwrite, option_verbose, option_bundled);
+}
+
+} // unopkg
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_main.c b/desktop/source/pkgchk/unopkg/unopkg_main.c
new file mode 100644
index 000000000000..5b715f7aeb59
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_main.c
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unopkg_main.c,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+
+#include "sal/main.h"
+
+#include "unopkg_main.h"
+
+SAL_IMPLEMENT_MAIN() {
+ return unopkg_main();
+}
diff --git a/desktop/source/pkgchk/unopkg/unopkg_main.h b/desktop/source/pkgchk/unopkg/unopkg_main.h
new file mode 100644
index 000000000000..78cb8ac5a3f7
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_main.h
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unopkg_main.h,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_PKGCHK_UNOPKG_UNOPKG_MAIN_H
+#define INCLUDED_DESKTOP_SOURCE_PKGCHK_UNOPKG_UNOPKG_MAIN_H
+
+#include "sal/config.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+int unopkg_main(void);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
new file mode 100644
index 000000000000..70b469fa58fa
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
@@ -0,0 +1,509 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unopkg_misc.cxx,v $
+ * $Revision: 1.15.52.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "deployment.hrc"
+#include "unopkg_shared.h"
+#include "dp_identifier.hxx"
+#include "../../deployment/gui/dp_gui.hrc"
+#include "../../app/lockfile.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+#include "rtl/bootstrap.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "osl/process.h"
+#include "osl/file.hxx"
+#include "osl/thread.hxx"
+#include "tools/getprocessworkingdir.hxx"
+#include "ucbhelper/contentbroker.hxx"
+#include "ucbhelper/configurationkeys.hxx"
+#include "unotools/processfactory.hxx"
+#include "unotools/configmgr.hxx"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "cppuhelper/bootstrap.hxx"
+#include <stdio.h>
+
+using ::rtl::OUString;
+using ::rtl::OString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+
+namespace unopkg {
+
+bool getLockFilePath(OUString & out);
+
+::rtl::OUString toString( OptionInfo const * info )
+{
+ OSL_ASSERT( info != 0 );
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii("--");
+ buf.appendAscii(info->m_name);
+ if (info->m_short_option != '\0')
+ {
+ buf.appendAscii(" (short -" );
+ buf.append(info->m_short_option );
+ buf.appendAscii(")");
+ }
+ if (info->m_has_argument)
+ buf.appendAscii(" <argument>" );
+ return buf.makeStringAndClear();
+}
+
+//==============================================================================
+OptionInfo const * getOptionInfo(
+ OptionInfo const * list,
+ OUString const & opt, sal_Unicode copt )
+{
+ for ( ; list->m_name != 0; ++list )
+ {
+ OptionInfo const & option_info = *list;
+ if (opt.getLength() > 0)
+ {
+ if (opt.equalsAsciiL(
+ option_info.m_name, option_info.m_name_length ) &&
+ (copt == '\0' || copt == option_info.m_short_option))
+ {
+ return &option_info;
+ }
+ }
+ else
+ {
+ OSL_ASSERT( copt != '\0' );
+ if (copt == option_info.m_short_option)
+ {
+ return &option_info;
+ }
+ }
+ }
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ opt, osl_getThreadTextEncoding() ).getStr() );
+ return 0;
+}
+
+//==============================================================================
+bool isOption( OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ OSL_ASSERT( option_info != 0 );
+ if (osl_getCommandArgCount() <= *pIndex)
+ return false;
+
+ OUString arg;
+ osl_getCommandArg( *pIndex, &arg.pData );
+ sal_Int32 len = arg.getLength();
+
+ if (len < 2 || arg[ 0 ] != '-')
+ return false;
+
+ if (len == 2 && arg[ 1 ] == option_info->m_short_option)
+ {
+ ++(*pIndex);
+ dp_misc::TRACE(OUSTR(__FILE__": identified option \'")
+ + OUSTR("\'") + OUString( option_info->m_short_option ) + OUSTR("\n"));
+ return true;
+ }
+ if (arg[ 1 ] == '-' && rtl_ustr_ascii_compare(
+ arg.pData->buffer + 2, option_info->m_name ) == 0)
+ {
+ ++(*pIndex);
+ dp_misc::TRACE(OUSTR( __FILE__": identified option \'")
+ + OUString::createFromAscii(option_info->m_name) + OUSTR("\'\n"));
+ return true;
+ }
+ return false;
+}
+//==============================================================================
+
+bool isBootstrapVariable(sal_uInt32 * pIndex)
+{
+ OSL_ASSERT(osl_getCommandArgCount() >= *pIndex);
+
+ OUString arg;
+ osl_getCommandArg(*pIndex, &arg.pData);
+ if (arg.matchAsciiL("-env:", 5))
+ {
+ ++(*pIndex);
+ return true;
+ }
+ return false;
+}
+
+//==============================================================================
+bool readArgument(
+ OUString * pValue, OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ if (isOption( option_info, pIndex ))
+ {
+ if (*pIndex < osl_getCommandArgCount())
+ {
+ OSL_ASSERT( pValue != 0 );
+ osl_getCommandArg( *pIndex, &pValue->pData );
+ dp_misc::TRACE(OUSTR( __FILE__": argument value: ")
+ + *pValue + OUSTR("\n"));
+ ++(*pIndex);
+ return true;
+ }
+ --(*pIndex);
+ }
+ return false;
+}
+
+//##############################################################################
+
+namespace {
+struct ExecutableDir : public rtl::StaticWithInit<
+ const OUString, ExecutableDir> {
+ const OUString operator () () {
+ OUString path;
+ if (osl_getExecutableFile( &path.pData ) != osl_Process_E_None) {
+ throw RuntimeException(
+ OUSTR("cannot locate executable directory!"),0 );
+ }
+ return path.copy( 0, path.lastIndexOf( '/' ) );
+ }
+};
+struct ProcessWorkingDir : public rtl::StaticWithInit<
+ const OUString, ProcessWorkingDir> {
+ const OUString operator () () {
+ OUString workingDir;
+ tools::getProcessWorkingDir(&workingDir);
+ return workingDir;
+ }
+};
+} // anon namespace
+
+//==============================================================================
+OUString const & getExecutableDir()
+{
+ return ExecutableDir::get();
+}
+
+//==============================================================================
+OUString const & getProcessWorkingDir()
+{
+ return ProcessWorkingDir::get();
+}
+
+//==============================================================================
+OUString makeAbsoluteFileUrl(
+ OUString const & sys_path, OUString const & base_url, bool throw_exc )
+{
+ // system path to file url
+ OUString file_url;
+ oslFileError rc = osl_getFileURLFromSystemPath( sys_path.pData, &file_url.pData );
+ if ( rc != osl_File_E_None) {
+ OUString tempPath;
+ if ( osl_getSystemPathFromFileURL( sys_path.pData, &tempPath.pData) == osl_File_E_None )
+ {
+ file_url = sys_path;
+ }
+ else if (throw_exc)
+ {
+ throw RuntimeException(
+ OUSTR("cannot get file url from system path: ") +
+ sys_path, Reference< XInterface >() );
+ }
+ }
+
+ OUString abs;
+ if (osl_getAbsoluteFileURL(
+ base_url.pData, file_url.pData, &abs.pData ) != osl_File_E_None)
+ {
+ if (throw_exc) {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "making absolute file url failed: \"") );
+ buf.append( base_url );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\" (base-url) and \"") );
+ buf.append( file_url );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" (file-url)!") );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+ return OUString();
+ }
+ return abs[ abs.getLength() -1 ] == '/'
+ ? abs.copy( 0, abs.getLength() -1 ) : abs;
+}
+
+//##############################################################################
+
+namespace {
+
+//------------------------------------------------------------------------------
+inline void printf_space( sal_Int32 space )
+{
+ while (space--)
+ dp_misc::writeConsole(" ");
+}
+
+//------------------------------------------------------------------------------
+void printf_line(
+ OUString const & name, OUString const & value, sal_Int32 level )
+{
+ printf_space( level );
+ dp_misc::writeConsole(name + OUSTR(": ") + value + OUSTR("\n"));
+}
+
+//------------------------------------------------------------------------------
+void printf_package(
+ Reference<deployment::XPackage> const & xPackage,
+ Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level )
+{
+ beans::Optional< OUString > id(
+ level == 0
+ ? beans::Optional< OUString >(
+ true, dp_misc::getIdentifier( xPackage ) )
+ : xPackage->getIdentifier() );
+ if (id.IsPresent)
+ printf_line( OUSTR("Identifier"), id.Value, level );
+ OUString version(xPackage->getVersion());
+ if (version.getLength() != 0)
+ printf_line( OUSTR("Version"), version, level + 1 );
+ printf_line( OUSTR("URL"), xPackage->getURL(), level + 1 );
+
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ xPackage->isRegistered( Reference<task::XAbortChannel>(), xCmdEnv ) );
+ OUString value;
+ if (option.IsPresent) {
+ beans::Ambiguous<sal_Bool> const & reg = option.Value;
+ if (reg.IsAmbiguous)
+ value = OUSTR("unknown");
+ else
+ value = reg.Value ? OUSTR("yes") : OUSTR("no");
+ }
+ else
+ value = OUSTR("n/a");
+ printf_line( OUSTR("is registered"), value, level + 1 );
+
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is()) {
+ printf_line( OUSTR("Media-Type"),
+ xPackageType->getMediaType(), level + 1 );
+ }
+ printf_line( OUSTR("Description"), xPackage->getDescription(), level + 1 );
+ if (xPackage->isBundle()) {
+ Sequence< Reference<deployment::XPackage> > seq(
+ xPackage->getBundle( Reference<task::XAbortChannel>(), xCmdEnv ) );
+ printf_space( level + 1 );
+ dp_misc::writeConsole("bundled Packages: {\n");
+ printf_packages( seq, xCmdEnv, level + 2 );
+ printf_space( level + 1 );
+ dp_misc::writeConsole("}\n");
+ }
+}
+
+} // anon namespace
+
+//==============================================================================
+void printf_packages(
+ Sequence< Reference<deployment::XPackage> > const & seq,
+ Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level )
+{
+ sal_Int32 len = seq.getLength();
+ Reference< deployment::XPackage > const * p = seq.getConstArray();
+ if (len == 0) {
+ printf_space( level );
+ dp_misc::writeConsole("<none>\n");
+ }
+ else {
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ printf_package( p[ pos ], xCmdEnv, level );
+ }
+}
+
+//##############################################################################
+
+namespace {
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> bootstrapStandAlone(
+ DisposeGuard & disposeGuard, bool /*verbose */)
+{
+ Reference<XComponentContext> xContext =
+ ::cppu::defaultBootstrap_InitialComponentContext();
+
+ // assure disposing of local component context:
+ disposeGuard.reset(
+ Reference<lang::XComponent>( xContext, UNO_QUERY ) );
+
+ Reference<lang::XMultiServiceFactory> xServiceManager(
+ xContext->getServiceManager(), UNO_QUERY_THROW );
+ // set global process service factory used by unotools config helpers
+ ::utl::setProcessServiceFactory( xServiceManager );
+
+ // initialize the ucbhelper ucb,
+ // because the package implementation uses it
+ Sequence<Any> ucb_args( 2 );
+ ucb_args[ 0 ] <<= OUSTR(UCB_CONFIGURATION_KEY1_LOCAL);
+ ucb_args[ 1 ] <<= OUSTR(UCB_CONFIGURATION_KEY2_OFFICE);
+ if (! ::ucbhelper::ContentBroker::initialize( xServiceManager, ucb_args ))
+ throw RuntimeException( OUSTR("cannot initialize UCB!"), 0 );
+
+ return xContext;
+}
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> connectToOffice(
+ Reference<XComponentContext> const & xLocalComponentContext,
+ bool verbose )
+{
+ Sequence<OUString> args( 3 );
+ args[ 0 ] = OUSTR("-nologo");
+ args[ 1 ] = OUSTR("-nodefault");
+
+ OUString pipeId( ::dp_misc::generateRandomPipeId() );
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("-accept=pipe,name=") );
+ buf.append( pipeId );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(";urp;") );
+ args[ 2 ] = buf.makeStringAndClear();
+ OUString appURL( getExecutableDir() + OUSTR("/soffice") );
+
+ if (verbose)
+ {
+ dp_misc::writeConsole(
+ OUSTR("Raising process: ") +
+ appURL +
+ OUSTR("\nArguments: -nologo -nodefault ") +
+ args[2] +
+ OUSTR("\n"));
+ }
+
+ ::dp_misc::raiseProcess( appURL, args );
+
+ if (verbose)
+ dp_misc::writeConsole("Ok. Connecting...");
+
+ OSL_ASSERT( buf.getLength() == 0 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") );
+ buf.append( pipeId );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ ";urp;StarOffice.ComponentContext") );
+ Reference<XComponentContext> xRet(
+ ::dp_misc::resolveUnoURL(
+ buf.makeStringAndClear(), xLocalComponentContext ),
+ UNO_QUERY_THROW );
+ if (verbose)
+ dp_misc::writeConsole("Ok.\n");
+
+ return xRet;
+}
+
+} // anon namespace
+
+/** returns the path to the lock file used by unopkg.
+ @return the path. An empty string signifies an error.
+*/
+OUString getLockFilePath()
+{
+ OUString ret;
+ OUString sBootstrap(RTL_CONSTASCII_USTRINGPARAM("${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}"));
+ rtl::Bootstrap::expandMacros(sBootstrap);
+ OUString sAbs;
+ if (::osl::File::E_None == ::osl::File::getAbsoluteFileURL(
+ sBootstrap, OUSTR(".lock"), sAbs))
+ {
+ if (::osl::File::E_None ==
+ ::osl::File::getSystemPathFromFileURL(sAbs, sBootstrap))
+ {
+ ret = sBootstrap;
+ }
+ }
+
+ return ret;
+}
+//==============================================================================
+Reference<XComponentContext> getUNO(
+ DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
+ Reference<XComponentContext> & out_localContext)
+{
+ // do not create any user data (for the root user) in --shared mode:
+ if (shared) {
+ rtl::Bootstrap::set(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CFG_CacheUrl")),
+ rtl::OUString());
+ }
+
+ // hold lock during process runtime:
+ static ::desktop::Lockfile s_lockfile( false /* no IPC server */ );
+ Reference<XComponentContext> xComponentContext(
+ bootstrapStandAlone( disposeGuard, verbose ) );
+ out_localContext = xComponentContext;
+ if (::dp_misc::office_is_running()) {
+ xComponentContext.set(
+ connectToOffice( xComponentContext, verbose ) );
+ }
+ else
+ {
+ if (! s_lockfile.check( 0 ))
+ {
+ String sMsg(ResId(RID_STR_CONCURRENTINSTANCE, *DeploymentResMgr::get()));
+ //Create this string before we call DeInitVCL, because this will kill
+ //the ResMgr
+ String sError(ResId(RID_STR_UNOPKG_ERROR, *DeploymentResMgr::get()));
+
+ sMsg = sMsg + OUSTR("\n") + getLockFilePath();
+
+ if (bGui)
+ {
+ //We show a message box or print to the console that there
+ //is another instance already running
+ if ( ! InitVCL( Reference<lang::XMultiServiceFactory>(
+ xComponentContext->getServiceManager(),
+ UNO_QUERY_THROW ) ))
+ throw RuntimeException( OUSTR("Cannot initialize VCL!"),
+ NULL );
+ {
+ WarningBox warn(NULL, WB_OK | WB_DEF_OK, sMsg);
+ warn.SetText(::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME).get<OUString>());
+ warn.SetIcon(0);
+ warn.Execute();
+ }
+ DeInitVCL();
+ }
+
+ throw LockFileException(
+ OUSTR("\n") + sError + sMsg + OUSTR("\n"));
+ }
+ }
+
+ return xComponentContext;
+}
+
+}
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_shared.h b/desktop/source/pkgchk/unopkg/unopkg_shared.h
new file mode 100644
index 000000000000..18314811f63f
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_shared.h
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unopkg_shared.h,v $
+ * $Revision: 1.9.8.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_misc.h"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "tools/resmgr.hxx"
+#include "rtl/ustring.hxx"
+#include "unotools/configmgr.hxx"
+
+
+#define APP_NAME "unopkg"
+
+namespace css = ::com::sun::star;
+
+namespace unopkg {
+
+ inline ::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang )
+ {
+ ::com::sun::star::lang::Locale locale;
+ sal_Int32 nIndex = 0;
+ locale.Language = slang.getToken( 0, '-', nIndex );
+ locale.Country = slang.getToken( 0, '-', nIndex );
+ locale.Variant = slang.getToken( 0, '-', nIndex );
+ return locale;
+ }
+
+
+ struct OfficeLocale :
+ public rtl::StaticWithInit<const css::lang::Locale, OfficeLocale> {
+ const css::lang::Locale operator () () {
+ ::rtl::OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw css::uno::RuntimeException( OUSTR("Cannot determine language!"), 0 );
+ if (slang.getLength() == 0)
+ slang = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US"));
+ return toLocale(slang);
+ }
+};
+
+struct DeploymentResMgr : public rtl::StaticWithInit< ResMgr *, DeploymentResMgr >
+{
+ ResMgr * operator () () {
+ return ResMgr::CreateResMgr( "deployment", OfficeLocale::get());
+ }
+};
+
+struct OptionInfo
+{
+ char const * m_name;
+ sal_uInt32 m_name_length;
+ sal_Unicode m_short_option;
+ bool m_has_argument;
+};
+
+struct LockFileException : public css::uno::Exception
+{
+ LockFileException(::rtl::OUString const & sMessage) :
+ css::uno::Exception(sMessage, css::uno::Reference< css::uno::XInterface > ()) {}
+};
+
+//==============================================================================
+::rtl::OUString toString( OptionInfo const * info );
+
+//==============================================================================
+OptionInfo const * getOptionInfo(
+ OptionInfo const * list,
+ ::rtl::OUString const & opt, sal_Unicode copt = '\0' );
+
+//==============================================================================
+bool isOption( OptionInfo const * option_info, sal_uInt32 * pIndex );
+
+//==============================================================================
+bool readArgument(
+ ::rtl::OUString * pValue, OptionInfo const * option_info,
+ sal_uInt32 * pIndex );
+
+//==============================================================================
+inline bool readOption(
+ bool * flag, OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ if (isOption( option_info, pIndex )) {
+ OSL_ASSERT( flag != 0 );
+ *flag = true;
+ return true;
+ }
+ return false;
+}
+//==============================================================================
+
+/** checks if an argument is a bootstrap variable. These start with -env:. For example
+ -env:UNO_JAVA_JFW_USER_DATA=file:///d:/user
+*/
+bool isBootstrapVariable(sal_uInt32 * pIndex);
+//==============================================================================
+::rtl::OUString const & getExecutableDir();
+
+//==============================================================================
+::rtl::OUString const & getProcessWorkingDir();
+
+//==============================================================================
+::rtl::OUString makeAbsoluteFileUrl(
+ ::rtl::OUString const & sys_path, ::rtl::OUString const & base_url,
+ bool throw_exc = true );
+
+//##############################################################################
+
+//==============================================================================
+class DisposeGuard
+{
+ css::uno::Reference<css::lang::XComponent> m_xComp;
+
+public:
+ inline DisposeGuard() {}
+ inline DisposeGuard(
+ css::uno::Reference<css::lang::XComponent> const & xComp )
+ : m_xComp( xComp ) {}
+
+ inline ~DisposeGuard()
+ {
+ if (m_xComp.is())
+ m_xComp->dispose();
+ }
+
+ inline void reset(
+ css::uno::Reference<css::lang::XComponent> const & xComp )
+ {
+ m_xComp = xComp;
+ }
+};
+
+//==============================================================================
+css::uno::Reference<css::ucb::XCommandEnvironment> createCmdEnv(
+ css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & logFile,
+ bool option_force_overwrite,
+ bool option_verbose,
+ bool option_bundled);
+
+//==============================================================================
+void printf_packages(
+ css::uno::Sequence<
+ css::uno::Reference<css::deployment::XPackage> > const & seq,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ sal_Int32 level = 0 );
+
+//##############################################################################
+
+//==============================================================================
+css::uno::Reference<css::uno::XComponentContext> getUNO(
+ DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
+ css::uno::Reference<css::uno::XComponentContext> & out_LocalComponentContext);
+
+}
+
diff --git a/desktop/source/pkgchk/unopkg/version.map b/desktop/source/pkgchk/unopkg/version.map
new file mode 100644
index 000000000000..b770ff129565
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/version.map
@@ -0,0 +1,38 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: version.map,v $
+#
+# $Revision: 1.3 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+unopkg.3 {
+ global:
+ unopkg_main;
+
+ local:
+ *;
+};