diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2011-10-26 19:07:28 +0200 |
---|---|---|
committer | Tomas Bzatek <tbzatek@redhat.com> | 2012-05-21 15:50:27 +0200 |
commit | 22859c3caec11cfd4472701b138b5fa4c985c5fb (patch) | |
tree | 89a3aa87e0166aed3979f7d807744a869b5363d7 | |
parent | 15dc2dc69cb5b4fe1594c089c5f259dfd63895ce (diff) | |
download | gvfs-22859c3caec11cfd4472701b138b5fa4c985c5fb.tar.gz |
gdbus: Port metadata
Some TODOs:
* print better error messages when we can't own the dbus name
* remove dbus.h includes and CFLAGS once gvfsdaemonprotocol.h is ported
* "Get" method call unused?
-rw-r--r-- | client/gdaemonfile.c | 80 | ||||
-rw-r--r-- | client/gdaemonvfs.c | 223 | ||||
-rw-r--r-- | client/gdaemonvfs.h | 2 | ||||
-rw-r--r-- | metadata/Makefile.am | 23 | ||||
-rw-r--r-- | metadata/meta-daemon.c | 668 | ||||
-rw-r--r-- | metadata/meta-set.c | 139 |
6 files changed, 458 insertions, 677 deletions
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c index 15c368c8..4f400fae 100644 --- a/client/gdaemonfile.c +++ b/client/gdaemonfile.c @@ -41,6 +41,7 @@ #include "gmountoperationdbus.h" #include <gio/gio.h> #include "metatree.h" +#include <metadata-dbus.h> static void g_daemon_file_file_iface_init (GFileIface *iface); @@ -2215,53 +2216,62 @@ set_metadata_attribute (GFile *file, GError **error) { GDaemonFile *daemon_file; - DBusMessage *message; char *treename; const char *metatreefile; MetaTree *tree; int appended; gboolean res; + GVfsMetadata *proxy; + GVariantBuilder *builder; daemon_file = G_DAEMON_FILE (file); treename = g_mount_spec_to_string (daemon_file->mount_spec); tree = meta_tree_lookup_by_name (treename, FALSE); g_free (treename); - - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET); - g_assert (message != NULL); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &daemon_file->path, - 0); - - appended = _g_daemon_vfs_append_metadata_for_set (message, - tree, - daemon_file->path, - attribute, - type, - value); - - res = TRUE; - if (appended == -1) - { - res = FALSE; - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - _("Error setting file metadata: %s"), - _("values must be string or list of strings")); + + res = FALSE; + proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + G_VFS_DBUS_METADATA_NAME, + G_VFS_DBUS_METADATA_PATH, + cancellable, + error); + + if (proxy) + { + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + + metatreefile = meta_tree_get_filename (tree); + + appended = _g_daemon_vfs_append_metadata_for_set (builder, + tree, + daemon_file->path, + attribute, + type, + value); + + res = TRUE; + if (appended == -1) + { + res = FALSE; + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error setting file metadata: %s"), + _("values must be string or list of strings")); + } + else if (appended > 0 && + !gvfs_metadata_call_set_sync (proxy, + metatreefile, + daemon_file->path, + g_variant_builder_end (builder), + cancellable, + error)) + res = FALSE; + + g_variant_builder_unref (builder); + g_object_unref (proxy); } - else if (appended > 0 && - !_g_daemon_vfs_send_message_sync (message, - cancellable, error)) - res = FALSE; - - dbus_message_unref (message); meta_tree_unref (tree); diff --git a/client/gdaemonvfs.c b/client/gdaemonvfs.c index e62da9b8..df2a33d1 100644 --- a/client/gdaemonvfs.c +++ b/client/gdaemonvfs.c @@ -41,6 +41,7 @@ #include "gvfsiconloadable.h" #include <glib/gi18n-lib.h> #include <glib/gstdio.h> +#include <metadata-dbus.h> typedef struct { char *type; @@ -1170,19 +1171,6 @@ g_daemon_vfs_add_writable_namespaces (GVfs *vfs, G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); } -static void -send_message_oneway (DBusMessage *message) -{ - DBusConnection *connection; - - connection = _g_dbus_connection_get_sync (NULL, NULL); - if (connection == NULL) - return; - - dbus_connection_send (connection, message, NULL); - dbus_connection_flush (connection); -} - /* Sends a message on the session bus and blocks for the reply, using the thread local connection */ gboolean @@ -1239,7 +1227,7 @@ strv_equal (char **a, char **b) /* -1 => error, otherwise number of added items */ int -_g_daemon_vfs_append_metadata_for_set (DBusMessage *message, +_g_daemon_vfs_append_metadata_for_set (GVariantBuilder *builder, MetaTree *tree, const char *path, const char *attribute, @@ -1261,10 +1249,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, if (current == NULL || strcmp (current, val) != 0) { res = 1; - _g_dbus_message_append_args (message, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_STRING, &val, - 0); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (val)); } g_free (current); } @@ -1276,10 +1261,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, if (current == NULL || !strv_equal (current, val)) { res = 1; - _g_dbus_message_append_args (message, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &val, g_strv_length (val), - 0); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const *) val, -1)); } g_strfreev (current); } @@ -1290,10 +1272,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, char c = 0; res = 1; /* Byte => unset */ - _g_dbus_message_append_args (message, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_BYTE, &c, - 0); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_byte (c)); } } else @@ -1319,10 +1298,11 @@ g_daemon_vfs_local_file_set_attributes (GVfs *vfs, MetaTree *tree; int errsv; int i, num_set; - DBusMessage *message; gboolean res; int appended; gpointer value; + GVfsMetadata *proxy; + GVariantBuilder *builder; res = TRUE; if (g_file_info_has_namespace (info, "metadata")) @@ -1352,65 +1332,77 @@ g_daemon_vfs_local_file_set_attributes (GVfs *vfs, statbuf.st_dev, FALSE, &tree_path); - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET); - g_assert (message != NULL); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - 0); - meta_lookup_cache_free (cache); - - num_set = 0; - for (i = 0; attributes[i] != NULL; i++) + + proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + G_VFS_DBUS_METADATA_NAME, + G_VFS_DBUS_METADATA_PATH, + NULL, + error); + + if (proxy == NULL) { - if (g_file_info_get_attribute_data (info, attributes[i], &type, &value, NULL)) - { - appended = _g_daemon_vfs_append_metadata_for_set (message, - tree, - tree_path, - attributes[i], - type, - value); - if (appended != -1) - { - num_set += appended; - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_SET); - } - else - { - res = FALSE; - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - _("Error setting file metadata: %s"), - _("values must be string or list of strings")); - error = NULL; /* Don't set further errors */ - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); - } - } + res = FALSE; + error = NULL; /* Don't set further errors */ } - - meta_tree_unref (tree); - g_free (tree_path); - - if (num_set > 0 && - !_g_daemon_vfs_send_message_sync (message, - cancellable, error)) + else { - res = FALSE; - error = NULL; /* Don't set further errors */ - for (i = 0; attributes[i] != NULL; i++) - g_file_info_set_attribute_status (info, attributes[i], - G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + metatreefile = meta_tree_get_filename (tree); + num_set = 0; + + for (i = 0; attributes[i] != NULL; i++) + { + if (g_file_info_get_attribute_data (info, attributes[i], &type, &value, NULL)) + { + appended = _g_daemon_vfs_append_metadata_for_set (builder, + tree, + tree_path, + attributes[i], + type, + value); + if (appended != -1) + { + num_set += appended; + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_SET); + } + else + { + res = FALSE; + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Error setting file metadata: %s"), + _("values must be string or list of strings")); + error = NULL; /* Don't set further errors */ + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + } + } + } + + if (num_set > 0 && + ! gvfs_metadata_call_set_sync (proxy, + metatreefile, + tree_path, + g_variant_builder_end (builder), + NULL, + error)) + { + res = FALSE; + error = NULL; /* Don't set further errors */ + for (i = 0; attributes[i] != NULL; i++) + g_file_info_set_attribute_status (info, attributes[i], + G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING); + } + + g_variant_builder_unref (builder); + g_object_unref (proxy); + + meta_lookup_cache_free (cache); + meta_tree_unref (tree); + g_free (tree_path); } - - dbus_message_unref (message); } g_strfreev (attributes); @@ -1424,10 +1416,10 @@ g_daemon_vfs_local_file_removed (GVfs *vfs, const char *filename) { MetaLookupCache *cache; - DBusMessage *message; const char *metatreefile; MetaTree *tree; char *tree_path; + GVfsMetadata *proxy; cache = meta_lookup_cache_new (); tree = meta_lookup_cache_lookup_path (cache, @@ -1437,19 +1429,24 @@ g_daemon_vfs_local_file_removed (GVfs *vfs, &tree_path); if (tree) { - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_REMOVE); - g_assert (message != NULL); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - 0); - send_message_oneway (message); - dbus_message_unref (message); + proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + G_VFS_DBUS_METADATA_NAME, + G_VFS_DBUS_METADATA_PATH, + NULL, + NULL); + + if (proxy) + { + metatreefile = meta_tree_get_filename (tree); + gvfs_metadata_call_remove_sync (proxy, + metatreefile, + tree_path, + NULL, + NULL); + g_object_unref (proxy); + } + meta_tree_unref (tree); g_free (tree_path); } @@ -1463,10 +1460,10 @@ g_daemon_vfs_local_file_moved (GVfs *vfs, const char *dest) { MetaLookupCache *cache; - DBusMessage *message; const char *metatreefile; MetaTree *tree1, *tree2; char *tree_path1, *tree_path2; + GVfsMetadata *proxy; cache = meta_lookup_cache_new (); tree1 = meta_lookup_cache_lookup_path (cache, @@ -1481,20 +1478,24 @@ g_daemon_vfs_local_file_moved (GVfs *vfs, &tree_path2); if (tree1 && tree2 && tree1 == tree2) { - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_MOVE); - g_assert (message != NULL); - metatreefile = meta_tree_get_filename (tree1); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path1, - G_DBUS_TYPE_CSTRING, &tree_path2, - 0); - send_message_oneway (message); - dbus_message_unref (message); + proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + G_VFS_DBUS_METADATA_NAME, + G_VFS_DBUS_METADATA_PATH, + NULL, + NULL); + + if (proxy) + { + metatreefile = meta_tree_get_filename (tree1); + gvfs_metadata_call_move_sync (proxy, + metatreefile, + tree_path1, + tree_path2, + NULL, + NULL); + g_object_unref (proxy); + } } if (tree1) diff --git a/client/gdaemonvfs.h b/client/gdaemonvfs.h index 16d01a70..5b1b72eb 100644 --- a/client/gdaemonvfs.h +++ b/client/gdaemonvfs.h @@ -71,7 +71,7 @@ DBusConnection *_g_daemon_vfs_get_async_bus (void); gboolean _g_daemon_vfs_send_message_sync (DBusMessage *message, GCancellable *cancellable, GError **error); -int _g_daemon_vfs_append_metadata_for_set (DBusMessage *message, +int _g_daemon_vfs_append_metadata_for_set (GVariantBuilder *builder, MetaTree *tree, const char *path, const char *attribute, diff --git a/metadata/Makefile.am b/metadata/Makefile.am index d3f25be3..1f59972b 100644 --- a/metadata/Makefile.am +++ b/metadata/Makefile.am @@ -1,5 +1,14 @@ NULL = +dbus_built_sources = metadata-dbus.c metadata-dbus.h +$(dbus_built_sources) : Makefile.am dbus-interface.xml + gdbus-codegen \ + --interface-prefix org.gtk.vfs. \ + --c-namespace GVfs \ + --generate-c-code metadata-dbus \ + dbus-interface.xml \ + $(NULL) + noinst_LTLIBRARIES=libmetadata.la APPS = \ @@ -30,6 +39,7 @@ libmetadata_la_SOURCES = \ metatree.c metatree.h \ metabuilder.c metabuilder.h \ crc32.c crc32.h \ + $(dbus_built_sources) \ $(NULL) libmetadata_la_LIBADD = $(GLIB_LIBS) $(UDEV_LIBS) @@ -37,7 +47,7 @@ libmetadata_la_LIBADD = $(GLIB_LIBS) $(UDEV_LIBS) meta_ls_LDADD = libmetadata.la meta_ls_SOURCES = meta-ls.c -meta_set_LDADD = libmetadata.la $(DBUS_LIBS) ../common/libgvfscommon.la +meta_set_LDADD = libmetadata.la ../common/libgvfscommon.la meta_set_SOURCES = meta-set.c meta_get_LDADD = libmetadata.la @@ -49,7 +59,7 @@ meta_get_tree_SOURCES = meta-get-tree.c convert_nautilus_metadata_LDADD = libmetadata.la $(LIBXML_LIBS) convert_nautilus_metadata_SOURCES = metadata-nautilus.c -gvfsd_metadata_LDADD = libmetadata.la $(DBUS_LIBS) ../common/libgvfscommon.la +gvfsd_metadata_LDADD = libmetadata.la ../common/libgvfscommon.la gvfsd_metadata_SOURCES = meta-daemon.c # D-BUS service file @@ -60,7 +70,14 @@ servicedir = $(DBUS_SERVICE_DIR) service_in_files = gvfs-metadata.service.in service_DATA = gvfs-metadata.service -EXTRA_DIST = gvfs-metadata.service.in +EXTRA_DIST = \ + gvfs-metadata.service.in \ + dbus-interface.xml \ + $(NULL) clean-local: rm -f gvfs-metadata.service + +CLEANFILES = \ + $(dbus_built_sources) \ + $(NULL) diff --git a/metadata/meta-daemon.c b/metadata/meta-daemon.c index 0e21696b..5a1362f8 100644 --- a/metadata/meta-daemon.c +++ b/metadata/meta-daemon.c @@ -27,10 +27,11 @@ #include <glib/gstdio.h> #include <locale.h> #include <stdlib.h> +/* TODO: remove + remove traces in Makefile.am */ #include <dbus/dbus.h> -#include "gvfsdbusutils.h" #include "metatree.h" #include "gvfsdaemonprotocol.h" +#include "metadata-dbus.h" #define WRITEOUT_TIMEOUT_SECS 60 @@ -41,6 +42,7 @@ typedef struct { } TreeInfo; static GHashTable *tree_infos = NULL; +static GVfsMetadata *skeleton = NULL; static void tree_info_free (TreeInfo *info) @@ -109,174 +111,90 @@ tree_info_lookup (const char *filename) } static gboolean -metadata_set (const char *treefile, - const char *path, - DBusMessageIter *iter, - DBusError *derror) +handle_set (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *treefile, + const gchar *path, + GVariant *data, + GVfsMetadata *daemon) { TreeInfo *info; - const char *str; - char **strv; - gboolean res; - const char *key; - int n_elements; - char c; + const gchar *str; + const gchar **strv; + const gchar *key; + GError *error; + GVariantIter iter; + GVariant *value; info = tree_info_lookup (treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return FALSE; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + treefile); + return TRUE; } - res = TRUE; - while (dbus_message_iter_get_arg_type (iter) != 0) - { - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_STRING, &key, - 0)) - { - res = FALSE; - break; - } + error = NULL; - if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY) + g_variant_iter_init (&iter, data); + while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) + { + if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) { /* stringv */ - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &strv, &n_elements, - 0)) + strv = g_variant_get_strv (value, NULL); + if (!meta_tree_set_stringv (info->tree, path, key, (gchar **) strv)) { - res = FALSE; - break; + g_set_error_literal (&error, G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to set metadata key")); } - if (!meta_tree_set_stringv (info->tree, path, key, strv)) - { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to set metadata key")); - res = FALSE; - } - g_strfreev (strv); + g_free (strv); } - else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) + else if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { /* string */ - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_STRING, &str, - 0)) - { - res = FALSE; - break; - } + str = g_variant_get_string (value, NULL); if (!meta_tree_set_string (info->tree, path, key, str)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to set metadata key")); - res = FALSE; + g_set_error_literal (&error, G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to set metadata key")); } } - else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BYTE) + else if (g_variant_is_of_type (value, G_VARIANT_TYPE_BYTE)) { /* Unset */ - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_BYTE, &c, - 0)) - { - res = FALSE; - break; - } if (!meta_tree_unset (info->tree, path, key)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to unset metadata key")); - res = FALSE; + g_set_error_literal (&error, G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to unset metadata key")); } } + g_variant_unref (value); } tree_info_schedule_writeout (info); - return res; -} - -static void -append_string (DBusMessageIter *iter, - const char *key, - const char *string) -{ - DBusMessageIter variant_iter, struct_iter; - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_STRUCT, - NULL, - &struct_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_append_basic (&struct_iter, - DBUS_TYPE_STRING, - &key)) - _g_dbus_oom (); - - if (!dbus_message_iter_open_container (&struct_iter, - DBUS_TYPE_VARIANT, - DBUS_TYPE_STRING_AS_STRING, - &variant_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_append_basic (&variant_iter, - DBUS_TYPE_STRING, &string)) - _g_dbus_oom (); - - if (!dbus_message_iter_close_container (&struct_iter, &variant_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_close_container (iter, &struct_iter)) - _g_dbus_oom (); -} - -static void -append_stringv (DBusMessageIter *iter, - const char *key, - char **stringv) -{ - DBusMessageIter variant_iter, struct_iter; - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_STRUCT, - NULL, - &struct_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_append_basic (&struct_iter, - DBUS_TYPE_STRING, - &key)) - _g_dbus_oom (); - - if (!dbus_message_iter_open_container (&struct_iter, - DBUS_TYPE_VARIANT, - DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, - &variant_iter)) - _g_dbus_oom (); - - _g_dbus_message_iter_append_args (&variant_iter, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &stringv, g_strv_length (stringv), - 0); - - if (!dbus_message_iter_close_container (&struct_iter, &variant_iter)) - _g_dbus_oom (); - - if (!dbus_message_iter_close_container (iter, &struct_iter)) - _g_dbus_oom (); + if (error) + { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + } + else + { + gvfs_metadata_complete_set (object, invocation); + } + + return TRUE; } static void -append_key (DBusMessageIter *iter, +append_key (GVariantBuilder *builder, MetaTree *tree, const char *path, const char *key) @@ -290,13 +208,13 @@ append_key (DBusMessageIter *iter, if (keytype == META_KEY_TYPE_STRING) { str = meta_tree_lookup_string (tree, path, key); - append_string (iter, key, str); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (str)); g_free (str); } else if (keytype == META_KEY_TYPE_STRINGV) { strv = meta_tree_lookup_stringv (tree, path, key); - append_stringv (iter, key, strv); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const *) strv, -1)); g_strfreev (strv); } } @@ -313,382 +231,220 @@ enum_keys (const char *key, return TRUE; } -static DBusMessage * -metadata_get (const char *treefile, - const char *path, - DBusMessage *message, - DBusMessageIter *iter, - DBusError *derror) +static gboolean +handle_get (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *treefile, + const gchar *path, + const gchar *const *keys, + GVfsMetadata *daemon) { TreeInfo *info; - char *key; - DBusMessage *reply; - DBusMessageIter reply_iter; - GPtrArray *keys; - int i; + GPtrArray *meta_keys; gboolean free_keys; + gchar **iter_keys; + gchar **i; + GVariantBuilder *builder; info = tree_info_lookup (treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return NULL; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + treefile); + return TRUE; } - reply = dbus_message_new_method_return (message); - dbus_message_iter_init_append (reply, &reply_iter); - - keys = g_ptr_array_new (); - if (dbus_message_iter_get_arg_type (iter) == 0) + if (keys == NULL) { /* Get all keys */ free_keys = TRUE; - meta_tree_enumerate_keys (info->tree, path, enum_keys, keys); + meta_keys = g_ptr_array_new (); + meta_tree_enumerate_keys (info->tree, path, enum_keys, meta_keys); + iter_keys = (gchar **) g_ptr_array_free (meta_keys, FALSE); } else { free_keys = FALSE; - while (dbus_message_iter_get_arg_type (iter) != 0) - { - if (!_g_dbus_message_iter_get_args (iter, derror, - DBUS_TYPE_STRING, &key, - 0)) - break; - - g_ptr_array_add (keys, key); - } + iter_keys = (gchar **) keys; } - for (i = 0; i < keys->len; i++) - { - key = g_ptr_array_index (keys, i); - append_key (&reply_iter, info->tree, path, key); - if (free_keys) - g_free (key); - } - g_ptr_array_free (keys, TRUE); + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + + for (i = iter_keys; *i; i++) + append_key (builder, info->tree, path, *i); + if (free_keys) + g_strfreev (iter_keys); + + gvfs_metadata_complete_get (object, invocation, + g_variant_builder_end (builder)); + g_variant_builder_unref (builder); - return reply; + return TRUE; } static gboolean -metadata_unset (const char *treefile, - const char *path, - const char *key, - DBusError *derror) +handle_unset (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *treefile, + const gchar *path, + const gchar *key, + GVfsMetadata *daemon) { TreeInfo *info; info = tree_info_lookup (treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return FALSE; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + treefile); + return TRUE; } if (!meta_tree_unset (info->tree, path, key)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to unset metadata key")); - return FALSE; + g_dbus_method_invocation_return_error_literal (invocation, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to unset metadata key")); + return TRUE; } tree_info_schedule_writeout (info); + gvfs_metadata_complete_unset (object, invocation); + return TRUE; } static gboolean -metadata_remove (const char *treefile, - const char *path, - DBusError *derror) +handle_remove (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *treefile, + const gchar *path, + GVfsMetadata *daemon) { TreeInfo *info; info = tree_info_lookup (treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return FALSE; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + treefile); + return TRUE; } if (!meta_tree_remove (info->tree, path)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to remove metadata keys")); - return FALSE; + g_dbus_method_invocation_return_error_literal (invocation, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to remove metadata keys")); + return TRUE; } tree_info_schedule_writeout (info); + gvfs_metadata_complete_remove (object, invocation); + return TRUE; } static gboolean -metadata_move (const char *treefile, - const char *src_path, - const char *dest_path, - DBusError *derror) +handle_move (GVfsMetadata *object, + GDBusMethodInvocation *invocation, + const gchar *treefile, + const gchar *path, + const gchar *dest_path, + GVfsMetadata *daemon) { TreeInfo *info; info = tree_info_lookup (treefile); if (info == NULL) { - dbus_set_error (derror, - DBUS_ERROR_FILE_NOT_FOUND, - _("Can't find metadata file %s"), - treefile); - return FALSE; + g_dbus_method_invocation_return_error (invocation, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Can't find metadata file %s"), + treefile); + return TRUE; } /* Overwrites any dest */ - if (!meta_tree_copy (info->tree, src_path, dest_path)) + if (!meta_tree_copy (info->tree, path, dest_path)) { - dbus_set_error (derror, - DBUS_ERROR_FAILED, - _("Unable to move metadata keys")); - return FALSE; + g_dbus_method_invocation_return_error_literal (invocation, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Unable to move metadata keys")); + return TRUE; } /* Remove source if copy succeeded (ignoring errors) */ - meta_tree_remove (info->tree, src_path); + meta_tree_remove (info->tree, path); tree_info_schedule_writeout (info); + gvfs_metadata_complete_move (object, invocation); + return TRUE; } -static gboolean -register_name (DBusConnection *conn, - gboolean replace) -{ - DBusError error; - unsigned int flags; - int ret; - - flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT | DBUS_NAME_FLAG_DO_NOT_QUEUE; - if (replace) - flags |= DBUS_NAME_FLAG_REPLACE_EXISTING; - - dbus_error_init (&error); - ret = dbus_bus_request_name (conn, G_VFS_DBUS_METADATA_NAME, flags, &error); - if (ret == -1) - { - g_printerr ("Failed to acquire daemon name: %s", error.message); - dbus_error_free (&error); - return FALSE; - } - else if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS) - { - g_printerr ("Metadata daemon already running, exiting.\n"); - return FALSE; - } - else if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - g_printerr ("Not primary owner of the service, exiting.\n"); - return FALSE; - } - return TRUE; -} - -static DBusHandlerResult -dbus_message_filter_func (DBusConnection *conn, - DBusMessage *message, - gpointer data) +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) { - char *name; + GError *error; + + g_warning ("Acquired the name %s on the session message bus\n", name); + + skeleton = gvfs_metadata_skeleton_new (); + + g_signal_connect (skeleton, "handle-set", G_CALLBACK (handle_set), skeleton); + g_signal_connect (skeleton, "handle-unset", G_CALLBACK (handle_unset), skeleton); + g_signal_connect (skeleton, "handle-get", G_CALLBACK (handle_get), skeleton); + g_signal_connect (skeleton, "handle-remove", G_CALLBACK (handle_remove), skeleton); + g_signal_connect (skeleton, "handle-move", G_CALLBACK (handle_move), skeleton); - if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameLost")) + error = NULL; + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton), connection, + G_VFS_DBUS_METADATA_PATH, &error)) { - if (dbus_message_get_args (message, NULL, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID) && - strcmp (name, G_VFS_DBUS_METADATA_NAME) == 0) - { - /* Someone else got the name (i.e. someone used --replace), exit */ - exit (1); - } + g_printerr ("Error exporting volume monitor: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static void -metadata_unregistered (DBusConnection *connection, - void *user_data) +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) { -} - -static DBusHandlerResult -metadata_message (DBusConnection *connection, - DBusMessage *message, - void *user_data) -{ - DBusMessageIter iter; - DBusError derror; - DBusMessage *reply; - char *treefile; - char *path, *dest_path; - const char *key; - - reply = NULL; - dbus_message_iter_init (message, &iter); - dbus_error_init (&derror); - - if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET)) - { - treefile = NULL; - path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - 0) || - !metadata_set (treefile, path, &iter, &derror)) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - else - reply = dbus_message_new_method_return (message); - - g_free (treefile); - g_free (path); - } - - else if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_UNSET)) - { - treefile = NULL; - path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - DBUS_TYPE_STRING, &key, - 0) || - !metadata_unset (treefile, path, key, &derror)) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - else - reply = dbus_message_new_method_return (message); - - g_free (treefile); - g_free (path); - } - - if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_GET)) - { - treefile = NULL; - path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - 0) || - (reply = metadata_get (treefile, path, message, &iter, &derror)) == NULL) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - - g_free (treefile); - g_free (path); - } - - else if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_REMOVE)) - { - treefile = NULL; - path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - 0) || - !metadata_remove (treefile, path, &derror)) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - else - reply = dbus_message_new_method_return (message); - - g_free (treefile); - g_free (path); - } + GMainLoop *loop = user_data; - else if (dbus_message_is_method_call (message, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_MOVE)) - { - treefile = NULL; - path = NULL; - dest_path = NULL; - if (!_g_dbus_message_iter_get_args (&iter, &derror, - G_DBUS_TYPE_CSTRING, &treefile, - G_DBUS_TYPE_CSTRING, &path, - G_DBUS_TYPE_CSTRING, &dest_path, - 0) || - !metadata_move (treefile, path, dest_path, &derror)) - { - reply = dbus_message_new_error (message, - derror.name, - derror.message); - dbus_error_free (&derror); - } - else - reply = dbus_message_new_method_return (message); - - g_free (treefile); - g_free (path); - g_free (dest_path); - } - - if (reply) - { - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); - return DBUS_HANDLER_RESULT_HANDLED; - } - else - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + /* means that someone has claimed our name (we allow replacement) */ + g_warning ("Got NameLost, some other instance replaced us"); + g_main_loop_quit (loop); } -static struct DBusObjectPathVTable metadata_dbus_vtable = { - metadata_unregistered, - metadata_message -}; int main (int argc, char *argv[]) { GMainLoop *loop; - DBusConnection *conn; + GDBusConnection *conn; gboolean replace; GError *error; - DBusError derror; + guint name_owner_id; + GBusNameOwnerFlags flags; GOptionContext *context; const GOptionEntry options[] = { { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, N_("Replace old daemon."), NULL }, @@ -709,6 +465,7 @@ main (int argc, char *argv[]) g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); replace = FALSE; + name_owner_id = 0; error = NULL; if (!g_option_context_parse (context, &argc, &argv, &error)) @@ -731,56 +488,43 @@ main (int argc, char *argv[]) loop = g_main_loop_new (NULL, FALSE); - dbus_error_init (&derror); - conn = dbus_bus_get (DBUS_BUS_SESSION, &derror); + error = NULL; + conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (!conn) { - g_printerr ("Failed to connect to the D-BUS daemon: %s\n", - derror.message); - - dbus_error_free (&derror); - return 1; - } - - dbus_bus_add_match (conn, - "type='signal'," - "interface='org.freedesktop.DBus'," - "member='NameOwnerChanged'," - "arg0='"G_VFS_DBUS_METADATA_NAME"'", - &derror); - if (dbus_error_is_set (&derror)) - { - g_printerr ("Failed to add dbus match: %s\n", derror.message); - dbus_error_free (&derror); - return 1; - } - - if (!dbus_connection_add_filter (conn, - dbus_message_filter_func, NULL, NULL)) - { - g_printerr ("Failed to add dbus filter\n"); - return 1; - } - - if (!dbus_connection_register_object_path (conn, - G_VFS_DBUS_METADATA_PATH, - &metadata_dbus_vtable, NULL)) - { - g_printerr ("Failed to register object path\n"); + g_printerr ("Failed to connect to the D-BUS daemon: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); return 1; } - - if (!register_name (conn, replace)) - return 1; - - _g_dbus_connection_integrate_with_main (conn); - + + flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; + if (replace) + flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; + + name_owner_id = g_bus_own_name_on_connection (conn, + G_VFS_DBUS_METADATA_NAME, + flags, + on_name_acquired, + on_name_lost, + loop, + NULL); + tree_infos = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)tree_info_free); g_main_loop_run (loop); + + if (skeleton) + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (skeleton)); + if (name_owner_id != 0) + g_bus_unown_name (name_owner_id); + if (conn) + g_object_unref (conn); + if (loop != NULL) + g_main_loop_unref (loop); return 0; } diff --git a/metadata/meta-set.c b/metadata/meta-set.c index 22af1fcd..04a6b38e 100644 --- a/metadata/meta-set.c +++ b/metadata/meta-set.c @@ -1,9 +1,10 @@ #include "config.h" #include "metatree.h" #include <glib/gstdio.h> +/* TODO: remove + remove traces in Makefile.am */ #include <dbus/dbus.h> #include "gvfsdaemonprotocol.h" -#include "gvfsdbusutils.h" +#include "metadata-dbus.h" static gboolean unset = FALSE; static gboolean list = FALSE; @@ -28,12 +29,12 @@ main (int argc, MetaLookupCache *lookup; struct stat statbuf; const char *path, *key; - DBusConnection *connection; - DBusMessage *message, *reply; const char *metatreefile; - DBusError derror; char *tree_path; - + GVfsMetadata *proxy; + + g_type_init(); + context = g_option_context_new ("<path> <key> <value> - set metadata"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); if (!g_option_context_parse (context, &argc, &argv, &error)) @@ -96,39 +97,42 @@ main (int argc, } } - connection = NULL; + proxy = NULL; if (use_dbus) { - dbus_error_init (&derror); - connection = dbus_bus_get (DBUS_BUS_SESSION, &derror); - if (connection == NULL) + proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + G_VFS_DBUS_METADATA_NAME, + G_VFS_DBUS_METADATA_PATH, + NULL, + &error); + + if (proxy == NULL) { - g_printerr ("Unable to connect to dbus: %s\n", derror.message); - dbus_error_free (&derror); + g_printerr ("Unable to connect to dbus: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); return 1; } + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), 1000*30); } if (unset) { if (use_dbus) { - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_UNSET); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - DBUS_TYPE_STRING, &key, - 0); - reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30, - &derror); - if (reply == NULL) + metatreefile = meta_tree_get_filename (tree); + + if (! gvfs_metadata_call_unset_sync (proxy, + metatreefile, + tree_path, + key, + NULL, + &error)) { - g_printerr ("Unset error: %s\n", derror.message); + g_printerr ("Unset error: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); return 1; } } @@ -146,26 +150,27 @@ main (int argc, if (use_dbus) { char **strv; - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET); - metatreefile = meta_tree_get_filename (tree); - strv = &argv[3]; - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &strv, argc - 3, - 0); - reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30, - &derror); - if (reply == NULL) - { - g_printerr ("SetStringv error: %s\n", derror.message); - return 1; - } + GVariantBuilder *builder; + + metatreefile = meta_tree_get_filename (tree); + strv = &argv[3]; + + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const *) strv, -1)); + + if (! gvfs_metadata_call_set_sync (proxy, + metatreefile, + tree_path, + g_variant_builder_end (builder), + NULL, + &error)) + { + g_printerr ("SetStringv error: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + return 1; + } + + g_variant_builder_unref (builder); } else { @@ -180,25 +185,26 @@ main (int argc, { if (use_dbus) { - message = - dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME, - G_VFS_DBUS_METADATA_PATH, - G_VFS_DBUS_METADATA_INTERFACE, - G_VFS_DBUS_METADATA_OP_SET); - metatreefile = meta_tree_get_filename (tree); - _g_dbus_message_append_args (message, - G_DBUS_TYPE_CSTRING, &metatreefile, - G_DBUS_TYPE_CSTRING, &tree_path, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_STRING, &argv[3], - 0); - reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30, - &derror); - if (reply == NULL) - { - g_printerr ("SetString error: %s\n", derror.message); - return 1; - } + GVariantBuilder *builder; + + metatreefile = meta_tree_get_filename (tree); + + builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (argv[3])); + + if (! gvfs_metadata_call_set_sync (proxy, + metatreefile, + tree_path, + g_variant_builder_end (builder), + NULL, + &error)) + { + g_printerr ("SetString error: %s (%s, %d)\n", + error->message, g_quark_to_string (error->domain), error->code); + return 1; + } + + g_variant_builder_unref (builder); } else { @@ -210,5 +216,8 @@ main (int argc, } } + if (proxy) + g_object_unref (proxy); + return 0; } |