Added GMountMountFlags enum and added a flags argument to all mount calls.
[platform/upstream/glib.git] / gio / gvolume.c
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., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  *         David Zeuthen <davidz@redhat.com>
22  */
23
24 #include <config.h>
25 #include "gmount.h"
26 #include "gvolume.h"
27 #include "gsimpleasyncresult.h"
28 #include "glibintl.h"
29
30 #include "gioalias.h"
31
32 /**
33  * SECTION:gvolume
34  * @short_description: Volume management
35  * @include: gio.h
36  * 
37  * The #GVolume interface represents user-visible objects that can be
38  * mounted. Note, when porting from GnomeVFS, #GVolume is the moral
39  * equivalent of #GnomeVFSDrive.
40  *
41  * Mounting a #GVolume instance is an asynchronous operation. For more
42  * information about asynchronous operations, see #GAsyncReady and
43  * #GSimpleAsyncReady. To mount a #GVolume, first call
44  * g_volume_mount() with (at least) the #GVolume instance, optionally
45  * a #GMountOperation object and a #GAsyncReadyCallback. 
46  *
47  * Typically, one will only want to pass %NULL for the
48  * #GMountOperation if automounting all volumes when a desktop session
49  * starts since it's not desirable to put up a lot of dialogs asking
50  * for credentials.
51  *
52  * The callback will be fired when the operation has resolved (either
53  * with success or failure), and a #GAsyncReady structure will be
54  * passed to the callback.  That callback should then call
55  * g_volume_mount_finish() with the #GVolume instance and the
56  * #GAsyncReady data to see if the operation was completed
57  * successfully.  If an @error is present when g_volume_mount_finish()
58  * is called, then it will be filled with any error information.
59  *
60  * <para id="volume-identifier">
61  * It is sometimes necessary to directly access the underlying 
62  * operating system object behind a volume (e.g. for passing a volume
63  * to an application via the commandline). For this purpose, GIO
64  * allows to obtain an 'identifier' for the volume. There can be
65  * different kinds of identifiers, such as Hal UDIs, filesystem labels,
66  * traditional Unix devices (e.g. <filename>/dev/sda2</filename>),
67  * uuids. GIO uses predefind strings as names for the different kinds
68  * of identifiers: #G_VOLUME_IDENTIFIER_KIND_HAL_UDI, 
69  * #G_VOLUME_IDENTIFIER_KIND_LABEL, etc. Use g_volume_get_identifier() 
70  * to obtain an identifier for a volume.
71  * </para>
72  **/
73
74 static void g_volume_base_init (gpointer g_class);
75 static void g_volume_class_init (gpointer g_class,
76                                  gpointer class_data);
77
78 GType
79 g_volume_get_type (void)
80 {
81   static GType volume_type = 0;
82
83   if (! volume_type)
84     {
85       static const GTypeInfo volume_info =
86       {
87         sizeof (GVolumeIface), /* class_size */
88         g_volume_base_init,   /* base_init */
89         NULL,           /* base_finalize */
90         g_volume_class_init,
91         NULL,           /* class_finalize */
92         NULL,           /* class_data */
93         0,
94         0,              /* n_preallocs */
95         NULL
96       };
97
98       volume_type =
99         g_type_register_static (G_TYPE_INTERFACE, I_("GVolume"),
100                                 &volume_info, 0);
101
102       g_type_interface_add_prerequisite (volume_type, G_TYPE_OBJECT);
103     }
104
105   return volume_type;
106 }
107
108 static void
109 g_volume_class_init (gpointer g_class,
110                      gpointer class_data)
111 {
112 }
113
114 static void
115 g_volume_base_init (gpointer g_class)
116 {
117   static gboolean initialized = FALSE;
118
119   if (! initialized)
120     {
121      /**
122       * GVolume::changed:
123       * 
124       * Emitted when the volume has been changed.
125       **/
126       g_signal_new (I_("changed"),
127                     G_TYPE_VOLUME,
128                     G_SIGNAL_RUN_LAST,
129                     G_STRUCT_OFFSET (GVolumeIface, changed),
130                     NULL, NULL,
131                     g_cclosure_marshal_VOID__VOID,
132                     G_TYPE_NONE, 0);
133
134      /**
135       * GVolume::removed:
136       * 
137       * This signal is emitted when the #GVolume have been removed. If
138       * the recipient is holding references to the object they should
139       * release them so the object can be finalized.
140       **/
141       g_signal_new (I_("removed"),
142                     G_TYPE_VOLUME,
143                     G_SIGNAL_RUN_LAST,
144                     G_STRUCT_OFFSET (GVolumeIface, removed),
145                     NULL, NULL,
146                     g_cclosure_marshal_VOID__VOID,
147                     G_TYPE_NONE, 0);
148
149       initialized = TRUE;
150     }
151 }
152
153 /**
154  * g_volume_get_name:
155  * @volume: a #GVolume.
156  * 
157  * Gets the name of @volume.
158  * 
159  * Returns: the name for the given @volume. The returned string should 
160  * be freed when no longer needed.
161  **/
162 char *
163 g_volume_get_name (GVolume *volume)
164 {
165   GVolumeIface *iface;
166
167   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
168
169   iface = G_VOLUME_GET_IFACE (volume);
170
171   return (* iface->get_name) (volume);
172 }
173
174 /**
175  * g_volume_get_icon:
176  * @volume: a #GVolume.
177  * 
178  * Gets the icon for @volume.
179  * 
180  * Returns: a #GIcon.
181  **/
182 GIcon *
183 g_volume_get_icon (GVolume *volume)
184 {
185   GVolumeIface *iface;
186
187   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
188
189   iface = G_VOLUME_GET_IFACE (volume);
190
191   return (* iface->get_icon) (volume);
192 }
193
194 /**
195  * g_volume_get_uuid:
196  * @volume: a #GVolume.
197  * 
198  * Gets the UUID for the @volume. The reference is typically based on
199  * the file system UUID for the volume in question and should be
200  * considered an opaque string. Returns %NULL if there is no UUID
201  * available.
202  * 
203  * Returns: the UUID for @volume or %NULL if no UUID can be computed.
204  **/
205 char *
206 g_volume_get_uuid (GVolume *volume)
207 {
208   GVolumeIface *iface;
209
210   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
211
212   iface = G_VOLUME_GET_IFACE (volume);
213
214   return (* iface->get_uuid) (volume);
215 }
216   
217 /**
218  * g_volume_get_drive:
219  * @volume: a #GVolume.
220  * 
221  * Gets the drive for the @volume.
222  * 
223  * Returns: a #GDrive or %NULL if @volume is not associated with a drive.
224  **/
225 GDrive *
226 g_volume_get_drive (GVolume *volume)
227 {
228   GVolumeIface *iface;
229
230   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
231
232   iface = G_VOLUME_GET_IFACE (volume);
233
234   return (* iface->get_drive) (volume);
235 }
236
237 /**
238  * g_volume_get_mount:
239  * @volume: a #GVolume.
240  * 
241  * Gets the mount for the @volume.
242  * 
243  * Returns: a #GMount or %NULL if @volume isn't mounted.
244  **/
245 GMount *
246 g_volume_get_mount (GVolume *volume)
247 {
248   GVolumeIface *iface;
249
250   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
251
252   iface = G_VOLUME_GET_IFACE (volume);
253
254   return (* iface->get_mount) (volume);
255 }
256
257
258 /**
259  * g_volume_can_mount:
260  * @volume: a #GVolume.
261  * 
262  * Checks if a volume can be mounted.
263  * 
264  * Returns: %TRUE if the @volume can be mounted. %FALSE otherwise.
265  **/
266 gboolean
267 g_volume_can_mount (GVolume *volume)
268 {
269   GVolumeIface *iface;
270
271   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
272
273   iface = G_VOLUME_GET_IFACE (volume);
274
275   if (iface->can_mount == NULL)
276     return FALSE;
277
278   return (* iface->can_mount) (volume);
279 }
280
281 /**
282  * g_volume_can_eject:
283  * @volume: a #GVolume.
284  * 
285  * Checks if a volume can be ejected.
286  * 
287  * Returns: %TRUE if the @volume can be ejected. %FALSE otherwise.
288  **/
289 gboolean
290 g_volume_can_eject (GVolume *volume)
291 {
292   GVolumeIface *iface;
293
294   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
295
296   iface = G_VOLUME_GET_IFACE (volume);
297
298   if (iface->can_eject == NULL)
299     return FALSE;
300
301   return (* iface->can_eject) (volume);
302 }
303
304 /**
305  * g_volume_should_automount:
306  * @volume: a #GVolume
307  *
308  * Returns whether the volume should be automatically mounted.
309  * 
310  * Returns: %TRUE if the volume should be automatically mounted.
311  */
312 gboolean
313 g_volume_should_automount (GVolume *volume)
314 {
315   GVolumeIface *iface;
316
317   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
318
319   iface = G_VOLUME_GET_IFACE (volume);
320
321   if (iface->should_automount == NULL)
322     return FALSE;
323
324   return (* iface->should_automount) (volume);
325 }
326
327
328 /**
329  * g_volume_mount:
330  * @volume: a #GVolume.
331  * @flags: flags affecting the operation
332  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
333  * @cancellable: optional #GCancellable object, %NULL to ignore.
334  * @callback: a #GAsyncReadyCallback, or %NULL.
335  * @user_data: a #gpointer.
336  * 
337  * Mounts a volume.
338  **/
339 void
340 g_volume_mount (GVolume    *volume,
341                 GMountMountFlags     flags,
342                 GMountOperation     *mount_operation,
343                 GCancellable        *cancellable,
344                 GAsyncReadyCallback  callback,
345                 gpointer             user_data)
346 {
347   GVolumeIface *iface;
348
349   g_return_if_fail (G_IS_VOLUME (volume));
350
351   iface = G_VOLUME_GET_IFACE (volume);
352
353   if (iface->mount_fn == NULL)
354     {
355       g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
356                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
357                                            _("volume doesn't implement mount"));
358       
359       return;
360     }
361   
362   (* iface->mount_fn) (volume, flags, mount_operation, cancellable, callback, user_data);
363 }
364
365 /**
366  * g_volume_mount_finish:
367  * @volume: pointer to a #GVolume.
368  * @result: a #GAsyncResult.
369  * @error: a #GError.
370  * 
371  * Finishes mounting a volume.
372  * 
373  * Returns: %TRUE, %FALSE if operation failed.
374  **/
375 gboolean
376 g_volume_mount_finish (GVolume  *volume,
377                        GAsyncResult      *result,
378                        GError           **error)
379 {
380   GVolumeIface *iface;
381
382   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
383   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
384
385   if (G_IS_SIMPLE_ASYNC_RESULT (result))
386     {
387       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
388       if (g_simple_async_result_propagate_error (simple, error))
389         return FALSE;
390     }
391   
392   iface = G_VOLUME_GET_IFACE (volume);
393   return (* iface->mount_finish) (volume, result, error);
394 }
395
396 /**
397  * g_volume_eject:
398  * @volume: a #GVolume.
399  * @flags: flags affecting the unmount if required for eject
400  * @cancellable: optional #GCancellable object, %NULL to ignore.
401  * @callback: a #GAsyncReadyCallback, or %NULL.
402  * @user_data: a #gpointer.
403  * 
404  * Ejects a volume.
405  **/
406 void
407 g_volume_eject (GVolume    *volume,
408                 GMountUnmountFlags   flags,
409                 GCancellable        *cancellable,
410                 GAsyncReadyCallback  callback,
411                 gpointer             user_data)
412 {
413   GVolumeIface *iface;
414
415   g_return_if_fail (G_IS_VOLUME (volume));
416
417   iface = G_VOLUME_GET_IFACE (volume);
418
419   if (iface->eject == NULL)
420     {
421       g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
422                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
423                                            _("volume doesn't implement eject"));
424       
425       return;
426     }
427   
428   (* iface->eject) (volume, flags, cancellable, callback, user_data);
429 }
430
431 /**
432  * g_volume_eject_finish:
433  * @volume: pointer to a #GVolume.
434  * @result: a #GAsyncResult.
435  * @error: a #GError.
436  * 
437  * Finishes ejecting a volume.
438  * 
439  * Returns: %TRUE, %FALSE if operation failed.
440  **/
441 gboolean
442 g_volume_eject_finish (GVolume  *volume,
443                        GAsyncResult      *result,
444                        GError           **error)
445 {
446   GVolumeIface *iface;
447
448   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
449   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
450
451   if (G_IS_SIMPLE_ASYNC_RESULT (result))
452     {
453       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
454       if (g_simple_async_result_propagate_error (simple, error))
455         return FALSE;
456     }
457   
458   iface = G_VOLUME_GET_IFACE (volume);
459   return (* iface->eject_finish) (volume, result, error);
460 }
461
462 /**
463  * g_volume_get_identifier:
464  * @volume: a #GVolume
465  * @kind: the kind of identifier to return
466  *
467  * Gets the identifier of the given kind for @volume. 
468  * See the <link linkend="volume-identifier">introduction</link>
469  * for more information about volume identifiers.
470  *
471  * Returns: a newly allocated string containing the
472  *   requested identfier, or %NULL if the #GVolume
473  *   doesn't have this kind of identifier
474  */
475 char *
476 g_volume_get_identifier (GVolume    *volume,
477                          const char *kind)
478 {
479   GVolumeIface *iface;
480
481   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
482   g_return_val_if_fail (kind != NULL, NULL);
483
484   iface = G_VOLUME_GET_IFACE (volume);
485
486   if (iface->get_identifier == NULL)
487     return NULL;
488   
489   return (* iface->get_identifier) (volume, kind);
490 }
491
492 /**
493  * g_volume_enumerate_identifiers:
494  * @volume: a #GVolume
495  * 
496  * Gets the kinds of <link linkend="volume-identifier">identifiers</link>
497  * that @volume has. Use g_volume_get_identifer() to obtain 
498  * the identifiers themselves.
499  *
500  * Returns: a %NULL-terminated array of strings containing
501  *   kinds of identifiers. Use g_strfreev() to free.
502  */
503 char **
504 g_volume_enumerate_identifiers (GVolume *volume)
505 {
506   GVolumeIface *iface;
507
508   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
509   iface = G_VOLUME_GET_IFACE (volume);
510
511   if (iface->enumerate_identifiers == NULL)
512     return NULL;
513   
514   return (* iface->enumerate_identifiers) (volume);
515 }
516
517
518 #define __G_VOLUME_C__
519 #include "gioaliasdef.c"