nautilus-3.6.3/libnautilus-private/nautilus-desktop-metadata.c

No issues found

Incomplete coverage

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
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  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 }