GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-environment.c
1 /*
2  * gnc-environment.c:
3  *
4  * Copyright (C) 2013 Geert Janssens <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, contact:
18  *
19  * Free Software Foundation Voice: +1-617-542-5942
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21  * Boston, MA 02110-1301, USA [email protected]
22  */
23 
24 #include <glib.h>
25 #include <string.h>
26 #include "gnc-environment.h"
27 #include "gnc-path.h"
28 
29 static gchar *environment_expand(gchar *param)
30 {
31  gchar *search_start;
32  gchar *opening_brace;
33  gchar *closing_brace;
34  gchar *result;
35  gchar *tmp;
36  gchar *expanded = NULL;
37 
38  if (!param)
39  return NULL;
40 
41  /* Set an initial return value, so we can always use g_strconcat below) */
42  result = g_strdup ("x");
43 
44  /* Look for matching pairs of { and }. Anything in between should be expanded */
45  search_start = param;
46  opening_brace = g_strstr_len (search_start, -1, "{");
47  closing_brace = g_strstr_len (search_start, -1, "}");
48 
49  /* Note: the test on valid braces is fairly simple:
50  * * if no pair of opening/closing braces is found, no expansion occurs
51  * * braces can't be nested, this will give unexpected results
52  * * the string should contain no other braces than those used to mark
53  * expandable variables, or unexpected results will be returned.
54  */
55  while ( opening_brace && closing_brace && (closing_brace > opening_brace) )
56  {
57  /* Found a first matching pair */
58  gchar *to_expand;
59  const gchar *env_val;
60 
61  /* If the string had characters before the opening {, copy them first */
62  if (opening_brace > search_start)
63  {
64  gchar *prefix = g_strndup (search_start, opening_brace - search_start);
65 
66  tmp = g_strconcat (result, prefix, NULL);
67  g_free (result);
68  result = tmp;
69  g_free (prefix);
70  }
71 
72  /* Expand the variable we found and append it to the result */
73  to_expand = g_strndup (opening_brace + 1, closing_brace - opening_brace - 1);
74  env_val = g_getenv (to_expand);
75  tmp = g_strconcat (result, env_val, NULL);
76  g_free (result);
77  result = tmp;
78  g_free (to_expand);
79 
80  /* Look for matching pairs of { and }. Anything in between should be expanded */
81  search_start = closing_brace + 1;
82  opening_brace = g_strstr_len (search_start, -1, "{");
83  closing_brace = g_strstr_len (search_start, -1, "}");
84  }
85 
86  /* No more braces found, append the remaining characters */
87  tmp = g_strconcat (result, search_start, NULL);
88  g_free (result);
89  result = tmp;
90 
91  /* Remove the "x" from our result */
92  if (g_strcmp0 (result, "x"))
93  expanded = g_strdup (result + 1);
94  g_free (result);
95 
96  return expanded;
97 }
98 
99 void
101 {
102  gchar *config_path;
103  gchar *env_file;
104  GKeyFile *keyfile = g_key_file_new();
105  GError *error;
106  gchar **env_vars;
107  gsize param_count;
108  gint i;
109  gboolean got_keyfile;
110  gchar *env_parm;
111 
112  /* Export default parameters to the environment */
113  env_parm = gnc_path_get_prefix();
114  if (!g_setenv("GNC_HOME", env_parm, FALSE))
115  g_warning ("Couldn't set/override environment variable GNC_HOME.");
116  g_free (env_parm);
117  env_parm = gnc_path_get_bindir();
118  if (!g_setenv("GNC_BIN", env_parm, FALSE))
119  g_warning ("Couldn't set/override environment variable GNC_BIN.");
120  g_free (env_parm);
121  env_parm = gnc_path_get_pkglibdir();
122  if (!g_setenv("GNC_LIB", env_parm, FALSE))
123  g_warning ("Couldn't set/override environment variable GNC_LIB.");
124  g_free (env_parm);
125  env_parm = gnc_path_get_pkgdatadir();
126  if (!g_setenv("GNC_DATA", env_parm, FALSE))
127  g_warning ("Couldn't set/override environment variable GNC_DATA.");
128  g_free (env_parm);
129  env_parm = gnc_path_get_pkgsysconfdir();
130  if (!g_setenv("GNC_CONF", env_parm, FALSE))
131  g_warning ("Couldn't set/override environment variable GNC_CONF.");
132  g_free (env_parm);
133  env_parm = gnc_path_get_libdir();
134  if (!g_setenv("SYS_LIB", env_parm, FALSE))
135  g_warning ("Couldn't set/override environment variable SYS_LIB.");
136  g_free (env_parm);
137 
138  config_path = gnc_path_get_pkgsysconfdir();
139 #ifdef G_OS_WIN32
140  {
141  /* unhide files without extension */
142  gchar *pathext = g_build_path(";", ".", g_getenv("PATHEXT"),
143  (gchar*) NULL);
144  g_setenv("PATHEXT", pathext, TRUE);
145  g_free(pathext);
146  }
147 #endif
148 
149  env_file = g_build_filename (config_path, "environment", NULL);
150  got_keyfile = g_key_file_load_from_file (keyfile, env_file, G_KEY_FILE_NONE, &error);
151  g_free (config_path);
152  g_free (env_file);
153  if ( !got_keyfile )
154  {
155  g_key_file_free(keyfile);
156  return;
157  }
158 
159  /* Read the environment overrides and apply them */
160  env_vars = g_key_file_get_keys(keyfile, "Variables", &param_count, &error);
161  for ( i = 0; i < param_count; i++ )
162  {
163  gchar **val_list;
164  gsize val_count;
165  gint j;
166  gchar *new_val = NULL, *tmp_val;
167 
168  /* For each variable, read its new value, optionally expand it and set/unset it */
169  val_list = g_key_file_get_string_list (keyfile, "Variables",
170  env_vars[i], &val_count,
171  &error );
172  if ( val_count == 0 )
173  g_unsetenv (env_vars[i]);
174  else
175  {
176  /* Set an initial return value, so we can always use g_build_path below) */
177  tmp_val = g_strdup ("x");
178  for ( j = 0; j < val_count; j++ )
179  {
180  gchar *expanded = environment_expand (val_list[j]);
181  if (expanded && strlen(expanded))
182  {
183  new_val = g_build_path (G_SEARCHPATH_SEPARATOR_S, tmp_val, expanded, NULL);
184  g_free (tmp_val);
185  g_free(expanded);
186  tmp_val = new_val;
187  }
188  }
189  g_strfreev (val_list);
190 
191  /* Remove the "x" from our result */
192  if (g_strcmp0 (tmp_val, "x"))
193  new_val = g_strdup (tmp_val + sizeof (G_SEARCHPATH_SEPARATOR_S));
194  g_free (tmp_val);
195 
196  if (!g_setenv (env_vars[i], new_val, TRUE))
197  g_warning ("Couldn't properly override environment variable \"%s\". "
198  "This may lead to unexpected results", env_vars[i]);
199  g_free(new_val);
200  }
201  }
202 
203  g_strfreev(env_vars);
204  g_key_file_free(keyfile);
205 }
code to set up the environment for proper gnucash functioning.
void gnc_environment_setup(void)