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: */
|