Update ooo320-m1
[ooovba.git] / connectivity / source / drivers / mozab / bootstrap / MNSProfileDiscover.cxx
blob26fab98748ff6e595dd374d113ff0f93a629f214
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MNSProfileDiscover.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
34 #include "MNSProfileDiscover.hxx"
35 #ifndef MINIMAL_PROFILEDISCOVER
36 #include "MNSProfile.hxx"
38 #include "pratom.h"
39 #include "prmem.h"
40 #include "plstr.h"
41 #include "prenv.h"
43 #include "nsIEnumerator.h"
44 #include "prprf.h"
45 #include "nsCOMPtr.h"
46 #include "nsIComponentManager.h"
47 #include "nsEscape.h"
48 #include "nsDirectoryServiceDefs.h"
49 #include "nsAppDirectoryServiceDefs.h"
50 #include "nsILocalFile.h"
51 #include "nsReadableUtils.h"
54 #if defined(XP_MAC) || defined(XP_MACOSX)
55 #include <Processes.h>
56 #include <CFBundle.h>
57 #include "nsILocalFileMac.h"
58 #endif
60 #ifdef XP_UNIX
61 #include <unistd.h>
62 #include <fcntl.h>
63 #include <errno.h>
64 #include <signal.h>
65 #include "prnetdb.h"
66 #include "prsystem.h"
67 #endif
69 #ifdef VMS
70 #include <rmsdef.h>
71 #endif
73 #include "nsICharsetConverterManager.h"
74 #include "nsIPlatformCharset.h"
77 #if defined (XP_UNIX)
78 #define USER_ENVIRONMENT_VARIABLE "USER"
79 #define LOGNAME_ENVIRONMENT_VARIABLE "LOGNAME"
80 #define HOME_ENVIRONMENT_VARIABLE "HOME"
81 #define PROFILE_NAME_ENVIRONMENT_VARIABLE "PROFILE_NAME"
82 #define PROFILE_HOME_ENVIRONMENT_VARIABLE "PROFILE_HOME"
83 #define DEFAULT_UNIX_PROFILE_NAME "default"
84 #ifndef XP_MACOSX /* Don't use symlink-based locking on OS X */
85 #define USE_SYMLINK_LOCKING
86 #endif
87 #elif defined (XP_BEOS)
88 #endif
90 // IID and CIDs of all the services needed
91 static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
92 #endif
94 // Registry Keys
96 static ::rtl::OUString szProfileSubtreeString=::rtl::OUString::createFromAscii("Profiles");
97 static ::rtl::OUString szCurrentProfileString= ::rtl::OUString::createFromAscii("CurrentProfile");
98 static ::rtl::OUString szDirectoryString =::rtl::OUString::createFromAscii("directory");
100 #ifndef MAXPATHLEN
101 #define MAXPATHLEN 1024
102 #endif
103 #include <MNSFolders.hxx>
104 #include <MNSINIParser.hxx>
106 namespace connectivity
108 namespace mozab
110 ProfileStruct::ProfileStruct(MozillaProductType aProduct,::rtl::OUString aProfileName,
111 #ifdef MINIMAL_PROFILEDISCOVER
112 const ::rtl::OUString& aProfilePath
113 #else
114 nsILocalFile * aProfilePath
115 #endif
118 product=aProduct;
119 profileName = aProfileName;
120 profilePath = aProfilePath;
122 ::rtl::OUString ProfileStruct::getProfilePath()
124 #ifdef MINIMAL_PROFILEDISCOVER
125 return profilePath;
126 #else
127 if (profilePath)
129 nsAutoString path;
130 nsresult rv = profilePath->GetPath(path);
131 NS_ENSURE_SUCCESS(rv, ::rtl::OUString());
132 // PRUnichar != sal_Unicode in mingw
133 return ::rtl::OUString(reinterpret_cast_mingw_only<const sal_Unicode *>(path.get()));
135 else
136 return ::rtl::OUString();
137 #endif
140 ProfileAccess::~ProfileAccess()
143 ProfileAccess::ProfileAccess()
145 LoadProductsInfo();
148 sal_Int32 ProfileAccess::LoadProductsInfo()
150 #ifndef MINIMAL_PROFILEDISCOVER
151 //load mozilla profiles to m_ProductProfileList
152 LoadMozillaProfiles();
153 #endif
154 sal_Int32 count=static_cast<sal_Int32>(m_ProductProfileList[MozillaProductType_Mozilla].mProfileList.size());
156 //load thunderbird profiles to m_ProductProfileList
157 count += LoadXPToolkitProfiles(MozillaProductType_Thunderbird);
159 //load firefox profiles to m_ProductProfileList
160 //firefox profile does not containt address book, but maybe others need them
161 count += LoadXPToolkitProfiles(MozillaProductType_Firefox);
162 return count;
164 #ifndef MINIMAL_PROFILEDISCOVER
165 nsresult ProfileAccess::LoadMozillaProfiles()
167 sal_Int32 index=MozillaProductType_Mozilla;
168 ProductStruct &m_Product = m_ProductProfileList[index];
169 nsresult rv = NS_OK;
171 //step 1 : get mozilla registry file
172 nsCOMPtr<nsILocalFile> localFile;
173 ::rtl::OUString regDir( getRegistryFileName( MozillaProductType_Mozilla ) );
174 // PRUnichar != sal_Unicode in mingw
175 nsAutoString registryDir(reinterpret_cast_mingw_only<const PRUnichar *>(regDir.getStr()));
176 rv = NS_NewLocalFile(registryDir, PR_TRUE,
177 getter_AddRefs(localFile));
178 NS_ENSURE_SUCCESS(rv,rv);
179 PRBool bExist;
180 rv = localFile->Exists(&bExist);
181 NS_ENSURE_SUCCESS(rv,rv);
182 if (!bExist)
183 return rv;
184 nsCOMPtr<nsIRegistry> registry(do_CreateInstance(NS_REGISTRY_CONTRACTID, &rv));
185 NS_ENSURE_SUCCESS(rv,rv);
186 //step 2: open mozilla registry file
187 rv = registry->Open(localFile);
188 NS_ENSURE_SUCCESS(rv,rv);
190 nsCOMPtr<nsIEnumerator> enumKeys;
191 nsRegistryKey profilesTreeKey;
193 //step 3:Enumerator it
194 rv = registry->GetKey(nsIRegistry::Common,
195 // PRUnichar != sal_Unicode in mingw
196 reinterpret_cast_mingw_only<const PRUnichar *>(szProfileSubtreeString.getStr()),
197 &profilesTreeKey);
198 if (NS_FAILED(rv)) return rv;
200 nsXPIDLString tmpCurrentProfile;
202 // Get the current profile
203 rv = registry->GetString(profilesTreeKey,
204 // PRUnichar != sal_Unicode in mingw
205 reinterpret_cast_mingw_only<const PRUnichar *>(szCurrentProfileString.getStr()),
206 getter_Copies(tmpCurrentProfile));
208 if (tmpCurrentProfile)
210 // PRUnichar != sal_Unicode in mingw
211 m_Product.setCurrentProfile ( reinterpret_cast_mingw_only<const sal_Unicode *>(NS_STATIC_CAST(const PRUnichar*, tmpCurrentProfile)));
215 rv = registry->EnumerateSubtrees( profilesTreeKey, getter_AddRefs(enumKeys));
216 NS_ENSURE_SUCCESS(rv,rv);
218 rv = enumKeys->First();
219 NS_ENSURE_SUCCESS(rv,rv);
221 while (NS_OK != enumKeys->IsDone())
223 nsCOMPtr<nsISupports> base;
225 rv = enumKeys->CurrentItem( getter_AddRefs(base) );
226 NS_ENSURE_SUCCESS(rv,rv);
227 rv = enumKeys->Next();
228 NS_ENSURE_SUCCESS(rv,rv);
230 // Get specific interface.
231 nsCOMPtr <nsIRegistryNode> node;
232 nsIID nodeIID = NS_IREGISTRYNODE_IID;
234 rv = base->QueryInterface( nodeIID, getter_AddRefs(node));
235 if (NS_FAILED(rv)) continue;
237 // Get node name.
238 nsXPIDLString profile;
239 rv = node->GetName(getter_Copies(profile));
240 if (NS_FAILED(rv)) continue;
242 nsRegistryKey profKey;
243 rv = node->GetKey(&profKey);
244 if (NS_FAILED(rv)) continue;
247 nsCOMPtr<nsILocalFile> tempLocal;
249 nsXPIDLString regData;
250 rv = registry->GetString(profKey,
251 // PRUnichar != sal_Unicode in mingw
252 reinterpret_cast_mingw_only<const PRUnichar *>(szDirectoryString.getStr()),
253 getter_Copies(regData));
254 if (NS_FAILED(rv)) continue;
256 #if defined(XP_MAC) || defined(XP_MACOSX) || defined(MACOSX)
257 rv = NS_NewNativeLocalFile(nsCString(), PR_TRUE, getter_AddRefs(tempLocal));
258 if (NS_SUCCEEDED(rv))
259 rv = tempLocal->SetPersistentDescriptor(NS_LossyConvertUCS2toASCII(regData));
260 #else
261 rv = NS_NewLocalFile(regData, PR_TRUE, getter_AddRefs(tempLocal));
262 #endif
263 //Add found profile to profile lists
264 if (NS_SUCCEEDED(rv) && tempLocal)
266 // PRUnichar != sal_Unicode in mingw
267 ProfileStruct* profileItem = new ProfileStruct(MozillaProductType_Mozilla,reinterpret_cast_mingw_only<const sal_Unicode *>(NS_STATIC_CAST(const PRUnichar*, profile)),tempLocal);
268 m_Product.mProfileList[profileItem->getProfileName()] = profileItem;
272 return rv;
274 #endif
275 //Thunderbird and firefox profiles are saved in profiles.ini
276 sal_Int32 ProfileAccess::LoadXPToolkitProfiles(MozillaProductType product)
278 sal_Int32 index=product;
279 ProductStruct &m_Product = m_ProductProfileList[index];
281 #ifndef MINIMAL_PROFILEDISCOVER
282 nsresult rv;
283 #endif
284 ::rtl::OUString regDir = getRegistryDir(product);
285 ::rtl::OUString profilesIni( regDir );
286 profilesIni += ::rtl::OUString::createFromAscii( "profiles.ini" );
287 IniParser parser( profilesIni );
288 IniSectionMap &mAllSection = *(parser.getAllSection());
290 IniSectionMap::iterator iBegin = mAllSection.begin();
291 IniSectionMap::iterator iEnd = mAllSection.end();
292 for(;iBegin != iEnd;iBegin++)
294 ini_Section *aSection = &(*iBegin).second;
295 ::rtl::OUString profileName;
296 ::rtl::OUString profilePath;
297 ::rtl::OUString sIsRelative;
298 ::rtl::OUString sIsDefault;
300 for(NameValueList::iterator itor=aSection->lList.begin();
301 itor != aSection->lList.end();
302 itor++)
304 struct ini_NameValue * aValue = &(*itor);
305 if (aValue->sName.equals(::rtl::OUString::createFromAscii("Name")))
307 profileName = aValue->sValue;
309 else if (aValue->sName.equals(::rtl::OUString::createFromAscii("IsRelative")))
311 sIsRelative = aValue->sValue;
313 else if (aValue->sName.equals(::rtl::OUString::createFromAscii("Path")))
315 profilePath = aValue->sValue;
317 else if (aValue->sName.equals(::rtl::OUString::createFromAscii("Default")))
319 sIsDefault = aValue->sValue;
322 if (profileName.getLength() != 0 || profilePath.getLength() != 0)
324 sal_Int32 isRelative = 0;
325 if (sIsRelative.getLength() != 0)
327 isRelative = sIsRelative.toInt32();
330 #ifndef MINIMAL_PROFILEDISCOVER
331 nsCOMPtr<nsILocalFile> rootDir;
332 rv = NS_NewLocalFile(EmptyString(), PR_TRUE,
333 getter_AddRefs(rootDir));
334 if (NS_FAILED(rv)) continue;
336 OString sPath = OUStringToOString(profilePath, RTL_TEXTENCODING_UTF8);
337 nsCAutoString filePath(sPath.getStr());
339 if (isRelative) {
340 // PRUnichar != sal_Unicode in mingw
341 nsAutoString registryDir( reinterpret_cast_mingw_only<const PRUnichar *>(regDir.getStr()) );
342 nsCOMPtr<nsILocalFile> mAppData;
343 rv = NS_NewLocalFile(registryDir, PR_TRUE,
344 getter_AddRefs(mAppData));
345 if (NS_FAILED(rv)) continue;
346 rv = rootDir->SetRelativeDescriptor(mAppData, filePath);
347 } else {
348 rv = rootDir->SetPersistentDescriptor(filePath);
350 if (NS_FAILED(rv)) continue;
351 #endif
353 ProfileStruct* profileItem = new ProfileStruct(product,profileName,
354 #ifdef MINIMAL_PROFILEDISCOVER
355 regDir + profilePath
356 #else
357 rootDir
358 #endif
360 m_Product.mProfileList[profileName] = profileItem;
362 sal_Int32 isDefault = 0;
363 if (sIsDefault.getLength() != 0)
365 isDefault = sIsDefault.toInt32();
367 if (isDefault)
368 m_Product.mCurrentProfileName = profileName;
373 return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
376 ::rtl::OUString ProfileAccess::getProfilePath( ::com::sun::star::mozilla::MozillaProductType product, const ::rtl::OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
378 sal_Int32 index=product;
379 ProductStruct &m_Product = m_ProductProfileList[index];
380 if (!m_Product.mProfileList.size() || m_Product.mProfileList.find(profileName) == m_Product.mProfileList.end())
382 //Profile not found
383 return ::rtl::OUString();
385 else
386 return m_Product.mProfileList[profileName]->getProfilePath();
389 ::sal_Int32 ProfileAccess::getProfileCount( ::com::sun::star::mozilla::MozillaProductType product) throw (::com::sun::star::uno::RuntimeException)
391 sal_Int32 index=product;
392 ProductStruct &m_Product = m_ProductProfileList[index];
393 return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
395 ::sal_Int32 ProfileAccess::getProfileList( ::com::sun::star::mozilla::MozillaProductType product, ::com::sun::star::uno::Sequence< ::rtl::OUString >& list ) throw (::com::sun::star::uno::RuntimeException)
397 sal_Int32 index=product;
398 ProductStruct &m_Product = m_ProductProfileList[index];
399 list.realloc(static_cast<sal_Int32>(m_Product.mProfileList.size()));
400 sal_Int32 i=0;
401 for(ProfileList::iterator itor=m_Product.mProfileList.begin();
402 itor != m_Product.mProfileList.end();
403 itor++)
405 ProfileStruct * aProfile = (*itor).second;
406 list[i] = aProfile->getProfileName();
407 i++;
410 return static_cast< ::sal_Int32 >(m_Product.mProfileList.size());
413 ::rtl::OUString ProfileAccess::getDefaultProfile( ::com::sun::star::mozilla::MozillaProductType product ) throw (::com::sun::star::uno::RuntimeException)
415 sal_Int32 index=product;
416 ProductStruct &m_Product = m_ProductProfileList[index];
417 if (m_Product.mCurrentProfileName.getLength() != 0)
419 //default profile setted in mozilla registry
420 return m_Product.mCurrentProfileName;
422 if (m_Product.mProfileList.size() == 0)
424 //there are not any profiles
425 return ::rtl::OUString();
427 ProfileStruct * aProfile = (*m_Product.mProfileList.begin()).second;
428 return aProfile->getProfileName();
430 #ifndef MINIMAL_PROFILEDISCOVER
431 nsresult ProfileAccess::isExistFileOrSymlink(nsILocalFile* aFile,PRBool *bExist)
433 nsresult rv;
434 nsAutoString path;
435 aFile->GetPath(path);
436 rv = aFile->Exists(bExist);
437 NS_ENSURE_SUCCESS(rv, rv);
438 if (!*bExist)
440 rv = aFile->IsSymlink(bExist);
441 NS_ENSURE_SUCCESS(rv, rv);
443 return rv;
445 nsresult ProfileAccess::isLockExist(nsILocalFile* aFile)
447 #if defined (XP_MACOSX)
448 NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, ".parentlock");
449 NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "parent.lock");
450 #elif defined (XP_UNIX)
451 NS_ConvertASCIItoUTF16 OLD_LOCKFILE_NAME("lock");
452 NS_ConvertASCIItoUTF16 LOCKFILE_NAME(".parentlock");
453 #else
454 NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "parent.lock");
455 NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, "parent.lock");
456 #endif
458 nsresult rv;
460 PRBool isDir;
461 rv = aFile->IsDirectory(&isDir);
462 NS_ENSURE_SUCCESS(rv, rv);
463 if (!isDir)
464 return NS_ERROR_FILE_NOT_DIRECTORY;
466 nsCOMPtr<nsILocalFile> lockFile;
467 rv = aFile->Clone((nsIFile **)((void **)getter_AddRefs(lockFile)));
468 NS_ENSURE_SUCCESS(rv, rv);
470 rv = lockFile->Append(LOCKFILE_NAME);
471 NS_ENSURE_SUCCESS(rv, rv);
472 PRBool nExist=PR_FALSE;
473 rv = isExistFileOrSymlink(lockFile,&nExist);
474 NS_ENSURE_SUCCESS(rv, rv);
475 if (!nExist) // Check OLD_LOCKFILE_NAME
477 nsCOMPtr<nsILocalFile> oldlockFile;
478 rv = aFile->Clone((nsIFile **)((void **)getter_AddRefs(oldlockFile)));
479 NS_ENSURE_SUCCESS(rv, rv);
481 rv = oldlockFile->Append(OLD_LOCKFILE_NAME);
482 NS_ENSURE_SUCCESS(rv, rv);
483 rv = isExistFileOrSymlink(oldlockFile,&nExist);
484 NS_ENSURE_SUCCESS(rv, rv);
486 return nExist;
489 #endif
490 ::sal_Bool ProfileAccess::isProfileLocked( ::com::sun::star::mozilla::MozillaProductType product, const ::rtl::OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
492 #ifdef MINIMAL_PROFILEDISCOVER
493 (void)product; /* avoid warning about unused parameter */
494 (void)profileName; /* avoid warning about unused parameter */
495 return sal_True;
496 #else
497 ::rtl::OUString path = getProfilePath(product,profileName);
498 if (!path.getLength())
499 return sal_True;
501 // PRUnichar != sal_Unicode in mingw
502 nsAutoString filePath(reinterpret_cast_mingw_only<const PRUnichar *>(path.getStr()));
504 nsresult rv;
505 nsCOMPtr<nsILocalFile> localFile;
506 rv = NS_NewLocalFile(filePath, PR_TRUE,
507 getter_AddRefs(localFile));
508 NS_ENSURE_SUCCESS(rv,sal_True);
510 PRBool exists = PR_FALSE;
511 rv = localFile->Exists(&exists);
512 NS_ENSURE_SUCCESS(rv, sal_True);
513 if (!exists)
514 return sal_True;
516 // If the profile is locked, we return true
517 rv = isLockExist(localFile);
518 if (rv)
519 return sal_True;
520 return sal_False;
521 #endif
524 ::sal_Bool ProfileAccess::getProfileExists( ::com::sun::star::mozilla::MozillaProductType product, const ::rtl::OUString& profileName ) throw (::com::sun::star::uno::RuntimeException)
526 sal_Int32 index=product;
527 ProductStruct &m_Product = m_ProductProfileList[index];
528 if (!m_Product.mProfileList.size() || m_Product.mProfileList.find(profileName) == m_Product.mProfileList.end())
530 return sal_False;
532 else
533 return sal_True;