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