Branch data 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 : :
21 : : #include "MNSProfileDiscover.hxx"
22 : : #ifndef MINIMAL_PROFILEDISCOVER
23 : : #include "MNSProfile.hxx"
24 : :
25 : : #include "pratom.h"
26 : : #include "prmem.h"
27 : : #include "plstr.h"
28 : : #include "prenv.h"
29 : :
30 : : #include "nsIEnumerator.h"
31 : : #include "prprf.h"
32 : : #include "nsCOMPtr.h"
33 : : #include "nsIComponentManager.h"
34 : : #include "nsEscape.h"
35 : : #include "nsDirectoryServiceDefs.h"
36 : : #include "nsAppDirectoryServiceDefs.h"
37 : : #include "nsILocalFile.h"
38 : : #include "nsReadableUtils.h"
39 : :
40 : :
41 : : #if defined(XP_MAC) || defined(XP_MACOSX)
42 : : #include <Processes.h>
43 : : #include <CFBundle.h>
44 : : #include "nsILocalFileMac.h"
45 : : #endif
46 : :
47 : : #ifdef XP_UNIX
48 : : #include <unistd.h>
49 : : #include <fcntl.h>
50 : : #include <errno.h>
51 : : #include <signal.h>
52 : : #include "prnetdb.h"
53 : : #include "prsystem.h"
54 : : #endif
55 : :
56 : : #ifdef VMS
57 : : #include <rmsdef.h>
58 : : #endif
59 : :
60 : : #include "pre_include_mozilla.h"
61 : : #include "nsICharsetConverterManager.h"
62 : : #include "nsIPlatformCharset.h"
63 : : #include "post_include_mozilla.h"
64 : :
65 : : #if defined (XP_UNIX)
66 : : # define USER_ENVIRONMENT_VARIABLE "USER"
67 : : # define LOGNAME_ENVIRONMENT_VARIABLE "LOGNAME"
68 : : # define HOME_ENVIRONMENT_VARIABLE "HOME"
69 : : # define PROFILE_NAME_ENVIRONMENT_VARIABLE "PROFILE_NAME"
70 : : # define PROFILE_HOME_ENVIRONMENT_VARIABLE "PROFILE_HOME"
71 : : # define DEFAULT_UNIX_PROFILE_NAME "default"
72 : : # ifndef XP_MACOSX /* Don't use symlink-based locking on OS X */
73 : : # define USE_SYMLINK_LOCKING
74 : : # endif
75 : : #endif
76 : :
77 : : // IID and CIDs of all the services needed
78 : : static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
79 : : #endif
80 : :
81 : : #ifndef MAXPATHLEN
82 : : #define MAXPATHLEN 1024
83 : : #endif
84 : : #include <MNSFolders.hxx>
85 : : #include <MNSINIParser.hxx>
86 : :
87 : : namespace connectivity
88 : : {
89 : : namespace mozab
90 : : {
91 : 0 : ProfileStruct::ProfileStruct(MozillaProductType aProduct,::rtl::OUString aProfileName,
92 : : #ifdef MINIMAL_PROFILEDISCOVER
93 : : const ::rtl::OUString& aProfilePath
94 : : #else
95 : : nsILocalFile * aProfilePath
96 : : #endif
97 : 0 : )
98 : : {
99 : 0 : product=aProduct;
100 : 0 : profileName = aProfileName;
101 : 0 : profilePath = aProfilePath;
102 : 0 : }
103 : 0 : ::rtl::OUString ProfileStruct::getProfilePath()
104 : : {
105 : : #ifdef MINIMAL_PROFILEDISCOVER
106 : 0 : return profilePath;
107 : : #else
108 : : if (profilePath)
109 : : {
110 : : nsAutoString path;
111 : : nsresult rv = profilePath->GetPath(path);
112 : : NS_ENSURE_SUCCESS(rv, ::rtl::OUString());
113 : : // PRUnichar != sal_Unicode in mingw
114 : : return ::rtl::OUString(reinterpret_cast_mingw_only<const sal_Unicode *>(path.get()));
115 : : }
116 : : else
117 : : return ::rtl::OUString();
118 : : #endif
119 : : }
120 : :
121 : 0 : ProfileAccess::~ProfileAccess()
122 : : {
123 : 0 : }
124 : 0 : ProfileAccess::ProfileAccess()
125 : : {
126 : 0 : LoadProductsInfo();
127 : 0 : }
128 : :
129 : 0 : sal_Int32 ProfileAccess::LoadProductsInfo()
130 : : {
131 : : //load SeaMonkey 2 profiles to m_ProductProfileList
132 : 0 : sal_Int32 count = LoadXPToolkitProfiles(MozillaProductType_Mozilla);
133 : :
134 : : //load thunderbird profiles to m_ProductProfileList
135 : 0 : count += LoadXPToolkitProfiles(MozillaProductType_Thunderbird);
136 : :
137 : : //load firefox profiles to m_ProductProfileList
138 : : //firefox profile does not containt address book, but maybe others need them
139 : 0 : count += LoadXPToolkitProfiles(MozillaProductType_Firefox);
140 : 0 : return count;
141 : : }
142 : : //Thunderbird and firefox profiles are saved in profiles.ini
143 : 0 : sal_Int32 ProfileAccess::LoadXPToolkitProfiles(MozillaProductType product)
144 : : {
145 : 0 : sal_Int32 index=product;
146 : 0 : ProductStruct &m_Product = m_ProductProfileList[index];
147 : :
148 : : #ifndef MINIMAL_PROFILEDISCOVER
149 : : nsresult rv;
150 : : #endif
151 : 0 : ::rtl::OUString regDir = getRegistryDir(product);
152 : 0 : ::rtl::OUString profilesIni( regDir );
153 : 0 : profilesIni += ::rtl::OUString("profiles.ini");
154 : 0 : IniParser parser( profilesIni );
155 : 0 : IniSectionMap &mAllSection = *(parser.getAllSection());
156 : :
157 : 0 : IniSectionMap::iterator iBegin = mAllSection.begin();
158 : 0 : IniSectionMap::iterator iEnd = mAllSection.end();
159 : 0 : for(;iBegin != iEnd;++iBegin)
160 : : {
161 : 0 : ini_Section *aSection = &(*iBegin).second;
162 : 0 : ::rtl::OUString profileName;
163 : 0 : ::rtl::OUString profilePath;
164 : 0 : ::rtl::OUString sIsRelative;
165 : 0 : ::rtl::OUString sIsDefault;
166 : :
167 : 0 : for(NameValueList::iterator itor=aSection->lList.begin();
168 : 0 : itor != aSection->lList.end();
169 : : ++itor)
170 : : {
171 : 0 : struct ini_NameValue * aValue = &(*itor);
172 : 0 : if ( aValue->sName == "Name" )
173 : : {
174 : 0 : profileName = aValue->sValue;
175 : : }
176 : 0 : else if ( aValue->sName == "IsRelative" )
177 : : {
178 : 0 : sIsRelative = aValue->sValue;
179 : : }
180 : 0 : else if ( aValue->sName == "Path" )
181 : : {
182 : 0 : profilePath = aValue->sValue;
183 : : }
184 : 0 : else if ( aValue->sName == "Default" )
185 : : {
186 : 0 : sIsDefault = aValue->sValue;
187 : : }
188 : : }
189 : 0 : if (!(profileName.isEmpty() && profilePath.isEmpty()))
190 : : {
191 : 0 : sal_Int32 isRelative = 0;
192 : 0 : if (!sIsRelative.isEmpty())
193 : : {
194 : 0 : isRelative = sIsRelative.toInt32();
195 : : }
196 : :
197 : : #ifndef MINIMAL_PROFILEDISCOVER
198 : : nsCOMPtr<nsILocalFile> rootDir;
199 : : rv = NS_NewLocalFile(EmptyString(), PR_TRUE,
200 : : getter_AddRefs(rootDir));
201 : : if (NS_FAILED(rv)) continue;
202 : :
203 : : OString sPath = OUStringToOString(profilePath, RTL_TEXTENCODING_UTF8);
204 : : nsCAutoString filePath(sPath.getStr());
205 : :
206 : : if (isRelative) {
207 : : // PRUnichar != sal_Unicode in mingw
208 : : nsAutoString registryDir( reinterpret_cast_mingw_only<const PRUnichar *>(regDir.getStr()) );
209 : : nsCOMPtr<nsILocalFile> mAppData;
210 : : rv = NS_NewLocalFile(registryDir, PR_TRUE,
211 : : getter_AddRefs(mAppData));
212 : : if (NS_FAILED(rv)) continue;
213 : : rv = rootDir->SetRelativeDescriptor(mAppData, filePath);
214 : : } else {
215 : : rv = rootDir->SetPersistentDescriptor(filePath);
216 : : }
217 : : if (NS_FAILED(rv)) continue;
218 : : #else
219 : 0 : rtl::OUString fullProfilePath;
220 : 0 : if(isRelative)
221 : : {
222 : 0 : fullProfilePath = regDir + profilePath;
223 : : }
224 : : else
225 : : {
226 : 0 : fullProfilePath = profilePath;
227 : : }
228 : : #endif
229 : :
230 : : ProfileStruct* profileItem = new ProfileStruct(product,profileName,
231 : : #ifdef MINIMAL_PROFILEDISCOVER
232 : : fullProfilePath
233 : : #else
234 : : rootDir
235 : : #endif
236 : 0 : );
237 : 0 : m_Product.mProfileList[profileName] = profileItem;
238 : :
239 : 0 : sal_Int32 isDefault = 0;
240 : 0 : if (!sIsDefault.isEmpty())
241 : : {
242 : 0 : isDefault = sIsDefault.toInt32();
243 : : }
244 : 0 : if (isDefault)
245 : 0 : m_Product.mCurrentProfileName = profileName;
246 : :
247 : : }
248 : :
249 : 0 : }
250 : 0 : return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
251 : : }
252 : :
253 : 0 : ::rtl::OUString ProfileAccess::getProfilePath( ::com::sun::star::mozilla::MozillaProductType product, const ::rtl::OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
254 : : {
255 : 0 : sal_Int32 index=product;
256 : 0 : ProductStruct &m_Product = m_ProductProfileList[index];
257 : 0 : if (!m_Product.mProfileList.size() || m_Product.mProfileList.find(profileName) == m_Product.mProfileList.end())
258 : : {
259 : : //Profile not found
260 : 0 : return ::rtl::OUString();
261 : : }
262 : : else
263 : 0 : return m_Product.mProfileList[profileName]->getProfilePath();
264 : : }
265 : :
266 : 0 : ::sal_Int32 ProfileAccess::getProfileCount( ::com::sun::star::mozilla::MozillaProductType product) throw (::com::sun::star::uno::RuntimeException)
267 : : {
268 : 0 : sal_Int32 index=product;
269 : 0 : ProductStruct &m_Product = m_ProductProfileList[index];
270 : 0 : return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
271 : : }
272 : 0 : ::sal_Int32 ProfileAccess::getProfileList( ::com::sun::star::mozilla::MozillaProductType product, ::com::sun::star::uno::Sequence< ::rtl::OUString >& list ) throw (::com::sun::star::uno::RuntimeException)
273 : : {
274 : 0 : sal_Int32 index=product;
275 : 0 : ProductStruct &m_Product = m_ProductProfileList[index];
276 : 0 : list.realloc(static_cast<sal_Int32>(m_Product.mProfileList.size()));
277 : 0 : sal_Int32 i=0;
278 : 0 : for(ProfileList::iterator itor=m_Product.mProfileList.begin();
279 : 0 : itor != m_Product.mProfileList.end();
280 : : ++itor)
281 : : {
282 : 0 : ProfileStruct * aProfile = (*itor).second;
283 : 0 : list[i] = aProfile->getProfileName();
284 : 0 : i++;
285 : : }
286 : :
287 : 0 : return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
288 : : }
289 : :
290 : 0 : ::rtl::OUString ProfileAccess::getDefaultProfile( ::com::sun::star::mozilla::MozillaProductType product ) throw (::com::sun::star::uno::RuntimeException)
291 : : {
292 : 0 : sal_Int32 index=product;
293 : 0 : ProductStruct &m_Product = m_ProductProfileList[index];
294 : 0 : if (!m_Product.mCurrentProfileName.isEmpty())
295 : : {
296 : : //default profile setted in mozilla registry
297 : 0 : return m_Product.mCurrentProfileName;
298 : : }
299 : 0 : if (m_Product.mProfileList.empty())
300 : : {
301 : : //there are not any profiles
302 : 0 : return ::rtl::OUString();
303 : : }
304 : 0 : ProfileStruct * aProfile = (*m_Product.mProfileList.begin()).second;
305 : 0 : return aProfile->getProfileName();
306 : : }
307 : : #ifndef MINIMAL_PROFILEDISCOVER
308 : : nsresult ProfileAccess::isExistFileOrSymlink(nsILocalFile* aFile,PRBool *bExist)
309 : : {
310 : : nsresult rv;
311 : : nsAutoString path;
312 : : aFile->GetPath(path);
313 : : rv = aFile->Exists(bExist);
314 : : NS_ENSURE_SUCCESS(rv, rv);
315 : : if (!*bExist)
316 : : {
317 : : rv = aFile->IsSymlink(bExist);
318 : : NS_ENSURE_SUCCESS(rv, rv);
319 : : }
320 : : return rv;
321 : : }
322 : : nsresult ProfileAccess::isLockExist(nsILocalFile* aFile)
323 : : {
324 : : #if defined (XP_MACOSX)
325 : : NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, ".parentlock");
326 : : NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "parent.lock");
327 : : #elif defined (XP_UNIX)
328 : : NS_ConvertASCIItoUTF16 OLD_LOCKFILE_NAME("lock");
329 : : NS_ConvertASCIItoUTF16 LOCKFILE_NAME(".parentlock");
330 : : #else
331 : : NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "parent.lock");
332 : : NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, "parent.lock");
333 : : #endif
334 : :
335 : : nsresult rv;
336 : :
337 : : PRBool isDir;
338 : : rv = aFile->IsDirectory(&isDir);
339 : : NS_ENSURE_SUCCESS(rv, rv);
340 : : if (!isDir)
341 : : return NS_ERROR_FILE_NOT_DIRECTORY;
342 : :
343 : : nsCOMPtr<nsILocalFile> lockFile;
344 : : rv = aFile->Clone((nsIFile **)((void **)getter_AddRefs(lockFile)));
345 : : NS_ENSURE_SUCCESS(rv, rv);
346 : :
347 : : rv = lockFile->Append(LOCKFILE_NAME);
348 : : NS_ENSURE_SUCCESS(rv, rv);
349 : : PRBool nExist=PR_FALSE;
350 : : rv = isExistFileOrSymlink(lockFile,&nExist);
351 : : NS_ENSURE_SUCCESS(rv, rv);
352 : : if (!nExist) // Check OLD_LOCKFILE_NAME
353 : : {
354 : : nsCOMPtr<nsILocalFile> oldlockFile;
355 : : rv = aFile->Clone((nsIFile **)((void **)getter_AddRefs(oldlockFile)));
356 : : NS_ENSURE_SUCCESS(rv, rv);
357 : :
358 : : rv = oldlockFile->Append(OLD_LOCKFILE_NAME);
359 : : NS_ENSURE_SUCCESS(rv, rv);
360 : : rv = isExistFileOrSymlink(oldlockFile,&nExist);
361 : : NS_ENSURE_SUCCESS(rv, rv);
362 : : }
363 : : return nExist;
364 : : }
365 : :
366 : : #endif
367 : 0 : ::sal_Bool ProfileAccess::isProfileLocked( ::com::sun::star::mozilla::MozillaProductType product, const ::rtl::OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
368 : : {
369 : : #ifdef MINIMAL_PROFILEDISCOVER
370 : : (void)product; /* avoid warning about unused parameter */
371 : : (void)profileName; /* avoid warning about unused parameter */
372 : 0 : return sal_True;
373 : : #else
374 : : ::rtl::OUString path = getProfilePath(product,profileName);
375 : : if (path.isEmpty())
376 : : return sal_True;
377 : :
378 : : // PRUnichar != sal_Unicode in mingw
379 : : nsAutoString filePath(reinterpret_cast_mingw_only<const PRUnichar *>(path.getStr()));
380 : :
381 : : nsresult rv;
382 : : nsCOMPtr<nsILocalFile> localFile;
383 : : rv = NS_NewLocalFile(filePath, PR_TRUE,
384 : : getter_AddRefs(localFile));
385 : : NS_ENSURE_SUCCESS(rv,sal_True);
386 : :
387 : : PRBool exists = PR_FALSE;
388 : : rv = localFile->Exists(&exists);
389 : : NS_ENSURE_SUCCESS(rv, sal_True);
390 : : if (!exists)
391 : : return sal_True;
392 : :
393 : : // If the profile is locked, we return true
394 : : rv = isLockExist(localFile);
395 : : if (rv)
396 : : return sal_True;
397 : : return sal_False;
398 : : #endif
399 : : }
400 : :
401 : 0 : ::sal_Bool ProfileAccess::getProfileExists( ::com::sun::star::mozilla::MozillaProductType product, const ::rtl::OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
402 : : {
403 : 0 : sal_Int32 index=product;
404 : 0 : ProductStruct &m_Product = m_ProductProfileList[index];
405 : 0 : if (!m_Product.mProfileList.size() || m_Product.mProfileList.find(profileName) == m_Product.mProfileList.end())
406 : : {
407 : 0 : return sal_False;
408 : : }
409 : : else
410 : 0 : return sal_True;
411 : : }
412 : : }
413 : : }
414 : :
415 : :
416 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|