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 : #include "MNSFolders.hxx"
82 : #include "MNSINIParser.hxx"
83 :
84 : namespace connectivity
85 : {
86 : namespace mozab
87 : {
88 3 : ProfileStruct::ProfileStruct(MozillaProductType aProduct, const OUString& aProfileName,
89 : #ifdef MINIMAL_PROFILEDISCOVER
90 : const OUString& aProfilePath
91 : #else
92 : nsILocalFile * aProfilePath
93 : #endif
94 3 : )
95 : {
96 3 : product=aProduct;
97 3 : profileName = aProfileName;
98 3 : profilePath = aProfilePath;
99 3 : }
100 0 : OUString ProfileStruct::getProfilePath()
101 : {
102 : #ifdef MINIMAL_PROFILEDISCOVER
103 0 : return profilePath;
104 : #else
105 : if (profilePath)
106 : {
107 : nsAutoString path;
108 : nsresult rv = profilePath->GetPath(path);
109 : NS_ENSURE_SUCCESS(rv, OUString());
110 : // PRUnichar != sal_Unicode in mingw
111 : return OUString(reinterpret_cast_mingw_only<const sal_Unicode *>(path.get()));
112 : }
113 : else
114 : return OUString();
115 : #endif
116 : }
117 :
118 0 : ProfileAccess::~ProfileAccess()
119 : {
120 0 : }
121 1 : ProfileAccess::ProfileAccess()
122 : {
123 1 : LoadProductsInfo();
124 1 : }
125 :
126 1 : sal_Int32 ProfileAccess::LoadProductsInfo()
127 : {
128 : //tdf#39279: LO should search Thunderbird first then Seamonkey and finally Firefox
129 : //load thunderbird profiles to m_ProductProfileList
130 1 : sal_Int32 count = LoadXPToolkitProfiles(MozillaProductType_Thunderbird);
131 :
132 : //load SeaMonkey 2 profiles to m_ProductProfileList
133 1 : count += LoadXPToolkitProfiles(MozillaProductType_Mozilla);
134 :
135 : //load firefox profiles to m_ProductProfileList
136 : //firefox profile does not containt address book, but maybe others need them
137 1 : count += LoadXPToolkitProfiles(MozillaProductType_Firefox);
138 1 : return count;
139 : }
140 : //Thunderbird and firefox profiles are saved in profiles.ini
141 3 : sal_Int32 ProfileAccess::LoadXPToolkitProfiles(MozillaProductType product)
142 : {
143 3 : sal_Int32 index=product;
144 3 : ProductStruct &m_Product = m_ProductProfileList[index];
145 :
146 : #ifndef MINIMAL_PROFILEDISCOVER
147 : nsresult rv;
148 : #endif
149 3 : OUString regDir = getRegistryDir(product);
150 6 : OUString profilesIni = regDir + "profiles.ini";
151 6 : IniParser parser( profilesIni );
152 3 : IniSectionMap &mAllSection = parser.getAllSection();
153 :
154 3 : IniSectionMap::iterator iBegin = mAllSection.begin();
155 3 : IniSectionMap::iterator iEnd = mAllSection.end();
156 8 : for(;iBegin != iEnd;++iBegin)
157 : {
158 5 : ini_Section *aSection = &(*iBegin).second;
159 5 : OUString profileName;
160 10 : OUString profilePath;
161 10 : OUString sIsRelative;
162 10 : OUString sIsDefault;
163 :
164 51 : for(NameValueList::iterator itor=aSection->lList.begin();
165 34 : itor != aSection->lList.end();
166 : ++itor)
167 : {
168 12 : struct ini_NameValue * aValue = &(*itor);
169 12 : if ( aValue->sName == "Name" )
170 : {
171 3 : profileName = aValue->sValue;
172 : }
173 9 : else if ( aValue->sName == "IsRelative" )
174 : {
175 3 : sIsRelative = aValue->sValue;
176 : }
177 6 : else if ( aValue->sName == "Path" )
178 : {
179 3 : profilePath = aValue->sValue;
180 : }
181 3 : else if ( aValue->sName == "Default" )
182 : {
183 1 : sIsDefault = aValue->sValue;
184 : }
185 : }
186 5 : if (!(profileName.isEmpty() && profilePath.isEmpty()))
187 : {
188 3 : sal_Int32 isRelative = 0;
189 3 : if (!sIsRelative.isEmpty())
190 : {
191 3 : isRelative = sIsRelative.toInt32();
192 : }
193 :
194 : #ifndef MINIMAL_PROFILEDISCOVER
195 : nsCOMPtr<nsILocalFile> rootDir;
196 : rv = NS_NewLocalFile(EmptyString(), PR_TRUE,
197 : getter_AddRefs(rootDir));
198 : if (NS_FAILED(rv)) continue;
199 :
200 : OString sPath = OUStringToOString(profilePath, RTL_TEXTENCODING_UTF8);
201 : nsCAutoString filePath(sPath.getStr());
202 :
203 : if (isRelative) {
204 : // PRUnichar != sal_Unicode in mingw
205 : nsAutoString registryDir( reinterpret_cast_mingw_only<const PRUnichar *>(regDir.getStr()) );
206 : nsCOMPtr<nsILocalFile> mAppData;
207 : rv = NS_NewLocalFile(registryDir, PR_TRUE,
208 : getter_AddRefs(mAppData));
209 : if (NS_FAILED(rv)) continue;
210 : rv = rootDir->SetRelativeDescriptor(mAppData, filePath);
211 : } else {
212 : rv = rootDir->SetPersistentDescriptor(filePath);
213 : }
214 : if (NS_FAILED(rv)) continue;
215 : #else
216 3 : OUString fullProfilePath;
217 3 : if(isRelative)
218 : {
219 3 : fullProfilePath = regDir + profilePath;
220 : }
221 : else
222 : {
223 0 : fullProfilePath = profilePath;
224 : }
225 : #endif
226 :
227 : ProfileStruct* profileItem = new ProfileStruct(product,profileName,
228 : #ifdef MINIMAL_PROFILEDISCOVER
229 : fullProfilePath
230 : #else
231 : rootDir
232 : #endif
233 3 : );
234 3 : m_Product.mProfileList[profileName] = profileItem;
235 :
236 3 : sal_Int32 isDefault = 0;
237 3 : if (!sIsDefault.isEmpty())
238 : {
239 1 : isDefault = sIsDefault.toInt32();
240 : }
241 3 : if (isDefault)
242 1 : m_Product.mCurrentProfileName = profileName;
243 :
244 : }
245 :
246 5 : }
247 6 : return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
248 : }
249 :
250 0 : OUString ProfileAccess::getProfilePath( ::com::sun::star::mozilla::MozillaProductType product, const OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
251 : {
252 0 : sal_Int32 index=product;
253 0 : ProductStruct &m_Product = m_ProductProfileList[index];
254 0 : if (!m_Product.mProfileList.size() || m_Product.mProfileList.find(profileName) == m_Product.mProfileList.end())
255 : {
256 : //Profile not found
257 0 : return OUString();
258 : }
259 : else
260 0 : return m_Product.mProfileList[profileName]->getProfilePath();
261 : }
262 :
263 0 : ::sal_Int32 ProfileAccess::getProfileCount( ::com::sun::star::mozilla::MozillaProductType product) throw (::com::sun::star::uno::RuntimeException)
264 : {
265 0 : sal_Int32 index=product;
266 0 : ProductStruct &m_Product = m_ProductProfileList[index];
267 0 : return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
268 : }
269 0 : ::sal_Int32 ProfileAccess::getProfileList( ::com::sun::star::mozilla::MozillaProductType product, ::com::sun::star::uno::Sequence< OUString >& list ) throw (::com::sun::star::uno::RuntimeException)
270 : {
271 0 : sal_Int32 index=product;
272 0 : ProductStruct &m_Product = m_ProductProfileList[index];
273 0 : list.realloc(static_cast<sal_Int32>(m_Product.mProfileList.size()));
274 0 : sal_Int32 i=0;
275 0 : for(ProfileList::iterator itor=m_Product.mProfileList.begin();
276 0 : itor != m_Product.mProfileList.end();
277 : ++itor)
278 : {
279 0 : ProfileStruct * aProfile = (*itor).second;
280 0 : list[i] = aProfile->getProfileName();
281 0 : i++;
282 : }
283 :
284 0 : return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
285 : }
286 :
287 0 : OUString ProfileAccess::getDefaultProfile( ::com::sun::star::mozilla::MozillaProductType product ) throw (::com::sun::star::uno::RuntimeException)
288 : {
289 0 : sal_Int32 index=product;
290 0 : ProductStruct &m_Product = m_ProductProfileList[index];
291 0 : if (!m_Product.mCurrentProfileName.isEmpty())
292 : {
293 : //default profile setted in mozilla registry
294 0 : return m_Product.mCurrentProfileName;
295 : }
296 0 : if (m_Product.mProfileList.empty())
297 : {
298 : //there are not any profiles
299 0 : return OUString();
300 : }
301 0 : ProfileStruct * aProfile = (*m_Product.mProfileList.begin()).second;
302 0 : return aProfile->getProfileName();
303 : }
304 : #ifndef MINIMAL_PROFILEDISCOVER
305 : nsresult ProfileAccess::isExistFileOrSymlink(nsILocalFile* aFile,PRBool *bExist)
306 : {
307 : nsresult rv;
308 : nsAutoString path;
309 : aFile->GetPath(path);
310 : rv = aFile->Exists(bExist);
311 : NS_ENSURE_SUCCESS(rv, rv);
312 : if (!*bExist)
313 : {
314 : rv = aFile->IsSymlink(bExist);
315 : NS_ENSURE_SUCCESS(rv, rv);
316 : }
317 : return rv;
318 : }
319 : nsresult ProfileAccess::isLockExist(nsILocalFile* aFile)
320 : {
321 : #if defined (XP_MACOSX)
322 : NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, ".parentlock");
323 : NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "parent.lock");
324 : #elif defined (XP_UNIX)
325 : NS_ConvertASCIItoUTF16 OLD_LOCKFILE_NAME("lock");
326 : NS_ConvertASCIItoUTF16 LOCKFILE_NAME(".parentlock");
327 : #else
328 : NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "parent.lock");
329 : NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, "parent.lock");
330 : #endif
331 :
332 : nsresult rv;
333 :
334 : PRBool isDir;
335 : rv = aFile->IsDirectory(&isDir);
336 : NS_ENSURE_SUCCESS(rv, rv);
337 : if (!isDir)
338 : return NS_ERROR_FILE_NOT_DIRECTORY;
339 :
340 : nsCOMPtr<nsILocalFile> lockFile;
341 : rv = aFile->Clone((nsIFile **)((void **)getter_AddRefs(lockFile)));
342 : NS_ENSURE_SUCCESS(rv, rv);
343 :
344 : rv = lockFile->Append(LOCKFILE_NAME);
345 : NS_ENSURE_SUCCESS(rv, rv);
346 : PRBool nExist=PR_FALSE;
347 : rv = isExistFileOrSymlink(lockFile,&nExist);
348 : NS_ENSURE_SUCCESS(rv, rv);
349 : if (!nExist) // Check OLD_LOCKFILE_NAME
350 : {
351 : nsCOMPtr<nsILocalFile> oldlockFile;
352 : rv = aFile->Clone((nsIFile **)((void **)getter_AddRefs(oldlockFile)));
353 : NS_ENSURE_SUCCESS(rv, rv);
354 :
355 : rv = oldlockFile->Append(OLD_LOCKFILE_NAME);
356 : NS_ENSURE_SUCCESS(rv, rv);
357 : rv = isExistFileOrSymlink(oldlockFile,&nExist);
358 : NS_ENSURE_SUCCESS(rv, rv);
359 : }
360 : return nExist;
361 : }
362 :
363 : #endif
364 0 : bool ProfileAccess::isProfileLocked( ::com::sun::star::mozilla::MozillaProductType product, const OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
365 : {
366 : #ifdef MINIMAL_PROFILEDISCOVER
367 : (void)product; /* avoid warning about unused parameter */
368 : (void)profileName; /* avoid warning about unused parameter */
369 0 : return true;
370 : #else
371 : OUString path = getProfilePath(product,profileName);
372 : if (path.isEmpty())
373 : return sal_True;
374 :
375 : // PRUnichar != sal_Unicode in mingw
376 : nsAutoString filePath(reinterpret_cast_mingw_only<const PRUnichar *>(path.getStr()));
377 :
378 : nsresult rv;
379 : nsCOMPtr<nsILocalFile> localFile;
380 : rv = NS_NewLocalFile(filePath, PR_TRUE,
381 : getter_AddRefs(localFile));
382 : NS_ENSURE_SUCCESS(rv,sal_True);
383 :
384 : PRBool exists = PR_FALSE;
385 : rv = localFile->Exists(&exists);
386 : NS_ENSURE_SUCCESS(rv, sal_True);
387 : if (!exists)
388 : return sal_True;
389 :
390 : // If the profile is locked, we return true
391 : rv = isLockExist(localFile);
392 : if (rv)
393 : return sal_True;
394 : return sal_False;
395 : #endif
396 : }
397 :
398 0 : bool ProfileAccess::getProfileExists( ::com::sun::star::mozilla::MozillaProductType product, const OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
399 : {
400 0 : sal_Int32 index=product;
401 0 : ProductStruct &m_Product = m_ProductProfileList[index];
402 0 : if (!m_Product.mProfileList.size() || m_Product.mProfileList.find(profileName) == m_Product.mProfileList.end())
403 : {
404 0 : return false;
405 : }
406 : else
407 0 : return true;
408 : }
409 : }
410 : }
411 :
412 :
413 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|