blob: 2356cab84c2e519db148fd9d6d782cdd61015e90 [file] [log] [blame]
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -04001#include "files.h"
2
3#include <memory>
4#include "config.h"
5#include <unistd.h> // to create symlinks
6#include <errno.h>
7#include <glib/gstdio.h> // for glib file utils
8#include <string.h>
9
10void
11autostart_symlink(gboolean autostart)
12{
13 /* autostart is enabled by creating a symlink to gnome-ring.desktop in
14 * $XDG_CONFIG_HOME/autostart (by default ~/.config/autostart)
15 * and removing it to disable autostart
16 */
17
18 GError *error = NULL;
19 gchar *autostart_path = g_strconcat(g_get_user_config_dir(), "/autostart/gnome-ring.desktop", NULL);
20
21 if (autostart) {
22 g_debug("enabling autostart");
23
24 gchar *desktop_path = NULL;
25 /* find where the .desktop file is by checking the following dirs in order
26 * - /usr/<data dir>
27 * - /usr/local/<data dir>
28 * - install data dir (check this last, as it might not be where the
29 * bin is actually isntalled on the system)
30 *
31 * note: no point in checking the local bin dir, even if the .desktop is
32 * there, if the binary is not installed on the system, the .desktop will
33 * not find it
34 */
35 int num_paths = 3;
36 gchar *desktop_paths[num_paths];
37 desktop_paths[0] = g_strconcat("/usr", RING_DATA_DIR, "/gnome-ring.desktop", NULL);
38 desktop_paths[1] = g_strconcat("/usr/local", RING_DATA_DIR, "/gnome-ring.desktop", NULL);
39 desktop_paths[2] = g_strconcat(RING_CLIENT_INSTALL, RING_DATA_DIR, "/gnome-ring.desktop", NULL);
40
41 for (int i = 0; i < num_paths && !desktop_path; ++i) {
42 g_debug("checking %s", desktop_paths[i]);
43 if (g_file_test(desktop_paths[i], G_FILE_TEST_IS_REGULAR))
44 desktop_path = desktop_paths[i];
45 }
46
47 if (!desktop_path) {
48 /* could not find where the .desktop is... default to the install one */
49 desktop_path = desktop_paths[1];
50 g_warning("cannot locate '%s', will try to create a symlink to it anyways", desktop_path);
51 }
52
53 /* we want autostart_path to be a symlink to the current desktop_path
54 * if it is not, delete it and create one */
55
56 gboolean symlink_to_desktop = FALSE;
57 if (g_file_test(autostart_path, G_FILE_TEST_IS_SYMLINK)) {
58 /* is symlink, check if its to the right file */
59 gchar *current_link = g_file_read_link(autostart_path, &error);
60 if (error) {
61 g_warning("could not read contents of symlink '%s': %s",autostart_path, error->message);
62 g_clear_error(&error);
63 }
64
65 /* compare even if error occurs, as function handles nullptr */
66 if (g_strcmp0(current_link, desktop_path) == 0) {
67 g_debug("'%s' is already a symlink to '%s'", autostart_path, desktop_path);
68 symlink_to_desktop = TRUE;
69 } else {
70 g_debug("'%s' exists but does not point to '%s', instead: '%s'", autostart_path, desktop_path, current_link);
71
72 /* we need to delete it */
73 if (g_remove(autostart_path) != 0) {
74 g_warning("could not remove '%s'", autostart_path);
75 }
76 }
77 g_free(current_link);
78 }
79
80 if (!symlink_to_desktop) {
81 g_debug("creating symlink");
82
83 /* make sure the directory exists */
84 gchar *autostart_dir = g_strconcat(g_get_user_config_dir(), "/autostart", NULL);
85 if (g_mkdir_with_parents(autostart_dir, 0700) != 0)
86 g_warning("'%s' dir doesn't exist and could not be created", autostart_dir);
87 g_free(autostart_dir);
88
89 if (symlink(desktop_path, autostart_path) != 0) {
90 g_warning("could not create symlink: %s", strerror(errno));
91 }
92 }
93
94 for (int i = 0; i < num_paths; ++i) {
95 g_free(desktop_paths[i]);
96 }
97 } else {
98 g_debug("disabling autostart");
99 /* need to remove symlink or .desktop, if it exists
100 * G_FILE_TEST_IS_REGULAR will test for both file and symlink, since it
101 * follows symlinks */
102 if (g_file_test(autostart_path, G_FILE_TEST_IS_REGULAR)) {
103 g_debug("'%s' exists, removing", autostart_path);
104
105 if (g_remove(autostart_path) != 0) {
106 g_warning("could not remove '%s'", autostart_path);
107 }
108 } else {
109 g_debug("'%s' doesn't exist, nothing to do", autostart_path);
110 }
111
112 }
113 g_free(autostart_path);
114}
115
116GSettingsSchema *
117get_ring_schema()
118{
119 static std::unique_ptr<GSettingsSchema, decltype(g_settings_schema_unref )&>
120 ring_schema(nullptr, g_settings_schema_unref);
121
122 if (ring_schema.get() == nullptr) {
123 GSettingsSchema *schema = NULL;
124
125 /* find gschema.compiled by checking the following dirs in order:
126 * - current bin dir
127 * - install data dir
128 * - default dir
129 * note that the install and default dir may be the same
130 */
131 GError *error = NULL;
132
133 /* try local first */
134 g_debug("looking for schema locally");
135 gchar *schema_dir_local = g_strconcat(".", NULL);
136 GSettingsSchemaSource *schema_source_local = NULL;
137 schema_source_local = g_settings_schema_source_new_from_directory(
138 schema_dir_local,
139 g_settings_schema_source_get_default(),
140 FALSE,
141 &error);
142
143 if (!error) {
144 schema = g_settings_schema_source_lookup(schema_source_local,
145 RING_CLIENT_APP_ID,
146 TRUE);
147 g_settings_schema_source_unref(schema_source_local);
148 } else {
149 g_debug("error looking up ring schema locally: %s", error->message);
150 g_clear_error(&error);
151 }
152 g_free(schema_dir_local);
153
154 if (!schema) {
155 /* try install dir */
156 g_debug("looking for schema in insall dir");
157 gchar *schema_dir_install = g_strconcat(RING_CLIENT_INSTALL, "/share/glib-2.0/schemas", NULL);
158 GSettingsSchemaSource *schema_source_install = NULL;
159 schema_source_install = g_settings_schema_source_new_from_directory(
160 schema_dir_install,
161 g_settings_schema_source_get_default(),
162 TRUE,
163 &error);
164
165 if (!error) {
166 schema = g_settings_schema_source_lookup(schema_source_install,
167 RING_CLIENT_APP_ID,
168 TRUE);
169 g_settings_schema_source_unref(schema_source_install);
170 } else {
171 g_debug("error looking up ring schema in install dir: %s", error->message);
172 g_clear_error(&error);
173 }
174 g_free(schema_dir_install);
175 }
176
177 if (!schema) {
178 /* try default dir */
179 g_debug("looking for schema in default dir");
180
181 schema = g_settings_schema_source_lookup(g_settings_schema_source_get_default(),
182 RING_CLIENT_APP_ID,
183 TRUE);
184 }
185 ring_schema.reset(schema);
186 }
187
188 return ring_schema.get();
189}