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 #include "MNSFolders.hxx"
23 #include "MNSINIParser.hxx"
24 
25 namespace connectivity
26 {
27     namespace mozab
28     {
ProfileStruct()29         ProfileStruct::ProfileStruct()
30         {
31         }
32 
ProfileStruct(const OUString & aProfileName,const OUString & aProfilePath)33         ProfileStruct::ProfileStruct(const OUString& aProfileName,
34                                      const OUString& aProfilePath)
35             : profileName(aProfileName)
36             , profilePath(aProfilePath)
37         {
38         }
39 
getProfilePath() const40         const OUString& ProfileStruct::getProfilePath() const
41         {
42             return profilePath;
43         }
44 
~ProfileAccess()45         ProfileAccess::~ProfileAccess()
46         {
47         }
48 
ProfileAccess()49         ProfileAccess::ProfileAccess()
50         {
51             LoadProductsInfo();
52         }
53 
LoadProductsInfo()54         void ProfileAccess::LoadProductsInfo()
55         {
56             //tdf#39279: LO should search Thunderbird first then Seamonkey and finally Firefox
57             //load thunderbird profiles to m_ProductProfileList
58             LoadXPToolkitProfiles(MozillaProductType_Thunderbird);
59 
60             //load SeaMonkey 2 profiles to m_ProductProfileList
61             LoadXPToolkitProfiles(MozillaProductType_Mozilla);
62 
63             //load firefox profiles to m_ProductProfileList
64             //firefox profile does not contain address book, but maybe others need them
65             LoadXPToolkitProfiles(MozillaProductType_Firefox);
66         }
67         //Thunderbird and firefox profiles are saved in profiles.ini
LoadXPToolkitProfiles(MozillaProductType product)68         void ProfileAccess::LoadXPToolkitProfiles(MozillaProductType product)
69         {
70             sal_Int32 index=static_cast<sal_Int32>(product);
71             ProductStruct &rProduct = m_ProductProfileList[index];
72 
73             OUString regDir = getRegistryDir(product);
74             OUString profilesIni = regDir + "profiles.ini";
75             IniParser parser( profilesIni );
76             IniSectionMap &rAllSection = parser.getAllSection();
77 
78             for(auto& rSection : rAllSection)
79             {
80                 ini_Section *aSection = &rSection.second;
81                 OUString profileName;
82                 OUString profilePath;
83                 OUString sIsRelative;
84                 OUString sIsDefault;
85 
86                 for(auto& rValue : aSection->vVector)
87                 {
88                     struct ini_NameValue * aValue = &rValue;
89                     if ( aValue->sName == "Name" )
90                     {
91                         profileName = aValue->sValue;
92                     }
93                     else if ( aValue->sName == "IsRelative" )
94                     {
95                         sIsRelative = aValue->sValue;
96                     }
97                     else if ( aValue->sName == "Path" )
98                     {
99                         profilePath = aValue->sValue;
100                     }
101                     else if ( aValue->sName == "Default" )
102                     {
103                         sIsDefault = aValue->sValue;
104                     }
105                 }
106                 if (!(profileName.isEmpty() && profilePath.isEmpty()))
107                 {
108                     sal_Int32 isRelative = 0;
109                     if (!sIsRelative.isEmpty())
110                     {
111                         isRelative = sIsRelative.toInt32();
112                     }
113 
114                     OUString fullProfilePath;
115                     if(isRelative)
116                     {
117                         fullProfilePath = regDir + profilePath;
118                     }
119                     else
120                     {
121                         fullProfilePath = profilePath;
122                     }
123 
124                     rProduct.mProfileList[profileName] = ProfileStruct(profileName,fullProfilePath);
125 
126                     sal_Int32 isDefault = 0;
127                     if (!sIsDefault.isEmpty())
128                     {
129                         isDefault = sIsDefault.toInt32();
130                     }
131                     if (isDefault)
132                         rProduct.mCurrentProfileName = profileName;
133 
134                 }
135 
136                 // Depending on TB versions, some generate "default" profile
137                 // others "default-release" profile
138                 // See https://support.mozilla.org/gl/questions/1264072
139                 // for some background info (the link quotes Firefox but it seems
140                 // the same for TB).
141                 if (profileName == "default-release")
142                 {
143                     rProduct.mCurrentProfileName = profileName;
144                     break;
145                 }
146             }
147         }
148 
getProfilePath(css::mozilla::MozillaProductType product,const OUString & profileName)149         OUString ProfileAccess::getProfilePath( css::mozilla::MozillaProductType product, const OUString& profileName )
150         {
151             sal_Int32 index=static_cast<sal_Int32>(product);
152             ProductStruct &rProduct = m_ProductProfileList[index];
153             if (rProduct.mProfileList.empty() || rProduct.mProfileList.find(profileName) == rProduct.mProfileList.end())
154             {
155                 //Profile not found
156                 return OUString();
157             }
158             else
159                 return rProduct.mProfileList[profileName].getProfilePath();
160         }
161 
getProfileCount(css::mozilla::MozillaProductType product)162         ::sal_Int32 ProfileAccess::getProfileCount( css::mozilla::MozillaProductType product)
163         {
164             sal_Int32 index=static_cast<sal_Int32>(product);
165             ProductStruct &rProduct = m_ProductProfileList[index];
166             return static_cast< ::sal_Int32 >(rProduct.mProfileList.size());
167         }
getProfileList(css::mozilla::MozillaProductType product,css::uno::Sequence<OUString> & list)168         ::sal_Int32 ProfileAccess::getProfileList( css::mozilla::MozillaProductType product, css::uno::Sequence< OUString >& list )
169         {
170             sal_Int32 index=static_cast<sal_Int32>(product);
171             ProductStruct &rProduct = m_ProductProfileList[index];
172             list.realloc(static_cast<sal_Int32>(rProduct.mProfileList.size()));
173             sal_Int32 i=0;
174             for(const auto& rEntry : rProduct.mProfileList)
175             {
176                 const ProfileStruct& rProfile = rEntry.second;
177                 list[i] = rProfile.getProfileName();
178                 i++;
179             }
180 
181             return static_cast< ::sal_Int32 >(rProduct.mProfileList.size());
182         }
183 
getDefaultProfile(css::mozilla::MozillaProductType product)184         OUString ProfileAccess::getDefaultProfile( css::mozilla::MozillaProductType product )
185         {
186             sal_Int32 index=static_cast<sal_Int32>(product);
187             ProductStruct &rProduct = m_ProductProfileList[index];
188             if (!rProduct.mCurrentProfileName.isEmpty())
189             {
190                 //default profile set in mozilla registry
191                 return rProduct.mCurrentProfileName;
192             }
193             if (rProduct.mProfileList.empty())
194             {
195                 //there are not any profiles
196                 return OUString();
197             }
198             const ProfileStruct& rProfile = (*rProduct.mProfileList.begin()).second;
199             return rProfile.getProfileName();
200         }
201 
getProfileExists(css::mozilla::MozillaProductType product,const OUString & profileName)202         bool ProfileAccess::getProfileExists( css::mozilla::MozillaProductType product, const OUString& profileName )
203         {
204             sal_Int32 index=static_cast<sal_Int32>(product);
205             ProductStruct &rProduct = m_ProductProfileList[index];
206             return rProduct.mProfileList.find(profileName) != rProduct.mProfileList.end();
207         }
208     }
209 }
210 
211 
212 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
213