2 * Copyright 2015 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 * Author: Matthias Clasen <mclasen@redhat.com>
32 #define STDIN_FILENO 0
40 static int outstanding_mounts
= 0;
41 static GMainLoop
*main_loop
;
42 static GVolumeMonitor
*volume_monitor
;
44 static gboolean mount_mountable
= FALSE
;
45 static gboolean mount_unmount
= FALSE
;
46 static gboolean mount_eject
= FALSE
;
47 static gboolean force
= FALSE
;
48 static gboolean anonymous
= FALSE
;
49 static gboolean mount_list
= FALSE
;
50 static gboolean extra_detail
= FALSE
;
51 static gboolean mount_monitor
= FALSE
;
52 static gboolean tcrypt_hidden
= FALSE
;
53 static gboolean tcrypt_system
= FALSE
;
54 static guint tcrypt_pim
= 0;
55 static const char *unmount_scheme
= NULL
;
56 static const char *mount_device_file
= NULL
;
57 static const char *stop_device_file
= NULL
;
58 static gboolean success
= TRUE
;
61 static const GOptionEntry entries
[] =
63 { "mountable", 'm', 0, G_OPTION_ARG_NONE
, &mount_mountable
, N_("Mount as mountable"), NULL
},
64 { "device", 'd', 0, G_OPTION_ARG_STRING
, &mount_device_file
, N_("Mount volume with device file"), N_("DEVICE") },
65 { "unmount", 'u', 0, G_OPTION_ARG_NONE
, &mount_unmount
, N_("Unmount"), NULL
},
66 { "eject", 'e', 0, G_OPTION_ARG_NONE
, &mount_eject
, N_("Eject"), NULL
},
67 { "stop", 't', 0, G_OPTION_ARG_STRING
, &stop_device_file
, N_("Stop drive with device file"), N_("DEVICE") },
68 { "unmount-scheme", 's', 0, G_OPTION_ARG_STRING
, &unmount_scheme
, N_("Unmount all mounts with the given scheme"), N_("SCHEME") },
69 { "force", 'f', 0, G_OPTION_ARG_NONE
, &force
, N_("Ignore outstanding file operations when unmounting or ejecting"), NULL
},
70 { "anonymous", 'a', 0, G_OPTION_ARG_NONE
, &anonymous
, N_("Use an anonymous user when authenticating"), NULL
},
71 /* Translator: List here is a verb as in 'List all mounts' */
72 { "list", 'l', 0, G_OPTION_ARG_NONE
, &mount_list
, N_("List"), NULL
},
73 { "monitor", 'o', 0, G_OPTION_ARG_NONE
, &mount_monitor
, N_("Monitor events"), NULL
},
74 { "detail", 'i', 0, G_OPTION_ARG_NONE
, &extra_detail
, N_("Show extra information"), NULL
},
75 { "tcrypt-pim", 0, 0, G_OPTION_ARG_INT
, &tcrypt_pim
, N_("The numeric PIM when unlocking a VeraCrypt volume"), N_("PIM")},
76 { "tcrypt-hidden", 0, 0, G_OPTION_ARG_NONE
, &tcrypt_hidden
, N_("Mount a TCRYPT hidden volume"), NULL
},
77 { "tcrypt-system", 0, 0, G_OPTION_ARG_NONE
, &tcrypt_system
, N_("Mount a TCRYPT system volume"), NULL
},
82 prompt_for (const char *prompt
, const char *default_value
, gboolean echo
)
85 struct termios term_attr
;
87 gboolean restore_flags
;
92 if (default_value
&& *default_value
!= 0)
93 g_print ("%s [%s]: ", prompt
, default_value
);
95 g_print ("%s: ", prompt
);
100 restore_flags
= FALSE
;
101 if (!echo
&& tcgetattr (STDIN_FILENO
, &term_attr
) == 0)
103 old_flags
= term_attr
.c_lflag
;
104 term_attr
.c_lflag
&= ~ECHO
;
105 restore_flags
= TRUE
;
107 if (tcsetattr (STDIN_FILENO
, TCSAFLUSH
, &term_attr
) != 0)
108 g_print ("Warning! Password will be echoed");
113 fgets(data
, sizeof (data
), stdin
);
115 #ifdef HAVE_TERMIOS_H
118 term_attr
.c_lflag
= old_flags
;
119 tcsetattr (STDIN_FILENO
, TCSAFLUSH
, &term_attr
);
129 if (data
[len
-1] == '\n')
135 if (*data
== 0 && default_value
)
136 return g_strdup (default_value
);
137 return g_strdup (data
);
141 ask_password_cb (GMountOperation
*op
,
143 const char *default_user
,
144 const char *default_domain
,
145 GAskPasswordFlags flags
)
147 if ((flags
& G_ASK_PASSWORD_ANONYMOUS_SUPPORTED
) && anonymous
)
149 g_mount_operation_set_anonymous (op
, TRUE
);
154 g_print ("%s\n", message
);
156 if (flags
& G_ASK_PASSWORD_NEED_USERNAME
)
158 s
= prompt_for ("User", default_user
, TRUE
);
161 g_mount_operation_set_username (op
, s
);
165 if (flags
& G_ASK_PASSWORD_NEED_DOMAIN
)
167 s
= prompt_for ("Domain", default_domain
, TRUE
);
170 g_mount_operation_set_domain (op
, s
);
174 if (flags
& G_ASK_PASSWORD_NEED_PASSWORD
)
176 s
= prompt_for ("Password", NULL
, FALSE
);
179 g_mount_operation_set_password (op
, s
);
184 if (flags
& G_ASK_PASSWORD_TCRYPT
)
187 g_mount_operation_set_pim (op
, tcrypt_pim
);
189 g_mount_operation_set_is_tcrypt_hidden_volume (op
, TRUE
);
191 g_mount_operation_set_is_tcrypt_system_volume (op
, TRUE
);
194 /* Only try anonymous access once. */
196 GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op
), "state")) == MOUNT_OP_ASKED
)
198 g_object_set_data (G_OBJECT (op
), "state", GINT_TO_POINTER (MOUNT_OP_ABORTED
));
199 g_mount_operation_reply (op
, G_MOUNT_OPERATION_ABORTED
);
203 g_object_set_data (G_OBJECT (op
), "state", GINT_TO_POINTER (MOUNT_OP_ASKED
));
204 g_mount_operation_reply (op
, G_MOUNT_OPERATION_HANDLED
);
210 g_mount_operation_reply (op
, G_MOUNT_OPERATION_ABORTED
);
214 ask_question_cb (GMountOperation
*op
,
219 char **ptr
= choices
;
223 g_print ("%s\n", message
);
228 g_print ("[%d] %s\n", i
, *ptr
++);
232 s
= prompt_for ("Choice", NULL
, TRUE
);
237 if (choice
> 0 && choice
< i
)
239 g_mount_operation_set_choice (op
, choice
- 1);
240 g_mount_operation_reply (op
, G_MOUNT_OPERATION_HANDLED
);
247 g_mount_operation_reply (op
, G_MOUNT_OPERATION_ABORTED
);
251 mount_mountable_done_cb (GObject
*object
,
256 GError
*error
= NULL
;
257 GMountOperation
*op
= user_data
;
259 target
= g_file_mount_mountable_finish (G_FILE (object
), res
, &error
);
264 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op
), "state")) == MOUNT_OP_ABORTED
)
265 print_file_error (G_FILE (object
), _("Anonymous access denied"));
266 else if (!g_error_matches (error
, G_IO_ERROR
, G_IO_ERROR_FAILED_HANDLED
))
267 print_file_error (G_FILE (object
), error
->message
);
269 g_error_free (error
);
272 g_object_unref (target
);
276 outstanding_mounts
--;
278 if (outstanding_mounts
== 0)
279 g_main_loop_quit (main_loop
);
283 mount_done_cb (GObject
*object
,
288 GError
*error
= NULL
;
289 GMountOperation
*op
= user_data
;
291 succeeded
= g_file_mount_enclosing_volume_finish (G_FILE (object
), res
, &error
);
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op
), "state")) == MOUNT_OP_ABORTED
)
297 print_file_error (G_FILE (object
), _("Anonymous access denied"));
298 else if (!g_error_matches (error
, G_IO_ERROR
, G_IO_ERROR_FAILED_HANDLED
))
299 print_file_error (G_FILE (object
), error
->message
);
301 g_error_free (error
);
306 outstanding_mounts
--;
308 if (outstanding_mounts
== 0)
309 g_main_loop_quit (main_loop
);
312 static GMountOperation
*
317 op
= g_mount_operation_new ();
319 g_object_set_data (G_OBJECT (op
), "state", GINT_TO_POINTER (MOUNT_OP_NONE
));
321 g_signal_connect (op
, "ask_password", G_CALLBACK (ask_password_cb
), NULL
);
322 g_signal_connect (op
, "ask_question", G_CALLBACK (ask_question_cb
), NULL
);
324 /* TODO: we *should* also connect to the "aborted" signal but since the
325 * main thread is blocked handling input we won't get that signal anyway...
340 op
= new_mount_op ();
343 g_file_mount_mountable (file
, 0, op
, NULL
, mount_mountable_done_cb
, op
);
345 g_file_mount_enclosing_volume (file
, 0, op
, NULL
, mount_done_cb
, op
);
347 outstanding_mounts
++;
351 unmount_done_cb (GObject
*object
,
356 GError
*error
= NULL
;
357 GFile
*file
= G_FILE (user_data
);
359 succeeded
= g_mount_unmount_with_operation_finish (G_MOUNT (object
), res
, &error
);
361 g_object_unref (G_MOUNT (object
));
365 print_file_error (file
, error
->message
);
367 g_error_free (error
);
370 g_object_unref (file
);
372 outstanding_mounts
--;
374 if (outstanding_mounts
== 0)
375 g_main_loop_quit (main_loop
);
379 unmount (GFile
*file
)
382 GError
*error
= NULL
;
383 GMountOperation
*mount_op
;
384 GMountUnmountFlags flags
;
389 mount
= g_file_find_enclosing_mount (file
, NULL
, &error
);
392 print_file_error (file
, error
->message
);
394 g_error_free (error
);
398 mount_op
= new_mount_op ();
399 flags
= force
? G_MOUNT_UNMOUNT_FORCE
: G_MOUNT_UNMOUNT_NONE
;
400 g_mount_unmount_with_operation (mount
, flags
, mount_op
, NULL
, unmount_done_cb
, g_object_ref (file
));
401 g_object_unref (mount_op
);
403 outstanding_mounts
++;
407 eject_done_cb (GObject
*object
,
412 GError
*error
= NULL
;
413 GFile
*file
= G_FILE (user_data
);
415 succeeded
= g_mount_eject_with_operation_finish (G_MOUNT (object
), res
, &error
);
417 g_object_unref (G_MOUNT (object
));
421 print_file_error (file
, error
->message
);
423 g_error_free (error
);
426 g_object_unref (file
);
428 outstanding_mounts
--;
430 if (outstanding_mounts
== 0)
431 g_main_loop_quit (main_loop
);
438 GError
*error
= NULL
;
439 GMountOperation
*mount_op
;
440 GMountUnmountFlags flags
;
445 mount
= g_file_find_enclosing_mount (file
, NULL
, &error
);
448 print_file_error (file
, error
->message
);
450 g_error_free (error
);
454 mount_op
= new_mount_op ();
455 flags
= force
? G_MOUNT_UNMOUNT_FORCE
: G_MOUNT_UNMOUNT_NONE
;
456 g_mount_eject_with_operation (mount
, flags
, mount_op
, NULL
, eject_done_cb
, g_object_ref (file
));
457 g_object_unref (mount_op
);
459 outstanding_mounts
++;
463 stop_with_device_file_cb (GObject
*object
,
467 GError
*error
= NULL
;
468 gchar
*device_path
= user_data
;
470 if (!g_drive_stop_finish (G_DRIVE (object
), res
, &error
))
472 print_error ("%s: %s", device_path
, error
->message
);
473 g_error_free (error
);
477 g_free (device_path
);
479 outstanding_mounts
--;
481 if (outstanding_mounts
== 0)
482 g_main_loop_quit (main_loop
);
486 stop_with_device_file (const char *device_file
)
491 drives
= g_volume_monitor_get_connected_drives (volume_monitor
);
492 for (l
= drives
; l
!= NULL
; l
= l
->next
)
494 GDrive
*drive
= G_DRIVE (l
->data
);
497 id
= g_drive_get_identifier (drive
, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE
);
498 if (g_strcmp0 (id
, device_file
) == 0)
501 GMountUnmountFlags flags
;
503 op
= new_mount_op ();
504 flags
= force
? G_MOUNT_UNMOUNT_FORCE
: G_MOUNT_UNMOUNT_NONE
;
509 stop_with_device_file_cb
,
510 g_steal_pointer (&id
));
513 outstanding_mounts
++;
518 g_list_free_full (drives
, g_object_unref
);
520 if (outstanding_mounts
== 0)
522 print_error ("%s: %s", device_file
, _("No drive for device file"));
528 iterate_gmain_timeout_function (gpointer data
)
530 g_main_loop_quit (main_loop
);
537 g_timeout_add (500, iterate_gmain_timeout_function
, NULL
);
538 g_main_loop_run (main_loop
);
542 show_themed_icon_names (GThemedIcon
*icon
, gboolean symbolic
, int indent
)
547 g_print ("%*s%sthemed icons:", indent
, " ", symbolic
? "symbolic " : "");
551 g_object_get (icon
, "names", &names
, NULL
);
553 for (iter
= names
; *iter
; iter
++)
554 g_print (" [%s]", *iter
);
560 /* don't copy-paste this code */
562 get_type_name (gpointer object
)
564 const char *type_name
;
567 type_name
= g_type_name (G_TYPE_FROM_INSTANCE (object
));
568 if (strcmp ("GProxyDrive", type_name
) == 0)
570 ret
= g_strdup_printf ("%s (%s)",
572 (const char *) g_object_get_data (G_OBJECT (object
),
573 "g-proxy-drive-volume-monitor-name"));
575 else if (strcmp ("GProxyVolume", type_name
) == 0)
577 ret
= g_strdup_printf ("%s (%s)",
579 (const char *) g_object_get_data (G_OBJECT (object
),
580 "g-proxy-volume-volume-monitor-name"));
582 else if (strcmp ("GProxyMount", type_name
) == 0)
584 ret
= g_strdup_printf ("%s (%s)",
586 (const char *) g_object_get_data (G_OBJECT (object
),
587 "g-proxy-mount-volume-monitor-name"));
589 else if (strcmp ("GProxyShadowMount", type_name
) == 0)
591 ret
= g_strdup_printf ("%s (%s)",
593 (const char *) g_object_get_data (G_OBJECT (object
),
594 "g-proxy-shadow-mount-volume-monitor-name"));
598 ret
= g_strdup (type_name
);
605 list_mounts (GList
*mounts
,
607 gboolean only_with_no_volume
)
613 char *name
, *uuid
, *uri
;
614 GFile
*root
, *default_location
;
616 char **x_content_types
;
618 const gchar
*sort_key
;
620 for (c
= 0, l
= mounts
; l
!= NULL
; l
= l
->next
, c
++)
622 mount
= (GMount
*) l
->data
;
624 if (only_with_no_volume
)
626 volume
= g_mount_get_volume (mount
);
629 g_object_unref (volume
);
634 name
= g_mount_get_name (mount
);
635 root
= g_mount_get_root (mount
);
636 uri
= g_file_get_uri (root
);
638 g_print ("%*sMount(%d): %s -> %s\n", indent
, "", c
, name
, uri
);
640 type_name
= get_type_name (mount
);
641 g_print ("%*sType: %s\n", indent
+2, "", type_name
);
646 uuid
= g_mount_get_uuid (mount
);
648 g_print ("%*suuid=%s\n", indent
+ 2, "", uuid
);
650 default_location
= g_mount_get_default_location (mount
);
651 if (default_location
)
653 char *loc_uri
= g_file_get_uri (default_location
);
654 g_print ("%*sdefault_location=%s\n", indent
+ 2, "", loc_uri
);
656 g_object_unref (default_location
);
659 icon
= g_mount_get_icon (mount
);
662 if (G_IS_THEMED_ICON (icon
))
663 show_themed_icon_names (G_THEMED_ICON (icon
), FALSE
, indent
+ 2);
665 g_object_unref (icon
);
668 icon
= g_mount_get_symbolic_icon (mount
);
671 if (G_IS_THEMED_ICON (icon
))
672 show_themed_icon_names (G_THEMED_ICON (icon
), TRUE
, indent
+ 2);
674 g_object_unref (icon
);
677 x_content_types
= g_mount_guess_content_type_sync (mount
, FALSE
, NULL
, NULL
);
678 if (x_content_types
!= NULL
&& g_strv_length (x_content_types
) > 0)
681 g_print ("%*sx_content_types:", indent
+ 2, "");
682 for (n
= 0; x_content_types
[n
] != NULL
; n
++)
683 g_print (" %s", x_content_types
[n
]);
686 g_strfreev (x_content_types
);
688 g_print ("%*scan_unmount=%d\n", indent
+ 2, "", g_mount_can_unmount (mount
));
689 g_print ("%*scan_eject=%d\n", indent
+ 2, "", g_mount_can_eject (mount
));
690 g_print ("%*sis_shadowed=%d\n", indent
+ 2, "", g_mount_is_shadowed (mount
));
691 sort_key
= g_mount_get_sort_key (mount
);
692 if (sort_key
!= NULL
)
693 g_print ("%*ssort_key=%s\n", indent
+ 2, "", sort_key
);
697 g_object_unref (root
);
704 list_volumes (GList
*volumes
,
706 gboolean only_with_no_drive
)
715 GFile
*activation_root
;
719 const gchar
*sort_key
;
721 for (c
= 0, l
= volumes
; l
!= NULL
; l
= l
->next
, c
++)
723 volume
= (GVolume
*) l
->data
;
725 if (only_with_no_drive
)
727 drive
= g_volume_get_drive (volume
);
730 g_object_unref (drive
);
735 name
= g_volume_get_name (volume
);
737 g_print ("%*sVolume(%d): %s\n", indent
, "", c
, name
);
740 type_name
= get_type_name (volume
);
741 g_print ("%*sType: %s\n", indent
+2, "", type_name
);
746 ids
= g_volume_enumerate_identifiers (volume
);
747 if (ids
&& ids
[0] != NULL
)
749 g_print ("%*sids:\n", indent
+2, "");
750 for (i
= 0; ids
[i
] != NULL
; i
++)
752 char *id
= g_volume_get_identifier (volume
,
754 g_print ("%*s %s: '%s'\n", indent
+2, "", ids
[i
], id
);
760 uuid
= g_volume_get_uuid (volume
);
762 g_print ("%*suuid=%s\n", indent
+ 2, "", uuid
);
763 activation_root
= g_volume_get_activation_root (volume
);
767 uri
= g_file_get_uri (activation_root
);
768 g_print ("%*sactivation_root=%s\n", indent
+ 2, "", uri
);
770 g_object_unref (activation_root
);
772 icon
= g_volume_get_icon (volume
);
775 if (G_IS_THEMED_ICON (icon
))
776 show_themed_icon_names (G_THEMED_ICON (icon
), FALSE
, indent
+ 2);
778 g_object_unref (icon
);
781 icon
= g_volume_get_symbolic_icon (volume
);
784 if (G_IS_THEMED_ICON (icon
))
785 show_themed_icon_names (G_THEMED_ICON (icon
), TRUE
, indent
+ 2);
787 g_object_unref (icon
);
790 g_print ("%*scan_mount=%d\n", indent
+ 2, "", g_volume_can_mount (volume
));
791 g_print ("%*scan_eject=%d\n", indent
+ 2, "", g_volume_can_eject (volume
));
792 g_print ("%*sshould_automount=%d\n", indent
+ 2, "", g_volume_should_automount (volume
));
793 sort_key
= g_volume_get_sort_key (volume
);
794 if (sort_key
!= NULL
)
795 g_print ("%*ssort_key=%s\n", indent
+ 2, "", sort_key
);
799 mount
= g_volume_get_mount (volume
);
802 mounts
= g_list_prepend (NULL
, mount
);
803 list_mounts (mounts
, indent
+ 2, FALSE
);
804 g_list_free (mounts
);
805 g_object_unref (mount
);
811 list_drives (GList
*drives
,
821 const gchar
*sort_key
;
823 for (c
= 0, l
= drives
; l
!= NULL
; l
= l
->next
, c
++)
825 drive
= (GDrive
*) l
->data
;
826 name
= g_drive_get_name (drive
);
828 g_print ("%*sDrive(%d): %s\n", indent
, "", c
, name
);
831 type_name
= get_type_name (drive
);
832 g_print ("%*sType: %s\n", indent
+2, "", type_name
);
837 GEnumValue
*enum_value
;
840 ids
= g_drive_enumerate_identifiers (drive
);
841 if (ids
&& ids
[0] != NULL
)
843 g_print ("%*sids:\n", indent
+2, "");
844 for (i
= 0; ids
[i
] != NULL
; i
++)
846 char *id
= g_drive_get_identifier (drive
,
848 g_print ("%*s %s: '%s'\n", indent
+2, "", ids
[i
], id
);
854 icon
= g_drive_get_icon (drive
);
857 if (G_IS_THEMED_ICON (icon
))
858 show_themed_icon_names (G_THEMED_ICON (icon
), FALSE
, indent
+ 2);
859 g_object_unref (icon
);
862 icon
= g_drive_get_symbolic_icon (drive
);
865 if (G_IS_THEMED_ICON (icon
))
866 show_themed_icon_names (G_THEMED_ICON (icon
), TRUE
, indent
+ 2);
868 g_object_unref (icon
);
871 g_print ("%*sis_removable=%d\n", indent
+ 2, "", g_drive_is_removable (drive
));
872 g_print ("%*sis_media_removable=%d\n", indent
+ 2, "", g_drive_is_media_removable (drive
));
873 g_print ("%*shas_media=%d\n", indent
+ 2, "", g_drive_has_media (drive
));
874 g_print ("%*sis_media_check_automatic=%d\n", indent
+ 2, "", g_drive_is_media_check_automatic (drive
));
875 g_print ("%*scan_poll_for_media=%d\n", indent
+ 2, "", g_drive_can_poll_for_media (drive
));
876 g_print ("%*scan_eject=%d\n", indent
+ 2, "", g_drive_can_eject (drive
));
877 g_print ("%*scan_start=%d\n", indent
+ 2, "", g_drive_can_start (drive
));
878 g_print ("%*scan_stop=%d\n", indent
+ 2, "", g_drive_can_stop (drive
));
881 klass
= g_type_class_ref (G_TYPE_DRIVE_START_STOP_TYPE
);
884 enum_value
= g_enum_get_value (klass
, g_drive_get_start_stop_type (drive
));
885 g_print ("%*sstart_stop_type=%s\n", indent
+ 2, "",
886 enum_value
!= NULL
? enum_value
->value_nick
: "UNKNOWN");
887 g_type_class_unref (klass
);
890 sort_key
= g_drive_get_sort_key (drive
);
891 if (sort_key
!= NULL
)
892 g_print ("%*ssort_key=%s\n", indent
+ 2, "", sort_key
);
894 volumes
= g_drive_get_volumes (drive
);
895 list_volumes (volumes
, indent
+ 2, FALSE
);
896 g_list_free_full (volumes
, g_object_unref
);
902 list_monitor_items (void)
904 GList
*drives
, *volumes
, *mounts
;
906 /* populate gvfs network mounts */
909 drives
= g_volume_monitor_get_connected_drives (volume_monitor
);
910 list_drives (drives
, 0);
911 g_list_free_full (drives
, g_object_unref
);
913 volumes
= g_volume_monitor_get_volumes (volume_monitor
);
914 list_volumes (volumes
, 0, TRUE
);
915 g_list_free_full (volumes
, g_object_unref
);
917 mounts
= g_volume_monitor_get_mounts (volume_monitor
);
918 list_mounts (mounts
, 0, TRUE
);
919 g_list_free_full (mounts
, g_object_unref
);
923 unmount_all_with_scheme (const char *scheme
)
928 /* populate gvfs network mounts */
931 mounts
= g_volume_monitor_get_mounts (volume_monitor
);
932 for (l
= mounts
; l
!= NULL
; l
= l
->next
) {
933 GMount
*mount
= G_MOUNT (l
->data
);
936 root
= g_mount_get_root (mount
);
937 if (g_file_has_uri_scheme (root
, scheme
)) {
940 g_object_unref (root
);
942 g_list_free_full (mounts
, g_object_unref
);
946 mount_with_device_file_cb (GObject
*object
,
952 GError
*error
= NULL
;
953 gchar
*device_path
= (gchar
*)user_data
;
955 volume
= G_VOLUME (object
);
957 succeeded
= g_volume_mount_finish (volume
, res
, &error
);
961 print_error ("%s: %s", device_path
, error
->message
);
962 g_error_free (error
);
971 mount
= g_volume_get_mount (volume
);
972 root
= g_mount_get_root (mount
);
973 mount_path
= g_file_get_path (root
);
975 g_print (_("Mounted %s at %s\n"), device_path
, mount_path
);
977 g_object_unref (mount
);
978 g_object_unref (root
);
982 g_free (device_path
);
984 outstanding_mounts
--;
986 if (outstanding_mounts
== 0)
987 g_main_loop_quit (main_loop
);
991 mount_with_device_file (const char *device_file
)
996 volumes
= g_volume_monitor_get_volumes (volume_monitor
);
997 for (l
= volumes
; l
!= NULL
; l
= l
->next
)
999 GVolume
*volume
= G_VOLUME (l
->data
);
1002 id
= g_volume_get_identifier (volume
, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE
);
1003 if (g_strcmp0 (id
, device_file
) == 0)
1005 GMountOperation
*op
;
1007 op
= new_mount_op ();
1009 g_volume_mount (volume
,
1013 mount_with_device_file_cb
,
1016 g_object_unref (op
);
1018 outstanding_mounts
++;
1023 g_list_free_full (volumes
, g_object_unref
);
1025 if (outstanding_mounts
== 0)
1027 print_error ("%s: %s", device_file
, _("No volume for device file"));
1033 monitor_print_mount (GMount
*mount
)
1038 l
= g_list_prepend (NULL
, mount
);
1039 list_mounts (l
, 2, FALSE
);
1046 monitor_print_volume (GVolume
*volume
)
1051 l
= g_list_prepend (NULL
, volume
);
1052 list_volumes (l
, 2, FALSE
);
1059 monitor_print_drive (GDrive
*drive
)
1064 l
= g_list_prepend (NULL
, drive
);
1072 monitor_mount_added (GVolumeMonitor
*volume_monitor
, GMount
*mount
)
1075 name
= g_mount_get_name (mount
);
1076 g_print ("Mount added: '%s'\n", name
);
1078 monitor_print_mount (mount
);
1082 monitor_mount_removed (GVolumeMonitor
*volume_monitor
, GMount
*mount
)
1085 name
= g_mount_get_name (mount
);
1086 g_print ("Mount removed: '%s'\n", name
);
1088 monitor_print_mount (mount
);
1092 monitor_mount_changed (GVolumeMonitor
*volume_monitor
, GMount
*mount
)
1095 name
= g_mount_get_name (mount
);
1096 g_print ("Mount changed: '%s'\n", name
);
1098 monitor_print_mount (mount
);
1102 monitor_mount_pre_unmount (GVolumeMonitor
*volume_monitor
, GMount
*mount
)
1105 name
= g_mount_get_name (mount
);
1106 g_print ("Mount pre-unmount: '%s'\n", name
);
1108 monitor_print_mount (mount
);
1112 monitor_volume_added (GVolumeMonitor
*volume_monitor
, GVolume
*volume
)
1115 name
= g_volume_get_name (volume
);
1116 g_print ("Volume added: '%s'\n", name
);
1118 monitor_print_volume (volume
);
1122 monitor_volume_removed (GVolumeMonitor
*volume_monitor
, GVolume
*volume
)
1125 name
= g_volume_get_name (volume
);
1126 g_print ("Volume removed: '%s'\n", name
);
1128 monitor_print_volume (volume
);
1132 monitor_volume_changed (GVolumeMonitor
*volume_monitor
, GVolume
*volume
)
1135 name
= g_volume_get_name (volume
);
1136 g_print ("Volume changed: '%s'\n", name
);
1138 monitor_print_volume (volume
);
1142 monitor_drive_connected (GVolumeMonitor
*volume_monitor
, GDrive
*drive
)
1145 name
= g_drive_get_name (drive
);
1146 g_print ("Drive connected: '%s'\n", name
);
1148 monitor_print_drive (drive
);
1152 monitor_drive_disconnected (GVolumeMonitor
*volume_monitor
, GDrive
*drive
)
1155 name
= g_drive_get_name (drive
);
1156 g_print ("Drive disconnected: '%s'\n", name
);
1158 monitor_print_drive (drive
);
1162 monitor_drive_changed (GVolumeMonitor
*volume_monitor
, GDrive
*drive
)
1165 name
= g_drive_get_name (drive
);
1166 g_print ("Drive changed: '%s'\n", name
);
1168 monitor_print_drive (drive
);
1172 monitor_drive_eject_button (GVolumeMonitor
*volume_monitor
, GDrive
*drive
)
1175 name
= g_drive_get_name (drive
);
1176 g_print ("Drive eject button: '%s'\n", name
);
1183 g_signal_connect (volume_monitor
, "mount-added", (GCallback
) monitor_mount_added
, NULL
);
1184 g_signal_connect (volume_monitor
, "mount-removed", (GCallback
) monitor_mount_removed
, NULL
);
1185 g_signal_connect (volume_monitor
, "mount-changed", (GCallback
) monitor_mount_changed
, NULL
);
1186 g_signal_connect (volume_monitor
, "mount-pre-unmount", (GCallback
) monitor_mount_pre_unmount
, NULL
);
1187 g_signal_connect (volume_monitor
, "volume-added", (GCallback
) monitor_volume_added
, NULL
);
1188 g_signal_connect (volume_monitor
, "volume-removed", (GCallback
) monitor_volume_removed
, NULL
);
1189 g_signal_connect (volume_monitor
, "volume-changed", (GCallback
) monitor_volume_changed
, NULL
);
1190 g_signal_connect (volume_monitor
, "drive-connected", (GCallback
) monitor_drive_connected
, NULL
);
1191 g_signal_connect (volume_monitor
, "drive-disconnected", (GCallback
) monitor_drive_disconnected
, NULL
);
1192 g_signal_connect (volume_monitor
, "drive-changed", (GCallback
) monitor_drive_changed
, NULL
);
1193 g_signal_connect (volume_monitor
, "drive-eject-button", (GCallback
) monitor_drive_eject_button
, NULL
);
1195 g_print ("Monitoring events. Press Ctrl+C to quit.\n");
1197 g_main_loop_run (main_loop
);
1201 handle_mount (int argc
, char *argv
[], gboolean do_help
)
1203 GOptionContext
*context
;
1205 GError
*error
= NULL
;
1209 g_set_prgname ("gio mount");
1211 /* Translators: commandline placeholder */
1212 param
= g_strdup_printf ("[%s…]", _("LOCATION"));
1213 context
= g_option_context_new (param
);
1215 g_option_context_set_help_enabled (context
, FALSE
);
1216 g_option_context_set_summary (context
, _("Mount or unmount the locations."));
1217 g_option_context_add_main_entries (context
, entries
, GETTEXT_PACKAGE
);
1221 show_help (context
, NULL
);
1222 g_option_context_free (context
);
1226 if (!g_option_context_parse (context
, &argc
, &argv
, &error
))
1228 show_help (context
, error
->message
);
1229 g_error_free (error
);
1230 g_option_context_free (context
);
1234 main_loop
= g_main_loop_new (NULL
, FALSE
);
1235 volume_monitor
= g_volume_monitor_get ();
1238 list_monitor_items ();
1239 else if (mount_device_file
!= NULL
)
1240 mount_with_device_file (mount_device_file
);
1241 else if (stop_device_file
)
1242 stop_with_device_file (stop_device_file
);
1243 else if (unmount_scheme
!= NULL
)
1244 unmount_all_with_scheme (unmount_scheme
);
1245 else if (mount_monitor
)
1249 for (i
= 1; i
< argc
; i
++)
1251 file
= g_file_new_for_commandline_arg (argv
[i
]);
1254 else if (mount_eject
)
1258 g_object_unref (file
);
1263 show_help (context
, _("No locations given"));
1264 g_option_context_free (context
);
1265 g_object_unref (volume_monitor
);
1269 g_option_context_free (context
);
1271 if (outstanding_mounts
> 0)
1272 g_main_loop_run (main_loop
);
1274 g_object_unref (volume_monitor
);
1276 return success
? 0 : 2;