EFL 1.7 svn doobies
[profile/ivi/efreet.git] / src / lib / efreet.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #undef alloca
6 #ifdef HAVE_ALLOCA_H
7 # include <alloca.h>
8 #elif defined __GNUC__
9 # define alloca __builtin_alloca
10 #elif defined _AIX
11 # define alloca __alloca
12 #elif defined _MSC_VER
13 # include <malloc.h>
14 # define alloca _alloca
15 #else
16 # include <stddef.h>
17 # ifdef  __cplusplus
18 extern "C"
19 # endif
20 void *alloca (size_t);
21 #endif
22
23 #include <unistd.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26
27 #include <Eet.h>
28 #include <Ecore.h>
29 #include <Ecore_File.h>
30
31 /* define macros and variable for using the eina logging system  */
32 #define EFREET_MODULE_LOG_DOM /* no logging in this file */
33
34 #include "Efreet.h"
35 #include "efreet_private.h"
36 #include "efreet_xml.h"
37
38 /*
39  * Needs EAPI because of helper binaries
40  */
41 EAPI int efreet_cache_update = 1;
42
43 static int _efreet_init_count = 0;
44 static int efreet_parsed_locale = 0;
45 static const char *efreet_lang = NULL;
46 static const char *efreet_lang_country = NULL;
47 static const char *efreet_lang_modifier = NULL;
48 static void efreet_parse_locale(void);
49 static int efreet_parse_locale_setting(const char *env);
50
51 #ifndef _WIN32
52 static uid_t ruid;
53 static uid_t rgid;
54 #endif
55
56 EAPI int
57 efreet_init(void)
58 {
59 #ifndef _WIN32
60     char *tmp;
61 #endif
62
63     if (++_efreet_init_count != 1)
64         return _efreet_init_count;
65
66 #ifndef _WIN32
67     /* Find users real uid and gid */
68     tmp = getenv("SUDO_UID");
69     if (tmp)
70         ruid = strtoul(tmp, NULL, 10);
71     else
72         ruid = getuid();
73
74     tmp = getenv("SUDO_GID");
75     if (tmp)
76         rgid = strtoul(tmp, NULL, 10);
77     else
78         rgid = getgid();
79 #endif
80
81     if (!eina_init())
82         return --_efreet_init_count;
83     if (!eet_init())
84         goto shutdown_eina;
85     if (!ecore_init())
86         goto shutdown_eet;
87     if (!ecore_file_init())
88         goto shutdown_ecore;
89
90     if (!efreet_base_init())
91         goto shutdown_ecore_file;
92
93     if (!efreet_cache_init())
94         goto shutdown_efreet_base;
95
96     if (!efreet_xml_init())
97         goto shutdown_efreet_cache;
98
99     if (!efreet_icon_init())
100         goto shutdown_efreet_xml;
101
102     if (!efreet_ini_init())
103         goto shutdown_efreet_icon;
104
105     if (!efreet_desktop_init())
106         goto shutdown_efreet_ini;
107
108     if (!efreet_menu_init())
109         goto shutdown_efreet_desktop;
110
111     if (!efreet_util_init())
112         goto shutdown_efreet_menu;
113
114 #ifdef ENABLE_NLS
115     bindtextdomain(PACKAGE, LOCALE_DIR);
116     bind_textdomain_codeset(PACKAGE, "UTF-8");
117 #endif
118
119     return _efreet_init_count;
120
121 shutdown_efreet_menu:
122     efreet_menu_shutdown();
123 shutdown_efreet_desktop:
124     efreet_desktop_shutdown();
125 shutdown_efreet_ini:
126     efreet_ini_shutdown();
127 shutdown_efreet_icon:
128     efreet_icon_shutdown();
129 shutdown_efreet_xml:
130     efreet_xml_shutdown();
131 shutdown_efreet_cache:
132     efreet_cache_shutdown();
133 shutdown_efreet_base:
134     efreet_base_shutdown();
135 shutdown_ecore_file:
136     ecore_file_shutdown();
137 shutdown_ecore:
138     ecore_shutdown();
139 shutdown_eet:
140     eet_shutdown();
141 shutdown_eina:
142     eina_shutdown();
143
144     return --_efreet_init_count;
145 }
146
147 EAPI int
148 efreet_shutdown(void)
149 {
150     if (_efreet_init_count <= 0)
151       {
152          EINA_LOG_ERR("Init count not greater than 0 in shutdown.");
153          return 0;
154       }
155     if (--_efreet_init_count != 0)
156         return _efreet_init_count;
157
158     efreet_util_shutdown();
159     efreet_menu_shutdown();
160     efreet_desktop_shutdown();
161     efreet_ini_shutdown();
162     efreet_icon_shutdown();
163     efreet_xml_shutdown();
164     efreet_cache_shutdown();
165     efreet_base_shutdown();
166
167     IF_RELEASE(efreet_lang);
168     IF_RELEASE(efreet_lang_country);
169     IF_RELEASE(efreet_lang_modifier);
170     efreet_parsed_locale = 0;  /* reset this in case they init efreet again */
171
172     ecore_file_shutdown();
173     ecore_shutdown();
174     eet_shutdown();
175     eina_shutdown();
176
177     return _efreet_init_count;
178 }
179
180 EAPI void
181 efreet_lang_reset(void)
182 {
183     IF_RELEASE(efreet_lang);
184     IF_RELEASE(efreet_lang_country);
185     IF_RELEASE(efreet_lang_modifier);
186     efreet_parsed_locale = 0;  /* reset this in case they init efreet again */
187
188     efreet_dirs_reset();
189     efreet_cache_desktop_close();
190     efreet_cache_desktop_update();
191 }
192
193  /**
194  * @internal
195  * @return Returns the current users language setting or NULL if none set
196  * @brief Retrieves the current language setting
197  */
198 const char *
199 efreet_lang_get(void)
200 {
201     if (efreet_parsed_locale) return efreet_lang;
202
203     efreet_parse_locale();
204     return efreet_lang;
205 }
206
207 /**
208  * @internal
209  * @return Returns the current language country setting or NULL if none set
210  * @brief Retrieves the current country setting for the current language or
211  */
212 const char *
213 efreet_lang_country_get(void)
214 {
215     if (efreet_parsed_locale) return efreet_lang_country;
216
217     efreet_parse_locale();
218     return efreet_lang_country;
219 }
220
221 /**
222  * @internal
223  * @return Returns the current language modifier setting or NULL if none
224  * set.
225  * @brief Retrieves the modifier setting for the language.
226  */
227 const char *
228 efreet_lang_modifier_get(void)
229 {
230     if (efreet_parsed_locale) return efreet_lang_modifier;
231
232     efreet_parse_locale();
233     return efreet_lang_modifier;
234 }
235
236 /**
237  * @internal
238  * @return Returns no value
239  * @brief Parses out the language, country and modifer setting from the
240  * LC_MESSAGES environment variable
241  */
242 static void
243 efreet_parse_locale(void)
244 {
245     efreet_parsed_locale = 1;
246
247     if (efreet_parse_locale_setting("LANG"))
248         return;
249
250     if (efreet_parse_locale_setting("LC_ALL"))
251         return;
252
253     efreet_parse_locale_setting("LC_MESSAGES");
254 }
255
256 /**
257  * @internal
258  * @param env The environment variable to grab
259  * @return Returns 1 if we parsed something of @a env, 0 otherwise
260  * @brief Tries to parse the lang settings out of the given environment
261  * variable
262  */
263 static int
264 efreet_parse_locale_setting(const char *env)
265 {
266     int found = 0;
267     char *setting;
268     char *p;
269     size_t len;
270
271     p = getenv(env);
272     if (!p) return 0;
273     len = strlen(p) + 1;
274     setting = alloca(len);
275     memcpy(setting, p, len);
276
277     /* pull the modifier off the end */
278     p = strrchr(setting, '@');
279     if (p)
280     {
281         *p = '\0';
282         efreet_lang_modifier = eina_stringshare_add(p + 1);
283         found = 1;
284     }
285
286     /* if there is an encoding we ignore it */
287     p = strrchr(setting, '.');
288     if (p) *p = '\0';
289
290     /* get the country if available */
291     p = strrchr(setting, '_');
292     if (p)
293     {
294         *p = '\0';
295         efreet_lang_country = eina_stringshare_add(p + 1);
296         found = 1;
297     }
298
299     if (*setting != '\0')
300     {
301         efreet_lang = eina_stringshare_add(setting);
302         found = 1;
303     }
304
305     return found;
306 }
307
308 /**
309  * @internal
310  * @param buffer The destination buffer
311  * @param size The destination buffer size
312  * @param strs The strings to concatenate together
313  * @return Returns the size of the string in @a buffer
314  * @brief Concatenates the strings in @a strs into the given @a buffer not
315  * exceeding the given @a size.
316  */
317 size_t
318 efreet_array_cat(char *buffer, size_t size, const char *strs[])
319 {
320     int i;
321     size_t n;
322     for (i = 0, n = 0; n < size && strs[i]; i++)
323     {
324         n += eina_strlcpy(buffer + n, strs[i], size - n);
325     }
326     return n;
327 }
328
329 #ifndef _WIN32
330 EAPI void
331 efreet_fsetowner(int fd)
332 {
333     struct stat st;
334
335     if (fd < 0) return;
336     if (fstat(fd, &st) < 0) return;
337     if (st.st_uid == ruid) return;
338
339     if (fchown(fd, ruid, rgid) != 0) return;
340 }
341 #else
342 EAPI void
343 efreet_fsetowner(int fd __UNUSED__)
344 {
345 }
346 #endif
347
348 #ifndef _WIN32
349 EAPI void
350 efreet_setowner(const char *path)
351 {
352     EINA_SAFETY_ON_NULL_RETURN(path);
353
354     int fd;
355
356     fd = open(path, O_RDONLY);
357     if (fd < 0) return;
358     efreet_fsetowner(fd);
359     close(fd);
360 }
361 #else
362 EAPI void
363 efreet_setowner(const char *path __UNUSED__)
364 {
365 }
366 #endif