tracker-0.16.2/src/miners/fs/tracker-miner-files-index.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found tracker-miner-files-index.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 /*
  2  * Copyright (C) 2010, Nokia <ivan.frade@nokia.com>
  3  *
  4  * This library is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) any later version.
  8  *
  9  * This library is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU General Public
 15  * License along with this library; if not, write to the
 16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17  * Boston, MA  02110-1301, USA.
 18  */
 19 
 20 #include "config.h"
 21 
 22 #include <libtracker-common/tracker-dbus.h>
 23 #include <libtracker-sparql/tracker-sparql.h>
 24 #include <libtracker-miner/tracker-miner-dbus.h>
 25 
 26 #include "tracker-miner-files-index.h"
 27 #include "tracker-marshal.h"
 28 
 29 
 30 static const gchar introspection_xml[] =
 31   "<node>"
 32   "  <interface name='org.freedesktop.Tracker1.Miner.Files.Index'>"
 33   "    <method name='ReindexMimeTypes'>"
 34   "      <arg type='as' name='mime_types' direction='in' />"
 35   "    </method>"
 36   "    <method name='IndexFile'>"
 37   "      <arg type='s' name='file_uri' direction='in' />"
 38   "    </method>"
 39   "  </interface>"
 40   "</node>";
 41 
 42 /* If defined, then a file provided to be indexed MUST be a child in
 43  * an configured path. if undefined, any file can be indexed, however
 44  * it is up to applications to maintain files outside the configured
 45  * locations.
 46  */
 47 #undef REQUIRE_LOCATION_IN_CONFIG
 48 
 49 typedef struct {
 50 	TrackerDBusRequest *request;
 51 	GDBusMethodInvocation *invocation;
 52 	TrackerSparqlConnection *connection;
 53 	TrackerMinerFiles *miner_files;
 54 } MimeTypesData;
 55 
 56 typedef struct {
 57 	TrackerMinerFiles *files_miner;
 58 	GDBusConnection *d_connection;
 59 	GDBusNodeInfo *introspection_data;
 60 	guint registration_id;
 61 	gchar *full_name;
 62 	gchar *full_path;
 63 } TrackerMinerFilesIndexPrivate;
 64 
 65 enum {
 66 	PROP_0,
 67 	PROP_FILES_MINER
 68 };
 69 
 70 #define TRACKER_MINER_FILES_INDEX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER_FILES_INDEX, TrackerMinerFilesIndexPrivate))
 71 
 72 static void     index_set_property        (GObject              *object,
 73                                            guint                 param_id,
 74                                            const GValue         *value,
 75                                            GParamSpec           *pspec);
 76 static void     index_get_property        (GObject              *object,
 77                                            guint                 param_id,
 78                                            GValue               *value,
 79                                            GParamSpec           *pspec);
 80 static void     index_finalize            (GObject              *object);
 81 
 82 G_DEFINE_TYPE(TrackerMinerFilesIndex, tracker_miner_files_index, G_TYPE_OBJECT)
 83 
 84 static void
 85 tracker_miner_files_index_class_init (TrackerMinerFilesIndexClass *klass)
 86 {
 87 	GObjectClass *object_class;
 88 
 89 	object_class = G_OBJECT_CLASS (klass);
 90 
 91 	object_class->finalize = index_finalize;
 92 	object_class->set_property = index_set_property;
 93 	object_class->get_property = index_get_property;
 94 
 95 	g_object_class_install_property (object_class,
 96 	                                 PROP_FILES_MINER,
 97 	                                 g_param_spec_object ("files_miner",
 98 	                                                      "files_miner",
 99 	                                                      "The FS Miner",
100 	                                                      TRACKER_TYPE_MINER_FILES,
101 	                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
102 
103 	g_type_class_add_private (klass, sizeof (TrackerMinerFilesIndexPrivate));
104 }
105 
106 static void
107 index_set_property (GObject      *object,
108                     guint         param_id,
109                     const GValue *value,
110                     GParamSpec   *pspec)
111 {
112 	TrackerMinerFilesIndexPrivate *priv;
113 
114 	priv = TRACKER_MINER_FILES_INDEX_GET_PRIVATE (object);
115 
116 	switch (param_id) {
117 	case PROP_FILES_MINER:
118 		priv->files_miner = g_value_dup_object (value);
119 		break;
120 	default:
121 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
122 		break;
123 	}
124 }
125 
126 
127 static void
128 index_get_property (GObject    *object,
129                     guint       param_id,
130                     GValue     *value,
131                     GParamSpec *pspec)
132 {
133 	TrackerMinerFilesIndexPrivate *priv;
134 
135 	priv = TRACKER_MINER_FILES_INDEX_GET_PRIVATE (object);
136 
137 	switch (param_id) {
138 	case PROP_FILES_MINER:
139 		g_value_set_object (value, priv->files_miner);
140 		break;
141 	default:
142 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
143 		break;
144 	}
145 }
146 
147 static void
148 index_finalize (GObject *object)
149 {
150 	TrackerMinerFilesIndexPrivate *priv = TRACKER_MINER_FILES_INDEX_GET_PRIVATE (object);
151 
152 	if (priv->registration_id != 0) {
153 		g_dbus_connection_unregister_object (priv->d_connection,
154 		                                     priv->registration_id);
155 	}
156 
157 	if (priv->introspection_data) {
158 		g_dbus_node_info_unref (priv->introspection_data);
159 	}
160 
161 	if (priv->d_connection) {
162 		g_object_unref (priv->d_connection);
163 	}
164 
165 	g_free (priv->full_name);
166 	g_free (priv->full_path);
167 
168 	g_object_unref (priv->files_miner);
169 }
170 
171 static MimeTypesData *
172 mime_types_data_new (TrackerDBusRequest      *request,
173                      GDBusMethodInvocation   *invocation,
174                      TrackerSparqlConnection *connection,
175                      TrackerMinerFiles       *miner_files)
176 {
177 	MimeTypesData *mtd;
178 
179 	mtd = g_slice_new0 (MimeTypesData);
180 
181 	mtd->miner_files = g_object_ref (miner_files);
182 	mtd->request = request;
183 	mtd->invocation = invocation;
184 	mtd->connection = g_object_ref (connection);
185 
186 	return mtd;
187 }
188 
189 static void
190 mime_types_data_destroy (gpointer data)
191 {
192 	MimeTypesData *mtd;
193 
194 	mtd = data;
195 
196 	g_object_unref (mtd->miner_files);
197 	g_object_unref (mtd->connection);
198 
199 	g_slice_free (MimeTypesData, mtd);
200 }
201 
202 static void
203 mime_types_cb (GObject      *object,
204                GAsyncResult *result,
205                gpointer      user_data)
206 {
207 	MimeTypesData *mtd = user_data;
208 	TrackerSparqlCursor *cursor;
209 	GError *error = NULL;
210 
211 	cursor = tracker_sparql_connection_query_finish (TRACKER_SPARQL_CONNECTION (object),
212 	                                                 result,
213 	                                                 &error);
214 
215 	if (cursor) {
216 		tracker_dbus_request_comment (mtd->request,
217 		                              "Found files that will need reindexing");
218 
219 		while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
220 			GFile *file;
221 			const gchar *url;
222 
223 			url = tracker_sparql_cursor_get_string (cursor, 0, NULL);
224 			file = g_file_new_for_uri (url);
225 			tracker_miner_fs_check_file (TRACKER_MINER_FS (mtd->miner_files), file, FALSE);
226 			g_object_unref (file);
227 		}
228 
229 		tracker_dbus_request_end (mtd->request, NULL);
230 		g_dbus_method_invocation_return_value (mtd->invocation, NULL);
231 	} else {
232 		tracker_dbus_request_end (mtd->request, error);
233 		g_dbus_method_invocation_return_gerror (mtd->invocation, error);
234 	}
235 
236 	mime_types_data_destroy (user_data);
237 }
238 
239 static void
240 tracker_miner_files_index_reindex_mime_types (TrackerMinerFilesIndex *miner,
241                                               GDBusMethodInvocation  *invocation,
242                                               GVariant               *parameters)
243 {
244 	TrackerMinerFilesIndexPrivate *priv;
245 	GString *query;
246 	GError *inner_error = NULL;
247 	TrackerSparqlConnection *connection;
248 	TrackerDBusRequest *request;
249 	gint len, i;
250 	GStrv mime_types = NULL;
251 
252 	priv = TRACKER_MINER_FILES_INDEX_GET_PRIVATE (miner);
253 
254 	g_variant_get (parameters, "(^a&s)", &mime_types);
255 
256 	len = mime_types ? g_strv_length (mime_types) : 0;
257 
258 	tracker_gdbus_async_return_if_fail (len > 0, invocation);
259 
260 	request = tracker_g_dbus_request_begin (invocation, "%s(%d mime types)",
261 	                                        __FUNCTION__,
262 	                                        len);
263 
264 	connection = tracker_sparql_connection_get (NULL, &inner_error);
265 
266 	if (!connection) {
267 		g_free (mime_types);
268 		tracker_dbus_request_end (request, inner_error);
269 		g_dbus_method_invocation_return_gerror (invocation, inner_error);
270 		g_error_free (inner_error);
271 		return;
272 	}
273 
274 	tracker_dbus_request_comment (request,
275 	                              "Attempting to reindex the following mime types:");
276 
277 	query = g_string_new ("SELECT ?url "
278 	                      "WHERE {"
279 	                      "  ?resource nie:url ?url ;"
280 	                      "  nie:mimeType ?mime ."
281 	                      "  FILTER(");
282 
283 	for (i = 0; i < len; i++) {
284 		tracker_dbus_request_comment (request, "  %s", mime_types[i]);
285 		g_string_append_printf (query, "?mime = '%s'", mime_types[i]);
286 
287 		if (i < len - 1) {
288 			g_string_append (query, " || ");
289 		}
290 	}
291 
292 	g_string_append (query, ") }");
293 
294 	/* FIXME: save last call id */
295 	tracker_sparql_connection_query_async (connection,
296 	                                       query->str,
297 	                                       NULL,
298 	                                       mime_types_cb,
299 	                                       mime_types_data_new (request,
300 	                                                            invocation,
301 	                                                            connection,
302 	                                                            priv->files_miner));
303 
304 	g_string_free (query, TRUE);
305 	g_object_unref (connection);
306 	g_free (mime_types);
307 }
308 
309 static void
310 handle_method_call_index_file (TrackerMinerFilesIndex *miner,
311                                GDBusMethodInvocation  *invocation,
312                                GVariant               *parameters)
313 {
314 	TrackerMinerFilesIndexPrivate *priv;
315 	TrackerDBusRequest *request;
316 	GFile *file;
317 	GFileInfo *file_info;
318 	gboolean is_dir;
319 	gboolean do_checks = FALSE;
320 	GError *internal_error;
321 	const gchar *file_uri;
322 
323 	priv = TRACKER_MINER_FILES_INDEX_GET_PRIVATE (miner);
324 
325 	g_variant_get (parameters, "(&s)", &file_uri);
326 
327 	tracker_gdbus_async_return_if_fail (file_uri != NULL, invocation);
328 
329 	request = tracker_g_dbus_request_begin (invocation, "%s(uri:'%s')", __FUNCTION__, file_uri);
330 
331 	file = g_file_new_for_uri (file_uri);
332 
333 	file_info = g_file_query_info (file,
334 	                               G_FILE_ATTRIBUTE_STANDARD_TYPE,
335 	                               G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
336 	                               NULL, NULL);
337 
338 	if (!file_info) {
339 		internal_error = g_error_new_literal (1, 0, "File does not exist");
340 		tracker_dbus_request_end (request, internal_error);
341 		g_dbus_method_invocation_return_gerror (invocation, internal_error);
342 
343 		g_error_free (internal_error);
344 
345 		g_object_unref (file);
346 
347 		return;
348 	}
349 
350 	is_dir = (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY);
351 	g_object_unref (file_info);
352 
353 #ifdef REQUIRE_LOCATION_IN_CONFIG
354 	do_checks = TRUE;
355 	if (!tracker_miner_files_is_file_eligible (priv->files_miner, file)) {
356 		internal_error = g_error_new_literal (1, 0, "File is not eligible to be indexed");
357 		tracker_dbus_request_end (request, internal_error);
358 		g_dbus_method_invocation_return_gerror (invocation, internal_error);
359 
360 		g_error_free (internal_error);
361 
362 		g_object_unref (file);
363 
364 		return;
365 	}
366 #endif /* REQUIRE_LOCATION_IN_CONFIG */
367 
368 	if (is_dir) {
369 		tracker_miner_fs_check_directory (TRACKER_MINER_FS (priv->files_miner), file, do_checks);
370 	} else {
371 		tracker_miner_fs_check_file (TRACKER_MINER_FS (priv->files_miner), file, do_checks);
372 	}
373 
374 	tracker_dbus_request_end (request, NULL);
375 	g_dbus_method_invocation_return_value (invocation, NULL);
376 
377 	g_object_unref (file);
378 }
379 
380 static void
381 handle_method_call (GDBusConnection       *connection,
382                     const gchar           *sender,
383                     const gchar           *object_path,
384                     const gchar           *interface_name,
385                     const gchar           *method_name,
386                     GVariant              *parameters,
387                     GDBusMethodInvocation *invocation,
388                     gpointer               user_data)
389 {
390 	TrackerMinerFilesIndex *miner = user_data;
391 
392 	tracker_gdbus_async_return_if_fail (miner != NULL, invocation);
393 	tracker_gdbus_async_return_if_fail (TRACKER_IS_MINER_FILES_INDEX (miner), invocation);
394 
395 	if (g_strcmp0 (method_name, "ReindexMimeTypes") == 0) {
396 		tracker_miner_files_index_reindex_mime_types (miner, invocation, parameters);
397 	} else if (g_strcmp0 (method_name, "IndexFile") == 0) {
398 		handle_method_call_index_file (miner, invocation, parameters);
399 	} else {
400 		g_assert_not_reached ();
401 	}
402 }
403 
404 static GVariant *
405 handle_get_property (GDBusConnection  *connection,
406                      const gchar      *sender,
407                      const gchar      *object_path,
408                      const gchar      *interface_name,
409                      const gchar      *property_name,
410                      GError          **error,
411                      gpointer          user_data)
412 {
413 	g_assert_not_reached ();
414 	return NULL;
415 }
416 
417 static gboolean
418 handle_set_property (GDBusConnection  *connection,
419                      const gchar      *sender,
420                      const gchar      *object_path,
421                      const gchar      *interface_name,
422                      const gchar      *property_name,
423                      GVariant         *value,
424                      GError          **error,
425                      gpointer          user_data)
426 {
427 	g_assert_not_reached ();
428 	return TRUE;
429 }
430 
431 static void
432 tracker_miner_files_index_init (TrackerMinerFilesIndex *object)
433 {
434 }
435 
436 TrackerMinerFilesIndex *
437 tracker_miner_files_index_new (TrackerMinerFiles *miner_files)
438 {
439 	GObject *miner;
440 	TrackerMinerFilesIndexPrivate *priv;
441 	gchar *full_path, *full_name;
442 	GVariant *reply;
443 	guint32 rval;
444 	GError *error = NULL;
445 	GDBusInterfaceVTable interface_vtable = {
446 		handle_method_call,
447 		handle_get_property,
448 		handle_set_property
449 	};
450 
451 	miner = g_object_new (TRACKER_TYPE_MINER_FILES_INDEX,
452 	                      "files-miner", miner_files,
453 	                      NULL);
454 
455 	priv = TRACKER_MINER_FILES_INDEX_GET_PRIVATE (miner);
456 
457 	priv->d_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
458 
459 	if (!priv->d_connection) {
460 		g_critical ("Could not connect to the D-Bus session bus, %s",
461 		            error ? error->message : "no error given.");
462 		g_clear_error (&error);
463 		g_object_unref (miner);
464 		return NULL;
465 	}
466 
467 	priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, &error);
468 	if (!priv->introspection_data) {
469 		g_critical ("Could not create node info from introspection XML, %s",
470 		            error ? error->message : "no error given.");
471 		g_clear_error (&error);
472 		return NULL;
473 	}
474 
475 	full_name = g_strconcat (TRACKER_MINER_DBUS_NAME_PREFIX, "Files.Index", NULL);
476 	priv->full_name = full_name;
477 
478 	/* Register the service name for the miner */
479 	full_path = g_strconcat (TRACKER_MINER_DBUS_PATH_PREFIX, "Files/Index", NULL);
480 
481 	g_message ("Registering D-Bus object...");
482 	g_message ("  Path:'%s'", full_path);
483 	g_message ("  Object Type:'%s'", G_OBJECT_TYPE_NAME (miner));
484 
485 	priv->registration_id =
486 		g_dbus_connection_register_object (priv->d_connection,
487 		                                   full_path,
488 		                                   priv->introspection_data->interfaces[0],
489 		                                   &interface_vtable,
490 		                                   miner,
491 		                                   NULL,
492 		                                   &error);
493 
494 	if (error) {
495 		g_critical ("Could not register the D-Bus object %s, %s",
496 		            full_path,
497 		            error ? error->message : "no error given.");
498 		g_clear_error (&error);
499 		g_object_unref (miner);
500 		return NULL;
501 	}
502 
503 	reply = g_dbus_connection_call_sync (priv->d_connection,
504 	                                     "org.freedesktop.DBus",
505 	                                     "/org/freedesktop/DBus",
506 	                                     "org.freedesktop.DBus",
507 	                                     "RequestName",
508 	                                     g_variant_new ("(su)", full_name, 0x4 /* DBUS_NAME_FLAG_DO_NOT_QUEUE */),
509 	                                     G_VARIANT_TYPE ("(u)"),
510 	                                     0, -1, NULL, &error);
511 
512 	if (error) {
513 		g_critical ("Could not acquire name:'%s', %s",
514 		            full_name,
515 		            error->message);
516 		g_clear_error (&error);
517 		g_object_unref (miner);
518 		return NULL;
519 	}
520 
521 	g_variant_get (reply, "(u)", &rval);
522 	g_variant_unref (reply);
523 
524 	if (rval != 1 /* DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */) {
525 		g_critical ("D-Bus service name:'%s' is already taken, "
526 		            "perhaps the daemon is already running?",
527 		            full_name);
528 		g_object_unref (miner);
529 		return NULL;
530 	}
531 
532 	priv->full_path = full_path;
533 
534 	return (TrackerMinerFilesIndex *) miner;
535 }