Commit edba66e5 authored by Sumaid Syed's avatar Sumaid Syed
parents 4ddf5f02 40cc9e9b
Pipeline #105908 failed with stage
in 1 minute and 46 seconds
......@@ -19,7 +19,7 @@ test-fedora-latest:
# that Tracker is installed on the host here, thanks to `dnf builddep`.
- su tracker -c 'mkdir subprojects; cd subprojects; git clone https://gitlab.gnome.org/GNOME/tracker'
- su tracker -c 'mkdir build'
- su tracker -c 'cd build; meson .. --prefix=/usr -Dtracker_core=subproject'
- su tracker -c 'cd build; meson .. --prefix=/usr -Dtracker_core=subproject -Db_lto=true'
- su tracker -c 'cd build; ninja'
- |
# Remove the many "CI_" variables from the environment. Meson dumps the
......
NEW in 2.2.99.0 - 2019-08-07
============================
* Support for reading Musicbrainz metadata from audio files.
* Tracker Writeback now uses GStreamer to write metadata to audio files,
instead of depending on taglib directly.
* Directories will now be ignored if they contain a file named `.nomedia`.
A file named `.trackerignore` has the same effect, but the `.nomedia` file
brings us in line with Android.
* Removed obsolete 'max-media-art-width' setting.
NEW in 2.2.2 - 2019-05-02
=========================
......
......@@ -156,7 +156,7 @@ Boston, MA 02110-1301, USA.
<key name="ignored-directories-with-content" type="as">
<summary>Ignored directories with content</summary>
<description>Avoid any directory containing a file blacklisted here</description>
<default>[ '.trackerignore', '.git', '.hg' ]</default>
<default>[ '.trackerignore', '.git', '.hg', '.nomedia' ]</default>
</key>
</schema>
</schemalist>
project('tracker-miners', 'c',
version: '2.3.0',
version: '2.2.99.0',
meson_version: '>=0.47')
gnome = import('gnome')
......@@ -118,7 +118,9 @@ add_project_arguments('-Wformat', '-Wformat-security', language: 'c')
# There are various gchar vs. unsigned char warnings that occur in extract
# modules, it's not worth adding casts everywhere so we disable the warning.
add_project_arguments('-Wno-pointer-sign', language: 'c')
add_project_arguments('-DTRACKER_COMPILATION', language: 'c')
add_project_arguments('-DG_LOG_DOMAIN="Tracker"', language: 'c')
##################################################################
# Check for libtracker-common: battery/mains power detection
......
This diff is collapsed.
......@@ -140,6 +140,39 @@ tracker_extract_new_equipment (const char *make,
return equipment;
}
/**
* tracker_extract_new_external_reference:
* @source_uri: the source uri of the external reference
* @identifier: the identifier of the external reference
*
* Create a new tracker:ExternalReference resource and set its source and its
* identifier. Both @source and @identifer must be non-%NULL.
*
* Returns: a newly allocated #TrackerResource instance, of type tracker:ExternalReference
*
* Since: 2.3.0
*/
TrackerResource *
tracker_extract_new_external_reference (const char *source_uri,
const char *identifier)
{
TrackerResource *external_reference;
gchar *uri;
g_return_val_if_fail (source_uri != NULL && identifier != NULL, NULL);
uri = tracker_sparql_escape_uri_printf ("tracker:ExternalReference:%s", source_uri);
external_reference = tracker_resource_new (uri);
tracker_resource_set_uri (external_reference, "rdf:type", "tracker:ExternalReference");
tracker_resource_set_uri (external_reference, "tracker:referenceSource", source_uri);
tracker_resource_set_string (external_reference, "tracker:referenceIdentifier", identifier);
g_free(uri);
return external_reference;
}
/**
* tracker_extract_new_location:
* @street_address: (allow none): main part of postal address, or %NULL
......
......@@ -32,6 +32,7 @@ G_BEGIN_DECLS
TrackerResource *tracker_extract_new_artist (const char *name);
TrackerResource *tracker_extract_new_contact (const char *fullname);
TrackerResource *tracker_extract_new_equipment (const char *make, const char *model);
TrackerResource *tracker_extract_new_external_reference (const char *source_uri, const char *identifier);
TrackerResource *tracker_extract_new_location (const char *address, const char *state, const char *city, const char *country, const char *gps_altitude, const char *gps_latitude, const char *gps_longitude);
TrackerResource *tracker_extract_new_music_album_disc (const char *album_title, TrackerResource *album_artist, int disc_number, const char *date);
TrackerResource *tracker_extract_new_tag (const char *label);
......
......@@ -21,48 +21,9 @@
#include "config-miners.h"
#include <string.h>
#include <gio/gio.h>
#include "tracker-domain-ontology.h"
typedef struct {
/* DomainOntologies section */
GFile *cache_location;
GFile *journal_location;
GFile *ontology_location;
gchar *name;
gchar *domain;
gchar *ontology_name;
gchar **miners;
} TrackerDomainOntologyPrivate;
enum {
PROP_0,
PROP_NAME
};
struct {
const gchar *var;
const gchar *(*func) (void);
} lookup_dirs[] = {
{ "HOME", g_get_home_dir },
{ "XDG_CACHE_HOME", g_get_user_cache_dir },
{ "XDG_DATA_HOME", g_get_user_data_dir },
{ "XDG_RUNTIME_DIR", g_get_user_runtime_dir },
};
struct {
const gchar *var;
GUserDirectory user_directory;
} lookup_special_dirs[] = {
{ "XDG_DESKTOP_DIR", G_USER_DIRECTORY_DESKTOP },
{ "XDG_DOCUMENTS_DIR", G_USER_DIRECTORY_DOCUMENTS },
{ "XDG_DOWNLOAD_DIR", G_USER_DIRECTORY_DOWNLOAD },
{ "XDG_MUSIC_DIR", G_USER_DIRECTORY_MUSIC },
{ "XDG_PICTURES_DIR", G_USER_DIRECTORY_PICTURES },
{ "XDG_PUBLICSHARE_DIR", G_USER_DIRECTORY_PUBLIC_SHARE },
{ "XDG_VIDEOS_DIR", G_USER_DIRECTORY_VIDEOS },
};
#define DOMAIN_ONTOLOGY_SECTION "DomainOntology"
#define CACHE_KEY "CacheLocation"
......@@ -74,194 +35,6 @@ struct {
#define DEFAULT_RULE "default.rule"
static void tracker_domain_ontology_initable_iface_init (GInitableIface *iface);
G_DEFINE_TYPE_WITH_CODE (TrackerDomainOntology, tracker_domain_ontology, G_TYPE_OBJECT,
G_ADD_PRIVATE (TrackerDomainOntology)
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_domain_ontology_initable_iface_init))
static void
tracker_domain_ontology_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TrackerDomainOntology *domain_ontology;
TrackerDomainOntologyPrivate *priv;
domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
switch (prop_id) {
case PROP_NAME:
priv->name = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
tracker_domain_ontology_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TrackerDomainOntology *domain_ontology;
TrackerDomainOntologyPrivate *priv;
domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, priv->name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
tracker_domain_ontology_finalize (GObject *object)
{
TrackerDomainOntology *domain_ontology;
TrackerDomainOntologyPrivate *priv;
domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
g_clear_object (&priv->cache_location);
g_clear_object (&priv->journal_location);
g_clear_object (&priv->ontology_location);
g_free (priv->ontology_name);
g_free (priv->name);
g_free (priv->domain);
g_strfreev (priv->miners);
G_OBJECT_CLASS (tracker_domain_ontology_parent_class)->finalize (object);
}
static void
tracker_domain_ontology_class_init (TrackerDomainOntologyClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = tracker_domain_ontology_set_property;
object_class->get_property = tracker_domain_ontology_get_property;
object_class->finalize = tracker_domain_ontology_finalize;
g_object_class_install_property (object_class,
PROP_NAME,
g_param_spec_string ("name",
"Name",
"Name",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
tracker_domain_ontology_init (TrackerDomainOntology *domain_ontology)
{
}
static const gchar *
lookup_dir (const gchar *variable,
gsize variable_len)
{
gint i;
for (i = 0; i < G_N_ELEMENTS (lookup_dirs); i++) {
if (strncmp (lookup_dirs[i].var, variable, variable_len) == 0) {
return lookup_dirs[i].func ();
}
}
for (i = 0; i < G_N_ELEMENTS (lookup_special_dirs); i++) {
if (strncmp (lookup_special_dirs[i].var, variable, variable_len) == 0) {
return g_get_user_special_dir (lookup_special_dirs[i].user_directory);
}
}
return NULL;
}
static GFile *
key_file_get_location (GKeyFile *key_file,
const gchar *section,
const gchar *key,
gboolean essential,
gboolean must_exist,
GError **error)
{
GError *inner_error = NULL;
gchar *value;
GFile *file;
value = g_key_file_get_string (key_file, section, key, &inner_error);
if (inner_error) {
if (essential)
g_propagate_error (error, inner_error);
else
g_error_free (inner_error);
return NULL;
}
if (value[0] == '$') {
const gchar *var_end, *prefix;
gchar *path;
/* This is a path relative from a xdg dir */
var_end = strchr (value, '/');
if (!var_end) {
/* We must take $VAR/subdir values */
g_set_error (error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_INVALID_VALUE,
"Path in key '%s' can not consist solely of a variable",
key);
g_free (value);
return NULL;
}
prefix = lookup_dir (&value[1], (var_end - &value[1]));
if (!prefix) {
g_set_error (error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_INVALID_VALUE,
"Unrecognized variable in '%s'", key);
g_free (value);
return NULL;
}
path = g_strconcat (prefix, var_end, NULL);
file = g_file_new_for_path (path);
g_free (path);
} else {
file = g_file_new_for_uri (value);
}
g_free (value);
if (must_exist && file &&
g_file_query_file_type (file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL) != G_FILE_TYPE_DIRECTORY) {
gchar *uri = g_file_get_uri (file);
g_set_error (error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_INVALID_VALUE,
"Uri '%s' is not a directory or does not exist", uri);
g_free (uri);
return NULL;
}
return file;
}
static gchar *
find_rule_in_data_dirs (const gchar *name)
{
......@@ -289,38 +62,33 @@ find_rule_in_data_dirs (const gchar *name)
return NULL;
}
static gboolean
tracker_domain_ontology_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
gboolean
tracker_load_domain_config (const gchar *name,
gchar **dbus_domain_name,
GError **error)
{
TrackerDomainOntology *domain_ontology;
TrackerDomainOntologyPrivate *priv;
GError *inner_error = NULL;
GKeyFile *key_file = NULL;
GKeyFile *key_file;
gchar *path, *path_for_tests;
GError *inner_error = NULL;
domain_ontology = TRACKER_DOMAIN_ONTOLOGY (initable);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
if (priv->name && priv->name[0] == '/') {
if (!g_file_test (priv->name, G_FILE_TEST_IS_REGULAR)) {
if (name && name[0] == '/') {
if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) {
inner_error = g_error_new (G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_NOT_FOUND,
"Could not find rule at '%s'",
priv->name);
name);
goto end;
}
path = g_strdup (priv->name);
} else if (priv->name) {
path = find_rule_in_data_dirs (priv->name);
path = g_strdup (name);
} else if (name) {
path = find_rule_in_data_dirs (name);
if (!path) {
inner_error = g_error_new (G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_NOT_FOUND,
"Could not find rule '%s' in data dirs",
priv->name);
name);
goto end;
}
} else {
......@@ -351,60 +119,11 @@ tracker_domain_ontology_initable_init (GInitable *initable,
if (inner_error)
goto end;
priv->domain = g_key_file_get_string (key_file, DOMAIN_ONTOLOGY_SECTION,
DOMAIN_KEY, &inner_error);
if (inner_error)
goto end;
priv->cache_location =
key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
CACHE_KEY, TRUE, FALSE, &inner_error);
if (inner_error)
goto end;
priv->journal_location =
key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
JOURNAL_KEY, FALSE, FALSE, &inner_error);
if (inner_error)
goto end;
priv->ontology_location =
key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
ONTOLOGY_KEY, FALSE, TRUE, &inner_error);
*dbus_domain_name = g_key_file_get_string (key_file, DOMAIN_ONTOLOGY_SECTION,
DOMAIN_KEY, &inner_error);
if (inner_error)
goto end;
priv->ontology_name = g_key_file_get_string (key_file, DOMAIN_ONTOLOGY_SECTION,
ONTOLOGY_NAME_KEY, NULL);
priv->miners = g_key_file_get_string_list (key_file, DOMAIN_ONTOLOGY_SECTION,
MINERS_KEY, NULL, NULL);
/* Consistency check, we need one of OntologyLocation and OntologyName,
* no more, no less.
*/
if ((priv->ontology_name && priv->ontology_location) ||
(!priv->ontology_name && !priv->ontology_location)) {
inner_error = g_error_new (G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_INVALID_VALUE,
"One of OntologyLocation and OntologyName must be provided");
}
/* Build ontology location from name if necessary */
if (!priv->ontology_location) {
gchar *ontology_path;
ontology_path = g_build_filename (SHAREDIR, "tracker", "ontologies",
priv->ontology_name, NULL);
if (!g_file_test (ontology_path, G_FILE_TEST_IS_DIR)) {
g_free (ontology_path);
ontology_path = g_strdup (g_getenv ("TRACKER_DB_ONTOLOGIES_DIR"));
}
priv->ontology_location = g_file_new_for_path (ontology_path);
g_free (ontology_path);
}
end:
if (key_file)
g_key_file_free (key_file);
......@@ -416,83 +135,3 @@ end:
return TRUE;
}
static void
tracker_domain_ontology_initable_iface_init (GInitableIface *iface)
{
iface->init = tracker_domain_ontology_initable_init;
}
TrackerDomainOntology *
tracker_domain_ontology_new (const gchar *domain_name,
GCancellable *cancellable,
GError **error)
{
return g_initable_new (TRACKER_TYPE_DOMAIN_ONTOLOGY,
cancellable, error,
"name", domain_name,
NULL);
}
GFile *
tracker_domain_ontology_get_cache (TrackerDomainOntology *domain_ontology)
{
TrackerDomainOntologyPrivate *priv;
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
return priv->cache_location;
}
GFile *
tracker_domain_ontology_get_journal (TrackerDomainOntology *domain_ontology)
{
TrackerDomainOntologyPrivate *priv;
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
return priv->journal_location;
}
GFile *
tracker_domain_ontology_get_ontology (TrackerDomainOntology *domain_ontology)
{
TrackerDomainOntologyPrivate *priv;
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
return priv->ontology_location;
}
gchar *
tracker_domain_ontology_get_domain (TrackerDomainOntology *domain_ontology,
const gchar *suffix)
{
TrackerDomainOntologyPrivate *priv;
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
if (suffix)
return g_strconcat (priv->domain, ".", suffix, NULL);
else
return g_strconcat (priv->domain, NULL);
}
gboolean
tracker_domain_ontology_uses_miner (TrackerDomainOntology *domain_ontology,
const gchar *suffix)
{
TrackerDomainOntologyPrivate *priv;
guint i;
g_return_val_if_fail (suffix != NULL, FALSE);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
if (!priv->miners)
return FALSE;
for (i = 0; priv->miners[i] != NULL; i++) {
if (strcmp (priv->miners[i], suffix) == 0) {
return TRUE;
}
}
return FALSE;
}
......@@ -27,43 +27,7 @@
#endif
#include <glib-object.h>
#include <gio/gio.h>
#define TRACKER_TYPE_DOMAIN_ONTOLOGY (tracker_domain_ontology_get_type())
#define TRACKER_DOMAIN_ONTOLOGY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntology))
#define TRACKER_DOMAIN_ONTOLOGY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntologyClass))
#define TRACKER_IS_DOMAIN_ONTOLOGY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY))
#define TRACKER_IS_DOMAIN_ONTOLOGY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_DOMAIN_ONTOLOGY))
#define TRACKER_DOMAIN_ONTOLOGY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntologyClass))
gboolean tracker_load_domain_config (const gchar *name, gchar **dbus_domain_name, GError **error);
typedef struct _TrackerDomainOntology TrackerDomainOntology;
typedef struct _TrackerDomainOntologyClass TrackerDomainOntologyClass;
struct _TrackerDomainOntology {
GObject parent_instance;
};
struct _TrackerDomainOntologyClass {
GObjectClass parent_class;
/*<private>*/
gpointer padding[10];
};
GType tracker_domain_ontology_get_type (void) G_GNUC_CONST;
TrackerDomainOntology * tracker_domain_ontology_new (const gchar *name,
GCancellable *cancellable,
GError **error);
GFile * tracker_domain_ontology_get_cache (TrackerDomainOntology *domain_ontology);
GFile * tracker_domain_ontology_get_journal (TrackerDomainOntology *domain_ontology);
GFile * tracker_domain_ontology_get_ontology (TrackerDomainOntology *domain_ontology);
gchar * tracker_domain_ontology_get_domain (TrackerDomainOntology *domain_ontology,
const gchar *suffix);
gboolean tracker_domain_ontology_uses_miner (TrackerDomainOntology *domain_ontology,
const gchar *suffix);
#endif /* __TRACKER_MINER_PROXY_H__ */
#endif /* __TRACKER_DOMAIN_ONTOLOGY_H__ */
......@@ -773,8 +773,7 @@ main (gint argc, gchar *argv[])
gboolean store_available;
TrackerMinerProxy *proxy;
GDBusConnection *connection;
TrackerDomainOntology *domain_ontology;
gchar *domain_name, *dbus_name;
gchar *dbus_domain_name, *dbus_name;
main_loop = NULL;
......@@ -814,8 +813,9 @@ main (gint argc, gchar *argv[])
tracker_sparql_connection_set_domain (domain_ontology_name);
domain_ontology = tracker_domain_ontology_new (domain_ontology_name, NULL, &error);
if (error) {
tracker_load_domain_config (domain_ontology_name, &dbus_domain_name, &error);
if (error != NULL) {
g_critical ("Could not load domain ontology '%s': %s",
domain_ontology_name, error->message);
g_error_free (error);
......@@ -856,18 +856,16 @@ main (gint argc, gchar *argv[])
main_loop = g_main_loop_new (NULL, FALSE);
if (domain_ontology && domain_ontology_name) {
if (domain_ontology_name) {
/* If we are running for a specific domain, we tie the lifetime of this
* process to the domain. For example, if the domain name is
* org.example.MyApp then this tracker-miner-fs process will exit as
* soon as org.example.MyApp exits.
*/
domain_name = tracker_domain_ontology_get_domain (domain_ontology, NULL);
g_bus_watch_name_on_connection (connection, domain_name,
g_bus_watch_name_on_connection (connection, dbus_domain_name,
G_BUS_NAME_WATCHER_FLAGS_NONE,
NULL, on_domain_vanished,
main_loop, NULL);
g_free (domain_name);
}
g_message ("Checking if we're running as a daemon:");
......@@ -922,7 +920,7 @@ main (gint argc, gchar *argv[])
}
/* Request DBus name */
dbus_name = tracker_domain_ontology_get_domain (domain_ontology, DBUS_NAME_SUFFIX);
dbus_name = g_strconcat (dbus_domain_name, ".", DBUS_NAME_SUFFIX, NULL);
if (!tracker_dbus_request_name (connection, dbus_name, &error)) {
g_critical ("Could not request DBus name '%s': %s",
......@@ -996,7 +994,8 @@ main (gint argc, gchar *argv[])
g_object_unref (proxy);
g_object_unref (connection);
g_object_unref (domain_ontology);
g_free (dbus_domain_name);
tracker_writeback_shutdown ();
tracker_log_shutdown ();
......
......@@ -2484,6 +2484,7 @@ process_file_cb (GObject *object,
priv->extraction_queue = g_list_remove (priv->extraction_queue, data);
process_file_data_free (data);
g_object_run_dispose (resource);
g_object_unref (resource);
g_object_unref (file_info);
g_free (sparql_str);
......
......@@ -78,8 +78,7 @@ main (int argc, char **argv)
GError *error = NULL;
GDBusConnection *connection;
TrackerMinerProxy *proxy;
TrackerDomainOntology *domain_ontology;
gchar *domain_name, *dbus_name;
gchar *dbus_domain_name, *dbus_name;
setlocale (LC_ALL, "");
......@@ -172,7 +171,8 @@ main (int argc, char **argv)
g_free (log_filename);
}
domain_ontology = tracker_domain_ontology_new (domain_ontology_name, NULL, &error);
tracker_load_domain_config (domain_ontology_name, &dbus_domain_name, &error);
if (error) {
g_critical ("Could not load domain ontology '%s': %s",
domain_ontology_name, error->message);
......@@ -203,7 +203,7 @@ main (int argc, char **argv)
return EXIT_FAILURE;
}
dbus_name = tracker_domain_ontology_get_domain (domain_ontology, DBUS_NAME_SUFFIX);
dbus_name = g_strconcat (dbus_domain_name, ".", DBUS_NAME_SUFFIX, NULL);
if (!tracker_dbus_request_name (connection, dbus_name, &error)) {
g_critical ("Could not request DBus name '%s': %s",
......@@ -217,18 +217,16 @@ main (int argc, char **argv)
loop = g_main_loop_new (NULL, FALSE);
if (domain_ontology && domain_ontology_name) {
if (domain_ontology_name) {
/* If we are running for a specific domain, we tie the lifetime of this
* process to the domain. For example, if the domain name is
* org.example.MyApp then this tracker-miner-rss process will exit as
* soon as org.example.MyApp exits.
*/
domain_name = tracker_domain_ontology_get_domain (domain_ontology, NULL);
g_bus_watch_name_on_connection (connection, domain_name,
g_bus_watch_name_on_connection (connection, dbus_domain_name,
G_BUS_NAME_WATCHER_FLAGS_NONE,
NULL, on_domain_vanished,
loop, NULL);
g_free (domain_name);
}
g_main_loop_run (loop);
......@@ -238,7 +236,7 @@ main (int argc, char **argv)
g_object_unref (miner);
g_object_unref (connection);
g_object_unref (proxy);
g_object_unref