diff options
-rw-r--r-- | client/gdaemonfile.c | 16 | ||||
-rw-r--r-- | client/gvfsdaemondbus.c | 146 | ||||
-rw-r--r-- | common/gvfsdaemonprotocol.c | 212 | ||||
-rw-r--r-- | common/gvfsdaemonprotocol.h | 39 | ||||
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/gvfsbackend.c | 5 | ||||
-rw-r--r-- | daemon/gvfsbackend.h | 19 | ||||
-rw-r--r-- | daemon/gvfsjobenumerate.c | 4 | ||||
-rw-r--r-- | daemon/gvfsjobgetfsinfo.c | 4 | ||||
-rw-r--r-- | daemon/gvfsjobgetinfo.c | 2 | ||||
-rw-r--r-- | daemon/gvfsjobsetattribute.c | 171 | ||||
-rw-r--r-- | daemon/gvfsjobsetattribute.h | 46 |
12 files changed, 480 insertions, 185 deletions
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c index f55b7779..664cd6e8 100644 --- a/client/gdaemonfile.c +++ b/client/gdaemonfile.c @@ -1319,7 +1319,6 @@ g_daemon_file_set_attribute (GFile *file, GCancellable *cancellable, GError **error) { -#if 0 GDaemonFile *daemon_file; DBusMessage *message, *reply; DBusMessageIter iter; @@ -1338,20 +1337,17 @@ g_daemon_file_set_attribute (GFile *file, DBUS_TYPE_UINT32, &flags_dbus); + _g_dbus_append_file_attribute (&iter, attribute, type, value_ptr); + + reply = _g_vfs_daemon_call_sync (message, + NULL, + NULL, NULL, NULL, + cancellable, error); - reply = do_sync_path_call (file, - G_VFS_DBUS_MOUNT_OP_SET_ATTRIBUTE, - NULL, cancellable, error, - DBUS_TYPE_STRING, &attribute, - DBUS_TYPE_UINT, &type, - DBUS_TYPE_UINT32, &flags_dbus, - g_dbus_type_from_file_attribute_type (type), &value, - 0); if (reply == NULL) return FALSE; dbus_message_unref (reply); -#endif return TRUE; } diff --git a/client/gvfsdaemondbus.c b/client/gvfsdaemondbus.c index 3b0975f2..50b32086 100644 --- a/client/gvfsdaemondbus.c +++ b/client/gvfsdaemondbus.c @@ -915,149 +915,3 @@ _g_dbus_connection_get_sync (const char *dbus_id, return connection; } - -/************************************************************************** - * GFileInfo demarshaller * - *************************************************************************/ - - -GFileInfo * -_g_dbus_get_file_info (DBusMessageIter *iter, - GError **error) -{ - GFileInfo *info; - DBusMessageIter struct_iter, array_iter, inner_struct_iter, variant_iter, cstring_iter, obj_iter; - const char *attribute; - - info = g_file_info_new (); - - if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRUCT) - goto error; - - dbus_message_iter_recurse (iter, &struct_iter); - - if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_ARRAY) - goto error; - - dbus_message_iter_recurse (&struct_iter, &array_iter); - - while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRUCT) - { - char *str; - char **strs; - int n_elements; - guint32 v_uint32; - gint32 v_int32; - guint64 v_uint64; - gint64 v_int64; - guint32 obj_type; - GObject *obj; - - dbus_message_iter_recurse (&array_iter, &inner_struct_iter); - - if (dbus_message_iter_get_arg_type (&inner_struct_iter) != DBUS_TYPE_STRING) - goto error; - - dbus_message_iter_get_basic (&inner_struct_iter, &attribute); - dbus_message_iter_next (&inner_struct_iter); - - if (dbus_message_iter_get_arg_type (&inner_struct_iter) != DBUS_TYPE_VARIANT) - goto error; - - dbus_message_iter_recurse (&inner_struct_iter, &variant_iter); - - switch (dbus_message_iter_get_arg_type (&variant_iter)) - { - case DBUS_TYPE_STRING: - dbus_message_iter_get_basic (&variant_iter, &str); - g_file_info_set_attribute_string (info, attribute, str); - break; - case DBUS_TYPE_ARRAY: - if (dbus_message_iter_get_element_type (&variant_iter) != DBUS_TYPE_BYTE) - goto error; - - dbus_message_iter_recurse (&variant_iter, &cstring_iter); - dbus_message_iter_get_fixed_array (&cstring_iter, - &str, &n_elements); - str = g_strndup (str, n_elements); - g_file_info_set_attribute_byte_string (info, attribute, str); - g_free (str); - break; - case DBUS_TYPE_UINT32: - dbus_message_iter_get_basic (&variant_iter, &v_uint32); - g_file_info_set_attribute_uint32 (info, attribute, v_uint32); - break; - case DBUS_TYPE_INT32: - dbus_message_iter_get_basic (&variant_iter, &v_int32); - g_file_info_set_attribute_int32 (info, attribute, v_int32); - break; - case DBUS_TYPE_UINT64: - dbus_message_iter_get_basic (&variant_iter, &v_uint64); - g_file_info_set_attribute_uint64 (info, attribute, v_uint64); - break; - case DBUS_TYPE_INT64: - dbus_message_iter_get_basic (&variant_iter, &v_int64); - g_file_info_set_attribute_int64 (info, attribute, v_int64); - break; - case DBUS_TYPE_STRUCT: - dbus_message_iter_recurse (&variant_iter, &obj_iter); - if (dbus_message_iter_get_arg_type (&obj_iter) != DBUS_TYPE_UINT32) - goto error; - - dbus_message_iter_get_basic (&obj_iter, &obj_type); - obj = NULL; - /* 0 == NULL */ - if (obj_type == 1) - { - /* G_THEMED_ICON */ - if (_g_dbus_message_iter_get_args (&obj_iter, - NULL, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &strs, &n_elements, 0)) - { - obj = G_OBJECT (g_themed_icon_new_from_names (strs, -1)); - dbus_free_string_array (strs); - } - } - else if (obj_type == 2) - { - /* G_FILE_ICON, w/ local file */ - if (_g_dbus_message_iter_get_args (&obj_iter, - NULL, - G_DBUS_TYPE_CSTRING, &str, - 0)) - { - GFile *file = g_file_get_for_path (str); - obj = G_OBJECT (g_file_icon_new (file)); - g_free (str); - } - } - else - { - /* NULL (or unsupported) */ - if (obj_type != 0) - g_warning ("Unsupported object type in file attribute"); - } - - g_file_info_set_attribute_object (info, attribute, obj); - - if (obj) - g_object_unref (obj); - - break; - default: - goto error; - } - - dbus_message_iter_next (&array_iter); - } - - dbus_message_iter_next (iter); - return info; - - error: - g_object_unref (info); - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - _("Invalid file info format")); - return NULL; -} diff --git a/common/gvfsdaemonprotocol.c b/common/gvfsdaemonprotocol.c index b52790d6..29663534 100644 --- a/common/gvfsdaemonprotocol.c +++ b/common/gvfsdaemonprotocol.c @@ -1,5 +1,8 @@ +#include <config.h> + #include <glib-object.h> #include <dbus/dbus.h> +#include <glib/gi18n-lib.h> #include <gvfsdaemonprotocol.h> #include <gdbusutils.h> #include <gio/gthemedicon.h> @@ -7,7 +10,7 @@ #include <gio/glocalfile.h> gchar * -g_dbus_type_from_file_attribute_type (GFileAttributeType type) +_g_dbus_type_from_file_attribute_type (GFileAttributeType type) { char *dbus_type; @@ -49,16 +52,12 @@ append_file_attribute (DBusMessageIter *iter, GFileAttributeType type, gconstpointer value) { - DBusMessageIter struct_iter, variant_iter, array_iter, inner_struct_iter, obj_struct_iter; + DBusMessageIter variant_iter, inner_struct_iter, obj_struct_iter; char *dbus_type; guint32 v_uint32; - gint32 v_int32; - guint64 v_uint64; - gint64 v_int64; - const char *str = NULL; GObject *obj = NULL; - dbus_type = g_dbus_type_from_file_attribute_type (type); + dbus_type = _g_dbus_type_from_file_attribute_type (type); if (!dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, @@ -72,7 +71,6 @@ append_file_attribute (DBusMessageIter *iter, &attribute)) _g_dbus_oom (); - if (!dbus_message_iter_open_container (&inner_struct_iter, DBUS_TYPE_VARIANT, dbus_type, @@ -196,17 +194,17 @@ append_file_attribute (DBusMessageIter *iter, } void -g_dbus_append_file_attribute (DBusMessageIter *iter, - const char *attribute, - GFileAttributeType type, - gconstpointer value) +_g_dbus_append_file_attribute (DBusMessageIter *iter, + const char *attribute, + GFileAttributeType type, + gconstpointer value) { append_file_attribute (iter, attribute, type, value); } void -g_dbus_append_file_info (DBusMessageIter *iter, - GFileInfo *info) +_g_dbus_append_file_info (DBusMessageIter *iter, + GFileInfo *info) { DBusMessageIter struct_iter, array_iter; char **attributes; @@ -298,3 +296,189 @@ g_dbus_append_file_info (DBusMessageIter *iter, if (!dbus_message_iter_close_container (iter, &struct_iter)) _g_dbus_oom (); } + +gboolean +_g_dbus_get_file_attribute (DBusMessageIter *iter, + gchar **attribute, + GFileAttributeType *type, + GFileAttributeValue *value) +{ + char *str; + char **strs; + int n_elements; + DBusMessageIter inner_struct_iter, variant_iter, cstring_iter, obj_iter; + const gchar *attribute_temp; + + dbus_message_iter_recurse (iter, &inner_struct_iter); + + if (dbus_message_iter_get_arg_type (&inner_struct_iter) != DBUS_TYPE_STRING) + goto error; + + dbus_message_iter_get_basic (&inner_struct_iter, &attribute_temp); + *attribute = g_strdup (attribute_temp); + + dbus_message_iter_next (&inner_struct_iter); + + if (dbus_message_iter_get_arg_type (&inner_struct_iter) != DBUS_TYPE_VARIANT) + goto error; + + dbus_message_iter_recurse (&inner_struct_iter, &variant_iter); + + switch (dbus_message_iter_get_arg_type (&variant_iter)) + { + case DBUS_TYPE_STRING: + dbus_message_iter_get_basic (&variant_iter, &value->v.v_str); + *type = G_FILE_ATTRIBUTE_TYPE_STRING; + break; + case DBUS_TYPE_ARRAY: + if (dbus_message_iter_get_element_type (&variant_iter) != DBUS_TYPE_BYTE) + goto error; + + *type = G_FILE_ATTRIBUTE_TYPE_BYTE_STRING; + + dbus_message_iter_recurse (&variant_iter, &cstring_iter); + dbus_message_iter_get_fixed_array (&cstring_iter, + &str, &n_elements); + value->v.v_str = g_strndup (str, n_elements); + break; + case DBUS_TYPE_UINT32: + dbus_message_iter_get_basic (&variant_iter, &value->v.v_uint32); + *type = G_FILE_ATTRIBUTE_TYPE_UINT32; + break; + case DBUS_TYPE_INT32: + dbus_message_iter_get_basic (&variant_iter, &value->v.v_int32); + *type = G_FILE_ATTRIBUTE_TYPE_INT32; + break; + case DBUS_TYPE_UINT64: + dbus_message_iter_get_basic (&variant_iter, &value->v.v_uint64); + *type = G_FILE_ATTRIBUTE_TYPE_UINT64; + break; + case DBUS_TYPE_INT64: + dbus_message_iter_get_basic (&variant_iter, &value->v.v_int64); + *type = G_FILE_ATTRIBUTE_TYPE_INT64; + break; + case DBUS_TYPE_STRUCT: + dbus_message_iter_recurse (&variant_iter, &obj_iter); + if (dbus_message_iter_get_arg_type (&obj_iter) != DBUS_TYPE_UINT32) + goto error; + + *type = G_FILE_ATTRIBUTE_TYPE_OBJECT; + + dbus_message_iter_get_basic (&obj_iter, &value->obj_type); + value->v.v_obj = NULL; + /* 0 == NULL */ + if (value->obj_type == 1) + { + /* G_THEMED_ICON */ + if (_g_dbus_message_iter_get_args (&obj_iter, + NULL, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + &strs, &n_elements, 0)) + { + value->v.v_obj = G_OBJECT (g_themed_icon_new_from_names (strs, -1)); + dbus_free_string_array (strs); + } + } + else if (value->obj_type == 2) + { + /* G_FILE_ICON, w/ local file */ + if (_g_dbus_message_iter_get_args (&obj_iter, + NULL, + G_DBUS_TYPE_CSTRING, &str, + 0)) + { + GFile *file = g_file_get_for_path (str); + value->v.v_obj = G_OBJECT (g_file_icon_new (file)); + g_free (str); + } + } + else + { + /* NULL (or unsupported) */ + if (value->obj_type != 0) + g_warning ("Unsupported object type in file attribute"); + } + break; + default: + goto error; + } + + return TRUE; + + error: + return FALSE; +} + +GFileInfo * +_g_dbus_get_file_info (DBusMessageIter *iter, + GError **error) +{ + GFileInfo *info; + DBusMessageIter struct_iter, array_iter; + gchar *attribute; + + info = g_file_info_new (); + + if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRUCT) + goto error; + + dbus_message_iter_recurse (iter, &struct_iter); + + if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_ARRAY) + goto error; + + dbus_message_iter_recurse (&struct_iter, &array_iter); + + while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRUCT) + { + GFileAttributeType type; + GFileAttributeValue value; + + if (!_g_dbus_get_file_attribute (&array_iter, &attribute, &type, &value)) + goto error; + + switch (type) + { + case G_FILE_ATTRIBUTE_TYPE_STRING: + g_file_info_set_attribute_string (info, attribute, value.v.v_str); + break; + case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: + g_file_info_set_attribute_byte_string (info, attribute, value.v.v_str); + g_free (value.v.v_str); + break; + case G_FILE_ATTRIBUTE_TYPE_UINT32: + g_file_info_set_attribute_uint32 (info, attribute, value.v.v_uint32); + break; + case G_FILE_ATTRIBUTE_TYPE_INT32: + g_file_info_set_attribute_int32 (info, attribute, value.v.v_int32); + break; + case G_FILE_ATTRIBUTE_TYPE_UINT64: + g_file_info_set_attribute_uint64 (info, attribute, value.v.v_uint64); + break; + case G_FILE_ATTRIBUTE_TYPE_INT64: + g_file_info_set_attribute_int64 (info, attribute, value.v.v_int64); + break; + case G_FILE_ATTRIBUTE_TYPE_OBJECT: + g_file_info_set_attribute_object (info, attribute, value.v.v_obj); + if (value.v.v_obj) + g_object_unref (value.v.v_obj); + break; + default: + g_assert_not_reached (); + continue; + } + + g_free (attribute); + + dbus_message_iter_next (&array_iter); + } + + dbus_message_iter_next (iter); + return info; + + error: + g_object_unref (info); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid file info format")); + return NULL; +} diff --git a/common/gvfsdaemonprotocol.h b/common/gvfsdaemonprotocol.h index 5d39dd36..b4d65dcf 100644 --- a/common/gvfsdaemonprotocol.h +++ b/common/gvfsdaemonprotocol.h @@ -33,6 +33,7 @@ G_BEGIN_DECLS #define G_VFS_DBUS_MOUNT_OP_MAKE_DIRECTORY "MakeDirectory" #define G_VFS_DBUS_MOUNT_OP_COPY "Copy" #define G_VFS_DBUS_MOUNT_OP_MOVE "Move" +#define G_VFS_DBUS_MOUNT_OP_SET_ATTRIBUTE "SetAttribute" /* Progress callback interface for copy and move */ #define G_VFS_DBUS_PROGRESS_INTERFACE "org.gtk.vfs.Progress" @@ -72,6 +73,23 @@ G_BEGIN_DECLS /* Normal ops are faster, one minute timeout */ #define G_VFS_DBUS_TIMEOUT_MSECS (1000*60) +typedef struct +{ + union + { + guint32 v_uint32; + gint32 v_int32; + guint64 v_uint64; + gint64 v_int64; + gchar *v_str; + GObject *v_obj; + } + v; + + guint32 obj_type; +} +GFileAttributeValue; + typedef struct { guint32 command; guint32 seq_nr; @@ -129,14 +147,19 @@ typedef struct { DBUS_STRUCT_END_CHAR_AS_STRING -char *g_dbus_get_file_info_signature (void); -gchar *g_dbus_type_from_file_attribute_type (GFileAttributeType type); -void g_dbus_append_file_attribute (DBusMessageIter *iter, - const char *attribute, - GFileAttributeType type, - gconstpointer value); -void g_dbus_append_file_info (DBusMessageIter *iter, - GFileInfo *file_info); +gchar *_g_dbus_type_from_file_attribute_type (GFileAttributeType type); +void _g_dbus_append_file_attribute (DBusMessageIter *iter, + const char *attribute, + GFileAttributeType type, + gconstpointer value); +void _g_dbus_append_file_info (DBusMessageIter *iter, + GFileInfo *file_info); +gboolean _g_dbus_get_file_attribute (DBusMessageIter *iter, + gchar **attribute, + GFileAttributeType *type, + GFileAttributeValue *value); +GFileInfo *_g_dbus_get_file_info (DBusMessageIter *iter, + GError **error); G_END_DECLS diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 7e01b13b..c7452bf1 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -77,6 +77,7 @@ libdaemon_la_SOURCES = \ gvfsjobcopy.c gvfsjobcopy.h \ gvfsjobmove.c gvfsjobmove.h \ gvfsjobmakedirectory.c gvfsjobmakedirectory.h \ + gvfsjobsetattribute.c gvfsjobsetattribute.h \ dbus-gmain.h dbus-gmain.c \ $(NULL) diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c index 49131e5d..55a2d82f 100644 --- a/daemon/gvfsbackend.c +++ b/daemon/gvfsbackend.c @@ -24,6 +24,7 @@ #include <gvfsjobmakedirectory.h> #include <gvfsjobcopy.h> #include <gvfsjobmove.h> +#include <gvfsjobsetattribute.h> #include <gdbusutils.h> enum { @@ -311,6 +312,10 @@ backend_dbus_handler (DBusConnection *connection, G_VFS_DBUS_MOUNT_INTERFACE, G_VFS_DBUS_MOUNT_OP_MOVE)) job = g_vfs_job_move_new (connection, message, backend); + else if (dbus_message_is_method_call (message, + G_VFS_DBUS_MOUNT_INTERFACE, + G_VFS_DBUS_MOUNT_OP_SET_ATTRIBUTE)) + job = g_vfs_job_set_attribute_new (connection, message, backend); if (job) { diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h index e4b99f68..cc0aece0 100644 --- a/daemon/gvfsbackend.h +++ b/daemon/gvfsbackend.h @@ -42,6 +42,7 @@ typedef struct _GVfsJobDelete GVfsJobDelete; typedef struct _GVfsJobMakeDirectory GVfsJobMakeDirectory; typedef struct _GVfsJobCopy GVfsJobCopy; typedef struct _GVfsJobMove GVfsJobMove; +typedef struct _GVfsJobSetAttribute GVfsJobSetAttribute; typedef gpointer GVfsBackendHandle; @@ -213,10 +214,10 @@ struct _GVfsBackendClass GVfsJobTrash *job, const char *filename); void (*make_directory) (GVfsBackend *backend, - GVfsJobMakeDirectory *make_directory, + GVfsJobMakeDirectory *job, const char *filename); gboolean (*try_make_directory)(GVfsBackend *backend, - GVfsJobMakeDirectory *make_directory, + GVfsJobMakeDirectory *job, const char *filename); void (*copy) (GVfsBackend *backend, GVfsJobCopy *job, @@ -246,6 +247,20 @@ struct _GVfsBackendClass GFileCopyFlags flags, GFileProgressCallback progress_callback, gpointer progress_callback_data); + void (*set_attribute) (GVfsBackend *backend, + GVfsJobSetAttribute *set_attribute, + const char *filename, + const char *attribute, + GFileAttributeType type, + gconstpointer value_ptr, + GFileGetInfoFlags flags); + gboolean (*try_set_attribute) (GVfsBackend *backend, + GVfsJobSetAttribute *set_attribute, + const char *filename, + const char *attribute, + GFileAttributeType type, + gconstpointer value_ptr, + GFileGetInfoFlags flags); }; GType g_vfs_backend_get_type (void) G_GNUC_CONST; diff --git a/daemon/gvfsjobenumerate.c b/daemon/gvfsjobenumerate.c index c36bd798..b29d9fd1 100644 --- a/daemon/gvfsjobenumerate.c +++ b/daemon/gvfsjobenumerate.c @@ -130,8 +130,8 @@ g_vfs_job_enumerate_add_info (GVfsJobEnumerate *job, num = 0; while (infos != NULL) { - g_dbus_append_file_info (&array_iter, - infos->data); + _g_dbus_append_file_info (&array_iter, + infos->data); infos = infos->next; if (++num > 100) break; diff --git a/daemon/gvfsjobgetfsinfo.c b/daemon/gvfsjobgetfsinfo.c index 9cb17d7e..ae1c80dd 100644 --- a/daemon/gvfsjobgetfsinfo.c +++ b/daemon/gvfsjobgetfsinfo.c @@ -150,8 +150,8 @@ create_reply (GVfsJob *job, dbus_message_iter_init_append (reply, &iter); - g_dbus_append_file_info (&iter, - op_job->file_info); + _g_dbus_append_file_info (&iter, + op_job->file_info); return reply; } diff --git a/daemon/gvfsjobgetinfo.c b/daemon/gvfsjobgetinfo.c index 1f935de7..94d0ef87 100644 --- a/daemon/gvfsjobgetinfo.c +++ b/daemon/gvfsjobgetinfo.c @@ -156,7 +156,7 @@ create_reply (GVfsJob *job, dbus_message_iter_init_append (reply, &iter); - g_dbus_append_file_info (&iter, + _g_dbus_append_file_info (&iter, op_job->file_info); return reply; diff --git a/daemon/gvfsjobsetattribute.c b/daemon/gvfsjobsetattribute.c new file mode 100644 index 00000000..52e22a84 --- /dev/null +++ b/daemon/gvfsjobsetattribute.c @@ -0,0 +1,171 @@ +#include <config.h> + +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <glib.h> +#include <dbus/dbus.h> +#include <glib/gi18n.h> +#include "gvfsjobmove.h" +#include "gdbusutils.h" +#include "gvfsdaemonprotocol.h" +#include "gvfsjobsetattribute.h" + +G_DEFINE_TYPE (GVfsJobSetAttribute, g_vfs_job_set_attribute, G_VFS_TYPE_JOB_DBUS); + +static void run (GVfsJob *job); +static gboolean try (GVfsJob *job); +static DBusMessage *create_reply (GVfsJob *job, + DBusConnection *connection, + DBusMessage *message); + +static void +g_vfs_job_set_attribute_finalize (GObject *object) +{ + GVfsJobSetAttribute *job; + + job = G_VFS_JOB_SET_ATTRIBUTE (object); + + g_free (job->filename); + g_free (job->attribute); + + if (G_OBJECT_CLASS (g_vfs_job_set_attribute_parent_class)->finalize) + (*G_OBJECT_CLASS (g_vfs_job_set_attribute_parent_class)->finalize) (object); +} + +static void +g_vfs_job_set_attribute_class_init (GVfsJobSetAttributeClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass); + GVfsJobDBusClass *job_dbus_class = G_VFS_JOB_DBUS_CLASS (klass); + + gobject_class->finalize = g_vfs_job_set_attribute_finalize; + job_class->run = run; + job_class->try = try; + job_dbus_class->create_reply = create_reply; +} + +static void +g_vfs_job_set_attribute_init (GVfsJobSetAttribute *job) +{ +} + +GVfsJob * +g_vfs_job_set_attribute_new (DBusConnection *connection, + DBusMessage *message, + GVfsBackend *backend) +{ + GVfsJobSetAttribute *job; + DBusMessage *reply; + DBusMessageIter iter, array_iter; + DBusError derror; + const gchar *filename = NULL; + gint filename_len; + GFileAttributeType type; + GFileAttributeValue value; + GFileGetInfoFlags flags; + gchar *attribute; + dbus_uint32_t flags_u32 = 0; + + dbus_error_init (&derror); + + dbus_message_iter_init (message, &iter); + + if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY && + dbus_message_iter_get_element_type (&iter) == DBUS_TYPE_BYTE) + { + dbus_message_iter_recurse (&iter, &array_iter); + dbus_message_iter_get_fixed_array (&array_iter, &filename, &filename_len); + } + + dbus_message_iter_next (&iter); + + if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32) + { + dbus_message_iter_get_basic (&iter, &flags_u32); + dbus_message_iter_next (&iter); + } + + flags = flags_u32; + + if (!(filename && _g_dbus_get_file_attribute (&iter, &attribute, &type, &value))) + { + reply = dbus_message_new_error (message, + DBUS_ERROR_FAILED, + _("Failed to demarshal message")); + dbus_error_free (&derror); + + dbus_connection_send (connection, reply, NULL); + return NULL; + } + + job = g_object_new (G_VFS_TYPE_JOB_SET_ATTRIBUTE, + "message", message, + "connection", connection, + NULL); + + job->backend = backend; + job->filename = g_strndup (filename, filename_len); + job->attribute = attribute; + job->type = type; + job->value = value; + job->flags = flags; + + return G_VFS_JOB (job); +} + +static void +run (GVfsJob *job) +{ + GVfsJobSetAttribute *op_job = G_VFS_JOB_SET_ATTRIBUTE (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + + if (class->set_attribute == NULL) + { + g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + _("Operation not supported by backend")); + return; + } + + class->set_attribute (op_job->backend, + op_job, + op_job->filename, + op_job->attribute, + op_job->type, + &op_job->value, + op_job->flags); +} + +static gboolean +try (GVfsJob *job) +{ + GVfsJobSetAttribute *op_job = G_VFS_JOB_SET_ATTRIBUTE (job); + GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + + if (class->try_set_attribute == NULL) + return FALSE; + + return class->try_set_attribute (op_job->backend, + op_job, + op_job->filename, + op_job->attribute, + op_job->type, + &op_job->value, + op_job->flags); +} + +/* Might be called on an i/o thread */ +static DBusMessage * +create_reply (GVfsJob *job, + DBusConnection *connection, + DBusMessage *message) +{ + DBusMessage *reply; + + reply = dbus_message_new_method_return (message); + + return reply; +} diff --git a/daemon/gvfsjobsetattribute.h b/daemon/gvfsjobsetattribute.h new file mode 100644 index 00000000..ad0e9d58 --- /dev/null +++ b/daemon/gvfsjobsetattribute.h @@ -0,0 +1,46 @@ +#ifndef __G_VFS_JOB_SET_ATTRIBUTE_H__ +#define __G_VFS_JOB_SET_ATTRIBUTE_H__ + +#include <gio/gfileinfo.h> +#include <gvfsjob.h> +#include <gvfsjobdbus.h> +#include <gvfsbackend.h> + +G_BEGIN_DECLS + +#define G_VFS_TYPE_JOB_SET_ATTRIBUTE (g_vfs_job_set_attribute_get_type ()) +#define G_VFS_JOB_SET_ATTRIBUTE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_JOB_SET_ATTRIBUTE, GVfsJobSetAttribute)) +#define G_VFS_JOB_SET_ATTRIBUTE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_JOB_SET_ATTRIBUTE, GVfsJobSetAttributeClass)) +#define G_VFS_IS_JOB_SET_ATTRIBUTE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_JOB_SET_ATTRIBUTE)) +#define G_VFS_IS_JOB_SET_ATTRIBUTE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_JOB_SET_ATTRIBUTE)) +#define G_VFS_JOB_SET_ATTRIBUTE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_JOB_SET_ATTRIBUTE, GVfsJobSetAttributeClass)) + +typedef struct _GVfsJobSetAttributeClass GVfsJobSetAttributeClass; + +struct _GVfsJobSetAttribute +{ + GVfsJobDBus parent_instance; + + GVfsBackend *backend; + + char *filename; + char *attribute; + GFileAttributeType type; + GFileAttributeValue value; + GFileGetInfoFlags flags; +}; + +struct _GVfsJobSetAttributeClass +{ + GVfsJobDBusClass parent_class; +}; + +GType g_vfs_job_set_attribute_get_type (void) G_GNUC_CONST; + +GVfsJob *g_vfs_job_set_attribute_new (DBusConnection *connection, + DBusMessage *message, + GVfsBackend *backend); + +G_END_DECLS + +#endif /* __G_VFS_JOB_SET_ATTRIBUTE_H__ */ |