getenv needs <stdlib.h>.
[AutoStart.git] / src / xdgautostart.c
blob94056c824180c52bfa22b93d367eee810079f822
1 /*
2 * By Tony Houghton, <h@realh.co.uk>.
3 */
5 #include "config.h"
7 #include <stdlib.h>
8 #include <string.h>
10 #include "xdgautostart.h"
12 static const char *locale_name = NULL;
13 static const char *short_locale_name = NULL;
15 static void desktop_entry_free_keyfile_mirrors(DesktopEntry *de)
17 g_free(de->name);
18 de->name = NULL;
19 g_free(de->exec);
20 de->exec = NULL;
21 g_free(de->path);
22 de->path = NULL;
23 g_free(de->try_exec);
24 de->try_exec = NULL;
25 g_strfreev(de->only_show_in);
26 de->only_show_in = NULL;
27 g_strfreev(de->not_show_in);
28 de->not_show_in = NULL;
31 static void desktop_entry_read_name_from_keyfile(DesktopEntry *xde)
33 g_free(xde->name);
34 if (locale_name)
36 xde->name = g_key_file_get_locale_string(xde->kf, _DE, "Name",
37 locale_name, NULL);
39 if (!xde->name && short_locale_name)
41 xde->name = g_key_file_get_locale_string(xde->kf, _DE, "Name",
42 short_locale_name, NULL);
44 if (!xde->name)
45 xde->name = g_key_file_get_string(xde->kf, _DE, "Name", NULL);
46 if (!xde->name)
47 xde->name = g_strdup(_("No name"));
50 void desktop_entry_read_keyfile(DesktopEntry *de)
52 GKeyFile *kf = de->kf;
54 desktop_entry_free_keyfile_mirrors(de);
55 desktop_entry_read_name_from_keyfile(de);
56 de->exec = g_key_file_get_string(kf, _DE, "Exec", NULL);
57 de->path = g_key_file_get_string(kf, _DE, "Path", NULL);
58 de->terminal = g_key_file_get_boolean(kf, _DE, "Terminal", NULL);
59 de->try_exec = g_key_file_get_string(kf, _DE, "TryExec", NULL);
60 de->only_show_in = g_key_file_get_string_list(kf, _DE, "OnlyShowIn",
61 NULL, NULL);
62 de->not_show_in = g_key_file_get_string_list(kf, _DE, "NotShowIn",
63 NULL, NULL);
66 gboolean desktop_entry_load(DesktopEntry *de, const char *pathname,
67 const char *basename, gboolean keep_keyfile, gboolean savable)
69 GKeyFile *kf = g_key_file_new();
70 GError *err = NULL;
72 de->kf = kf;
73 if (!g_key_file_load_from_file(kf, pathname,
74 keep_keyfile ?
75 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS :
76 G_KEY_FILE_NONE,
77 &err))
79 g_warning(_("Can't load key-file '%s': %s"), pathname,
80 err ? err->message : _("unknown reason"));
81 g_error_free(err);
82 return FALSE;
84 if (!g_key_file_has_group(kf, _DE))
86 g_warning(_("'%s' is not a .desktop file"), pathname);
87 return FALSE;
90 de->pathname = g_strdup(pathname);
91 de->basename = g_strdup(basename);
92 de->savable = savable;
93 de->deletable = savable;
95 desktop_entry_read_keyfile(de);
97 if (!keep_keyfile)
99 g_key_file_free(kf);
100 de->kf = NULL;
102 return TRUE;
105 void desktop_entry_free(DesktopEntry *de)
107 desktop_entry_free_keyfile_mirrors(de);
108 g_free(de->pathname);
109 de->pathname = NULL;
110 g_free(de->basename);
111 de->basename = NULL;
112 if (de->kf)
114 g_key_file_free(de->kf);
115 de->kf = NULL;
119 void desktop_entry_delete(DesktopEntry *de)
121 desktop_entry_free(de);
122 g_free(de);
125 DesktopEntry *desktop_entry_new(const char *pathname, const char *basename,
126 gboolean savable)
128 DesktopEntry *de = g_new0(DesktopEntry, 1);
130 if (!desktop_entry_load(de, pathname, basename, FALSE, savable))
132 desktop_entry_delete(de);
133 de = NULL;
135 return de;
138 gboolean desktop_entry_str_in_strv(char **v, const char *s)
140 for ( ; v && *v; ++v)
142 if (!strcmp(*v, s))
143 return TRUE;
145 return FALSE;
148 gboolean desktop_entry_get_show_in_environ(const DesktopEntry *de,
149 const char *environ)
151 if (de->only_show_in)
153 return desktop_entry_str_in_strv(de->only_show_in, environ);
155 if (de->not_show_in)
157 if (desktop_entry_str_in_strv(de->not_show_in, environ))
158 return FALSE;
160 return TRUE;
163 /* Also checks Exec and TryExec */
164 gboolean desktop_entry_can_start_in_rox(const DesktopEntry *de)
166 if (!desktop_entry_get_show_in_rox(de))
167 return FALSE;
168 if (!de->exec)
169 return FALSE;
170 if (de->try_exec)
172 if (!g_file_test(de->try_exec, G_FILE_TEST_EXISTS))
173 return FALSE;
175 if (de->exec[0] == '/')
177 return g_file_test(de->exec, G_FILE_TEST_IS_EXECUTABLE);
179 else
181 char *ef = g_find_program_in_path(de->exec);
182 gboolean result = ef != NULL;
184 g_free(ef);
185 return result;
187 return FALSE;
190 static GList *scan_dir(const char *dir, GList *desl,
191 DesktopEntryConstructor ctor, gboolean savable)
193 char *dir2 = g_build_filename(dir, "autostart", NULL);
194 GDir *dir0;
195 const char *basename;
197 if (!g_file_test(dir2, G_FILE_TEST_IS_DIR))
198 goto no_dir;
199 dir0 = g_dir_open(dir2, 0, NULL);
200 if (!dir0)
201 goto no_dir;
202 while ((basename = g_dir_read_name(dir0)) != NULL)
204 GList *node;
205 gboolean dupl = FALSE;
207 /* Don't add if there's already one with the same basename */
208 for (node = desl; node; node = g_list_next(node))
210 DesktopEntry *de = node->data;
212 if (!strcmp(basename, de->basename))
214 dupl = TRUE;
215 break;
218 if (!dupl)
220 char *pathname = g_build_filename(dir2, basename, NULL);
221 DesktopEntry *de = ctor(pathname, basename, savable);
223 if (de)
224 desl = g_list_append(desl, de);
225 g_free(pathname);
229 g_dir_close(dir0);
230 no_dir:
231 g_free(dir2);
232 return desl;
235 GList *get_desktop_entries(DesktopEntryConstructor ctor)
237 GList *desl = NULL;
238 const char *udir = g_get_user_config_dir();
239 const char * const * sdirs;
241 desl = scan_dir(udir, desl, ctor, TRUE);
242 for (sdirs = g_get_system_config_dirs(); sdirs && *sdirs; ++sdirs)
244 desl = scan_dir(*sdirs, desl, ctor, FALSE);
246 return desl;
249 gboolean str_v_is_empty(char **sv)
251 if (!sv)
252 return TRUE;
253 for ( ; *sv; ++sv)
255 if (*sv)
256 return FALSE;
258 return TRUE;
261 void desktop_entry_set_locale_names(const char *full_name,
262 const char *short_name)
264 locale_name = full_name;
265 short_locale_name = short_name;
268 void desktop_entry_init_locales(char const **long_name, char const **short_name)
270 char *lang = getenv("LANG");
272 if (lang)
274 char *sep = strchr(lang, '.');
275 int l = sep ? sep - lang : strlen(lang);
277 locale_name = g_strdup_printf("%.*s", l, lang);
278 sep = strchr(locale_name, '_');
279 if (sep)
281 short_locale_name = g_strdup_printf("%.*s",
282 (int) (sep - locale_name), locale_name);
285 else
287 locale_name = NULL;
289 if (long_name)
290 *long_name = locale_name;
291 if (short_name)
292 *short_name = short_locale_name;