No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | nautilus-desktop-metadata.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3 * Nautilus
4 *
5 * Copyright (C) 2011 Red Hat, Inc.
6 *
7 * Nautilus is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * Nautilus is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public
18 * License along with this program; see the file COPYING. If not,
19 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 *
22 * Authors: Cosimo Cecchi <cosimoc@redhat.com>
23 */
24
25 #include <config.h>
26
27 #include "nautilus-desktop-metadata.h"
28
29 #include "nautilus-directory-notify.h"
30 #include "nautilus-file-private.h"
31 #include "nautilus-file-utilities.h"
32
33 #include <glib/gstdio.h>
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38
39 static guint save_in_idle_source_id = 0;
40
41 static gchar *
42 get_keyfile_path (void)
43 {
44 gchar *xdg_dir, *retval;
45
46 xdg_dir = nautilus_get_user_directory ();
47 retval = g_build_filename (xdg_dir, "desktop-metadata", NULL);
48
49 g_free (xdg_dir);
50
51 return retval;
52 }
53
54 static gboolean
55 save_in_idle_cb (gpointer data)
56 {
57 GKeyFile *keyfile = data;
58 gchar *contents, *filename;
59 gsize length;
60 GError *error = NULL;
61
62 save_in_idle_source_id = 0;
63
64 contents = g_key_file_to_data (keyfile, &length, NULL);
65 filename = get_keyfile_path ();
66
67 if (contents != NULL) {
68 g_file_set_contents (filename,
69 contents, length,
70 &error);
71 g_free (contents);
72 }
73
74 if (error != NULL) {
75 g_warning ("Couldn't save the desktop metadata keyfile to disk: %s",
76 error->message);
77 g_error_free (error);
78 }
79
80 g_free (filename);
81
82 return FALSE;
83 }
84
85 static void
86 save_in_idle (GKeyFile *keyfile)
87 {
88 if (save_in_idle_source_id != 0) {
89 g_source_remove (save_in_idle_source_id);
90 }
91
92 save_in_idle_source_id = g_idle_add (save_in_idle_cb, keyfile);
93 }
94
95 static GKeyFile *
96 load_metadata_keyfile (void)
97 {
98 GKeyFile *retval;
99 GError *error = NULL;
100 gchar *filename;
101
102 retval = g_key_file_new ();
103 filename = get_keyfile_path ();
104
105 g_key_file_load_from_file (retval,
106 filename,
107 G_KEY_FILE_NONE,
108 &error);
109
110 if (error != NULL) {
111 if (!g_error_matches (error,
112 G_FILE_ERROR,
113 G_FILE_ERROR_NOENT)) {
114 g_print ("Unable to open the desktop metadata keyfile: %s\n",
115 error->message);
116 }
117
118 g_error_free (error);
119 }
120
121 g_free (filename);
122
123 return retval;
124 }
125
126 static GKeyFile *
127 get_keyfile (void)
128 {
129 static gboolean keyfile_loaded = FALSE;
130 static GKeyFile *keyfile = NULL;
131
132 if (!keyfile_loaded) {
133 keyfile = load_metadata_keyfile ();
134 keyfile_loaded = TRUE;
135 }
136
137 return keyfile;
138 }
139
140 void
141 nautilus_desktop_set_metadata_string (NautilusFile *file,
142 const gchar *name,
143 const gchar *key,
144 const gchar *string)
145 {
146 GKeyFile *keyfile;
147
148 keyfile = get_keyfile ();
149
150 g_key_file_set_string (keyfile,
151 name,
152 key,
153 string);
154
155 save_in_idle (keyfile);
156
157 if (nautilus_desktop_update_metadata_from_keyfile (file, name)) {
158 nautilus_file_changed (file);
159 }
160 }
161
162 #define STRV_TERMINATOR "@x-nautilus-desktop-metadata-term@"
163
164 void
165 nautilus_desktop_set_metadata_stringv (NautilusFile *file,
166 const char *name,
167 const char *key,
168 const char * const *stringv)
169 {
170 GKeyFile *keyfile;
171 guint length;
172 gchar **actual_stringv = NULL;
173 gboolean free_strv = FALSE;
174
175 keyfile = get_keyfile ();
176
177 /* if we would be setting a single-length strv, append a fake
178 * terminator to the array, to be able to differentiate it later from
179 * the single string case
180 */
181 length = g_strv_length ((gchar **) stringv);
182
183 if (length == 1) {
184 actual_stringv = g_malloc0 (3 * sizeof (gchar *));
185 actual_stringv[0] = (gchar *) stringv[0];
186 actual_stringv[1] = STRV_TERMINATOR;
187 actual_stringv[2] = NULL;
188
189 length = 2;
190 free_strv = TRUE;
191 } else {
192 actual_stringv = (gchar **) stringv;
193 }
194
195 g_key_file_set_string_list (keyfile,
196 name,
197 key,
198 (const gchar **) actual_stringv,
199 length);
200
201 save_in_idle (keyfile);
202
203 if (nautilus_desktop_update_metadata_from_keyfile (file, name)) {
204 nautilus_file_changed (file);
205 }
206
207 if (free_strv) {
208 g_free (actual_stringv);
209 }
210 }
211
212 gboolean
213 nautilus_desktop_update_metadata_from_keyfile (NautilusFile *file,
214 const gchar *name)
215 {
216 gchar **keys, **values;
217 const gchar *actual_values[2];
218 const gchar *key, *value;
219 gchar *gio_key;
220 gsize length, values_length;
221 GKeyFile *keyfile;
222 GFileInfo *info;
223 gint idx;
224 gboolean res;
225
226 keyfile = get_keyfile ();
227
228 keys = g_key_file_get_keys (keyfile,
229 name,
230 &length,
231 NULL);
232
233 if (keys == NULL) {
234 return FALSE;
235 }
236
237 info = g_file_info_new ();
238
239 for (idx = 0; idx < length; idx++) {
240 key = keys[idx];
241 values = g_key_file_get_string_list (keyfile,
242 name,
243 key,
244 &values_length,
245 NULL);
246
247 gio_key = g_strconcat ("metadata::", key, NULL);
248
249 if (values_length < 1) {
250 continue;
251 } else if (values_length == 1) {
252 g_file_info_set_attribute_string (info,
253 gio_key,
254 values[0]);
255 } else if (values_length == 2) {
256 /* deal with the fact that single-length strv are stored
257 * with an additional terminator in the keyfile string, to differentiate
258 * them from the regular string case.
259 */
260 value = values[1];
261
262 if (g_strcmp0 (value, STRV_TERMINATOR) == 0) {
263 /* if the 2nd value is the terminator, remove it */
264 actual_values[0] = values[0];
265 actual_values[1] = NULL;
266
267 g_file_info_set_attribute_stringv (info,
268 gio_key,
269 (gchar **) actual_values);
270 } else {
271 /* otherwise, set it as a regular strv */
272 g_file_info_set_attribute_stringv (info,
273 gio_key,
274 values);
275 }
276 } else {
277 g_file_info_set_attribute_stringv (info,
278 gio_key,
279 values);
280 }
281
282 g_free (gio_key);
283 g_strfreev (values);
284 }
285
286 res = nautilus_file_update_metadata_from_info (file, info);
287
288 g_strfreev (keys);
289 g_object_unref (info);
290
291 return res;
292 }