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 // config specified by environment overrides system config
125 char *env_profile = getenv("PRESAGE_CONFIG");
126 if (env_profile != NULL) {
127 profiles.push_back(env_profile);
128 } else {
129 // system etc directory
131 // installation config directory
132 profiles.push_back (static_cast<std::string>(sysconfdir) + '/' + DefaultProfile::DEFAULT_PROFILE_FILENAME);
133 }
134 // home dir dotfile
135 profiles.push_back (get_user_home_dir() + "/.presage/" + DefaultProfile::DEFAULT_PROFILE_FILENAME);
136 // user specified profile (if any)
137 if (! profilename.empty()) {
138 profiles.push_back(profilename);
139 }
140
141
142 // read data from each profile and write it to configuration
143 Profile* profile = 0;
144 for (std::list<std::string>::const_iterator it = profiles.begin();
145 it != profiles.end();
146 it++ ) {
147 delete profile;
148 profile = create_profile_from_xml (*it);
151 }
152
153 // remember last profile as writable profile
154 rw_profile = profile;
155}
156
157
159{
160 std::string result;
161
162#if defined(_WIN32)
163 DWORD size;
164 DWORD type;
165 LONG res;
166 HKEY reg_key = NULL;
167 char *dst = NULL;
168
169 res = RegOpenKeyExA (HKEY_CURRENT_USER, "Software\\Presage", 0,
170 KEY_READ, &reg_key);
171
172 if (res == ERROR_SUCCESS)
173 {
174 size = 64;
175 dst = (char*) malloc (size);
176
177 res = RegQueryValueExA (reg_key, "", 0, &type,
178 (LPBYTE) dst, &size);
179 if (res == ERROR_MORE_DATA && type == REG_SZ) {
180 char* tmp_dst = (char*) realloc (dst, size);
181 if (tmp_dst != NULL) {
182 dst = tmp_dst;
183 } else {
184 // realloc failed, try to free and malloc
185 free (dst);
186 dst = (char*) malloc (size);
187 if (dst == NULL) {
188 // malloc failed, cannot recover, just return empty result
189 return result;
190 }
191 }
192 res = RegQueryValueExA (reg_key, "", 0,
193 &type, (LPBYTE) dst,
194 &size);
195 }
196
197 if (type != REG_SZ || res != ERROR_SUCCESS)
198 {
199 result = ".";
200 }
201 else
202 {
203 result = dst;
204 result += "\\etc";
205 }
206
207 free (dst);
208 dst = 0;
209 RegCloseKey (reg_key);
210 }
211
212#else
213 result = "/etc";
214#endif
215
216 return result;
217}
218
219
221{
222 std::string result;
223
224#ifdef _WIN32
225 const char* USERPROFILE = "USERPROFILE";
226 char* value = getenv(USERPROFILE);
227 // check if USERPROFILE env var exists...
228 if (value) {
229 result = value;
230 }
231#else
232# ifdef HAVE_PWD_H
233 uid_t me;
234 struct passwd *my_passwd;
235
236 me = getuid ();
237 my_passwd = getpwuid (me);
238 if (!my_passwd) {
239 // got passwd for user
240 // read home dir from passwd struct
241 result = my_passwd->pw_dir;
242 } else
243 // unable to get passwd struct,
244 // read $HOME env variable
245# endif // HAVE_PWD_H
246 {
247 const char* HOME = "HOME";
248 char* value = getenv(HOME);
249 // check if HOME env var exists,
250 // assigning a null pointer to a string is
251 // not such a good idea...
252 if (value) {
253 result = value;
254 }
255 }
256#endif
257
258 return result;
259}
260
261
268{
270 bool saveOk = rw_profile->write_to_file ();
271 if (! saveOk) {
272 logger << ERROR << "Failed to save configuration to profile " << endl;
273 }
274}
275
277{
278 // since a Profile is being returned, we know we have a valid
279 // configuration object. Here, we obtain a temporary Configuration
280 // object to read the this ProfileManager configuration. We could
281 // not do this during profile manager construction because no
282 // profile was available at that time.
283 //
285 return config;
286}
287
288void ProfileManager::cache_log_message(Logger<char>::Level level, const std::string& message)
289{
290 static CachedLogMessage clm;
291 //clm.level = level;
292 clm.message = message;
293 //std::cerr << "Caching message: " << message << std::endl;
294 cached_log_messages.push_back(clm);
295}
296
298{
299 std::list<CachedLogMessage>::const_iterator it = cached_log_messages.begin();
300 while (it != cached_log_messages.end()) {
301 //std::cerr << "Flushing message: " << it->message << std::endl;
302 logger << NOTICE << it->message << endl;
303 it++;
304 }
305 cached_log_messages.clear();
306}
307
309{
310 try {
313 // if no config is available, turn on full logging for profile
314 // manager
315 logger << setlevel("ALL");
316 }
317
319}
320
321void ProfileManager::set_autopersist (const std::string& value)
322{
324 logger << INFO << "AUTOPERSIST: " << autopersist_config << endl;
325}
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