9acbf27ae5aaa251ee1c3170b229c018dabcd61f
[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, GUnixMount
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: optional #GCancellable object, %NULL to ignore.
333  * @callback: 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 occuring, 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: optional #GCancellable object, %NULL to ignore.
412  * @callback: 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 occuring, 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: a #GMountOperation or %NULL to avoid user interaction.
490  * @cancellable: optional #GCancellable object, %NULL to ignore.
491  * @callback: a #GAsyncReadyCallback, or %NULL.
492  * @user_data: user data passed to @callback.
493  *
494  * Unmounts a mount. This is an asynchronous operation, and is
495  * finished by calling g_mount_unmount_with_operation_finish() with the @mount 
496  * and #GAsyncResult data returned in the @callback.
497  *
498  * Since: 2.22
499  **/
500 void
501 g_mount_unmount_with_operation (GMount              *mount,
502                                 GMountUnmountFlags   flags,
503                                 GMountOperation     *mount_operation,
504                                 GCancellable        *cancellable,
505                                 GAsyncReadyCallback  callback,
506                                 gpointer             user_data)
507 {
508   GMountIface *iface;
509
510   g_return_if_fail (G_IS_MOUNT (mount));
511
512   iface = G_MOUNT_GET_IFACE (mount);
513
514   if (iface->unmount == NULL && iface->unmount_with_operation == NULL)
515     {
516       g_simple_async_report_error_in_idle (G_OBJECT (mount),
517                                            callback, user_data,
518                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
519                                            /* Translators: This is an error
520                                             * message for mount objects that
521                                             * don't implement any of unmount or unmount_with_operation. */
522                                            _("mount doesn't implement \"unmount\" or \"unmount_with_operation\""));
523
524       return;
525     }
526
527   if (iface->unmount_with_operation != NULL)
528     (* iface->unmount_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
529   else
530     (* iface->unmount) (mount, flags, cancellable, callback, user_data);
531 }
532
533 /**
534  * g_mount_unmount_with_operation_finish:
535  * @mount: a #GMount.
536  * @result: a #GAsyncResult.
537  * @error: a #GError location to store the error occuring, or %NULL to
538  *     ignore.
539  *
540  * Finishes unmounting a mount. If any errors occurred during the operation,
541  * @error will be set to contain the errors and %FALSE will be returned.
542  *
543  * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
544  *
545  * Since: 2.22
546  **/
547 gboolean
548 g_mount_unmount_with_operation_finish (GMount        *mount,
549                                        GAsyncResult  *result,
550                                        GError       **error)
551 {
552   GMountIface *iface;
553
554   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
555   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
556
557   if (G_IS_SIMPLE_ASYNC_RESULT (result))
558     {
559       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
560       if (g_simple_async_result_propagate_error (simple, error))
561         return FALSE;
562     }
563
564   iface = G_MOUNT_GET_IFACE (mount);
565   if (iface->unmount_with_operation_finish != NULL)
566     return (* iface->unmount_with_operation_finish) (mount, result, error);
567   else
568     return (* iface->unmount_finish) (mount, result, error);
569 }
570
571
572 /**
573  * g_mount_eject_with_operation:
574  * @mount: a #GMount.
575  * @flags: flags affecting the unmount if required for eject
576  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
577  * @cancellable: optional #GCancellable object, %NULL to ignore.
578  * @callback: a #GAsyncReadyCallback, or %NULL.
579  * @user_data: user data passed to @callback.
580  *
581  * Ejects a mount. This is an asynchronous operation, and is
582  * finished by calling g_mount_eject_with_operation_finish() with the @mount
583  * and #GAsyncResult data returned in the @callback.
584  *
585  * Since: 2.22
586  **/
587 void
588 g_mount_eject_with_operation (GMount              *mount,
589                               GMountUnmountFlags   flags,
590                               GMountOperation     *mount_operation,
591                               GCancellable        *cancellable,
592                               GAsyncReadyCallback  callback,
593                               gpointer             user_data)
594 {
595   GMountIface *iface;
596
597   g_return_if_fail (G_IS_MOUNT (mount));
598
599   iface = G_MOUNT_GET_IFACE (mount);
600
601   if (iface->eject == NULL && iface->eject_with_operation == NULL)
602     {
603       g_simple_async_report_error_in_idle (G_OBJECT (mount),
604                                            callback, user_data,
605                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
606                                            /* Translators: This is an error
607                                             * message for mount objects that
608                                             * don't implement any of eject or eject_with_operation. */
609                                            _("mount doesn't implement \"eject\" or \"eject_with_operation\""));
610       return;
611     }
612
613   if (iface->eject_with_operation != NULL)
614     (* iface->eject_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
615   else
616     (* iface->eject) (mount, flags, cancellable, callback, user_data);
617 }
618
619 /**
620  * g_mount_eject_with_operation_finish:
621  * @mount: a #GMount.
622  * @result: a #GAsyncResult.
623  * @error: a #GError location to store the error occuring, or %NULL to
624  *     ignore.
625  *
626  * Finishes ejecting a mount. If any errors occurred during the operation,
627  * @error will be set to contain the errors and %FALSE will be returned.
628  *
629  * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
630  *
631  * Since: 2.22
632  **/
633 gboolean
634 g_mount_eject_with_operation_finish (GMount        *mount,
635                                      GAsyncResult  *result,
636                                      GError       **error)
637 {
638   GMountIface *iface;
639
640   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
641   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
642
643   if (G_IS_SIMPLE_ASYNC_RESULT (result))
644     {
645       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
646       if (g_simple_async_result_propagate_error (simple, error))
647         return FALSE;
648     }
649
650   iface = G_MOUNT_GET_IFACE (mount);
651   if (iface->eject_with_operation_finish != NULL)
652     return (* iface->eject_with_operation_finish) (mount, result, error);
653   else
654     return (* iface->eject_finish) (mount, result, error);
655 }
656
657 /**
658  * g_mount_remount:
659  * @mount: a #GMount.
660  * @flags: flags affecting the operation
661  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
662  * @cancellable: optional #GCancellable object, %NULL to ignore.
663  * @callback: a #GAsyncReadyCallback, or %NULL.
664  * @user_data: user data passed to @callback.
665  * 
666  * Remounts a mount. This is an asynchronous operation, and is 
667  * finished by calling g_mount_remount_finish() with the @mount 
668  * and #GAsyncResults data returned in the @callback.
669  *
670  * Remounting is useful when some setting affecting the operation
671  * of the volume has been changed, as these may need a remount to
672  * take affect. While this is semantically equivalent with unmounting
673  * and then remounting not all backends might need to actually be
674  * unmounted.
675  **/
676 void
677 g_mount_remount (GMount              *mount,
678                  GMountMountFlags     flags,
679                  GMountOperation     *mount_operation,
680                  GCancellable        *cancellable,
681                  GAsyncReadyCallback  callback,
682                  gpointer             user_data)
683 {
684   GMountIface *iface;
685
686   g_return_if_fail (G_IS_MOUNT (mount));
687   
688   iface = G_MOUNT_GET_IFACE (mount);
689
690   if (iface->remount == NULL)
691     { 
692       g_simple_async_report_error_in_idle (G_OBJECT (mount),
693                                            callback, user_data,
694                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
695                                            /* Translators: This is an error
696                                             * message for mount objects that
697                                             * don't implement remount. */
698                                            _("mount doesn't implement \"remount\""));
699       
700       return;
701     }
702   
703   (* iface->remount) (mount, flags, mount_operation, cancellable, callback, user_data);
704 }
705
706 /**
707  * g_mount_remount_finish:
708  * @mount: a #GMount.
709  * @result: a #GAsyncResult.
710  * @error: a #GError location to store the error occuring, or %NULL to 
711  *     ignore.
712  * 
713  * Finishes remounting a mount. If any errors occurred during the operation, 
714  * @error will be set to contain the errors and %FALSE will be returned.
715  * 
716  * Returns: %TRUE if the mount was successfully remounted. %FALSE otherwise.
717  **/
718 gboolean
719 g_mount_remount_finish (GMount        *mount,
720                         GAsyncResult  *result,
721                         GError       **error)
722 {
723   GMountIface *iface;
724
725   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
726   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
727
728   if (G_IS_SIMPLE_ASYNC_RESULT (result))
729     {
730       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
731       if (g_simple_async_result_propagate_error (simple, error))
732         return FALSE;
733     }
734   
735   iface = G_MOUNT_GET_IFACE (mount);
736   return (* iface->remount_finish) (mount, result, error);
737 }
738
739 /**
740  * g_mount_guess_content_type:
741  * @mount: a #GMount
742  * @force_rescan: Whether to force a rescan of the content. 
743  *     Otherwise a cached result will be used if available
744  * @cancellable: optional #GCancellable object, %NULL to ignore
745  * @callback: a #GAsyncReadyCallback
746  * @user_data: user data passed to @callback
747  * 
748  * Tries to guess the type of content stored on @mount. Returns one or
749  * more textual identifiers of well-known content types (typically
750  * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 
751  * memory cards. See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
752  * specification for more on x-content types.
753  *
754  * This is an asynchronous operation (see
755  * g_mount_guess_content_type_sync() for the synchronous version), and
756  * is finished by calling g_mount_guess_content_type_finish() with the
757  * @mount and #GAsyncResult data returned in the @callback.
758  *
759  * Since: 2.18
760  */
761 void
762 g_mount_guess_content_type (GMount              *mount,
763                             gboolean             force_rescan,
764                             GCancellable        *cancellable,
765                             GAsyncReadyCallback  callback,
766                             gpointer             user_data)
767 {
768   GMountIface *iface;
769
770   g_return_if_fail (G_IS_MOUNT (mount));
771
772   iface = G_MOUNT_GET_IFACE (mount);
773
774   if (iface->guess_content_type == NULL)
775     {
776       g_simple_async_report_error_in_idle (G_OBJECT (mount),
777                                            callback, user_data,
778                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
779                                            /* Translators: This is an error
780                                             * message for mount objects that
781                                             * don't implement content type guessing. */
782                                            _("mount doesn't implement content type guessing"));
783
784       return;
785     }
786   
787   (* iface->guess_content_type) (mount, force_rescan, cancellable, callback, user_data);
788 }
789
790 /**
791  * g_mount_guess_content_type_finish:
792  * @mount: a #GMount
793  * @result: a #GAsyncResult
794  * @error: a #GError location to store the error occuring, or %NULL to 
795  *     ignore
796  * 
797  * Finishes guessing content types of @mount. If any errors occured
798  * during the operation, @error will be set to contain the errors and
799  * %FALSE will be returned. In particular, you may get an 
800  * %G_IO_ERROR_NOT_SUPPORTED if the mount does not support content 
801  * guessing.
802  * 
803  * Returns: (transfer full) (element-type utf8): a %NULL-terminated array of content types or %NULL on error. 
804  *     Caller should free this array with g_strfreev() when done with it.
805  *
806  * Since: 2.18
807  **/
808 gchar **
809 g_mount_guess_content_type_finish (GMount        *mount,
810                                    GAsyncResult  *result,
811                                    GError       **error)
812 {
813   GMountIface *iface;
814
815   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
816   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
817
818   if (G_IS_SIMPLE_ASYNC_RESULT (result))
819     {
820       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
821       if (g_simple_async_result_propagate_error (simple, error))
822         return NULL;
823     }
824   
825   iface = G_MOUNT_GET_IFACE (mount);
826   return (* iface->guess_content_type_finish) (mount, result, error);
827 }
828
829 /**
830  * g_mount_guess_content_type_sync:
831  * @mount: a #GMount
832  * @force_rescan: Whether to force a rescan of the content.
833  *     Otherwise a cached result will be used if available
834  * @cancellable: optional #GCancellable object, %NULL to ignore
835  * @error: a #GError location to store the error occuring, or %NULL to
836  *     ignore
837  *
838  * Tries to guess the type of content stored on @mount. Returns one or
839  * more textual identifiers of well-known content types (typically
840  * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 
841  * memory cards. See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
842  * specification for more on x-content types.
843  *
844  * This is an synchronous operation and as such may block doing IO;
845  * see g_mount_guess_content_type() for the asynchronous version.
846  *
847  * Returns: (transfer full) (element-type utf8): a %NULL-terminated array of content types or %NULL on error.
848  *     Caller should free this array with g_strfreev() when done with it.
849  *
850  * Since: 2.18
851  */
852 char **
853 g_mount_guess_content_type_sync (GMount              *mount,
854                                  gboolean             force_rescan,
855                                  GCancellable        *cancellable,
856                                  GError             **error)
857 {
858   GMountIface *iface;
859
860   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
861
862   iface = G_MOUNT_GET_IFACE (mount);
863
864   if (iface->guess_content_type_sync == NULL)
865     {
866       g_set_error_literal (error,
867                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
868                            /* Translators: This is an error
869                             * message for mount objects that
870                             * don't implement content type guessing. */
871                            _("mount doesn't implement synchronous content type guessing"));
872
873       return NULL;
874     }
875
876   return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error);
877 }
878
879 G_LOCK_DEFINE_STATIC (priv_lock);
880
881 /* only access this structure when holding priv_lock */
882 typedef struct
883 {
884   gint shadow_ref_count;
885 } GMountPrivate;
886
887 static void
888 free_private (GMountPrivate *private)
889 {
890   G_LOCK (priv_lock);
891   g_free (private);
892   G_UNLOCK (priv_lock);
893 }
894
895 /* may only be called when holding priv_lock */
896 static GMountPrivate *
897 get_private (GMount *mount)
898 {
899   GMountPrivate *private;
900
901   private = g_object_get_data (G_OBJECT (mount), "g-mount-private");
902   if (G_LIKELY (private != NULL))
903     goto out;
904
905   private = g_new0 (GMountPrivate, 1);
906   g_object_set_data_full (G_OBJECT (mount),
907                           "g-mount-private",
908                           private,
909                           (GDestroyNotify) free_private);
910
911  out:
912   return private;
913 }
914
915 /**
916  * g_mount_is_shadowed:
917  * @mount: A #GMount.
918  *
919  * Determines if @mount is shadowed. Applications or libraries should
920  * avoid displaying @mount in the user interface if it is shadowed.
921  *
922  * A mount is said to be shadowed if there exists one or more user
923  * visible objects (currently #GMount objects) with a root that is
924  * inside the root of @mount.
925  *
926  * One application of shadow mounts is when exposing a single file
927  * system that is used to address several logical volumes. In this
928  * situation, a #GVolumeMonitor implementation would create two
929  * #GVolume objects (for example, one for the camera functionality of
930  * the device and one for a SD card reader on the device) with
931  * activation URIs <literal>gphoto2://[usb:001,002]/store1/</literal>
932  * and <literal>gphoto2://[usb:001,002]/store2/</literal>. When the
933  * underlying mount (with root
934  * <literal>gphoto2://[usb:001,002]/</literal>) is mounted, said
935  * #GVolumeMonitor implementation would create two #GMount objects
936  * (each with their root matching the corresponding volume activation
937  * root) that would shadow the original mount.
938  *
939  * The proxy monitor in GVfs 2.26 and later, automatically creates and
940  * manage shadow mounts (and shadows the underlying mount) if the
941  * activation root on a #GVolume is set.
942  *
943  * Returns: %TRUE if @mount is shadowed.
944  *
945  * Since: 2.20
946  **/
947 gboolean
948 g_mount_is_shadowed (GMount *mount)
949 {
950   GMountPrivate *priv;
951   gboolean ret;
952
953   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
954
955   G_LOCK (priv_lock);
956   priv = get_private (mount);
957   ret = (priv->shadow_ref_count > 0);
958   G_UNLOCK (priv_lock);
959
960   return ret;
961 }
962
963 /**
964  * g_mount_shadow:
965  * @mount: A #GMount.
966  *
967  * Increments the shadow count on @mount. Usually used by
968  * #GVolumeMonitor implementations when creating a shadow mount for
969  * @mount, see g_mount_is_shadowed() for more information. The caller
970  * will need to emit the #GMount::changed signal on @mount manually.
971  *
972  * Since: 2.20
973  **/
974 void
975 g_mount_shadow (GMount *mount)
976 {
977   GMountPrivate *priv;
978
979   g_return_if_fail (G_IS_MOUNT (mount));
980
981   G_LOCK (priv_lock);
982   priv = get_private (mount);
983   priv->shadow_ref_count += 1;
984   G_UNLOCK (priv_lock);
985 }
986
987 /**
988  * g_mount_unshadow:
989  * @mount: A #GMount.
990  *
991  * Decrements the shadow count on @mount. Usually used by
992  * #GVolumeMonitor implementations when destroying a shadow mount for
993  * @mount, see g_mount_is_shadowed() for more information. The caller
994  * will need to emit the #GMount::changed signal on @mount manually.
995  *
996  * Since: 2.20
997  **/
998 void
999 g_mount_unshadow (GMount *mount)
1000 {
1001   GMountPrivate *priv;
1002
1003   g_return_if_fail (G_IS_MOUNT (mount));
1004
1005   G_LOCK (priv_lock);
1006   priv = get_private (mount);
1007   priv->shadow_ref_count -= 1;
1008   if (priv->shadow_ref_count < 0)
1009     g_warning ("Shadow ref count on GMount is negative");
1010   G_UNLOCK (priv_lock);
1011 }