docs: Correct GUnixMount → GUnixMountEntry
[platform/upstream/glib.git] / gio / gmount.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /* GIO - GLib Input, Output and Streaming Library
4  * 
5  * Copyright (C) 2006-2008 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * Author: Alexander Larsson <alexl@redhat.com>
23  *         David Zeuthen <davidz@redhat.com>
24  */
25
26 #include "config.h"
27
28 #include <string.h>
29
30 #include "gmount.h"
31 #include "gmountprivate.h"
32 #include "gasyncresult.h"
33 #include "gsimpleasyncresult.h"
34 #include "gioerror.h"
35 #include "glibintl.h"
36
37
38 /**
39  * SECTION:gmount
40  * @short_description: Mount management
41  * @include: gio/gio.h
42  * @see_also: GVolume, GUnixMountEntry, GUnixMountPoint
43  *
44  * The #GMount interface represents user-visible mounts. Note, when 
45  * porting from GnomeVFS, #GMount is the moral equivalent of #GnomeVFSVolume.
46  *
47  * #GMount is a "mounted" filesystem that you can access. Mounted is in
48  * quotes because it's not the same as a unix mount, it might be a gvfs
49  * mount, but you can still access the files on it if you use GIO. Might or
50  * might not be related to a volume object.
51  * 
52  * Unmounting a #GMount instance is an asynchronous operation. For
53  * more information about asynchronous operations, see #GAsyncReady
54  * and #GSimpleAsyncReady. To unmount a #GMount instance, first call
55  * g_mount_unmount_with_operation() with (at least) the #GMount instance and a
56  * #GAsyncReadyCallback.  The callback will be fired when the
57  * operation has resolved (either with success or failure), and a
58  * #GAsyncReady structure will be passed to the callback.  That
59  * callback should then call g_mount_unmount_with_operation_finish() with the #GMount
60  * and the #GAsyncReady data to see if the operation was completed
61  * successfully.  If an @error is present when g_mount_unmount_with_operation_finish() 
62  * is called, then it will be filled with any error information.
63  **/
64
65 typedef GMountIface GMountInterface;
66 G_DEFINE_INTERFACE (GMount, g_mount, G_TYPE_OBJECT)
67
68 static void
69 g_mount_default_init (GMountInterface *iface)
70 {
71   /**
72    * GMount::changed:
73    * @mount: the object on which the signal is emitted
74    *
75    * Emitted when the mount has been changed.
76    **/
77   g_signal_new (I_("changed"),
78                 G_TYPE_MOUNT,
79                 G_SIGNAL_RUN_LAST,
80                 G_STRUCT_OFFSET (GMountIface, changed),
81                 NULL, NULL,
82                 g_cclosure_marshal_VOID__VOID,
83                 G_TYPE_NONE, 0);
84
85   /**
86    * GMount::unmounted:
87    * @mount: the object on which the signal is emitted
88    *
89    * This signal is emitted when the #GMount have been
90    * unmounted. If the recipient is holding references to the
91    * object they should release them so the object can be
92    * finalized.
93    **/
94   g_signal_new (I_("unmounted"),
95                 G_TYPE_MOUNT,
96                 G_SIGNAL_RUN_LAST,
97                 G_STRUCT_OFFSET (GMountIface, unmounted),
98                 NULL, NULL,
99                 g_cclosure_marshal_VOID__VOID,
100                 G_TYPE_NONE, 0);
101   /**
102    * GMount::pre-unmount:
103    * @mount: the object on which the signal is emitted
104    *
105    * This signal is emitted when the #GMount is about to be
106    * unmounted.
107    *
108    * Since: 2.22
109    **/
110   g_signal_new (I_("pre-unmount"),
111                 G_TYPE_MOUNT,
112                 G_SIGNAL_RUN_LAST,
113                 G_STRUCT_OFFSET (GMountIface, pre_unmount),
114                 NULL, NULL,
115                 g_cclosure_marshal_VOID__VOID,
116                 G_TYPE_NONE, 0);
117 }
118
119 /**
120  * g_mount_get_root:
121  * @mount: a #GMount.
122  * 
123  * Gets the root directory on @mount.
124  * 
125  * Returns: (transfer full): a #GFile. 
126  *      The returned object should be unreffed with 
127  *      g_object_unref() when no longer needed.
128  **/
129 GFile *
130 g_mount_get_root (GMount *mount)
131 {
132   GMountIface *iface;
133
134   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
135
136   iface = G_MOUNT_GET_IFACE (mount);
137
138   return (* iface->get_root) (mount);
139 }
140
141 /**
142  * g_mount_get_default_location:
143  * @mount: a #GMount.
144  *
145  * Gets the default location of @mount. The default location of the given
146  * @mount is a path that reflects the main entry point for the user (e.g.
147  * the home directory, or the root of the volume).
148  *
149  * Returns: (transfer full): a #GFile.
150  *      The returned object should be unreffed with
151  *      g_object_unref() when no longer needed.
152  **/
153 GFile *
154 g_mount_get_default_location (GMount *mount)
155 {
156   GMountIface *iface;
157   GFile       *file;
158
159   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
160
161   iface = G_MOUNT_GET_IFACE (mount);
162   
163   /* Fallback to get_root when default_location () is not available */
164   if (iface->get_default_location)
165     file = (* iface->get_default_location) (mount);
166   else
167     file = (* iface->get_root) (mount);
168
169   return file;
170 }
171
172 /**
173  * g_mount_get_name:
174  * @mount: a #GMount.
175  * 
176  * Gets the name of @mount.
177  * 
178  * Returns: the name for the given @mount. 
179  *     The returned string should be freed with g_free()
180  *     when no longer needed.
181  **/
182 char *
183 g_mount_get_name (GMount *mount)
184 {
185   GMountIface *iface;
186
187   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
188
189   iface = G_MOUNT_GET_IFACE (mount);
190
191   return (* iface->get_name) (mount);
192 }
193
194 /**
195  * g_mount_get_icon:
196  * @mount: a #GMount.
197  * 
198  * Gets the icon for @mount.
199  * 
200  * Returns: (transfer full): a #GIcon.
201  *      The returned object should be unreffed with 
202  *      g_object_unref() when no longer needed.
203  **/
204 GIcon *
205 g_mount_get_icon (GMount *mount)
206 {
207   GMountIface *iface;
208
209   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
210
211   iface = G_MOUNT_GET_IFACE (mount);
212
213   return (* iface->get_icon) (mount);
214 }
215
216 /**
217  * g_mount_get_uuid:
218  * @mount: a #GMount.
219  * 
220  * Gets the UUID for the @mount. The reference is typically based on
221  * the file system UUID for the mount in question and should be
222  * considered an opaque string. Returns %NULL if there is no UUID
223  * available.
224  * 
225  * Returns: the UUID for @mount or %NULL if no UUID can be computed.
226  *     The returned string should be freed with g_free()
227  *     when no longer needed.
228  **/
229 char *
230 g_mount_get_uuid (GMount *mount)
231 {
232   GMountIface *iface;
233
234   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
235
236   iface = G_MOUNT_GET_IFACE (mount);
237
238   return (* iface->get_uuid) (mount);
239 }
240
241 /**
242  * g_mount_get_volume:
243  * @mount: a #GMount.
244  * 
245  * Gets the volume for the @mount.
246  * 
247  * Returns: (transfer full): a #GVolume or %NULL if @mount is not associated with a volume.
248  *      The returned object should be unreffed with 
249  *      g_object_unref() when no longer needed.
250  **/
251 GVolume *
252 g_mount_get_volume (GMount *mount)
253 {
254   GMountIface *iface;
255
256   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
257
258   iface = G_MOUNT_GET_IFACE (mount);
259
260   return (* iface->get_volume) (mount);
261 }
262
263 /**
264  * g_mount_get_drive:
265  * @mount: a #GMount.
266  * 
267  * Gets the drive for the @mount.
268  *
269  * This is a convenience method for getting the #GVolume and then
270  * using that object to get the #GDrive.
271  * 
272  * Returns: (transfer full): a #GDrive or %NULL if @mount is not associated with a volume or a drive.
273  *      The returned object should be unreffed with 
274  *      g_object_unref() when no longer needed.
275  **/
276 GDrive *
277 g_mount_get_drive (GMount *mount)
278 {
279   GMountIface *iface;
280
281   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
282
283   iface = G_MOUNT_GET_IFACE (mount);
284
285   return (* iface->get_drive) (mount);
286 }
287
288 /**
289  * g_mount_can_unmount: 
290  * @mount: a #GMount.
291  * 
292  * Checks if @mount can be mounted.
293  * 
294  * Returns: %TRUE if the @mount can be unmounted.
295  **/
296 gboolean
297 g_mount_can_unmount (GMount *mount)
298 {
299   GMountIface *iface;
300
301   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
302
303   iface = G_MOUNT_GET_IFACE (mount);
304
305   return (* iface->can_unmount) (mount);
306 }
307
308 /**
309  * g_mount_can_eject: 
310  * @mount: a #GMount.
311  * 
312  * Checks if @mount can be eject.
313  * 
314  * Returns: %TRUE if the @mount can be ejected.
315  **/
316 gboolean
317 g_mount_can_eject (GMount *mount)
318 {
319   GMountIface *iface;
320
321   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
322
323   iface = G_MOUNT_GET_IFACE (mount);
324
325   return (* iface->can_eject) (mount);
326 }
327
328 /**
329  * g_mount_unmount:
330  * @mount: a #GMount.
331  * @flags: flags affecting the operation
332  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
333  * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL.
334  * @user_data: user data passed to @callback.
335  * 
336  * Unmounts a mount. This is an asynchronous operation, and is 
337  * finished by calling g_mount_unmount_finish() with the @mount 
338  * and #GAsyncResult data returned in the @callback.
339  *
340  * Deprecated: 2.22: Use g_mount_unmount_with_operation() instead.
341  **/
342 void
343 g_mount_unmount (GMount              *mount,
344                  GMountUnmountFlags   flags,
345                  GCancellable        *cancellable,
346                  GAsyncReadyCallback  callback,
347                  gpointer             user_data)
348 {
349   GMountIface *iface;
350
351   g_return_if_fail (G_IS_MOUNT (mount));
352   
353   iface = G_MOUNT_GET_IFACE (mount);
354
355   if (iface->unmount == NULL)
356     {
357       g_simple_async_report_error_in_idle (G_OBJECT (mount),
358                                            callback, user_data,
359                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
360                                            /* Translators: This is an error
361                                             * message for mount objects that
362                                             * don't implement unmount. */
363                                            _("mount doesn't implement \"unmount\""));
364
365       return;
366     }
367   
368   (* iface->unmount) (mount, flags, cancellable, callback, user_data);
369 }
370
371 /**
372  * g_mount_unmount_finish:
373  * @mount: a #GMount.
374  * @result: a #GAsyncResult.
375  * @error: a #GError location to store the error occurring, or %NULL to 
376  *     ignore.
377  * 
378  * Finishes unmounting a mount. If any errors occurred during the operation, 
379  * @error will be set to contain the errors and %FALSE will be returned.
380  * 
381  * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
382  *
383  * Deprecated: 2.22: Use g_mount_unmount_with_operation_finish() instead.
384  **/
385 gboolean
386 g_mount_unmount_finish (GMount        *mount,
387                         GAsyncResult  *result,
388                         GError       **error)
389 {
390   GMountIface *iface;
391
392   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
393   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
394
395   if (G_IS_SIMPLE_ASYNC_RESULT (result))
396     {
397       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
398       if (g_simple_async_result_propagate_error (simple, error))
399         return FALSE;
400     }
401   
402   iface = G_MOUNT_GET_IFACE (mount);
403   return (* iface->unmount_finish) (mount, result, error);
404 }
405
406
407 /**
408  * g_mount_eject:
409  * @mount: a #GMount.
410  * @flags: flags affecting the unmount if required for eject
411  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
412  * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL.
413  * @user_data: user data passed to @callback.
414  * 
415  * Ejects a mount. This is an asynchronous operation, and is 
416  * finished by calling g_mount_eject_finish() with the @mount 
417  * and #GAsyncResult data returned in the @callback.
418  *
419  * Deprecated: 2.22: Use g_mount_eject_with_operation() instead.
420  **/
421 void
422 g_mount_eject (GMount              *mount,
423                GMountUnmountFlags   flags,
424                GCancellable        *cancellable,
425                GAsyncReadyCallback  callback,
426                gpointer             user_data)
427 {
428   GMountIface *iface;
429
430   g_return_if_fail (G_IS_MOUNT (mount));
431   
432   iface = G_MOUNT_GET_IFACE (mount);
433
434   if (iface->eject == NULL)
435     {
436       g_simple_async_report_error_in_idle (G_OBJECT (mount),
437                                            callback, user_data,
438                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
439                                            /* Translators: This is an error
440                                             * message for mount objects that
441                                             * don't implement eject. */
442                                            _("mount doesn't implement \"eject\""));
443       
444       return;
445     }
446   
447   (* iface->eject) (mount, flags, cancellable, callback, user_data);
448 }
449
450 /**
451  * g_mount_eject_finish:
452  * @mount: a #GMount.
453  * @result: a #GAsyncResult.
454  * @error: a #GError location to store the error occurring, or %NULL to 
455  *     ignore.
456  * 
457  * Finishes ejecting a mount. If any errors occurred during the operation, 
458  * @error will be set to contain the errors and %FALSE will be returned.
459  * 
460  * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
461  *
462  * Deprecated: 2.22: Use g_mount_eject_with_operation_finish() instead.
463  **/
464 gboolean
465 g_mount_eject_finish (GMount        *mount,
466                       GAsyncResult  *result,
467                       GError       **error)
468 {
469   GMountIface *iface;
470
471   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
472   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
473
474   if (G_IS_SIMPLE_ASYNC_RESULT (result))
475     {
476       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
477       if (g_simple_async_result_propagate_error (simple, error))
478         return FALSE;
479     }
480   
481   iface = G_MOUNT_GET_IFACE (mount);
482   return (* iface->eject_finish) (mount, result, error);
483 }
484
485 /**
486  * g_mount_unmount_with_operation:
487  * @mount: a #GMount.
488  * @flags: flags affecting the operation
489  * @mount_operation: (allow-none): a #GMountOperation or %NULL to avoid
490  *     user interaction.
491  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
492  * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL.
493  * @user_data: user data passed to @callback.
494  *
495  * Unmounts a mount. This is an asynchronous operation, and is
496  * finished by calling g_mount_unmount_with_operation_finish() with the @mount 
497  * and #GAsyncResult data returned in the @callback.
498  *
499  * Since: 2.22
500  **/
501 void
502 g_mount_unmount_with_operation (GMount              *mount,
503                                 GMountUnmountFlags   flags,
504                                 GMountOperation     *mount_operation,
505                                 GCancellable        *cancellable,
506                                 GAsyncReadyCallback  callback,
507                                 gpointer             user_data)
508 {
509   GMountIface *iface;
510
511   g_return_if_fail (G_IS_MOUNT (mount));
512
513   iface = G_MOUNT_GET_IFACE (mount);
514
515   if (iface->unmount == NULL && iface->unmount_with_operation == NULL)
516     {
517       g_simple_async_report_error_in_idle (G_OBJECT (mount),
518                                            callback, user_data,
519                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
520                                            /* Translators: This is an error
521                                             * message for mount objects that
522                                             * don't implement any of unmount or unmount_with_operation. */
523                                            _("mount doesn't implement \"unmount\" or \"unmount_with_operation\""));
524
525       return;
526     }
527
528   if (iface->unmount_with_operation != NULL)
529     (* iface->unmount_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
530   else
531     (* iface->unmount) (mount, flags, cancellable, callback, user_data);
532 }
533
534 /**
535  * g_mount_unmount_with_operation_finish:
536  * @mount: a #GMount.
537  * @result: a #GAsyncResult.
538  * @error: a #GError location to store the error occurring, or %NULL to
539  *     ignore.
540  *
541  * Finishes unmounting a mount. If any errors occurred during the operation,
542  * @error will be set to contain the errors and %FALSE will be returned.
543  *
544  * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
545  *
546  * Since: 2.22
547  **/
548 gboolean
549 g_mount_unmount_with_operation_finish (GMount        *mount,
550                                        GAsyncResult  *result,
551                                        GError       **error)
552 {
553   GMountIface *iface;
554
555   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
556   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
557
558   if (G_IS_SIMPLE_ASYNC_RESULT (result))
559     {
560       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
561       if (g_simple_async_result_propagate_error (simple, error))
562         return FALSE;
563     }
564
565   iface = G_MOUNT_GET_IFACE (mount);
566   if (iface->unmount_with_operation_finish != NULL)
567     return (* iface->unmount_with_operation_finish) (mount, result, error);
568   else
569     return (* iface->unmount_finish) (mount, result, error);
570 }
571
572
573 /**
574  * g_mount_eject_with_operation:
575  * @mount: a #GMount.
576  * @flags: flags affecting the unmount if required for eject
577  * @mount_operation: (allow-none): a #GMountOperation or %NULL to avoid
578  *     user interaction.
579  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
580  * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL.
581  * @user_data: user data passed to @callback.
582  *
583  * Ejects a mount. This is an asynchronous operation, and is
584  * finished by calling g_mount_eject_with_operation_finish() with the @mount
585  * and #GAsyncResult data returned in the @callback.
586  *
587  * Since: 2.22
588  **/
589 void
590 g_mount_eject_with_operation (GMount              *mount,
591                               GMountUnmountFlags   flags,
592                               GMountOperation     *mount_operation,
593                               GCancellable        *cancellable,
594                               GAsyncReadyCallback  callback,
595                               gpointer             user_data)
596 {
597   GMountIface *iface;
598
599   g_return_if_fail (G_IS_MOUNT (mount));
600
601   iface = G_MOUNT_GET_IFACE (mount);
602
603   if (iface->eject == NULL && iface->eject_with_operation == NULL)
604     {
605       g_simple_async_report_error_in_idle (G_OBJECT (mount),
606                                            callback, user_data,
607                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
608                                            /* Translators: This is an error
609                                             * message for mount objects that
610                                             * don't implement any of eject or eject_with_operation. */
611                                            _("mount doesn't implement \"eject\" or \"eject_with_operation\""));
612       return;
613     }
614
615   if (iface->eject_with_operation != NULL)
616     (* iface->eject_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
617   else
618     (* iface->eject) (mount, flags, cancellable, callback, user_data);
619 }
620
621 /**
622  * g_mount_eject_with_operation_finish:
623  * @mount: a #GMount.
624  * @result: a #GAsyncResult.
625  * @error: a #GError location to store the error occurring, or %NULL to
626  *     ignore.
627  *
628  * Finishes ejecting a mount. If any errors occurred during the operation,
629  * @error will be set to contain the errors and %FALSE will be returned.
630  *
631  * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
632  *
633  * Since: 2.22
634  **/
635 gboolean
636 g_mount_eject_with_operation_finish (GMount        *mount,
637                                      GAsyncResult  *result,
638                                      GError       **error)
639 {
640   GMountIface *iface;
641
642   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
643   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
644
645   if (G_IS_SIMPLE_ASYNC_RESULT (result))
646     {
647       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
648       if (g_simple_async_result_propagate_error (simple, error))
649         return FALSE;
650     }
651
652   iface = G_MOUNT_GET_IFACE (mount);
653   if (iface->eject_with_operation_finish != NULL)
654     return (* iface->eject_with_operation_finish) (mount, result, error);
655   else
656     return (* iface->eject_finish) (mount, result, error);
657 }
658
659 /**
660  * g_mount_remount:
661  * @mount: a #GMount.
662  * @flags: flags affecting the operation
663  * @mount_operation: (allow-none): a #GMountOperation or %NULL to avoid
664  *     user interaction.
665  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
666  * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL.
667  * @user_data: user data passed to @callback.
668  * 
669  * Remounts a mount. This is an asynchronous operation, and is 
670  * finished by calling g_mount_remount_finish() with the @mount 
671  * and #GAsyncResults data returned in the @callback.
672  *
673  * Remounting is useful when some setting affecting the operation
674  * of the volume has been changed, as these may need a remount to
675  * take affect. While this is semantically equivalent with unmounting
676  * and then remounting not all backends might need to actually be
677  * unmounted.
678  **/
679 void
680 g_mount_remount (GMount              *mount,
681                  GMountMountFlags     flags,
682                  GMountOperation     *mount_operation,
683                  GCancellable        *cancellable,
684                  GAsyncReadyCallback  callback,
685                  gpointer             user_data)
686 {
687   GMountIface *iface;
688
689   g_return_if_fail (G_IS_MOUNT (mount));
690   
691   iface = G_MOUNT_GET_IFACE (mount);
692
693   if (iface->remount == NULL)
694     { 
695       g_simple_async_report_error_in_idle (G_OBJECT (mount),
696                                            callback, user_data,
697                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
698                                            /* Translators: This is an error
699                                             * message for mount objects that
700                                             * don't implement remount. */
701                                            _("mount doesn't implement \"remount\""));
702       
703       return;
704     }
705   
706   (* iface->remount) (mount, flags, mount_operation, cancellable, callback, user_data);
707 }
708
709 /**
710  * g_mount_remount_finish:
711  * @mount: a #GMount.
712  * @result: a #GAsyncResult.
713  * @error: a #GError location to store the error occurring, or %NULL to 
714  *     ignore.
715  * 
716  * Finishes remounting a mount. If any errors occurred during the operation, 
717  * @error will be set to contain the errors and %FALSE will be returned.
718  * 
719  * Returns: %TRUE if the mount was successfully remounted. %FALSE otherwise.
720  **/
721 gboolean
722 g_mount_remount_finish (GMount        *mount,
723                         GAsyncResult  *result,
724                         GError       **error)
725 {
726   GMountIface *iface;
727
728   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
729   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
730
731   if (G_IS_SIMPLE_ASYNC_RESULT (result))
732     {
733       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
734       if (g_simple_async_result_propagate_error (simple, error))
735         return FALSE;
736     }
737   
738   iface = G_MOUNT_GET_IFACE (mount);
739   return (* iface->remount_finish) (mount, result, error);
740 }
741
742 /**
743  * g_mount_guess_content_type:
744  * @mount: a #GMount
745  * @force_rescan: Whether to force a rescan of the content. 
746  *     Otherwise a cached result will be used if available
747  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
748  * @callback: a #GAsyncReadyCallback
749  * @user_data: user data passed to @callback
750  * 
751  * Tries to guess the type of content stored on @mount. Returns one or
752  * more textual identifiers of well-known content types (typically
753  * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 
754  * memory cards. See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
755  * specification for more on x-content types.
756  *
757  * This is an asynchronous operation (see
758  * g_mount_guess_content_type_sync() for the synchronous version), and
759  * is finished by calling g_mount_guess_content_type_finish() with the
760  * @mount and #GAsyncResult data returned in the @callback.
761  *
762  * Since: 2.18
763  */
764 void
765 g_mount_guess_content_type (GMount              *mount,
766                             gboolean             force_rescan,
767                             GCancellable        *cancellable,
768                             GAsyncReadyCallback  callback,
769                             gpointer             user_data)
770 {
771   GMountIface *iface;
772
773   g_return_if_fail (G_IS_MOUNT (mount));
774
775   iface = G_MOUNT_GET_IFACE (mount);
776
777   if (iface->guess_content_type == NULL)
778     {
779       g_simple_async_report_error_in_idle (G_OBJECT (mount),
780                                            callback, user_data,
781                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
782                                            /* Translators: This is an error
783                                             * message for mount objects that
784                                             * don't implement content type guessing. */
785                                            _("mount doesn't implement content type guessing"));
786
787       return;
788     }
789   
790   (* iface->guess_content_type) (mount, force_rescan, cancellable, callback, user_data);
791 }
792
793 /**
794  * g_mount_guess_content_type_finish:
795  * @mount: a #GMount
796  * @result: a #GAsyncResult
797  * @error: a #GError location to store the error occurring, or %NULL to 
798  *     ignore
799  * 
800  * Finishes guessing content types of @mount. If any errors occurred
801  * during the operation, @error will be set to contain the errors and
802  * %FALSE will be returned. In particular, you may get an 
803  * %G_IO_ERROR_NOT_SUPPORTED if the mount does not support content 
804  * guessing.
805  * 
806  * Returns: (transfer full) (element-type utf8): a %NULL-terminated array of content types or %NULL on error. 
807  *     Caller should free this array with g_strfreev() when done with it.
808  *
809  * Since: 2.18
810  **/
811 gchar **
812 g_mount_guess_content_type_finish (GMount        *mount,
813                                    GAsyncResult  *result,
814                                    GError       **error)
815 {
816   GMountIface *iface;
817
818   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
819   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
820
821   if (G_IS_SIMPLE_ASYNC_RESULT (result))
822     {
823       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
824       if (g_simple_async_result_propagate_error (simple, error))
825         return NULL;
826     }
827   
828   iface = G_MOUNT_GET_IFACE (mount);
829   return (* iface->guess_content_type_finish) (mount, result, error);
830 }
831
832 /**
833  * g_mount_guess_content_type_sync:
834  * @mount: a #GMount
835  * @force_rescan: Whether to force a rescan of the content.
836  *     Otherwise a cached result will be used if available
837  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
838  * @error: a #GError location to store the error occurring, or %NULL to
839  *     ignore
840  *
841  * Tries to guess the type of content stored on @mount. Returns one or
842  * more textual identifiers of well-known content types (typically
843  * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 
844  * memory cards. See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
845  * specification for more on x-content types.
846  *
847  * This is an synchronous operation and as such may block doing IO;
848  * see g_mount_guess_content_type() for the asynchronous version.
849  *
850  * Returns: (transfer full) (element-type utf8): a %NULL-terminated array of content types or %NULL on error.
851  *     Caller should free this array with g_strfreev() when done with it.
852  *
853  * Since: 2.18
854  */
855 char **
856 g_mount_guess_content_type_sync (GMount              *mount,
857                                  gboolean             force_rescan,
858                                  GCancellable        *cancellable,
859                                  GError             **error)
860 {
861   GMountIface *iface;
862
863   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
864
865   iface = G_MOUNT_GET_IFACE (mount);
866
867   if (iface->guess_content_type_sync == NULL)
868     {
869       g_set_error_literal (error,
870                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
871                            /* Translators: This is an error
872                             * message for mount objects that
873                             * don't implement content type guessing. */
874                            _("mount doesn't implement synchronous content type guessing"));
875
876       return NULL;
877     }
878
879   return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error);
880 }
881
882 G_LOCK_DEFINE_STATIC (priv_lock);
883
884 /* only access this structure when holding priv_lock */
885 typedef struct
886 {
887   gint shadow_ref_count;
888 } GMountPrivate;
889
890 static void
891 free_private (GMountPrivate *private)
892 {
893   G_LOCK (priv_lock);
894   g_free (private);
895   G_UNLOCK (priv_lock);
896 }
897
898 /* may only be called when holding priv_lock */
899 static GMountPrivate *
900 get_private (GMount *mount)
901 {
902   GMountPrivate *private;
903
904   private = g_object_get_data (G_OBJECT (mount), "g-mount-private");
905   if (G_LIKELY (private != NULL))
906     goto out;
907
908   private = g_new0 (GMountPrivate, 1);
909   g_object_set_data_full (G_OBJECT (mount),
910                           "g-mount-private",
911                           private,
912                           (GDestroyNotify) free_private);
913
914  out:
915   return private;
916 }
917
918 /**
919  * g_mount_is_shadowed:
920  * @mount: A #GMount.
921  *
922  * Determines if @mount is shadowed. Applications or libraries should
923  * avoid displaying @mount in the user interface if it is shadowed.
924  *
925  * A mount is said to be shadowed if there exists one or more user
926  * visible objects (currently #GMount objects) with a root that is
927  * inside the root of @mount.
928  *
929  * One application of shadow mounts is when exposing a single file
930  * system that is used to address several logical volumes. In this
931  * situation, a #GVolumeMonitor implementation would create two
932  * #GVolume objects (for example, one for the camera functionality of
933  * the device and one for a SD card reader on the device) with
934  * activation URIs <literal>gphoto2://[usb:001,002]/store1/</literal>
935  * and <literal>gphoto2://[usb:001,002]/store2/</literal>. When the
936  * underlying mount (with root
937  * <literal>gphoto2://[usb:001,002]/</literal>) is mounted, said
938  * #GVolumeMonitor implementation would create two #GMount objects
939  * (each with their root matching the corresponding volume activation
940  * root) that would shadow the original mount.
941  *
942  * The proxy monitor in GVfs 2.26 and later, automatically creates and
943  * manage shadow mounts (and shadows the underlying mount) if the
944  * activation root on a #GVolume is set.
945  *
946  * Returns: %TRUE if @mount is shadowed.
947  *
948  * Since: 2.20
949  **/
950 gboolean
951 g_mount_is_shadowed (GMount *mount)
952 {
953   GMountPrivate *priv;
954   gboolean ret;
955
956   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
957
958   G_LOCK (priv_lock);
959   priv = get_private (mount);
960   ret = (priv->shadow_ref_count > 0);
961   G_UNLOCK (priv_lock);
962
963   return ret;
964 }
965
966 /**
967  * g_mount_shadow:
968  * @mount: A #GMount.
969  *
970  * Increments the shadow count on @mount. Usually used by
971  * #GVolumeMonitor implementations when creating a shadow mount for
972  * @mount, see g_mount_is_shadowed() for more information. The caller
973  * will need to emit the #GMount::changed signal on @mount manually.
974  *
975  * Since: 2.20
976  **/
977 void
978 g_mount_shadow (GMount *mount)
979 {
980   GMountPrivate *priv;
981
982   g_return_if_fail (G_IS_MOUNT (mount));
983
984   G_LOCK (priv_lock);
985   priv = get_private (mount);
986   priv->shadow_ref_count += 1;
987   G_UNLOCK (priv_lock);
988 }
989
990 /**
991  * g_mount_unshadow:
992  * @mount: A #GMount.
993  *
994  * Decrements the shadow count on @mount. Usually used by
995  * #GVolumeMonitor implementations when destroying a shadow mount for
996  * @mount, see g_mount_is_shadowed() for more information. The caller
997  * will need to emit the #GMount::changed signal on @mount manually.
998  *
999  * Since: 2.20
1000  **/
1001 void
1002 g_mount_unshadow (GMount *mount)
1003 {
1004   GMountPrivate *priv;
1005
1006   g_return_if_fail (G_IS_MOUNT (mount));
1007
1008   G_LOCK (priv_lock);
1009   priv = get_private (mount);
1010   priv->shadow_ref_count -= 1;
1011   if (priv->shadow_ref_count < 0)
1012     g_warning ("Shadow ref count on GMount is negative");
1013   G_UNLOCK (priv_lock);
1014 }
1015
1016 /**
1017  * g_mount_get_sort_key:
1018  * @mount: A #GMount.
1019  *
1020  * Gets the sort key for @mount, if any.
1021  *
1022  * Returns: Sorting key for @mount or %NULL if no such key is available.
1023  *
1024  * Since: 2.32
1025  */
1026 const gchar *
1027 g_mount_get_sort_key (GMount  *mount)
1028 {
1029   const gchar *ret = NULL;
1030   GMountIface *iface;
1031
1032   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
1033
1034   iface = G_MOUNT_GET_IFACE (mount);
1035   if (iface->get_sort_key != NULL)
1036     ret = iface->get_sort_key (mount);
1037
1038   return ret;
1039 }