d0e663067156781558ffd55d5a667470174f2c83
[framework/uifw/efreet.git] / src / lib / efreet_base.c
1 /* vim: set sw=4 ts=4 sts=4 et: */
2
3 #ifdef HAVE_CONFIG_H
4 # include <config.h>
5 #endif
6
7 #include <stdio.h>
8 #include <string.h>
9
10 #include "Efreet.h"
11 #include "efreet_private.h"
12
13 static const char *efreet_home_dir = NULL;
14 static const char *xdg_data_home = NULL;
15 static const char *xdg_config_home = NULL;
16 static const char *xdg_cache_home = NULL;
17 static Eina_List  *xdg_data_dirs = NULL;
18 static Eina_List  *xdg_config_dirs = NULL;
19
20 static const char *efreet_dir_get(const char *key, const char *fallback);
21 static Eina_List  *efreet_dirs_get(const char *key,
22                                         const char *fallback);
23
24 /**
25  * @internal
26  * @return Returns 1 on success or 0 on failure
27  * @brief Initializes the efreet base settings
28  */
29 int
30 efreet_base_init(void)
31 {
32     if (!eina_stringshare_init()) return 0;
33     if (!eina_list_init())
34     {
35         eina_stringshare_shutdown();
36         return 0;
37     }
38
39     return 1;
40 }
41
42 /**
43  * @internal
44  * @return Returns no value
45  * @brief Cleans up the efreet base settings system
46  */
47 void
48 efreet_base_shutdown(void)
49 {
50     IF_RELEASE(efreet_home_dir);
51     IF_RELEASE(xdg_data_home);
52     IF_RELEASE(xdg_config_home);
53     IF_RELEASE(xdg_cache_home);
54
55     IF_FREE_LIST(xdg_data_dirs, eina_stringshare_del);
56     IF_FREE_LIST(xdg_config_dirs, eina_stringshare_del);
57
58     eina_list_shutdown();
59     eina_stringshare_shutdown();
60 }
61
62 /**
63  * @internal
64  * @return Returns the users home directory
65  * @brief Gets the users home directory and returns it.
66  */
67 const char *
68 efreet_home_dir_get(void)
69 {
70     if (efreet_home_dir) return efreet_home_dir;
71
72     efreet_home_dir = getenv("HOME");
73     if (!efreet_home_dir || efreet_home_dir[0] == '\0')
74         efreet_home_dir = "/tmp";
75
76     efreet_home_dir = eina_stringshare_add(efreet_home_dir);
77
78     return efreet_home_dir;
79 }
80
81 /**
82  * @return Returns the XDG Data Home directory
83  * @brief Retrieves the XDG Data Home directory
84  */
85 EAPI const char *
86 efreet_data_home_get(void)
87 {
88     if (xdg_data_home) return xdg_data_home;
89     xdg_data_home = efreet_dir_get("XDG_DATA_HOME", "/.local/share");
90     return xdg_data_home;
91 }
92
93 /**
94  * @return Returns the Eina_List of preference ordered extra data directories
95  * @brief Returns the Eina_List of prefernece oredred extra data
96  * directories
97  *
98  * @note The returned list is static inside Efreet. If you add/remove from the
99  * list then the next call to efreet_data_dirs_get() will return your
100  * modified values. DO NOT free this list.
101  */
102 EAPI Eina_List *
103 efreet_data_dirs_get(void)
104 {
105     if (xdg_data_dirs) return xdg_data_dirs;
106     xdg_data_dirs = efreet_dirs_get("XDG_DATA_DIRS",
107                             PACKAGE_DATA_DIR ":/usr/share");
108     return xdg_data_dirs;
109 }
110
111 /**
112  * @return Returns the XDG Config Home directory
113  * @brief Retrieves the XDG Config Home directory
114  */
115 EAPI const char *
116 efreet_config_home_get(void)
117 {
118     if (xdg_config_home) return xdg_config_home;
119     xdg_config_home = efreet_dir_get("XDG_CONFIG_HOME", "/.config");
120     return xdg_config_home;
121 }
122
123 /**
124  * @return Returns the Eina_List of preference ordered extra config directories
125  * @brief Returns the Eina_List of prefernece ordered extra config
126  * directories
127  *
128  * @note The returned list is static inside Efreet. If you add/remove from the
129  * list then the next call to efreet_config_dirs_get() will return your
130  * modified values. DO NOT free this list.
131  */
132 EAPI Eina_List *
133 efreet_config_dirs_get(void)
134 {
135     if (xdg_config_dirs) return xdg_config_dirs;
136     xdg_config_dirs = efreet_dirs_get("XDG_CONFIG_DIRS", "/etc/xdg");
137     return xdg_config_dirs;
138 }
139
140 /**
141  * @return Returns the XDG Cache Home directory
142  * @brief Retrieves the XDG Cache Home directory
143  */
144 EAPI const char *
145 efreet_cache_home_get(void)
146 {
147     if (xdg_cache_home) return xdg_cache_home;
148     xdg_cache_home = efreet_dir_get("XDG_CACHE_HOME", "/.cache");
149     return xdg_cache_home;
150 }
151
152 /**
153  * @internal
154  * @param key: The environemnt key to lookup
155  * @param fallback: The fallback value to use
156  * @return Returns the directory related to the given key or the fallback
157  * @brief This trys to determine the correct directory name given the
158  * environment key @a key and fallbacks @a fallback.
159  */
160 static const char *
161 efreet_dir_get(const char *key, const char *fallback)
162 {
163     char *dir;
164     const char *t;
165
166     dir = getenv(key);
167     if (!dir || dir[0] == '\0')
168     {
169         int len;
170         const char *user;
171
172         user = efreet_home_dir_get();
173         len = strlen(user) + strlen(fallback) + 1;
174         dir = malloc(sizeof(char) * len);
175         snprintf(dir, len, "%s%s", user, fallback);
176
177         t = eina_stringshare_add(dir);
178         FREE(dir);
179     }
180     else t = eina_stringshare_add(dir);
181
182     return t;
183 }
184
185 /**
186  * @internal
187  * @param key: The environment key to lookup
188  * @param fallback: The fallback value to use
189  * @return Returns a list of directories specified by the given key @a key
190  * or from the list of fallbacks in @a fallback.
191  * @brief Creates a list of directories as given in the environment key @a
192  * key or from the fallbacks in @a fallback
193  */
194 static Eina_List *
195 efreet_dirs_get(const char *key, const char *fallback)
196 {
197     Eina_List *dirs = NULL;
198     const char *path;
199     char *tmp, *s, *p;
200
201     path = getenv(key);
202     if (!path || (path[0] == '\0')) path = fallback;
203
204     if (!path) return dirs;
205
206     tmp = strdup(path);
207     s = tmp;
208     p = strchr(s, ':');
209     while (p)
210     {
211         *p = '\0';
212         if (!eina_list_search_unsorted(dirs, EINA_COMPARE_CB(strcmp), s))
213             dirs = eina_list_append(dirs, (void *)eina_stringshare_add(s));
214
215         s = ++p;
216         p = strchr(s, ':');
217     }
218     if (!eina_list_search_unsorted(dirs, EINA_COMPARE_CB(strcmp), s))
219       dirs = eina_list_append(dirs, (void *)eina_stringshare_add(s));
220     FREE(tmp);
221
222     return dirs;
223 }