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 "sal/config.h"
21 :
22 : #include "userinstall.hxx"
23 : #include "langselect.hxx"
24 :
25 : #include <stdio.h>
26 : #include <rtl/ustring.hxx>
27 : #include <rtl/ustrbuf.hxx>
28 : #include <osl/file.hxx>
29 : #include <osl/mutex.hxx>
30 : #include <osl/process.h>
31 : #include <osl/diagnose.h>
32 : #include <osl/security.hxx>
33 : #include <rtl/ref.hxx>
34 :
35 : #include <officecfg/Setup.hxx>
36 : #include <unotools/bootstrap.hxx>
37 : #include <svl/languageoptions.hxx>
38 : #include <unotools/syslocaleoptions.hxx>
39 : #include <comphelper/processfactory.hxx>
40 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
41 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 : #include <i18npool/mslangid.hxx>
43 : #include <com/sun/star/lang/XLocalizable.hpp>
44 : #include <com/sun/star/lang/Locale.hpp>
45 :
46 : #include "app.hxx"
47 :
48 : using rtl::OString;
49 : using rtl::OUString;
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 0 : static bool is_user_install()
64 : {
65 : try
66 : {
67 : Reference< XMultiServiceFactory > theConfigProvider(
68 : com::sun::star::configuration::theDefaultProvider::get(
69 0 : comphelper::getProcessComponentContext() ) );
70 :
71 : // localize the provider to user selection
72 0 : Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW);
73 0 : OUString aUserLanguage = LanguageSelection::getLanguageString();
74 0 : LanguageTag aLanguageTag(aUserLanguage);
75 0 : localizable->setLocale(aLanguageTag.getLocale( false));
76 :
77 0 : 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 0 : UserInstall::UserInstallStatus UserInstall::finalize()
89 : {
90 0 : OUString aUserInstallPath;
91 : utl::Bootstrap::PathStatus aLocateResult =
92 0 : utl::Bootstrap::locateUserInstallation(aUserInstallPath);
93 :
94 0 : 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 0 : if ( is_user_install() )
106 : {
107 0 : 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 0 : return create_user_install(aUserInstallPath);
114 : default:
115 0 : return E_Unknown;
116 0 : }
117 : }
118 :
119 0 : static osl::FileBase::RC copy_recursive( const rtl::OUString& srcUnqPath, const rtl::OUString& dstUnqPath)
120 : {
121 : FileBase::RC err;
122 0 : DirectoryItem aDirItem;
123 0 : DirectoryItem::get(srcUnqPath, aDirItem);
124 0 : FileStatus aFileStatus(osl_FileStatus_Mask_All);
125 0 : aDirItem.getFileStatus(aFileStatus);
126 :
127 0 : if( aFileStatus.getFileType() == FileStatus::Directory)
128 : {
129 : // create directory if not already there
130 0 : err = Directory::create( dstUnqPath );
131 0 : if (err == osl::FileBase::E_EXIST)
132 0 : err = osl::FileBase::E_None;
133 :
134 0 : FileBase::RC next = err;
135 0 : if (err == osl::FileBase::E_None)
136 : {
137 : // iterate through directory contents
138 0 : Directory aDir( srcUnqPath );
139 0 : aDir.open();
140 0 : while (err == osl::FileBase::E_None &&
141 : (next = aDir.getNextItem( aDirItem )) == osl::FileBase::E_None)
142 : {
143 0 : aDirItem.getFileStatus(aFileStatus);
144 : // generate new src/dst pair and make recursive call
145 0 : rtl::OUString newSrcUnqPath = aFileStatus.getFileURL();
146 0 : rtl::OUString newDstUnqPath = dstUnqPath;
147 0 : rtl::OUString itemname = aFileStatus.getFileName();
148 : // append trailing '/' if needed
149 0 : if (newDstUnqPath.lastIndexOf(sal_Unicode('/')) != newDstUnqPath.getLength()-1)
150 0 : newDstUnqPath += rtl::OUString("/");
151 0 : newDstUnqPath += itemname;
152 : // recursion
153 0 : err = copy_recursive(newSrcUnqPath, newDstUnqPath);
154 0 : }
155 0 : aDir.close();
156 :
157 0 : if ( err != osl::FileBase::E_None )
158 0 : return err;
159 0 : if( next != FileBase::E_NOENT )
160 0 : err = FileBase::E_INVAL;
161 : }
162 : }
163 : else
164 : {
165 : // copy single file - foldback
166 0 : err = File::copy( srcUnqPath,dstUnqPath );
167 : }
168 :
169 : #ifdef ANDROID
170 : fprintf (stderr, "copy_recursive '%s' to '%s' returns (%d)0x%x\n",
171 : rtl::OUStringToOString(srcUnqPath, RTL_TEXTENCODING_UTF8).getStr(),
172 : rtl::OUStringToOString(dstUnqPath, RTL_TEXTENCODING_UTF8).getStr(),
173 : (int)err, (int)err);
174 : #endif
175 0 : return err;
176 : }
177 :
178 0 : static UserInstall::UserInstallStatus create_user_install(OUString& aUserPath)
179 : {
180 0 : OUString aBasePath;
181 0 : if (utl::Bootstrap::locateBaseInstallation(aBasePath) != utl::Bootstrap::PATH_EXISTS)
182 0 : return UserInstall::E_InvalidBaseinstall;
183 :
184 : // create the user directory
185 0 : FileBase::RC rc = Directory::createPath(aUserPath);
186 0 : if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) return UserInstall::E_Creation;
187 :
188 : #ifdef UNIX
189 : // Set safer permissions for the user directory by default:
190 0 : File::setAttributes(aUserPath, osl_File_Attribute_OwnWrite| osl_File_Attribute_OwnRead| osl_File_Attribute_OwnExe);
191 : #endif
192 :
193 : #ifndef ANDROID
194 : // as of now osl_copyFile does not work on Android => don't do this.
195 :
196 : // Copy data from shared data directory of base installation:
197 : rc = copy_recursive(
198 0 : aBasePath + rtl::OUString("/presets"),
199 0 : aUserPath + rtl::OUString("/user"));
200 0 : if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST))
201 : {
202 0 : if ( rc == FileBase::E_NOSPC )
203 0 : return UserInstall::E_NoDiskSpace;
204 0 : else if ( rc == FileBase::E_ACCES )
205 0 : return UserInstall::E_NoWriteAccess;
206 : else
207 0 : return UserInstall::E_Creation;
208 : }
209 : #endif
210 :
211 : boost::shared_ptr< comphelper::ConfigurationChanges > batch(
212 0 : comphelper::ConfigurationChanges::create());
213 0 : officecfg::Setup::Office::ooSetupInstCompleted::set(true, batch);
214 0 : batch->commit();
215 :
216 0 : return UserInstall::Created;
217 : }
218 : }
219 :
220 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|