nautilus-3.6.3/src/nautilus-convert-metadata.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found nautilus-convert-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-convert-metadata.c - Convert old metadata format to gvfs metadata.
  4  *
  5  * Copyright (C) 2009 Alexander Larsson
  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:
 23  *   Alexander Larsson <alexl@redhat.com>
 24  */
 25 
 26 #include <config.h>
 27 
 28 #include <glib.h>
 29 #include <gio/gio.h>
 30 #include <glib/gi18n.h>
 31 #include <string.h>
 32 #include <libxml/tree.h>
 33 
 34 #include <libnautilus-private/nautilus-metadata.h>
 35 
 36 static gboolean quiet = FALSE;
 37 
 38 static xmlNodePtr
 39 xml_get_children (xmlNodePtr parent)
 40 {
 41 	if (parent == NULL) {
 42 		return NULL;
 43 	}
 44 	return parent->children;
 45 }
 46 
 47 static xmlNodePtr
 48 xml_get_root_children (xmlDocPtr document)
 49 {
 50 	return xml_get_children (xmlDocGetRootElement (document));
 51 }
 52 
 53 
 54 static char *
 55 get_uri_from_nautilus_metafile_name (const char *filename)
 56 {
 57 	GString *s;
 58 	char c;
 59 	char *base_name, *p;
 60 	int len;
 61 
 62 	base_name = g_path_get_basename (filename);
 63 	len = strlen (base_name);
 64 	if (len <=  4 ||
 65 	    strcmp (base_name + len - 4, ".xml") != 0) {
 66 		g_free (base_name);
 67 		return NULL;
 68 	}
 69 	base_name[len-4] = 0;
 70 
 71 	s = g_string_new (NULL);
 72 
 73 	p = base_name;
 74 	while (*p) {
 75 		c = *p++;
 76 		if (c == '%') {
 77 			c = g_ascii_xdigit_value (p[0]) << 4 |
 78 			    g_ascii_xdigit_value (p[1]);
 79 			p += 2;
 80 		}
 81 		g_string_append_c (s, c);
 82 	}
 83 	g_free (base_name);
 84 
 85 	return g_string_free (s, FALSE);
 86 }
 87 
 88 static struct {
 89 	const char *old_key;
 90 	const char *new_key;
 91 } metadata_keys[] = {
 92 	{"background_color", "metadata::" NAUTILUS_METADATA_KEY_LOCATION_BACKGROUND_COLOR},
 93 	{"background_tile_image", "metadata::" NAUTILUS_METADATA_KEY_LOCATION_BACKGROUND_IMAGE},
 94 	{"icon_view_auto_layout", "metadata::" NAUTILUS_METADATA_KEY_ICON_VIEW_AUTO_LAYOUT},
 95 	{"icon_view_sort_by", "metadata::" NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY},
 96 	{"icon_view_sort_reversed", "metadata::" NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED},
 97 	{"icon_view_keep_aligned", "metadata::" NAUTILUS_METADATA_KEY_ICON_VIEW_KEEP_ALIGNED},
 98 	{"icon_view_layout_timestamp", "metadata::" NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP},
 99 	{"list_view_sort_column", "metadata::" NAUTILUS_METADATA_KEY_LIST_VIEW_SORT_COLUMN},
100 	{"list_view_sort_reversed", "metadata::" NAUTILUS_METADATA_KEY_LIST_VIEW_SORT_REVERSED},
101 	{"list_view_visible_columns", "metadata::" NAUTILUS_METADATA_KEY_LIST_VIEW_VISIBLE_COLUMNS},
102 	{"list_view_column_order", "metadata::" NAUTILUS_METADATA_KEY_LIST_VIEW_COLUMN_ORDER},
103 	{"window_geometry", "metadata::" NAUTILUS_METADATA_KEY_WINDOW_GEOMETRY},
104 	{"window_scroll_position", "metadata::" NAUTILUS_METADATA_KEY_WINDOW_SCROLL_POSITION},
105 	{"window_show_hidden_files", "metadata::" NAUTILUS_METADATA_KEY_WINDOW_SHOW_HIDDEN_FILES},
106 	{"window_maximized", "metadata::" NAUTILUS_METADATA_KEY_WINDOW_MAXIMIZED},
107 	{"window_sticky", "metadata::" NAUTILUS_METADATA_KEY_WINDOW_STICKY},
108 	{"window_keep_above", "metadata::" NAUTILUS_METADATA_KEY_WINDOW_KEEP_ABOVE},
109 	{"sidebar_background_color", "metadata::" NAUTILUS_METADATA_KEY_SIDEBAR_BACKGROUND_COLOR},
110 	{"sidebar_background_tile_image", "metadata::" NAUTILUS_METADATA_KEY_SIDEBAR_BACKGROUND_IMAGE},
111 	{"sidebar_buttons", "metadata::" NAUTILUS_METADATA_KEY_SIDEBAR_BUTTONS},
112 	{"annotation", "metadata::" NAUTILUS_METADATA_KEY_ANNOTATION},
113 	{"icon_position", "metadata::" NAUTILUS_METADATA_KEY_ICON_POSITION},
114 	{"icon_position_timestamp", "metadata::" NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP},
115 	{"icon_scale", "metadata::" NAUTILUS_METADATA_KEY_ICON_SCALE},
116 	{"custom_icon", "metadata::" NAUTILUS_METADATA_KEY_CUSTOM_ICON},
117 	{"screen", "metadata::" NAUTILUS_METADATA_KEY_SCREEN},
118 	{"keyword", "metadata::" NAUTILUS_METADATA_KEY_EMBLEMS},
119 };
120 
121 static const char *
122 convert_key_name (const char *old_key)
123 {
124 	int i;
125 
126 	for (i = 0; i < G_N_ELEMENTS (metadata_keys); i++) {
127 		if (strcmp (metadata_keys[i].old_key, old_key) == 0) {
128 			return metadata_keys[i].new_key;
129 		}
130 	}
131 
132 	return NULL;
133 }
134 
135 static void
136 parse_xml_node (GFile *file,
137 		xmlNodePtr filenode)
138 {
139 	xmlNodePtr node;
140 	xmlAttrPtr attr;
141 	xmlChar *property;
142 	const char *new_key;
143 	GHashTable *list_keys;
144 	GList *keys, *l;
145 	GHashTableIter iter;
146 	GFileInfo *info;
147 	int i;
148 	char **strv;
149 	GError *error;
150 
151 	info = g_file_info_new ();
152 
153 	for (attr = filenode->properties; attr != NULL; attr = attr->next) {
154 		if (strcmp ((char *)attr->name, "name") == 0 ||
155 		    strcmp ((char *)attr->name, "timestamp") == 0) {
156 			continue;
157 		}
158 
159 		new_key = convert_key_name ((const gchar *) attr->name);
160 		if (new_key) {
161 			property = xmlGetProp (filenode, attr->name);
162 			if (property) {
163 				g_file_info_set_attribute_string (info,
164 								  new_key,
165 								  (const gchar *) property);
166 				xmlFree (property);
167 			}
168 		}
169 	}
170 
171 	list_keys = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
172 	for (node = filenode->children; node != NULL; node = node->next) {
173 		for (attr = node->properties; attr != NULL; attr = attr->next) {
174 			new_key = convert_key_name ((const gchar *) node->name);
175 			if (new_key) {
176 				property = xmlGetProp (node, attr->name);
177 				if (property) {
178 					keys = g_hash_table_lookup (list_keys, new_key);
179 					keys = g_list_append (keys, property);
180 					g_hash_table_replace (list_keys, (char *)new_key, keys);
181 				}
182 			}
183 		}
184 	}
185 
186 	g_hash_table_iter_init (&iter, list_keys);
187 	while (g_hash_table_iter_next (&iter, (void **)&new_key, (void **)&keys)) {
188 		strv = g_new0 (char *, g_list_length (keys) + 1);
189 
190 		for (l = keys, i = 0; l != NULL; l = l->next, i++) {
191 			strv[i] = l->data;
192 		}
193 		g_file_info_set_attribute_stringv (info,
194 						   new_key,
195 						   strv);
196 		g_free (strv);
197 		g_list_foreach (keys, (GFunc)xmlFree, NULL);
198 		g_list_free (keys);
199 	}
200 	g_hash_table_destroy (list_keys);
201 
202 	if (info) {
203 		error = NULL;
204 		if (!g_file_set_attributes_from_info (file,
205 						      info,
206 						      0, NULL, &error)) {
207 			char *uri;
208 
209 			uri = g_file_get_uri (file);
210 			if (!quiet) {
211 				g_print ("error setting info for %s: %s\n", uri, error->message);
212 			}
213 			g_free (uri);
214 			g_error_free (error);
215 		}
216 		g_object_unref (info);
217 	}
218 }
219 
220 static void
221 convert_xml_file (xmlDocPtr xml,
222 		  GFile *dir)
223 {
224 	xmlNodePtr node;
225 	xmlChar *name;
226 	char *unescaped_name;
227 	GFile *file;
228 
229 	for (node = xml_get_root_children (xml);
230 	     node != NULL; node = node->next) {
231 		if (strcmp ((char *)node->name, "file") == 0) {
232 			name = xmlGetProp (node, (xmlChar *)"name");
233 			unescaped_name = g_uri_unescape_string ((char *)name, "/");
234 			xmlFree (name);
235 
236 			if (unescaped_name == NULL) {
237 				continue;
238 			}
239 
240 			if (strcmp (unescaped_name, ".") == 0) {
241 				file = g_object_ref (dir);
242 			} else  {
243 			    file = g_file_get_child (dir, unescaped_name);
244 			}
245 
246 			parse_xml_node (file, node);
247 			g_object_unref (file);
248 			g_free (unescaped_name);
249 		}
250 	}
251 }
252 
253 static void
254 convert_nautilus_file (char *file)
255 {
256 	GFile *dir;
257 	char *uri;
258 	gchar *contents;
259 	gsize length;
260 	xmlDocPtr xml;
261 
262 	if (!g_file_get_contents (file, &contents, &length, NULL)) {
263 		if (!quiet) {
264 			g_print ("failed to load %s\n", file);
265 		}
266 		return;
267 	}
268 
269 	uri = get_uri_from_nautilus_metafile_name (file);
270 	if (uri == NULL) {
271 		g_free (contents);
272 		return;
273 	}
274 
275 	dir = g_file_new_for_uri (uri);
276 	g_free (uri);
277 
278 	xml = xmlParseMemory (contents, length);
279 	g_free (contents);
280 	if (xml == NULL) {
281 		return;
282 	}
283 
284 	convert_xml_file (xml, dir);
285 	xmlFreeDoc (xml);
286 }
287 
288 static GOptionEntry entries[] =
289 {
290 	{ "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet,
291 	  "Don't show errors", NULL },
292 	{ NULL }
293 };
294 
295 int
296 main (int argc, char *argv[])
297 {
298 	GOptionContext *context;
299 	GError *error = NULL;
300 	int i;
301 
302 	g_type_init ();
303 
304 	context = g_option_context_new ("<nautilus metadata files> - convert nautilus metadata");
305 	g_option_context_add_main_entries (context, entries, NULL);
306 	if (!g_option_context_parse (context, &argc, &argv, &error)) {
307 		g_printerr ("option parsing failed: %s\n", error->message);
308 		return 1;
309 	}
310 
311 	if (argc < 2) {
312 		GDir *dir;
313 		char *metafile_dir;
314 		char *file;
315 		const char *entry;
316 
317 		/* Convert all metafiles */
318 
319 		metafile_dir = g_build_filename (g_get_home_dir (),
320 						 ".nautilus/metafiles", NULL);
321 
322 		dir = g_dir_open (metafile_dir, 0, NULL);
323 		if (dir) {
324 			while ((entry = g_dir_read_name (dir)) != NULL) {
325 				file = g_build_filename (metafile_dir, entry, NULL);
326 				if (g_str_has_suffix (file, ".xml"))
327 					convert_nautilus_file (file);
328 				g_free (file);
329 			}
330 			g_dir_close (dir);
331 		}
332 		g_free (metafile_dir);
333 	} else {
334 		for (i = 1; i < argc; i++) {
335 			convert_nautilus_file (argv[i]);
336 		}
337 	}
338 
339 	return 0;
340 }