1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright (C) 2006-2007 Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 * Author: Alexander Larsson <alexl@redhat.com>
21 */
22
23 #include <config.h>
24
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <sys/un.h>
29
30 #include <glib.h>
31 #include <glib/gi18n.h>
32 #include "gvfsjobsetdisplayname.h"
33
34 G_DEFINE_TYPE (GVfsJobSetDisplayName, g_vfs_job_set_display_name, G_VFS_TYPE_JOB_DBUS)
35
36 static void run (GVfsJob *job);
37 static gboolean try (GVfsJob *job);
38 static void create_reply (GVfsJob *job,
39 GVfsDBusMount *object,
40 GDBusMethodInvocation *invocation);
41
42 static void
g_vfs_job_set_display_name_finalize(GObject * object)43 g_vfs_job_set_display_name_finalize (GObject *object)
44 {
45 GVfsJobSetDisplayName *job;
46
47 job = G_VFS_JOB_SET_DISPLAY_NAME (object);
48
49 g_free (job->filename);
50 g_free (job->display_name);
51 g_free (job->new_path);
52
53 if (G_OBJECT_CLASS (g_vfs_job_set_display_name_parent_class)->finalize)
54 (*G_OBJECT_CLASS (g_vfs_job_set_display_name_parent_class)->finalize) (object);
55 }
56
57 static void
g_vfs_job_set_display_name_class_init(GVfsJobSetDisplayNameClass * klass)58 g_vfs_job_set_display_name_class_init (GVfsJobSetDisplayNameClass *klass)
59 {
60 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
61 GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass);
62 GVfsJobDBusClass *job_dbus_class = G_VFS_JOB_DBUS_CLASS (klass);
63
64 gobject_class->finalize = g_vfs_job_set_display_name_finalize;
65 job_class->run = run;
66 job_class->try = try;
67 job_dbus_class->create_reply = create_reply;
68 }
69
70 static void
g_vfs_job_set_display_name_init(GVfsJobSetDisplayName * job)71 g_vfs_job_set_display_name_init (GVfsJobSetDisplayName *job)
72 {
73 }
74
75 gboolean
g_vfs_job_set_display_name_new_handle(GVfsDBusMount * object,GDBusMethodInvocation * invocation,const gchar * arg_path_data,const gchar * arg_display_name,GVfsBackend * backend)76 g_vfs_job_set_display_name_new_handle (GVfsDBusMount *object,
77 GDBusMethodInvocation *invocation,
78 const gchar *arg_path_data,
79 const gchar *arg_display_name,
80 GVfsBackend *backend)
81 {
82 GVfsJobSetDisplayName *job;
83
84 if (g_vfs_backend_invocation_first_handler (object, invocation, backend))
85 return TRUE;
86
87 job = g_object_new (G_VFS_TYPE_JOB_SET_DISPLAY_NAME,
88 "object", object,
89 "invocation", invocation,
90 NULL);
91
92 job->filename = g_strdup (arg_path_data);
93 job->backend = backend;
94 job->display_name = g_strdup (arg_display_name);
95
96 g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job));
97 g_object_unref (job);
98
99 return TRUE;
100 }
101
102 static void
run(GVfsJob * job)103 run (GVfsJob *job)
104 {
105 GVfsJobSetDisplayName *op_job = G_VFS_JOB_SET_DISPLAY_NAME (job);
106 GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
107
108 if (class->set_display_name == NULL)
109 {
110 g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
111 _("Operation not supported"));
112 return;
113 }
114
115 class->set_display_name (op_job->backend,
116 op_job,
117 op_job->filename,
118 op_job->display_name);
119 }
120
121 static gboolean
try(GVfsJob * job)122 try (GVfsJob *job)
123 {
124 GVfsJobSetDisplayName *op_job = G_VFS_JOB_SET_DISPLAY_NAME (job);
125 GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
126
127 if (g_vfs_backend_get_readonly_lockdown (op_job->backend))
128 {
129 g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
130 _("Filesystem is read-only"));
131 return TRUE;
132 }
133
134 if (class->try_set_display_name == NULL)
135 return FALSE;
136
137 return class->try_set_display_name (op_job->backend,
138 op_job,
139 op_job->filename,
140 op_job->display_name);
141 }
142
143 void
g_vfs_job_set_display_name_set_new_path(GVfsJobSetDisplayName * job,const char * new_path)144 g_vfs_job_set_display_name_set_new_path (GVfsJobSetDisplayName *job,
145 const char *new_path)
146 {
147 job->new_path = g_strdup (new_path);
148 }
149
150 /* Might be called on an i/o thread */
151 static void
create_reply(GVfsJob * job,GVfsDBusMount * object,GDBusMethodInvocation * invocation)152 create_reply (GVfsJob *job,
153 GVfsDBusMount *object,
154 GDBusMethodInvocation *invocation)
155 {
156 GVfsJobSetDisplayName *op_job = G_VFS_JOB_SET_DISPLAY_NAME (job);
157
158 g_assert (op_job->new_path != NULL);
159
160 gvfs_dbus_mount_complete_set_display_name (object, invocation, op_job->new_path);
161 }
162