office-gobmx/desktop/source/app/userinstall.cxx
2011-11-27 13:06:47 -06:00

288 lines
10 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* 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 "userinstall.hxx"
#include "langselect.hxx"
#include <stdio.h>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <osl/file.hxx>
#include <osl/mutex.hxx>
#include <osl/process.h>
#include <osl/diagnose.h>
#include <osl/security.hxx>
#include <rtl/ref.hxx>
#include <tools/resmgr.hxx>
#include <unotools/bootstrap.hxx>
#include <svl/languageoptions.hxx>
#include <unotools/syslocaleoptions.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/configuration/theDefaultProvider.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <i18npool/mslangid.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XLocalizable.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include "app.hxx"
using rtl::OString;
using rtl::OUString;
using namespace osl;
using namespace utl;
using namespace com::sun::star::container;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::util;
namespace desktop {
static UserInstall::UserInstallError create_user_install(OUString&);
static bool is_user_install()
{
try
{
OUString sAccessSrvc(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.configuration.ConfigurationAccess" ) );
Reference< XMultiServiceFactory > theConfigProvider(
com::sun::star::configuration::theDefaultProvider::get(
comphelper::getProcessComponentContext() ) );
// localize the provider to user selection
Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW);
OUString aUserLanguage = LanguageSelection::getLanguageString();
Locale aLocale = LanguageSelection::IsoStringToLocale(aUserLanguage);
localizable->setLocale(aLocale);
Sequence< Any > theArgs(1);
NamedValue v;
v.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath"));
v.Value = makeAny(OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup")));
theArgs[0] <<= v;
Reference< XHierarchicalNameAccess> hnacc(
theConfigProvider->createInstanceWithArguments(
sAccessSrvc, theArgs), UNO_QUERY_THROW);
try
{
sal_Bool bValue = sal_False;
hnacc->getByHierarchicalName(
OUString( RTL_CONSTASCII_USTRINGPARAM(
"Office/ooSetupInstCompleted" ) ) ) >>= bValue;
return bValue ? true : false;
}
catch ( NoSuchElementException const & )
{
// just return false in this case.
}
}
catch (Exception const & e)
{
OString msg(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US));
OSL_FAIL(msg.getStr());
}
return false;
}
UserInstall::UserInstallError UserInstall::finalize()
{
OUString aUserInstallPath;
utl::Bootstrap::PathStatus aLocateResult =
utl::Bootstrap::locateUserInstallation(aUserInstallPath);
switch (aLocateResult) {
case utl::Bootstrap::DATA_INVALID:
case utl::Bootstrap::DATA_MISSING:
case utl::Bootstrap::DATA_UNKNOWN:
// cannot find a valid path or path is missing
return E_Unknown;
case utl::Bootstrap::PATH_EXISTS:
{
// path exists, check if an installation lives there
if ( is_user_install() )
{
return E_None;
}
// Note: fall-thru intended.
}
case utl::Bootstrap::PATH_VALID:
// found a path but need to create user install
return create_user_install(aUserInstallPath);
default:
return E_Unknown;
}
}
static osl::FileBase::RC copy_recursive( const rtl::OUString& srcUnqPath, const rtl::OUString& dstUnqPath)
{
FileBase::RC err;
DirectoryItem aDirItem;
DirectoryItem::get(srcUnqPath, aDirItem);
FileStatus aFileStatus(osl_FileStatus_Mask_All);
aDirItem.getFileStatus(aFileStatus);
if( aFileStatus.getFileType() == FileStatus::Directory)
{
// create directory if not already there
err = Directory::create( dstUnqPath );
if (err == osl::FileBase::E_EXIST)
err = osl::FileBase::E_None;
FileBase::RC next = err;
if (err == osl::FileBase::E_None)
{
// iterate through directory contents
Directory aDir( srcUnqPath );
aDir.open();
while (err == osl::FileBase::E_None &&
(next = aDir.getNextItem( aDirItem )) == osl::FileBase::E_None)
{
aDirItem.getFileStatus(aFileStatus);
// generate new src/dst pair and make recursive call
rtl::OUString newSrcUnqPath = aFileStatus.getFileURL();
rtl::OUString newDstUnqPath = dstUnqPath;
rtl::OUString itemname = aFileStatus.getFileName();
// append trailing '/' if needed
if (newDstUnqPath.lastIndexOf(sal_Unicode('/')) != newDstUnqPath.getLength()-1)
newDstUnqPath += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
newDstUnqPath += itemname;
// recursion
err = copy_recursive(newSrcUnqPath, newDstUnqPath);
}
aDir.close();
if ( err != osl::FileBase::E_None )
return err;
if( next != FileBase::E_NOENT )
err = FileBase::E_INVAL;
}
}
else
{
// copy single file - foldback
err = File::copy( srcUnqPath,dstUnqPath );
}
return err;
}
static const char *pszSrcList[] = {
"/presets",
NULL
};
static const char *pszDstList[] = {
"/user",
NULL
};
static UserInstall::UserInstallError create_user_install(OUString& aUserPath)
{
OUString aBasePath;
if (utl::Bootstrap::locateBaseInstallation(aBasePath) != utl::Bootstrap::PATH_EXISTS)
return UserInstall::E_InvalidBaseinstall;
// create the user directory
FileBase::RC rc = Directory::createPath(aUserPath);
if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) return UserInstall::E_Creation;
#ifdef UNIX
// set safer permissions for the user directory by default
File::setAttributes(aUserPath, osl_File_Attribute_OwnWrite| osl_File_Attribute_OwnRead| osl_File_Attribute_OwnExe);
#endif
// copy data from shared data directory of base installation
for (sal_Int32 i=0; pszSrcList[i]!=NULL && pszDstList[i]!=NULL; i++)
{
rc = copy_recursive(
aBasePath + OUString::createFromAscii(pszSrcList[i]),
aUserPath + OUString::createFromAscii(pszDstList[i]));
if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST))
{
if ( rc == FileBase::E_NOSPC )
return UserInstall::E_NoDiskSpace;
else if ( rc == FileBase::E_ACCES )
return UserInstall::E_NoWriteAccess;
else
return UserInstall::E_Creation;
}
}
try
{
OUString sAccessSrvc(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationUpdateAccess"));
Reference< XMultiServiceFactory > theConfigProvider(
com::sun::star::configuration::theDefaultProvider::get(
comphelper::getProcessComponentContext() ) );
Sequence< Any > theArgs(1);
NamedValue v(OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")), makeAny(OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup"))));
theArgs[0] <<= v;
Reference< XHierarchicalPropertySet> hpset(
theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
hpset->setHierarchicalPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Office/ooSetupInstCompleted")), makeAny(sal_True));
Reference< XChangesBatch >(hpset, UNO_QUERY_THROW)->commitChanges();
}
catch ( PropertyVetoException& )
{
// we are not allowed to change this
}
catch (Exception& e)
{
OString aMsg("create_user_install(): ");
aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
OSL_FAIL(aMsg.getStr());
return UserInstall::E_Creation;
}
return UserInstall::E_None;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */