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