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