ftp://ftp.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/gnome-vfs2-2.3.8-1.src.rpm
[gnome-vfs-httpcaptive.git] / monikers / bonobo-storage-vfs.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * gnome-storage-vfs.c: Gnome VFS based storage implementation
4  *
5  * Author:
6  *   Michael Meeks <michael@helixcode.com>
7  */
8 #include <config.h>
9 #include "bonobo-storage-vfs.h"
10
11 #include "bonobo-stream-vfs.h"
12 #include <bonobo/bonobo-storage.h>
13 #include <libgnomevfs/gnome-vfs-directory.h>
14 #include <libgnomevfs/gnome-vfs-ops.h>
15 #include <string.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18
19 static BonoboObjectClass *bonobo_storage_vfs_parent_class;
20
21 static char *
22 concat_dir_and_file (const char *dir, const char *file)
23 {
24         g_return_val_if_fail (dir != NULL, NULL);
25         g_return_val_if_fail (file != NULL, NULL);
26
27         /* If the directory name doesn't have a / on the end, we need
28            to add one so we get a proper path to the file */
29         if (dir[0] != '\0' && dir [strlen(dir) - 1] != '/')
30                 return g_strconcat (dir, "/", file, NULL);
31         else
32                 return g_strconcat (dir, file, NULL);
33 }
34
35 static Bonobo_StorageInfo*
36 vfs_get_info (PortableServer_Servant         storage,
37               const CORBA_char              *path,
38               const Bonobo_StorageInfoFields mask,
39               CORBA_Environment             *ev)
40 {
41         g_warning ("FIXME: get_info not yet implemented");
42         CORBA_exception_set (ev, CORBA_USER_EXCEPTION, 
43                              ex_Bonobo_Storage_NotSupported, 
44                              NULL);
45
46         return CORBA_OBJECT_NIL;
47 }
48
49 static void
50 vfs_set_info (PortableServer_Servant         storage,
51               const CORBA_char              *path,
52               const Bonobo_StorageInfo      *info,
53               const Bonobo_StorageInfoFields mask,
54               CORBA_Environment             *ev)
55 {
56         g_warning ("FIXME: set_info not yet implemented");
57         CORBA_exception_set (ev, CORBA_USER_EXCEPTION, 
58                              ex_Bonobo_Storage_NotSupported, 
59                              NULL);
60 }
61
62 static Bonobo_Stream
63 vfs_open_stream (PortableServer_Servant  storage,
64                  const CORBA_char       *path,
65                  Bonobo_Storage_OpenMode mode,
66                  CORBA_Environment      *ev)
67 {
68         BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS (
69                 bonobo_object (storage));
70         BonoboStreamVfs *stream;
71         char *full;
72
73         full = concat_dir_and_file (storage_vfs->path, path);
74         stream = bonobo_stream_vfs_open (full, mode, ev);
75         g_free (full);
76         if (stream) 
77                 return CORBA_Object_duplicate (BONOBO_OBJREF (stream), NULL);
78         else
79                 return CORBA_OBJECT_NIL;
80 }
81
82 /*
83  * Creates the Gtk object and the corba server bound to it
84  */
85 static BonoboStorageVfs *
86 do_bonobo_storage_vfs_create (const char *path)
87 {
88         BonoboStorageVfs *storage_vfs;
89
90         storage_vfs = g_object_new (bonobo_storage_vfs_get_type (), NULL);
91         storage_vfs->path = g_strdup (path);
92
93         return storage_vfs;
94 }
95
96 static void
97 vfs_rename (PortableServer_Servant storage,
98             const CORBA_char      *path,
99            const CORBA_char       *new_path,
100             CORBA_Environment     *ev)
101 {
102         g_warning ("Not yet implemented");
103         CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
104                              ex_Bonobo_Stream_IOError, NULL);
105 }
106
107 static void
108 vfs_commit (PortableServer_Servant storage,
109             CORBA_Environment     *ev)
110 {
111         CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
112                              ex_Bonobo_Stream_NotSupported, NULL);
113 }
114
115 static void
116 vfs_revert (PortableServer_Servant storage,
117             CORBA_Environment     *ev)
118 {
119         CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
120                              ex_Bonobo_Stream_NotSupported, NULL);
121 }
122
123 static Bonobo_Storage_DirectoryList *
124 vfs_list_contents (PortableServer_Servant   storage,
125                    const CORBA_char        *path, 
126                    Bonobo_StorageInfoFields mask,
127                    CORBA_Environment       *ev)
128 {
129         BonoboStorageVfs              *storage_vfs;
130         Bonobo_Storage_DirectoryList  *list = NULL;
131         GnomeVFSResult                 result;
132         GList                         *dir_list, *info;
133         char                          *uri;
134         int                            len, i;
135
136         storage_vfs = BONOBO_STORAGE_VFS (storage);
137
138         uri = concat_dir_and_file (storage_vfs->path, path);
139
140         result = gnome_vfs_directory_list_load (
141                 &dir_list, uri, 
142                 (mask & Bonobo_FIELD_CONTENT_TYPE) ?
143                 GNOME_VFS_FILE_INFO_GET_MIME_TYPE :
144                 GNOME_VFS_FILE_INFO_DEFAULT);
145
146         if (result != GNOME_VFS_OK) {
147                 CORBA_exception_set (ev, CORBA_USER_EXCEPTION, 
148                                      ex_Bonobo_Storage_NotFound, NULL);
149                 g_free (uri);
150                 return NULL;
151         }
152
153         len  = g_list_length (dir_list);
154         list = Bonobo_Storage_DirectoryList__alloc      ();
155         list->_buffer = CORBA_sequence_Bonobo_StorageInfo_allocbuf (len);
156         list->_length = len;
157         CORBA_sequence_set_release (list, TRUE); 
158
159         i = 0;
160         for (info = dir_list; info; info = info->next) {
161                 bonobo_stream_vfs_storageinfo_from_file_info (
162                         &list->_buffer [i++], info->data);
163                 gnome_vfs_file_info_unref (info->data);
164         }
165
166         g_list_free (dir_list);
167         g_free (uri);
168
169         return list;
170 }
171
172 /** 
173  * bonobo_storage_vfs_open:
174  * @path: path to existing directory that represents the storage
175  * @mode: open mode.
176  *
177  * Returns a BonoboStorage object that represents the storage at @path
178  */
179 BonoboStorageVfs *
180 bonobo_storage_vfs_open (const char *path,
181                          Bonobo_Storage_OpenMode mode,
182                          CORBA_Environment *ev)
183 {
184         GnomeVFSResult    result;
185         GnomeVFSFileInfo *info;
186         gboolean          create = FALSE;
187         
188         g_return_val_if_fail (path != NULL, NULL);
189
190         info = gnome_vfs_file_info_new ();
191         result = gnome_vfs_get_file_info (
192                 path, info, GNOME_VFS_FILE_INFO_DEFAULT);
193
194         if (result == GNOME_VFS_ERROR_NOT_FOUND &&
195             (mode & Bonobo_Storage_CREATE))
196                 create = TRUE;
197             
198         else if (mode & Bonobo_Storage_READ) {
199                 if (result != GNOME_VFS_OK) {
200                         CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
201                                              ex_Bonobo_Stream_NoPermission, NULL);
202                         return NULL;
203                 }
204
205                 if ((info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) &&
206                     (info->type != GNOME_VFS_FILE_TYPE_DIRECTORY)) {
207                         CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
208                                              ex_Bonobo_Stream_IOError, NULL);
209                         return NULL;
210                 }
211
212         } else if (mode & (Bonobo_Storage_WRITE)) {
213                 if (result == GNOME_VFS_ERROR_NOT_FOUND)
214                         create = TRUE;
215                 else
216                         if ((info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) &&
217                             (info->type != GNOME_VFS_FILE_TYPE_DIRECTORY)) {
218                                 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
219                                                      ex_Bonobo_Stream_IOError, NULL);
220                                 return NULL;
221                         }
222         }
223         gnome_vfs_file_info_unref (info);
224
225         if (create) {
226                 result = gnome_vfs_make_directory (
227                         path, GNOME_VFS_PERM_USER_ALL |
228                         GNOME_VFS_PERM_GROUP_ALL);
229
230                 if (result != GNOME_VFS_OK) {
231                         CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
232                                              ex_Bonobo_Stream_NoPermission, NULL);
233                         return NULL;
234                 }
235         }
236
237         return do_bonobo_storage_vfs_create (path);
238 }
239
240 static Bonobo_Storage
241 vfs_open_storage (PortableServer_Servant  storage,
242                   const CORBA_char       *path,
243                   Bonobo_Storage_OpenMode mode,
244                   CORBA_Environment      *ev)
245 {
246         BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS (
247                 bonobo_object (storage));
248         BonoboStorageVfs *new_storage;
249         GnomeVFSResult    result;
250         char *full;
251
252         full = concat_dir_and_file (storage_vfs->path, path);
253
254         result = gnome_vfs_make_directory (full, GNOME_VFS_PERM_USER_ALL);
255         if (result == GNOME_VFS_OK ||
256             result == GNOME_VFS_ERROR_FILE_EXISTS)
257                 new_storage = do_bonobo_storage_vfs_create (full);
258         else {
259                 new_storage = NULL;
260                 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
261                                      ex_Bonobo_Storage_NoPermission, NULL);
262         }
263
264         g_free (full);
265
266         if (new_storage)
267                 return CORBA_Object_duplicate (BONOBO_OBJREF (new_storage), NULL);
268         else
269                 return CORBA_OBJECT_NIL;
270 }
271
272 static void
273 vfs_erase (PortableServer_Servant storage,
274            const CORBA_char      *path,
275            CORBA_Environment     *ev)
276 {
277         BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS (
278                 bonobo_object (storage));
279         GnomeVFSResult    result;
280         char *full;
281
282         full = concat_dir_and_file (storage_vfs->path, path);
283
284         result = gnome_vfs_unlink (full);
285         g_free (full);
286
287         if (result != GNOME_VFS_OK)
288                 CORBA_exception_set (ev, CORBA_USER_EXCEPTION, 
289                                      ex_Bonobo_Storage_NoPermission, 
290                                      NULL);
291 }
292
293 static void
294 vfs_copy_to (PortableServer_Servant storage,
295              Bonobo_Storage         dest,
296              CORBA_Environment     *ev)
297 {
298         BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS (
299                 bonobo_object (storage));
300
301         bonobo_storage_copy_to (
302                 BONOBO_OBJREF (storage_vfs), dest, ev);
303 }
304
305 static void
306 bonobo_storage_vfs_finalize (GObject *object)
307 {
308         BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS (object);
309
310         g_free (storage_vfs->path);
311         storage_vfs->path = NULL;
312
313         G_OBJECT_CLASS (bonobo_storage_vfs_parent_class)->finalize (object);
314 }
315
316 static void
317 bonobo_storage_vfs_class_init (BonoboStorageVfsClass *klass)
318 {
319         GObjectClass *object_class = (GObjectClass *) klass;
320         POA_Bonobo_Storage__epv *epv = &klass->epv;
321         
322         bonobo_storage_vfs_parent_class = 
323                 g_type_class_peek_parent (klass);
324
325         epv->getInfo       = vfs_get_info;
326         epv->setInfo       = vfs_set_info;
327         epv->openStream    = vfs_open_stream;
328         epv->openStorage   = vfs_open_storage;
329         epv->copyTo        = vfs_copy_to;
330         epv->rename        = vfs_rename;
331         epv->commit        = vfs_commit;
332         epv->revert        = vfs_revert;
333         epv->listContents  = vfs_list_contents;
334         epv->erase         = vfs_erase;
335
336         object_class->finalize = bonobo_storage_vfs_finalize;
337 }
338
339 static void 
340 bonobo_storage_vfs_init (GObject *object)
341 {
342         /* nothing to do */
343 }
344
345 BONOBO_TYPE_FUNC_FULL (BonoboStorageVfs,
346                        Bonobo_Storage,
347                        bonobo_object_get_type (),
348                        bonobo_storage_vfs);