Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <config_features.h>
21 :
22 : #include "sal/config.h"
23 :
24 : #include "userinstall.hxx"
25 : #include "langselect.hxx"
26 :
27 : #include <stdio.h>
28 : #include <rtl/ustring.hxx>
29 : #include <rtl/ustrbuf.hxx>
30 : #include <osl/file.hxx>
31 : #include <osl/mutex.hxx>
32 : #include <osl/process.h>
33 : #include <osl/diagnose.h>
34 : #include <osl/security.hxx>
35 : #include <rtl/ref.hxx>
36 :
37 : #include <officecfg/Setup.hxx>
38 : #include <unotools/bootstrap.hxx>
39 : #include <svl/languageoptions.hxx>
40 : #include <unotools/syslocaleoptions.hxx>
41 : #include <comphelper/processfactory.hxx>
42 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
43 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 : #include <i18nlangtag/mslangid.hxx>
45 : #include <com/sun/star/lang/XLocalizable.hpp>
46 : #include <com/sun/star/lang/Locale.hpp>
47 :
48 : #include "app.hxx"
49 :
50 : using namespace osl;
51 : using namespace utl;
52 : using namespace com::sun::star::container;
53 : using namespace com::sun::star::uno;
54 : using namespace com::sun::star::lang;
55 : using namespace com::sun::star::beans;
56 : using namespace com::sun::star::util;
57 :
58 :
59 : namespace desktop {
60 :
61 : static UserInstall::UserInstallStatus create_user_install(OUString&);
62 :
63 83 : static bool is_user_install()
64 : {
65 : try
66 : {
67 : Reference< XMultiServiceFactory > theConfigProvider(
68 : com::sun::star::configuration::theDefaultProvider::get(
69 83 : comphelper::getProcessComponentContext() ) );
70 :
71 : // localize the provider to user selection
72 166 : Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW);
73 166 : OUString aUserLanguage = LanguageSelection::getLanguageString();
74 166 : LanguageTag aLanguageTag(aUserLanguage);
75 83 : localizable->setLocale(aLanguageTag.getLocale( false));
76 :
77 166 : return officecfg::Setup::Office::ooSetupInstCompleted::get();
78 : }
79 0 : catch (Exception const & e)
80 : {
81 0 : OString msg(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US));
82 0 : OSL_FAIL(msg.getStr());
83 : }
84 :
85 0 : return false;
86 : }
87 :
88 83 : UserInstall::UserInstallStatus UserInstall::finalize()
89 : {
90 83 : OUString aUserInstallPath;
91 : utl::Bootstrap::PathStatus aLocateResult =
92 83 : utl::Bootstrap::locateUserInstallation(aUserInstallPath);
93 :
94 83 : switch (aLocateResult) {
95 :
96 : case utl::Bootstrap::DATA_INVALID:
97 : case utl::Bootstrap::DATA_MISSING:
98 : case utl::Bootstrap::DATA_UNKNOWN:
99 : // cannot find a valid path or path is missing
100 0 : return E_Unknown;
101 :
102 : case utl::Bootstrap::PATH_EXISTS:
103 : {
104 : // path exists, check if an installation lives there
105 83 : if ( is_user_install() )
106 : {
107 51 : return Ok;
108 : }
109 : // Note: fall-thru intended.
110 : }
111 : case utl::Bootstrap::PATH_VALID:
112 : // found a path but need to create user install
113 32 : return create_user_install(aUserInstallPath);
114 : default:
115 0 : return E_Unknown;
116 83 : }
117 : }
118 :
119 : #if HAVE_FEATURE_DESKTOP
120 1344 : static osl::FileBase::RC copy_recursive( const OUString& srcUnqPath, const OUString& dstUnqPath)
121 : {
122 : FileBase::RC err;
123 1344 : DirectoryItem aDirItem;
124 1344 : DirectoryItem::get(srcUnqPath, aDirItem);
125 2688 : FileStatus aFileStatus(osl_FileStatus_Mask_All);
126 1344 : aDirItem.getFileStatus(aFileStatus);
127 :
128 1344 : if( aFileStatus.getFileType() == FileStatus::Directory)
129 : {
130 : // create directory if not already there
131 320 : err = Directory::create( dstUnqPath );
132 320 : if (err == osl::FileBase::E_EXIST)
133 32 : err = osl::FileBase::E_None;
134 :
135 320 : FileBase::RC next = err;
136 320 : if (err == osl::FileBase::E_None)
137 : {
138 : // iterate through directory contents
139 320 : Directory aDir( srcUnqPath );
140 320 : aDir.open();
141 1952 : while (err == osl::FileBase::E_None &&
142 : (next = aDir.getNextItem( aDirItem )) == osl::FileBase::E_None)
143 : {
144 1312 : aDirItem.getFileStatus(aFileStatus);
145 : // generate new src/dst pair and make recursive call
146 1312 : OUString newSrcUnqPath = aFileStatus.getFileURL();
147 2624 : OUString newDstUnqPath = dstUnqPath;
148 2624 : OUString itemname = aFileStatus.getFileName();
149 : // append trailing '/' if needed
150 1312 : if (newDstUnqPath.lastIndexOf(sal_Unicode('/')) != newDstUnqPath.getLength()-1)
151 1312 : newDstUnqPath += OUString("/");
152 1312 : newDstUnqPath += itemname;
153 : // recursion
154 1312 : err = copy_recursive(newSrcUnqPath, newDstUnqPath);
155 1312 : }
156 320 : aDir.close();
157 :
158 320 : if ( err != osl::FileBase::E_None )
159 0 : return err;
160 320 : if( next != FileBase::E_NOENT )
161 0 : err = FileBase::E_INVAL;
162 : }
163 : }
164 : else
165 : {
166 : // copy single file - foldback
167 1024 : err = File::copy( srcUnqPath,dstUnqPath );
168 : }
169 :
170 2688 : return err;
171 : }
172 : #endif
173 :
174 32 : static UserInstall::UserInstallStatus create_user_install(OUString& aUserPath)
175 : {
176 32 : OUString aBasePath;
177 32 : if (utl::Bootstrap::locateBaseInstallation(aBasePath) != utl::Bootstrap::PATH_EXISTS)
178 0 : return UserInstall::E_InvalidBaseinstall;
179 :
180 : // create the user directory
181 32 : FileBase::RC rc = Directory::createPath(aUserPath);
182 32 : if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) return UserInstall::E_Creation;
183 :
184 : #if defined(UNIX) && !defined(ANDROID) && !defined(IOS)
185 : // Set safer permissions for the user directory by default:
186 32 : File::setAttributes(aUserPath, osl_File_Attribute_OwnWrite| osl_File_Attribute_OwnRead| osl_File_Attribute_OwnExe);
187 : #endif
188 :
189 : #if !defined(ANDROID) && !defined(IOS)
190 : // as of now osl_copyFile does not work on Android => don't do this.
191 :
192 : // Copy data from shared data directory of base installation:
193 : rc = copy_recursive(
194 64 : aBasePath + OUString("/presets"),
195 96 : aUserPath + OUString("/user"));
196 32 : if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST))
197 : {
198 0 : if ( rc == FileBase::E_NOSPC )
199 0 : return UserInstall::E_NoDiskSpace;
200 0 : else if ( rc == FileBase::E_ACCES )
201 0 : return UserInstall::E_NoWriteAccess;
202 : else
203 0 : return UserInstall::E_Creation;
204 : }
205 : #endif
206 :
207 : boost::shared_ptr< comphelper::ConfigurationChanges > batch(
208 64 : comphelper::ConfigurationChanges::create());
209 32 : officecfg::Setup::Office::ooSetupInstCompleted::set(true, batch);
210 32 : batch->commit();
211 :
212 64 : return UserInstall::Created;
213 : }
214 249 : }
215 :
216 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|