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