1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
---|
2 | /* |
---|
3 | * bonobo-storage.c: Storage manipulation. |
---|
4 | * |
---|
5 | * Authors: |
---|
6 | * Miguel de Icaza (miguel@gnu.org) |
---|
7 | * Dietmar Maurer (dietmar@maurer-it.com) |
---|
8 | * |
---|
9 | * Copyright 1999 Helix Code, Inc. |
---|
10 | */ |
---|
11 | #include <config.h> |
---|
12 | #include <gmodule.h> |
---|
13 | |
---|
14 | #include <bonobo/bonobo-storage.h> |
---|
15 | #include <bonobo/bonobo-exception.h> |
---|
16 | #include <bonobo/bonobo-storage-plugin.h> |
---|
17 | |
---|
18 | #define PARENT_TYPE BONOBO_X_OBJECT_TYPE |
---|
19 | |
---|
20 | #define CLASS(o) BONOBO_STORAGE_CLASS (GTK_OBJECT(o)->klass) |
---|
21 | |
---|
22 | static inline BonoboStorage * |
---|
23 | bonobo_storage_from_servant (PortableServer_Servant servant) |
---|
24 | { |
---|
25 | return BONOBO_STORAGE (bonobo_object_from_servant (servant)); |
---|
26 | } |
---|
27 | |
---|
28 | static Bonobo_StorageInfo* |
---|
29 | impl_Bonobo_Storage_getInfo (PortableServer_Servant servant, |
---|
30 | const CORBA_char * path, |
---|
31 | const Bonobo_StorageInfoFields mask, |
---|
32 | CORBA_Environment *ev) |
---|
33 | { |
---|
34 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
35 | |
---|
36 | return CLASS (storage)->get_info (storage, path, mask, ev); |
---|
37 | } |
---|
38 | |
---|
39 | static void |
---|
40 | impl_Bonobo_Storage_setInfo (PortableServer_Servant servant, |
---|
41 | const CORBA_char * path, |
---|
42 | const Bonobo_StorageInfo *info, |
---|
43 | const Bonobo_StorageInfoFields mask, |
---|
44 | CORBA_Environment *ev) |
---|
45 | { |
---|
46 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
47 | |
---|
48 | CLASS (storage)->set_info (storage, path, info, mask, ev); |
---|
49 | } |
---|
50 | |
---|
51 | static Bonobo_Stream |
---|
52 | impl_Bonobo_Storage_openStream (PortableServer_Servant servant, |
---|
53 | const CORBA_char *path, |
---|
54 | Bonobo_Storage_OpenMode mode, |
---|
55 | CORBA_Environment *ev) |
---|
56 | { |
---|
57 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
58 | BonoboStream *stream; |
---|
59 | |
---|
60 | if ((stream = CLASS (storage)->open_stream (storage, path, mode, ev))) |
---|
61 | return (Bonobo_Stream) CORBA_Object_duplicate ( |
---|
62 | BONOBO_OBJREF (stream), ev); |
---|
63 | else |
---|
64 | return CORBA_OBJECT_NIL; |
---|
65 | } |
---|
66 | |
---|
67 | static Bonobo_Storage |
---|
68 | impl_Bonobo_Storage_openStorage (PortableServer_Servant servant, |
---|
69 | const CORBA_char *path, |
---|
70 | Bonobo_Storage_OpenMode mode, |
---|
71 | CORBA_Environment *ev) |
---|
72 | { |
---|
73 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
74 | BonoboStorage *open_storage; |
---|
75 | |
---|
76 | if ((open_storage = CLASS (storage)->open_storage ( |
---|
77 | storage, path, mode, ev))) |
---|
78 | |
---|
79 | return (Bonobo_Storage) CORBA_Object_duplicate ( |
---|
80 | BONOBO_OBJREF (open_storage), ev); |
---|
81 | else |
---|
82 | return CORBA_OBJECT_NIL; |
---|
83 | } |
---|
84 | |
---|
85 | static void |
---|
86 | impl_Bonobo_Storage_copyTo (PortableServer_Servant servant, |
---|
87 | Bonobo_Storage target, |
---|
88 | CORBA_Environment *ev) |
---|
89 | { |
---|
90 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
91 | Bonobo_Storage src = BONOBO_OBJREF (storage); |
---|
92 | |
---|
93 | if (CLASS (storage)->copy_to) |
---|
94 | CLASS (storage)->copy_to (storage, target, ev); |
---|
95 | else |
---|
96 | bonobo_storage_copy_to (src, target, ev); |
---|
97 | } |
---|
98 | |
---|
99 | static void |
---|
100 | impl_Bonobo_Storage_rename (PortableServer_Servant servant, |
---|
101 | const CORBA_char *path_name, |
---|
102 | const CORBA_char *new_path_name, |
---|
103 | CORBA_Environment *ev) |
---|
104 | { |
---|
105 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
106 | |
---|
107 | CLASS (storage)->rename (storage, path_name, new_path_name, ev); |
---|
108 | } |
---|
109 | |
---|
110 | static void |
---|
111 | impl_Bonobo_Storage_commit (PortableServer_Servant servant, |
---|
112 | CORBA_Environment *ev) |
---|
113 | { |
---|
114 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
115 | |
---|
116 | CLASS (storage)->commit (storage, ev); |
---|
117 | } |
---|
118 | |
---|
119 | static void |
---|
120 | impl_Bonobo_Storage_revert (PortableServer_Servant servant, |
---|
121 | CORBA_Environment *ev) |
---|
122 | { |
---|
123 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
124 | |
---|
125 | CLASS (storage)->commit (storage, ev); |
---|
126 | } |
---|
127 | |
---|
128 | static Bonobo_Storage_DirectoryList * |
---|
129 | impl_Bonobo_Storage_listContents (PortableServer_Servant servant, |
---|
130 | const CORBA_char *path, |
---|
131 | Bonobo_StorageInfoFields mask, |
---|
132 | CORBA_Environment *ev) |
---|
133 | { |
---|
134 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
135 | |
---|
136 | return CLASS (storage)->list_contents (storage, path, mask, ev); |
---|
137 | } |
---|
138 | |
---|
139 | static void |
---|
140 | impl_Bonobo_Storage_erase (PortableServer_Servant servant, |
---|
141 | const CORBA_char *path, |
---|
142 | CORBA_Environment *ev) |
---|
143 | { |
---|
144 | BonoboStorage *storage = bonobo_storage_from_servant (servant); |
---|
145 | |
---|
146 | CLASS (storage)->erase (storage, path, ev); |
---|
147 | } |
---|
148 | |
---|
149 | static void |
---|
150 | bonobo_storage_class_init (BonoboStorageClass *klass) |
---|
151 | { |
---|
152 | POA_Bonobo_Storage__epv *epv = &klass->epv; |
---|
153 | |
---|
154 | epv->getInfo = impl_Bonobo_Storage_getInfo; |
---|
155 | epv->setInfo = impl_Bonobo_Storage_setInfo; |
---|
156 | epv->openStream = impl_Bonobo_Storage_openStream; |
---|
157 | epv->openStorage = impl_Bonobo_Storage_openStorage; |
---|
158 | epv->copyTo = impl_Bonobo_Storage_copyTo; |
---|
159 | epv->rename = impl_Bonobo_Storage_rename; |
---|
160 | epv->commit = impl_Bonobo_Storage_commit; |
---|
161 | epv->revert = impl_Bonobo_Storage_revert; |
---|
162 | epv->listContents = impl_Bonobo_Storage_listContents; |
---|
163 | epv->erase = impl_Bonobo_Storage_erase; |
---|
164 | } |
---|
165 | |
---|
166 | static void |
---|
167 | bonobo_storage_init (GtkObject *object) |
---|
168 | { |
---|
169 | /* nothing to do */ |
---|
170 | } |
---|
171 | |
---|
172 | BONOBO_X_TYPE_FUNC_FULL (BonoboStorage, |
---|
173 | Bonobo_Storage, |
---|
174 | PARENT_TYPE, |
---|
175 | bonobo_storage); |
---|
176 | |
---|
177 | /** |
---|
178 | * bonobo_storage_open: |
---|
179 | * @driver: driver to use for opening. |
---|
180 | * @path: path where the base file resides |
---|
181 | * @flags: Bonobo Storage OpenMode |
---|
182 | * @mode: Unix open(2) mode |
---|
183 | * |
---|
184 | * Opens or creates the file named at @path with the stream driver @driver. |
---|
185 | * |
---|
186 | * @driver is one of: "efs", "vfs" or "fs" for now, please use |
---|
187 | * the macros for this though, see bonobo-stream.h eg. |
---|
188 | * BONOBO_IO_DRIVER_FS |
---|
189 | * |
---|
190 | * Returns: a created BonoboStorage object. |
---|
191 | */ |
---|
192 | BonoboStorage * |
---|
193 | bonobo_storage_open_full (const char *driver, const char *path, |
---|
194 | gint flags, gint mode, |
---|
195 | CORBA_Environment *opt_ev) |
---|
196 | { |
---|
197 | BonoboStorage *storage = NULL; |
---|
198 | StoragePlugin *p; |
---|
199 | CORBA_Environment ev, *my_ev; |
---|
200 | |
---|
201 | if (!opt_ev) { |
---|
202 | CORBA_exception_init (&ev); |
---|
203 | my_ev = &ev; |
---|
204 | } else |
---|
205 | my_ev = opt_ev; |
---|
206 | |
---|
207 | if (!driver || !path) |
---|
208 | CORBA_exception_set (my_ev, CORBA_USER_EXCEPTION, |
---|
209 | ex_Bonobo_Storage_IOError, NULL); |
---|
210 | |
---|
211 | else if (!(p = bonobo_storage_plugin_find (driver)) || |
---|
212 | !p->storage_open) |
---|
213 | CORBA_exception_set (my_ev, CORBA_USER_EXCEPTION, |
---|
214 | ex_Bonobo_Storage_NotSupported, NULL); |
---|
215 | else |
---|
216 | storage = p->storage_open (path, flags, mode, my_ev); |
---|
217 | |
---|
218 | if (!opt_ev) { |
---|
219 | if (BONOBO_EX (my_ev)) |
---|
220 | g_warning ("bonobo_storage_open failed '%s'", |
---|
221 | bonobo_exception_get_text (my_ev)); |
---|
222 | CORBA_exception_free (&ev); |
---|
223 | } |
---|
224 | |
---|
225 | return storage; |
---|
226 | } |
---|
227 | |
---|
228 | /** |
---|
229 | * bonobo_storage_open: |
---|
230 | * @driver: driver to use for opening. |
---|
231 | * @path: path where the base file resides |
---|
232 | * @flags: Bonobo Storage OpenMode |
---|
233 | * @mode: Unix open(2) mode |
---|
234 | * |
---|
235 | * Opens or creates the file named at @path with the stream driver |
---|
236 | * @driver. |
---|
237 | * |
---|
238 | * @driver is one of: "efs", "vfs" or "fs" for now, please use |
---|
239 | * the macros for this though, see bonobo-stream.h eg. |
---|
240 | * BONOBO_IO_DRIVER_FS |
---|
241 | * |
---|
242 | * Returns: a created BonoboStorage object. |
---|
243 | **/ |
---|
244 | BonoboStorage * |
---|
245 | bonobo_storage_open (const char *driver, const char *path, |
---|
246 | gint flags, gint mode) |
---|
247 | { |
---|
248 | return bonobo_storage_open_full (driver, path, flags, mode, NULL); |
---|
249 | } |
---|
250 | |
---|
251 | static void |
---|
252 | copy_stream (Bonobo_Stream src, Bonobo_Stream dest, CORBA_Environment *ev) |
---|
253 | { |
---|
254 | Bonobo_Stream_iobuf *buf; |
---|
255 | |
---|
256 | do { |
---|
257 | Bonobo_Stream_read (src, 4096, &buf, ev); |
---|
258 | if (BONOBO_EX (ev)) |
---|
259 | break; |
---|
260 | |
---|
261 | if (buf->_length == 0) { |
---|
262 | CORBA_free (buf); |
---|
263 | break; |
---|
264 | } |
---|
265 | |
---|
266 | Bonobo_Stream_write (dest, buf, ev); |
---|
267 | CORBA_free (buf); |
---|
268 | if (BONOBO_EX (ev)) |
---|
269 | break; |
---|
270 | |
---|
271 | } while (1); |
---|
272 | |
---|
273 | if (BONOBO_EX (ev)) /* we must return a Bonobo_Storage exception */ |
---|
274 | CORBA_exception_set (ev, CORBA_USER_EXCEPTION, |
---|
275 | ex_Bonobo_Storage_IOError, NULL); |
---|
276 | } |
---|
277 | |
---|
278 | /** |
---|
279 | * bonobo_storage_copy_to: |
---|
280 | * @src: the source storage |
---|
281 | * @dest: the destination storage |
---|
282 | * @ev: CORBA exception environment |
---|
283 | * |
---|
284 | * Implements a pure CORBA method for copying one storage into |
---|
285 | * another, this is used by several BonoboStorage implemetations |
---|
286 | * where a fast case localy copy cannot work. |
---|
287 | **/ |
---|
288 | void |
---|
289 | bonobo_storage_copy_to (Bonobo_Storage src, Bonobo_Storage dest, |
---|
290 | CORBA_Environment *ev) |
---|
291 | { |
---|
292 | Bonobo_Storage new_src, new_dest; |
---|
293 | Bonobo_Stream src_stream, dest_stream; |
---|
294 | Bonobo_Storage_DirectoryList *list; |
---|
295 | gint i; |
---|
296 | |
---|
297 | if ((src == CORBA_OBJECT_NIL) || (dest == CORBA_OBJECT_NIL) || !ev) { |
---|
298 | CORBA_exception_set (ev, CORBA_USER_EXCEPTION, |
---|
299 | ex_Bonobo_Storage_IOError, NULL); |
---|
300 | return; |
---|
301 | } |
---|
302 | |
---|
303 | list = Bonobo_Storage_listContents (src, "", |
---|
304 | Bonobo_FIELD_CONTENT_TYPE | |
---|
305 | Bonobo_FIELD_TYPE, |
---|
306 | ev); |
---|
307 | if (BONOBO_EX (ev)) |
---|
308 | return; |
---|
309 | |
---|
310 | for (i = 0; i <list->_length; i++) { |
---|
311 | |
---|
312 | if (list->_buffer[i].type == Bonobo_STORAGE_TYPE_DIRECTORY) { |
---|
313 | |
---|
314 | new_dest = Bonobo_Storage_openStorage |
---|
315 | (dest, list->_buffer[i].name, |
---|
316 | Bonobo_Storage_CREATE | |
---|
317 | Bonobo_Storage_FAILIFEXIST, ev); |
---|
318 | |
---|
319 | if (BONOBO_EX (ev)) |
---|
320 | break; |
---|
321 | |
---|
322 | Bonobo_Storage_setInfo (new_dest, "", |
---|
323 | &list->_buffer[i], |
---|
324 | Bonobo_FIELD_CONTENT_TYPE, |
---|
325 | ev); |
---|
326 | |
---|
327 | if (BONOBO_EX (ev)) { |
---|
328 | bonobo_object_release_unref (new_dest, NULL); |
---|
329 | break; |
---|
330 | } |
---|
331 | |
---|
332 | new_src = Bonobo_Storage_openStorage |
---|
333 | (src, list->_buffer[i].name, |
---|
334 | Bonobo_Storage_READ, ev); |
---|
335 | |
---|
336 | if (BONOBO_EX (ev)) { |
---|
337 | bonobo_object_release_unref (new_dest, NULL); |
---|
338 | break; |
---|
339 | } |
---|
340 | |
---|
341 | bonobo_storage_copy_to (new_src, new_dest, ev); |
---|
342 | |
---|
343 | bonobo_object_release_unref (new_src, NULL); |
---|
344 | bonobo_object_release_unref (new_dest, NULL); |
---|
345 | |
---|
346 | if (BONOBO_EX (ev)) |
---|
347 | break; |
---|
348 | |
---|
349 | } else { |
---|
350 | dest_stream = Bonobo_Storage_openStream |
---|
351 | (dest, list->_buffer[i].name, |
---|
352 | Bonobo_Storage_CREATE | |
---|
353 | Bonobo_Storage_FAILIFEXIST, ev); |
---|
354 | |
---|
355 | if (BONOBO_EX (ev)) |
---|
356 | break; |
---|
357 | |
---|
358 | Bonobo_Stream_setInfo (dest_stream, |
---|
359 | &list->_buffer[i], |
---|
360 | Bonobo_FIELD_CONTENT_TYPE, |
---|
361 | ev); |
---|
362 | |
---|
363 | if (BONOBO_EX (ev)) { |
---|
364 | CORBA_exception_set (ev, CORBA_USER_EXCEPTION, |
---|
365 | ex_Bonobo_Storage_IOError, |
---|
366 | NULL); |
---|
367 | bonobo_object_release_unref (dest_stream, |
---|
368 | NULL); |
---|
369 | break; |
---|
370 | } |
---|
371 | |
---|
372 | src_stream = Bonobo_Storage_openStream |
---|
373 | (src, list->_buffer[i].name, |
---|
374 | Bonobo_Storage_READ, ev); |
---|
375 | |
---|
376 | if (BONOBO_EX (ev)) { |
---|
377 | bonobo_object_release_unref (dest_stream, |
---|
378 | NULL); |
---|
379 | break; |
---|
380 | } |
---|
381 | |
---|
382 | copy_stream (src_stream, dest_stream, ev); |
---|
383 | |
---|
384 | bonobo_object_release_unref (src_stream, NULL); |
---|
385 | bonobo_object_release_unref (dest_stream, NULL); |
---|
386 | |
---|
387 | if (BONOBO_EX (ev)) |
---|
388 | break; |
---|
389 | } |
---|
390 | } |
---|
391 | |
---|
392 | CORBA_free (list); |
---|
393 | } |
---|