presage  0.8.8
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 
47 const char* ProfileManager::LOGGER = "Presage.ProfileManager.LOGGER";
48 const char* ProfileManager::AUTOPERSIST = "Presage.ProfileManager.AUTOPERSIST";
49 
55 ProfileManager::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 
71 {
73 
75  if (autopersist_config) {
76  save_profile ();
77  }
78 
79  delete config;
80  delete rw_profile;
81 }
82 
83 
84 Profile* ProfileManager::create_profile_from_xml (const std::string& filename)
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 
105  cache_log_message(logger.NOTICE, message);
106 
107  }
108 
109  return profile;
110 }
111 
112 
113 void 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
125  profiles.push_back (get_system_etc_dir() + '/' + DefaultProfile::DEFAULT_PROFILE_FILENAME);
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);
144  profile->read_into_configuration (config);
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  dst = (char*) realloc (dst, size);
175  res = RegQueryValueExA (reg_key, "", 0, &type,
176  (LPBYTE) dst, &size);
177  }
178 
179  if (type != REG_SZ || res != ERROR_SUCCESS)
180  {
181  result = ".";
182  }
183  else
184  {
185  result = dst;
186  result += "\\etc";
187  }
188 
189  free (dst);
190  dst = 0;
191  RegCloseKey (reg_key);
192  }
193 
194 #else
195  result = "/etc";
196 #endif
197 
198  return result;
199 }
200 
201 
203 {
204  std::string result;
205 
206 #ifdef _WIN32
207  const char* USERPROFILE = "USERPROFILE";
208  char* value = getenv(USERPROFILE);
209  // check if USERPROFILE env var exists...
210  if (value) {
211  result = value;
212  }
213 #else
214 # ifdef HAVE_PWD_H
215  uid_t me;
216  struct passwd *my_passwd;
217 
218  me = getuid ();
219  my_passwd = getpwuid (me);
220  if (!my_passwd) {
221  // got passwd for user
222  // read home dir from passwd struct
223  result = my_passwd->pw_dir;
224  } else
225  // unable to get passwd struct,
226  // read $HOME env variable
227 # endif // HAVE_PWD_H
228  {
229  const char* HOME = "HOME";
230  char* value = getenv(HOME);
231  // check if HOME env var exists,
232  // assigning a null pointer to a string is
233  // not such a good idea...
234  if (value) {
235  result = value;
236  }
237  }
238 #endif
239 
240  return result;
241 }
242 
243 
250 {
252  bool saveOk = rw_profile->write_to_file ();
253  if (! saveOk) {
254  logger << ERROR << "Failed to save configuration to profile " << endl;
255  }
256 }
257 
259 {
260  // since a Profile is being returned, we know we have a valid
261  // configuration object. Here, we obtain a temporary Configuration
262  // object to read the this ProfileManager configuration. We could
263  // not do this during profile manager construction because no
264  // profile was available at that time.
265  //
266  refresh_config();
267  return config;
268 }
269 
270 void ProfileManager::cache_log_message(Logger<char>::Level level, const std::string& message)
271 {
272  static CachedLogMessage clm;
273  //clm.level = level;
274  clm.message = message;
275  //std::cerr << "Caching message: " << message << std::endl;
276  cached_log_messages.push_back(clm);
277 }
278 
280 {
281  std::list<CachedLogMessage>::const_iterator it = cached_log_messages.begin();
282  while (it != cached_log_messages.end()) {
283  //std::cerr << "Flushing message: " << it->message << std::endl;
284  logger << NOTICE << it->message << endl;
285  it++;
286  }
287  cached_log_messages.clear();
288 }
289 
291 {
292  try {
295  // if no config is available, turn on full logging for profile
296  // manager
297  logger << setlevel("ALL");
298  }
299 
301 }
302 
303 void ProfileManager::set_autopersist (const std::string& value)
304 {
306  logger << INFO << "AUTOPERSIST: " << autopersist_config << endl;
307 }
Definition: logger.h:56
static const char * DEFAULT_PROFILE_FILENAME
Configuration * config
std::string get_user_home_dir() const
Configuration * get_configuration()
Logger< char > logger
std::string get_system_etc_dir() const
Variable * find(const std::string &variable) const
static const char * LOGGER
std::list< CachedLogMessage > cached_log_messages
_SetLevel setlevel(std::string __l)
Manipulator for level.
Definition: logger.h:46
Profile * rw_profile
const char HOME
Definition: charsets.h:38
bool loaded_at_least_one_profile
void read_from_configuration(Configuration *configuration)
Definition: profile.cpp:102
void set_autopersist(const std::string &value)
void init_profiles(const std::string &profilename)
bool file_read_ok() const
Definition: profile.cpp:45
void cache_log_message(Logger< char >::Level level, const std::string &message)
bool write_to_file() const
Definition: profile.cpp:96
static const char * AUTOPERSIST
void save_profile() const
void read_into_configuration(Configuration *configuration)
Definition: profile.cpp:50
static bool isTrue(const char *)
Definition: utility.cpp:107
void flush_cached_log_messages()
Profile * create_profile_from_xml(const std::string &filename)
ProfileManager(const std::string="")
std::string get_value() const
Definition: variable.cpp:62
const Logger< _charT, _Traits > & endl(const Logger< _charT, _Traits > &lgr)
Definition: logger.h:278