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