presage 0.9.1
profileManager.cpp
Go to the documentation of this file.
1
2/******************************************************
3 * Presage, an extensible predictive text entry system
4 * ---------------------------------------------------
5 *
6 * Copyright (C) 2008 Matteo Vescovi <matteo.vescovi@yahoo.co.uk>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 **********(*)*/
23
24
25#include "profileManager.h"
26#include "utility.h" // isYes isNo isTrue isFalse utility function
27#include "dirs.h" // sysconfdir macro define
28#include "configuration.h"
29
30#ifdef HAVE_PWD_H
31# include <pwd.h>
32#endif
33
34#if HAVE_UNISTD_H
35# include <sys/types.h>
36# include <unistd.h>
37#endif
38
39#if HAVE_STDLIB_H
40# include <stdlib.h>
41#endif
42
43#if defined(_WIN32)
44# include <windows.h>
45#endif
46
47const char* ProfileManager::LOGGER = "Presage.ProfileManager.LOGGER";
48const char* ProfileManager::AUTOPERSIST = "Presage.ProfileManager.AUTOPERSIST";
49
55ProfileManager::ProfileManager(const std::string profilename)
56 : logger("ProfileManager", std::cerr)
57{
58 config = new Configuration();
60 rw_profile = 0;
61 autopersist_config = false;
62
63 init_profiles (profilename);
64}
65
66
82
83
85{
86 Profile* profile = new Profile (filename);
87
88 std::string message;
89 if (profile->file_read_ok ()) {
90 // logger has not been init'd with configuration, because no
91 // profile is known yet, hence caching this logging item,
92 // which will be flushed when configuration is finally read in
93 //
94 message = "Loaded profile: " + filename;
95
97
98 } else {
99 // logger has not been init'd with configuration, because no
100 // profile is known yet, hence caching this logging item,
101 // which will be flushed when configuration is finally read in
102 //
103 message = "Failed to load profile: " + filename;
104
106
107 }
108
109 return profile;
110}
111
112
113void ProfileManager::init_profiles (const std::string& profilename)
114{
115 std::list<std::string> profiles;
116
117 {
118 // load default profile values
119 DefaultProfile default_profile ("");
120 default_profile.read_into_configuration (config);
121 }
122
123
124 // system etc directory
126 // installation config directory
127 profiles.push_back (static_cast<std::string>(sysconfdir) + '/' + DefaultProfile::DEFAULT_PROFILE_FILENAME);
128 // home dir dotfile
129 profiles.push_back (get_user_home_dir() + "/.presage/" + DefaultProfile::DEFAULT_PROFILE_FILENAME);
130 // user specified profile (if any)
131 if (! profilename.empty()) {
132 profiles.push_back(profilename);
133 }
134
135
136 // read data from each profile and write it to configuration
137 Profile* profile = 0;
138 for (std::list<std::string>::const_iterator it = profiles.begin();
139 it != profiles.end();
140 it++ ) {
141 delete profile;
142 profile = create_profile_from_xml (*it);
145 }
146
147 // remember last profile as writable profile
148 rw_profile = profile;
149}
150
151
153{
154 std::string result;
155
156#if defined(_WIN32)
157 DWORD size;
158 DWORD type;
159 LONG res;
160 HKEY reg_key = NULL;
161 char *dst = NULL;
162
163 res = RegOpenKeyExA (HKEY_CURRENT_USER, "Software\\Presage", 0,
164 KEY_READ, &reg_key);
165
166 if (res == ERROR_SUCCESS)
167 {
168 size = 64;
169 dst = (char*) malloc (size);
170
171 res = RegQueryValueExA (reg_key, "", 0, &type,
172 (LPBYTE) dst, &size);
173 if (res == ERROR_MORE_DATA && type == REG_SZ) {
174 char* tmp_dst = (char*) realloc (dst, size);
175 if (tmp_dst != NULL) {
176 dst = tmp_dst;
177 } else {
178 // realloc failed, try to free and malloc
179 free (dst);
180 dst = (char*) malloc (size);
181 if (dst == NULL) {
182 // malloc failed, cannot recover, just return empty result
183 return result;
184 }
185 }
186 res = RegQueryValueExA (reg_key, "", 0,
187 &type, (LPBYTE) dst,
188 &size);
189 }
190
191 if (type != REG_SZ || res != ERROR_SUCCESS)
192 {
193 result = ".";
194 }
195 else
196 {
197 result = dst;
198 result += "\\etc";
199 }
200
201 free (dst);
202 dst = 0;
203 RegCloseKey (reg_key);
204 }
205
206#else
207 result = "/etc";
208#endif
209
210 return result;
211}
212
213
215{
216 std::string result;
217
218#ifdef _WIN32
219 const char* USERPROFILE = "USERPROFILE";
220 char* value = getenv(USERPROFILE);
221 // check if USERPROFILE env var exists...
222 if (value) {
223 result = value;
224 }
225#else
226# ifdef HAVE_PWD_H
227 uid_t me;
228 struct passwd *my_passwd;
229
230 me = getuid ();
231 my_passwd = getpwuid (me);
232 if (!my_passwd) {
233 // got passwd for user
234 // read home dir from passwd struct
235 result = my_passwd->pw_dir;
236 } else
237 // unable to get passwd struct,
238 // read $HOME env variable
239# endif // HAVE_PWD_H
240 {
241 const char* HOME = "HOME";
242 char* value = getenv(HOME);
243 // check if HOME env var exists,
244 // assigning a null pointer to a string is
245 // not such a good idea...
246 if (value) {
247 result = value;
248 }
249 }
250#endif
251
252 return result;
253}
254
255
262{
264 bool saveOk = rw_profile->write_to_file ();
265 if (! saveOk) {
266 logger << ERROR << "Failed to save configuration to profile " << endl;
267 }
268}
269
271{
272 // since a Profile is being returned, we know we have a valid
273 // configuration object. Here, we obtain a temporary Configuration
274 // object to read the this ProfileManager configuration. We could
275 // not do this during profile manager construction because no
276 // profile was available at that time.
277 //
279 return config;
280}
281
282void ProfileManager::cache_log_message(Logger<char>::Level level, const std::string& message)
283{
284 static CachedLogMessage clm;
285 //clm.level = level;
286 clm.message = message;
287 //std::cerr << "Caching message: " << message << std::endl;
288 cached_log_messages.push_back(clm);
289}
290
292{
293 std::list<CachedLogMessage>::const_iterator it = cached_log_messages.begin();
294 while (it != cached_log_messages.end()) {
295 //std::cerr << "Flushing message: " << it->message << std::endl;
296 logger << NOTICE << it->message << endl;
297 it++;
298 }
299 cached_log_messages.clear();
300}
301
303{
304 try {
307 // if no config is available, turn on full logging for profile
308 // manager
309 logger << setlevel("ALL");
310 }
311
313}
314
315void ProfileManager::set_autopersist (const std::string& value)
316{
318 logger << INFO << "AUTOPERSIST: " << autopersist_config << endl;
319}
const char HOME
Definition charsets.h:38
Variable * find(const std::string &variable) const
static const char * DEFAULT_PROFILE_FILENAME
Level
Definition logger.h:61
@ NOTICE
Definition logger.h:68
bool loaded_at_least_one_profile
static const char * LOGGER
void set_autopersist(const std::string &value)
void cache_log_message(Logger< char >::Level level, const std::string &message)
Logger< char > logger
Profile * create_profile_from_xml(const std::string &filename)
std::list< CachedLogMessage > cached_log_messages
std::string get_system_etc_dir() const
std::string get_user_home_dir() const
void save_profile() const
static const char * AUTOPERSIST
void flush_cached_log_messages()
ProfileManager(const std::string="")
void init_profiles(const std::string &profilename)
Configuration * get_configuration()
Profile * rw_profile
Configuration * config
void read_from_configuration(Configuration *configuration)
Definition profile.cpp:102
void read_into_configuration(Configuration *configuration)
Definition profile.cpp:50
bool write_to_file() const
Definition profile.cpp:96
bool file_read_ok() const
Definition profile.cpp:45
static bool isTrue(const char *)
Definition utility.cpp:107
std::string get_value() const
Definition variable.cpp:62
_SetLevel setlevel(std::string __l)
Manipulator for level.
Definition logger.h:46
const Logger< _charT, _Traits > & endl(const Logger< _charT, _Traits > &lgr)
Definition logger.h:278