[gvfs] afp: implement setting of G_FILE_ATTRIBUTE_UNIX_[MODE|UID|GID]
- From: Christian Kellner <gicmo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs] afp: implement setting of G_FILE_ATTRIBUTE_UNIX_[MODE|UID|GID]
- Date: Thu, 25 Aug 2011 19:27:55 +0000 (UTC)
commit a71a17864a208a8f7f80d2744ea41397da9e658c
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date: Mon Jul 25 16:11:22 2011 +0200
afp: implement setting of G_FILE_ATTRIBUTE_UNIX_[MODE|UID|GID]
daemon/gvfsafpconnection.h | 1 +
daemon/gvfsbackendafp.c | 203 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 202 insertions(+), 2 deletions(-)
---
diff --git a/daemon/gvfsafpconnection.h b/daemon/gvfsafpconnection.h
index 791a4a9..4ee4cf0 100644
--- a/daemon/gvfsafpconnection.h
+++ b/daemon/gvfsafpconnection.h
@@ -197,6 +197,7 @@ typedef enum
AFP_COMMAND_SET_FORK_PARMS = 31,
AFP_COMMAND_WRITE = 33,
AFP_COMMAND_GET_FILE_DIR_PARMS = 34,
+ AFP_COMMAND_SET_FILEDIR_PARMS = 35,
AFP_COMMAND_GET_SRVR_MSG = 35,
AFP_COMMAND_GET_USER_INFO = 37,
AFP_COMMAND_EXCHANGE_FILES = 42,
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c
index 8760cde..c0aade6 100644
--- a/daemon/gvfsbackendafp.c
+++ b/daemon/gvfsbackendafp.c
@@ -36,6 +36,8 @@
#include "gvfsjobenumerate.h"
#include "gvfsjobqueryinfo.h"
#include "gvfsjobqueryfsinfo.h"
+#include "gvfsjobsetattribute.h"
+#include "gvfsjobqueryattributes.h"
#include "gvfsjobopenforread.h"
#include "gvfsjobcloseread.h"
#include "gvfsjobread.h"
@@ -363,18 +365,20 @@ static void fill_info (GVfsBackendAfp *afp_backend,
if (bitmap & AFP_FILEDIR_BITMAP_UNIX_PRIVS_BIT)
{
- guint32 uid, gid, permissions;
+ guint32 uid, gid, permissions, ua_permissions;
g_vfs_afp_reply_read_uint32 (reply, &uid);
g_vfs_afp_reply_read_uint32 (reply, &gid);
g_vfs_afp_reply_read_uint32 (reply, &permissions);
/* ua_permissions */
- g_vfs_afp_reply_read_uint32 (reply, NULL);
+ g_vfs_afp_reply_read_uint32 (reply, &ua_permissions);
g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, permissions);
g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID, uid);
g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID, gid);
+ g_file_info_set_attribute_uint32 (info, "afp::ua-permissions", ua_permissions);
+
if (uid == afp_backend->user_id)
set_access_attributes_trusted (info, (permissions >> 6) & 0x7);
else if (gid == afp_backend->group_id)
@@ -2533,6 +2537,199 @@ try_enumerate (GVfsBackend *backend,
return TRUE;
}
+static gboolean
+try_query_settable_attributes (GVfsBackend *backend,
+ GVfsJobQueryAttributes *job,
+ const char *filename)
+{
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
+ GFileAttributeInfoList *list;
+
+ list = g_file_attribute_info_list_new ();
+
+ if (afp_backend->vol_attrs_bitmap & AFP_VOLUME_ATTRIBUTES_BITMAP_SUPPORTS_UNIX_PRIVS)
+ {
+ g_file_attribute_info_list_add (list,
+ G_FILE_ATTRIBUTE_UNIX_MODE,
+ G_FILE_ATTRIBUTE_TYPE_UINT32,
+ G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE |
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
+ g_file_attribute_info_list_add (list,
+ G_FILE_ATTRIBUTE_UNIX_UID,
+ G_FILE_ATTRIBUTE_TYPE_UINT32,
+ G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE |
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
+ g_file_attribute_info_list_add (list,
+ G_FILE_ATTRIBUTE_UNIX_GID,
+ G_FILE_ATTRIBUTE_TYPE_UINT32,
+ G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE |
+ G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
+ }
+
+ g_vfs_job_query_attributes_set_list (job, list);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ g_file_attribute_info_list_unref (list);
+
+ return TRUE;
+}
+
+static void
+set_attribute_set_filedir_parms_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (source_object);
+ GVfsJobSetAttribute *job = G_VFS_JOB_SET_ATTRIBUTE (user_data);
+
+ GVfsAfpReply *reply;
+ GError *err = NULL;
+ AfpResultCode res_code;
+
+ reply = g_vfs_afp_connection_send_command_finish (afp_conn, res, &err);
+ if (!reply)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), err);
+ g_error_free (err);
+ return;
+ }
+
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ g_object_unref (reply);
+ if (res_code != AFP_RESULT_NO_ERROR)
+ {
+ switch (res_code)
+ {
+ case AFP_RESULT_ACCESS_DENIED:
+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ _("Permission denied"));
+ break;
+ case AFP_RESULT_OBJECT_NOT_FOUND:
+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ _("Target object doesn't exist"));
+ break;
+ case AFP_RESULT_VOL_LOCKED:
+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ _("Volume is read-only"));
+ break;
+ default:
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Got error code: %d from server"), res_code);
+ break;
+ }
+ return;
+ }
+
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+}
+
+static void
+set_attribute_get_filedir_parms_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (source_object);
+ GVfsJobSetAttribute *job = G_VFS_JOB_SET_ATTRIBUTE (user_data);
+
+ GFileInfo *info;
+ GError *err = NULL;
+
+ guint32 uid, gid, permissions, ua_permissions;
+ GVfsAfpCommand *comm;
+
+ info = get_filedir_parms_finish (afp_backend, res, &err);
+ if (!info)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), err);
+ g_error_free (err);
+ return;
+ }
+
+ uid = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID);
+ gid = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID);
+ permissions = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE);
+ ua_permissions = g_file_info_get_attribute_uint32 (info, "afp::ua-permissions");
+ g_object_unref (info);
+
+ comm = g_vfs_afp_command_new (AFP_COMMAND_SET_FILEDIR_PARMS);
+ /* pad byte */
+ g_vfs_afp_command_put_byte (comm, 0);
+
+ /* VolumeID */
+ g_vfs_afp_command_put_uint16 (comm, afp_backend->volume_id);
+ /* DirectoryID 2 == / */
+ g_vfs_afp_command_put_uint32 (comm, 2);
+ /* Bitmap */
+ g_vfs_afp_command_put_uint16 (comm, AFP_FILEDIR_BITMAP_UNIX_PRIVS_BIT);
+ /* Pathname */
+ put_pathname (comm, job->filename);
+ /* pad to even */
+ g_vfs_afp_command_pad_to_even (comm);
+
+ /* UID */
+ if (strcmp (job->attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0)
+ g_vfs_afp_command_put_uint32 (comm, job->value.uint32);
+ else
+ g_vfs_afp_command_put_uint32 (comm, uid);
+
+ /* GID */
+ if (strcmp (job->attribute, G_FILE_ATTRIBUTE_UNIX_GID) == 0)
+ g_vfs_afp_command_put_uint32 (comm, job->value.uint32);
+ else
+ g_vfs_afp_command_put_uint32 (comm, gid);
+
+ /* Permissions */
+ if (strcmp (job->attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0)
+ g_vfs_afp_command_put_uint32 (comm, job->value.uint32);
+ else
+ g_vfs_afp_command_put_uint32 (comm, permissions);
+
+ /* UAPermissions */
+ g_vfs_afp_command_put_uint32 (comm, ua_permissions);
+
+ g_vfs_afp_connection_send_command (afp_backend->server->conn, comm,
+ set_attribute_set_filedir_parms_cb,
+ G_VFS_JOB (job)->cancellable, job);
+ g_object_unref (comm);
+}
+
+static gboolean
+try_set_attribute (GVfsBackend *backend,
+ GVfsJobSetAttribute *job,
+ const char *filename,
+ const char *attribute,
+ GFileAttributeType type,
+ gpointer value_p,
+ GFileQueryInfoFlags flags)
+{
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
+
+ if ((strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0 ||
+ strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0 ||
+ strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_GID) == 0)
+ && afp_backend->vol_attrs_bitmap & AFP_VOLUME_ATTRIBUTES_BITMAP_SUPPORTS_UNIX_PRIVS)
+ {
+ if (type != G_FILE_ATTRIBUTE_TYPE_UINT32)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job),
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ "%s",
+ _("Invalid attribute type (uint32 expected)"));
+ return TRUE;
+ }
+
+ get_filedir_parms (afp_backend, filename, AFP_FILEDIR_BITMAP_UNIX_PRIVS_BIT,
+ AFP_FILEDIR_BITMAP_UNIX_PRIVS_BIT,
+ G_VFS_JOB (job)->cancellable, set_attribute_get_filedir_parms_cb,
+ job);
+ return TRUE;
+ }
+
+ else {
+ g_vfs_job_failed (G_VFS_JOB (job),
+ G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Operation unsupported"));
+ return TRUE;
+ }
+}
+
+
static void
query_fs_info_get_vol_parms_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
@@ -3005,6 +3202,8 @@ g_vfs_backend_afp_class_init (GVfsBackendAfpClass *klass)
backend_class->mount = do_mount;
backend_class->try_query_info = try_query_info;
backend_class->try_query_fs_info = try_query_fs_info;
+ backend_class->try_set_attribute = try_set_attribute;
+ backend_class->try_query_settable_attributes = try_query_settable_attributes;
backend_class->try_enumerate = try_enumerate;
backend_class->try_open_for_read = try_open_for_read;
backend_class->try_close_read = try_close_read;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]