Branch data Line data Source code
1 : : /*
2 : : * Copyright 2015 Red Hat, Inc.
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : *
19 : : * Author: Matthias Clasen <mclasen@redhat.com>
20 : : */
21 : :
22 : : #include "config.h"
23 : :
24 : : #include <gio/gio.h>
25 : : #include <gi18n.h>
26 : : #include <stdio.h>
27 : : #include <stdlib.h>
28 : : #ifdef HAVE_TERMIOS_H
29 : : #include <termios.h>
30 : : #endif
31 : :
32 : : #include "gio-tool.h"
33 : :
34 : : #define STDIN_FILENO 0
35 : :
36 : : typedef enum {
37 : : MOUNT_OP_NONE,
38 : : MOUNT_OP_ASKED,
39 : : MOUNT_OP_ABORTED
40 : : } MountOpState;
41 : :
42 : : static int outstanding_mounts = 0;
43 : : static GMainLoop *main_loop;
44 : : static GVolumeMonitor *global_volume_monitor;
45 : :
46 : : static gboolean mount_mountable = FALSE;
47 : : static gboolean mount_unmount = FALSE;
48 : : static gboolean mount_eject = FALSE;
49 : : static gboolean force = FALSE;
50 : : static gboolean anonymous = FALSE;
51 : : static gboolean mount_list = FALSE;
52 : : static gboolean extra_detail = FALSE;
53 : : static gboolean mount_monitor = FALSE;
54 : : static gboolean tcrypt_hidden = FALSE;
55 : : static gboolean tcrypt_system = FALSE;
56 : : static guint tcrypt_pim = 0;
57 : : static const char *unmount_scheme = NULL;
58 : : static const char *mount_id = NULL;
59 : : static const char *stop_device_file = NULL;
60 : : static gboolean success = TRUE;
61 : :
62 : :
63 : : static const GOptionEntry entries[] =
64 : : {
65 : : { "mountable", 'm', 0, G_OPTION_ARG_NONE, &mount_mountable, N_("Mount as mountable"), NULL },
66 : : { "device", 'd', 0, G_OPTION_ARG_STRING, &mount_id, N_("Mount volume with device file, or other identifier"), N_("ID") },
67 : : { "unmount", 'u', 0, G_OPTION_ARG_NONE, &mount_unmount, N_("Unmount"), NULL},
68 : : { "eject", 'e', 0, G_OPTION_ARG_NONE, &mount_eject, N_("Eject"), NULL},
69 : : { "stop", 't', 0, G_OPTION_ARG_STRING, &stop_device_file, N_("Stop drive with device file"), N_("DEVICE") },
70 : : { "unmount-scheme", 's', 0, G_OPTION_ARG_STRING, &unmount_scheme, N_("Unmount all mounts with the given scheme"), N_("SCHEME") },
71 : : { "force", 'f', 0, G_OPTION_ARG_NONE, &force, N_("Ignore outstanding file operations when unmounting or ejecting"), NULL },
72 : : { "anonymous", 'a', 0, G_OPTION_ARG_NONE, &anonymous, N_("Use an anonymous user when authenticating"), NULL },
73 : : /* Translator: List here is a verb as in 'List all mounts' */
74 : : { "list", 'l', 0, G_OPTION_ARG_NONE, &mount_list, N_("List"), NULL},
75 : : { "monitor", 'o', 0, G_OPTION_ARG_NONE, &mount_monitor, N_("Monitor events"), NULL},
76 : : { "detail", 'i', 0, G_OPTION_ARG_NONE, &extra_detail, N_("Show extra information"), NULL},
77 : : { "tcrypt-pim", 0, 0, G_OPTION_ARG_INT, &tcrypt_pim, N_("The numeric PIM when unlocking a VeraCrypt volume"), N_("PIM")},
78 : : { "tcrypt-hidden", 0, 0, G_OPTION_ARG_NONE, &tcrypt_hidden, N_("Mount a TCRYPT hidden volume"), NULL},
79 : : { "tcrypt-system", 0, 0, G_OPTION_ARG_NONE, &tcrypt_system, N_("Mount a TCRYPT system volume"), NULL},
80 : : G_OPTION_ENTRY_NULL
81 : : };
82 : :
83 : : static char *
84 : 0 : prompt_for (const char *prompt, const char *default_value, gboolean echo)
85 : : {
86 : : #ifdef HAVE_TERMIOS_H
87 : : struct termios term_attr;
88 : : int old_flags;
89 : : gboolean restore_flags;
90 : : #endif
91 : : char data[256];
92 : : size_t len;
93 : :
94 : 0 : if (default_value && *default_value != 0)
95 : 0 : g_print ("%s [%s]: ", prompt, default_value);
96 : : else
97 : 0 : g_print ("%s: ", prompt);
98 : :
99 : 0 : data[0] = 0;
100 : :
101 : : #ifdef HAVE_TERMIOS_H
102 : 0 : restore_flags = FALSE;
103 : 0 : if (!echo && tcgetattr (STDIN_FILENO, &term_attr) == 0)
104 : : {
105 : 0 : old_flags = term_attr.c_lflag;
106 : 0 : term_attr.c_lflag &= ~ECHO;
107 : 0 : restore_flags = TRUE;
108 : :
109 : 0 : if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
110 : 0 : g_print ("Warning! Password will be echoed");
111 : : }
112 : :
113 : : #endif
114 : :
115 : 0 : if (!fgets (data, sizeof (data), stdin))
116 : : {
117 : 0 : if (feof (stdin))
118 : : {
119 : 0 : g_print ("\n");
120 : 0 : return NULL;
121 : : }
122 : :
123 : 0 : g_error ("Failed to read from standard input");
124 : : }
125 : :
126 : : #ifdef HAVE_TERMIOS_H
127 : 0 : if (restore_flags)
128 : : {
129 : 0 : term_attr.c_lflag = old_flags;
130 : 0 : tcsetattr (STDIN_FILENO, TCSAFLUSH, &term_attr);
131 : : }
132 : : #endif
133 : :
134 : 0 : len = strlen (data);
135 : 0 : if (len == 0)
136 : : {
137 : 0 : g_print ("\n");
138 : 0 : return NULL;
139 : : }
140 : 0 : if (data[len-1] == '\n')
141 : 0 : data[len-1] = 0;
142 : :
143 : 0 : if (!echo)
144 : 0 : g_print ("\n");
145 : :
146 : 0 : if (*data == 0 && default_value)
147 : 0 : return g_strdup (default_value);
148 : 0 : return g_strdup (data);
149 : : }
150 : :
151 : : static void
152 : 0 : ask_password_cb (GMountOperation *op,
153 : : const char *message,
154 : : const char *default_user,
155 : : const char *default_domain,
156 : : GAskPasswordFlags flags)
157 : : {
158 : 0 : if ((flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED) && anonymous)
159 : : {
160 : 0 : g_mount_operation_set_anonymous (op, TRUE);
161 : : }
162 : : else
163 : : {
164 : : char *s;
165 : 0 : g_print ("%s\n", message);
166 : :
167 : 0 : if (flags & G_ASK_PASSWORD_NEED_USERNAME)
168 : : {
169 : 0 : s = prompt_for ("User", default_user, TRUE);
170 : 0 : if (!s)
171 : 0 : goto error;
172 : 0 : g_mount_operation_set_username (op, s);
173 : 0 : g_free (s);
174 : : }
175 : :
176 : 0 : if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
177 : : {
178 : 0 : s = prompt_for ("Domain", default_domain, TRUE);
179 : 0 : if (!s)
180 : 0 : goto error;
181 : 0 : g_mount_operation_set_domain (op, s);
182 : 0 : g_free (s);
183 : : }
184 : :
185 : 0 : if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
186 : : {
187 : 0 : s = prompt_for ("Password", NULL, FALSE);
188 : 0 : if (!s)
189 : 0 : goto error;
190 : 0 : g_mount_operation_set_password (op, s);
191 : 0 : g_free (s);
192 : : }
193 : : }
194 : :
195 : 0 : if (flags & G_ASK_PASSWORD_TCRYPT)
196 : : {
197 : 0 : if (tcrypt_pim)
198 : 0 : g_mount_operation_set_pim (op, tcrypt_pim);
199 : 0 : if (tcrypt_hidden)
200 : 0 : g_mount_operation_set_is_tcrypt_hidden_volume (op, TRUE);
201 : 0 : if (tcrypt_system)
202 : 0 : g_mount_operation_set_is_tcrypt_system_volume (op, TRUE);
203 : : }
204 : :
205 : : /* Only try anonymous access once. */
206 : 0 : if (anonymous &&
207 : 0 : GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op), "state")) == MOUNT_OP_ASKED)
208 : : {
209 : 0 : g_object_set_data (G_OBJECT (op), "state", GINT_TO_POINTER (MOUNT_OP_ABORTED));
210 : 0 : g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
211 : : }
212 : : else
213 : : {
214 : 0 : g_object_set_data (G_OBJECT (op), "state", GINT_TO_POINTER (MOUNT_OP_ASKED));
215 : 0 : g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
216 : : }
217 : :
218 : 0 : return;
219 : :
220 : 0 : error:
221 : 0 : g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
222 : : }
223 : :
224 : : static void
225 : 0 : ask_question_cb (GMountOperation *op,
226 : : char *message,
227 : : char **choices,
228 : : gpointer user_data)
229 : : {
230 : 0 : char **ptr = choices;
231 : : char *s;
232 : : int i, choice;
233 : :
234 : 0 : g_print ("%s\n", message);
235 : :
236 : 0 : i = 1;
237 : 0 : while (*ptr)
238 : : {
239 : 0 : g_print ("[%d] %s\n", i, *ptr++);
240 : 0 : i++;
241 : : }
242 : :
243 : 0 : s = prompt_for ("Choice", NULL, TRUE);
244 : 0 : if (!s)
245 : 0 : goto error;
246 : :
247 : 0 : choice = atoi (s);
248 : 0 : if (choice > 0 && choice < i)
249 : : {
250 : 0 : g_mount_operation_set_choice (op, choice - 1);
251 : 0 : g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
252 : : }
253 : 0 : g_free (s);
254 : :
255 : 0 : return;
256 : :
257 : 0 : error:
258 : 0 : g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
259 : : }
260 : :
261 : : static void
262 : 0 : mount_mountable_done_cb (GObject *object,
263 : : GAsyncResult *res,
264 : : gpointer user_data)
265 : : {
266 : : GFile *target;
267 : 0 : GError *error = NULL;
268 : 0 : GMountOperation *op = user_data;
269 : :
270 : 0 : target = g_file_mount_mountable_finish (G_FILE (object), res, &error);
271 : :
272 : 0 : if (target == NULL)
273 : : {
274 : 0 : success = FALSE;
275 : 0 : if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op), "state")) == MOUNT_OP_ABORTED)
276 : 0 : print_file_error (G_FILE (object), _("Anonymous access denied"));
277 : 0 : else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED))
278 : 0 : print_file_error (G_FILE (object), error->message);
279 : :
280 : 0 : g_error_free (error);
281 : : }
282 : : else
283 : 0 : g_object_unref (target);
284 : :
285 : 0 : g_object_unref (op);
286 : :
287 : 0 : outstanding_mounts--;
288 : :
289 : 0 : if (outstanding_mounts == 0)
290 : 0 : g_main_loop_quit (main_loop);
291 : 0 : }
292 : :
293 : : static void
294 : 0 : mount_done_cb (GObject *object,
295 : : GAsyncResult *res,
296 : : gpointer user_data)
297 : : {
298 : : gboolean succeeded;
299 : 0 : GError *error = NULL;
300 : 0 : GMountOperation *op = user_data;
301 : :
302 : 0 : succeeded = g_file_mount_enclosing_volume_finish (G_FILE (object), res, &error);
303 : :
304 : 0 : if (!succeeded)
305 : : {
306 : 0 : success = FALSE;
307 : 0 : if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (op), "state")) == MOUNT_OP_ABORTED)
308 : 0 : print_file_error (G_FILE (object), _("Anonymous access denied"));
309 : 0 : else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED))
310 : 0 : print_file_error (G_FILE (object), error->message);
311 : :
312 : 0 : g_error_free (error);
313 : : }
314 : :
315 : 0 : g_object_unref (op);
316 : :
317 : 0 : outstanding_mounts--;
318 : :
319 : 0 : if (outstanding_mounts == 0)
320 : 0 : g_main_loop_quit (main_loop);
321 : 0 : }
322 : :
323 : : static void
324 : 0 : show_unmount_progress (GMountOperation *self,
325 : : const gchar *message,
326 : : gint64 time_left,
327 : : gint64 bytes_left,
328 : : gpointer user_data)
329 : : {
330 : 0 : GStrv lines = NULL;
331 : 0 : gchar *one_line = NULL;
332 : :
333 : 0 : if (message == NULL)
334 : 0 : return;
335 : :
336 : 0 : lines = g_strsplit (message, "\n", -1);
337 : 0 : one_line = g_strjoinv (" - ", lines);
338 : :
339 : : /* Print just the message, the GVfsUDisks2VolumeMonitor doesn't report time or
340 : : * bytes.
341 : : */
342 : 0 : g_print ("%s\n", one_line);
343 : :
344 : 0 : g_free (one_line);
345 : 0 : g_strfreev (lines);
346 : : }
347 : :
348 : : static GMountOperation *
349 : 0 : new_mount_op (void)
350 : : {
351 : : GMountOperation *op;
352 : :
353 : 0 : op = g_mount_operation_new ();
354 : :
355 : 0 : g_object_set_data (G_OBJECT (op), "state", GINT_TO_POINTER (MOUNT_OP_NONE));
356 : :
357 : 0 : g_signal_connect (op, "ask_password", G_CALLBACK (ask_password_cb), NULL);
358 : 0 : g_signal_connect (op, "ask_question", G_CALLBACK (ask_question_cb), NULL);
359 : 0 : g_signal_connect (op, "show-unmount-progress", G_CALLBACK (show_unmount_progress), NULL);
360 : :
361 : : /* TODO: we *should* also connect to the "aborted" signal but since the
362 : : * main thread is blocked handling input we won't get that signal anyway...
363 : : */
364 : :
365 : 0 : return op;
366 : : }
367 : :
368 : :
369 : : static void
370 : 0 : mount (GFile *file)
371 : : {
372 : : GMountOperation *op;
373 : :
374 : 0 : if (file == NULL)
375 : 0 : return;
376 : :
377 : 0 : op = new_mount_op ();
378 : :
379 : 0 : if (mount_mountable)
380 : 0 : g_file_mount_mountable (file, 0, op, NULL, mount_mountable_done_cb, op);
381 : : else
382 : 0 : g_file_mount_enclosing_volume (file, 0, op, NULL, mount_done_cb, op);
383 : :
384 : 0 : outstanding_mounts++;
385 : : }
386 : :
387 : : static void
388 : 0 : unmount_done_cb (GObject *object,
389 : : GAsyncResult *res,
390 : : gpointer user_data)
391 : : {
392 : : gboolean succeeded;
393 : 0 : GError *error = NULL;
394 : 0 : GFile *file = G_FILE (user_data);
395 : :
396 : 0 : succeeded = g_mount_unmount_with_operation_finish (G_MOUNT (object), res, &error);
397 : :
398 : 0 : g_object_unref (G_MOUNT (object));
399 : :
400 : 0 : if (!succeeded)
401 : : {
402 : 0 : print_file_error (file, error->message);
403 : 0 : success = FALSE;
404 : 0 : g_error_free (error);
405 : : }
406 : :
407 : 0 : g_object_unref (file);
408 : :
409 : 0 : outstanding_mounts--;
410 : :
411 : 0 : if (outstanding_mounts == 0)
412 : 0 : g_main_loop_quit (main_loop);
413 : 0 : }
414 : :
415 : : static void
416 : 0 : unmount (GFile *file)
417 : : {
418 : : GMount *mount;
419 : 0 : GError *error = NULL;
420 : : GMountOperation *mount_op;
421 : : GMountUnmountFlags flags;
422 : :
423 : 0 : if (file == NULL)
424 : 0 : return;
425 : :
426 : 0 : mount = g_file_find_enclosing_mount (file, NULL, &error);
427 : 0 : if (mount == NULL)
428 : : {
429 : 0 : print_file_error (file, error->message);
430 : 0 : success = FALSE;
431 : 0 : g_error_free (error);
432 : 0 : return;
433 : : }
434 : :
435 : 0 : mount_op = new_mount_op ();
436 : 0 : flags = force ? G_MOUNT_UNMOUNT_FORCE : G_MOUNT_UNMOUNT_NONE;
437 : 0 : g_mount_unmount_with_operation (mount, flags, mount_op, NULL, unmount_done_cb, g_object_ref (file));
438 : 0 : g_object_unref (mount_op);
439 : :
440 : 0 : outstanding_mounts++;
441 : : }
442 : :
443 : : static void
444 : 0 : eject_done_cb (GObject *object,
445 : : GAsyncResult *res,
446 : : gpointer user_data)
447 : : {
448 : : gboolean succeeded;
449 : 0 : GError *error = NULL;
450 : 0 : GFile *file = G_FILE (user_data);
451 : :
452 : 0 : succeeded = g_mount_eject_with_operation_finish (G_MOUNT (object), res, &error);
453 : :
454 : 0 : g_object_unref (G_MOUNT (object));
455 : :
456 : 0 : if (!succeeded)
457 : : {
458 : 0 : print_file_error (file, error->message);
459 : 0 : success = FALSE;
460 : 0 : g_error_free (error);
461 : : }
462 : :
463 : 0 : g_object_unref (file);
464 : :
465 : 0 : outstanding_mounts--;
466 : :
467 : 0 : if (outstanding_mounts == 0)
468 : 0 : g_main_loop_quit (main_loop);
469 : 0 : }
470 : :
471 : : static void
472 : 0 : eject (GFile *file)
473 : : {
474 : : GMount *mount;
475 : 0 : GError *error = NULL;
476 : : GMountOperation *mount_op;
477 : : GMountUnmountFlags flags;
478 : :
479 : 0 : if (file == NULL)
480 : 0 : return;
481 : :
482 : 0 : mount = g_file_find_enclosing_mount (file, NULL, &error);
483 : 0 : if (mount == NULL)
484 : : {
485 : 0 : print_file_error (file, error->message);
486 : 0 : success = FALSE;
487 : 0 : g_error_free (error);
488 : 0 : return;
489 : : }
490 : :
491 : 0 : mount_op = new_mount_op ();
492 : 0 : flags = force ? G_MOUNT_UNMOUNT_FORCE : G_MOUNT_UNMOUNT_NONE;
493 : 0 : g_mount_eject_with_operation (mount, flags, mount_op, NULL, eject_done_cb, g_object_ref (file));
494 : 0 : g_object_unref (mount_op);
495 : :
496 : 0 : outstanding_mounts++;
497 : : }
498 : :
499 : : static void
500 : 0 : stop_with_device_file_cb (GObject *object,
501 : : GAsyncResult *res,
502 : : gpointer user_data)
503 : : {
504 : 0 : GError *error = NULL;
505 : 0 : gchar *device_path = user_data;
506 : :
507 : 0 : if (!g_drive_stop_finish (G_DRIVE (object), res, &error))
508 : : {
509 : 0 : print_error ("%s: %s", device_path, error->message);
510 : 0 : g_error_free (error);
511 : 0 : success = FALSE;
512 : : }
513 : :
514 : 0 : g_free (device_path);
515 : :
516 : 0 : outstanding_mounts--;
517 : :
518 : 0 : if (outstanding_mounts == 0)
519 : 0 : g_main_loop_quit (main_loop);
520 : 0 : }
521 : :
522 : : static void
523 : 0 : stop_with_device_file (const char *device_file)
524 : : {
525 : : GList *drives;
526 : : GList *l;
527 : :
528 : 0 : drives = g_volume_monitor_get_connected_drives (global_volume_monitor);
529 : 0 : for (l = drives; l != NULL; l = l->next)
530 : : {
531 : 0 : GDrive *drive = G_DRIVE (l->data);
532 : : gchar *id;
533 : :
534 : 0 : id = g_drive_get_identifier (drive, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
535 : 0 : if (g_strcmp0 (id, device_file) == 0)
536 : : {
537 : : GMountOperation *op;
538 : : GMountUnmountFlags flags;
539 : :
540 : 0 : op = new_mount_op ();
541 : 0 : flags = force ? G_MOUNT_UNMOUNT_FORCE : G_MOUNT_UNMOUNT_NONE;
542 : 0 : g_drive_stop (drive,
543 : : flags,
544 : : op,
545 : : NULL,
546 : : stop_with_device_file_cb,
547 : : g_steal_pointer (&id));
548 : 0 : g_object_unref (op);
549 : :
550 : 0 : outstanding_mounts++;
551 : : }
552 : :
553 : 0 : g_free (id);
554 : : }
555 : 0 : g_list_free_full (drives, g_object_unref);
556 : :
557 : 0 : if (outstanding_mounts == 0)
558 : : {
559 : 0 : print_error ("%s: %s", device_file, _("No drive for device file"));
560 : 0 : success = FALSE;
561 : : }
562 : 0 : }
563 : :
564 : : static gboolean
565 : 0 : iterate_gmain_timeout_function (gpointer data)
566 : : {
567 : 0 : g_main_loop_quit (main_loop);
568 : 0 : return FALSE;
569 : : }
570 : :
571 : : static void
572 : 0 : iterate_gmain(void)
573 : : {
574 : 0 : g_timeout_add (500, iterate_gmain_timeout_function, NULL);
575 : 0 : g_main_loop_run (main_loop);
576 : 0 : }
577 : :
578 : : static void
579 : 0 : show_themed_icon_names (GThemedIcon *icon, gboolean symbolic, int indent)
580 : : {
581 : : char **names;
582 : : char **iter;
583 : :
584 : 0 : g_print ("%*s%sthemed icons:", indent, " ", symbolic ? "symbolic " : "");
585 : :
586 : 0 : names = NULL;
587 : :
588 : 0 : g_object_get (icon, "names", &names, NULL);
589 : :
590 : 0 : for (iter = names; *iter; iter++)
591 : 0 : g_print (" [%s]", *iter);
592 : :
593 : 0 : g_print ("\n");
594 : 0 : g_strfreev (names);
595 : 0 : }
596 : :
597 : : /* don't copy-paste this code */
598 : : static char *
599 : 0 : get_type_name (gpointer object)
600 : : {
601 : : const char *type_name;
602 : : char *ret;
603 : :
604 : 0 : type_name = g_type_name (G_TYPE_FROM_INSTANCE (object));
605 : 0 : if (strcmp ("GProxyDrive", type_name) == 0)
606 : : {
607 : 0 : ret = g_strdup_printf ("%s (%s)",
608 : : type_name,
609 : 0 : (const char *) g_object_get_data (G_OBJECT (object),
610 : : "g-proxy-drive-volume-monitor-name"));
611 : : }
612 : 0 : else if (strcmp ("GProxyVolume", type_name) == 0)
613 : : {
614 : 0 : ret = g_strdup_printf ("%s (%s)",
615 : : type_name,
616 : 0 : (const char *) g_object_get_data (G_OBJECT (object),
617 : : "g-proxy-volume-volume-monitor-name"));
618 : : }
619 : 0 : else if (strcmp ("GProxyMount", type_name) == 0)
620 : : {
621 : 0 : ret = g_strdup_printf ("%s (%s)",
622 : : type_name,
623 : 0 : (const char *) g_object_get_data (G_OBJECT (object),
624 : : "g-proxy-mount-volume-monitor-name"));
625 : : }
626 : 0 : else if (strcmp ("GProxyShadowMount", type_name) == 0)
627 : : {
628 : 0 : ret = g_strdup_printf ("%s (%s)",
629 : : type_name,
630 : 0 : (const char *) g_object_get_data (G_OBJECT (object),
631 : : "g-proxy-shadow-mount-volume-monitor-name"));
632 : : }
633 : : else
634 : : {
635 : 0 : ret = g_strdup (type_name);
636 : : }
637 : :
638 : 0 : return ret;
639 : : }
640 : :
641 : : static void
642 : 0 : list_mounts (GList *mounts,
643 : : int indent,
644 : : gboolean only_with_no_volume)
645 : : {
646 : : GList *l;
647 : : int c;
648 : : GMount *mount;
649 : : GVolume *volume;
650 : : char *name, *uuid, *uri;
651 : : GFile *root, *default_location;
652 : : GIcon *icon;
653 : : char **x_content_types;
654 : : char *type_name;
655 : : const gchar *sort_key;
656 : :
657 : 0 : for (c = 0, l = mounts; l != NULL; l = l->next, c++)
658 : : {
659 : 0 : mount = (GMount *) l->data;
660 : :
661 : 0 : if (only_with_no_volume)
662 : : {
663 : 0 : volume = g_mount_get_volume (mount);
664 : 0 : if (volume != NULL)
665 : : {
666 : 0 : g_object_unref (volume);
667 : 0 : continue;
668 : : }
669 : : }
670 : :
671 : 0 : name = g_mount_get_name (mount);
672 : 0 : root = g_mount_get_root (mount);
673 : 0 : uri = g_file_get_uri (root);
674 : :
675 : 0 : g_print ("%*sMount(%d): %s -> %s\n", indent, "", c, name, uri);
676 : :
677 : 0 : type_name = get_type_name (mount);
678 : 0 : g_print ("%*sType: %s\n", indent+2, "", type_name);
679 : 0 : g_free (type_name);
680 : :
681 : 0 : if (extra_detail)
682 : : {
683 : 0 : uuid = g_mount_get_uuid (mount);
684 : 0 : if (uuid)
685 : 0 : g_print ("%*suuid=%s\n", indent + 2, "", uuid);
686 : :
687 : 0 : default_location = g_mount_get_default_location (mount);
688 : 0 : if (default_location)
689 : : {
690 : 0 : char *loc_uri = g_file_get_uri (default_location);
691 : 0 : g_print ("%*sdefault_location=%s\n", indent + 2, "", loc_uri);
692 : 0 : g_free (loc_uri);
693 : 0 : g_object_unref (default_location);
694 : : }
695 : :
696 : 0 : icon = g_mount_get_icon (mount);
697 : 0 : if (icon)
698 : : {
699 : 0 : if (G_IS_THEMED_ICON (icon))
700 : 0 : show_themed_icon_names (G_THEMED_ICON (icon), FALSE, indent + 2);
701 : :
702 : 0 : g_object_unref (icon);
703 : : }
704 : :
705 : 0 : icon = g_mount_get_symbolic_icon (mount);
706 : 0 : if (icon)
707 : : {
708 : 0 : if (G_IS_THEMED_ICON (icon))
709 : 0 : show_themed_icon_names (G_THEMED_ICON (icon), TRUE, indent + 2);
710 : :
711 : 0 : g_object_unref (icon);
712 : : }
713 : :
714 : 0 : x_content_types = g_mount_guess_content_type_sync (mount, FALSE, NULL, NULL);
715 : 0 : if (x_content_types != NULL && g_strv_length (x_content_types) > 0)
716 : : {
717 : : int n;
718 : 0 : g_print ("%*sx_content_types:", indent + 2, "");
719 : 0 : for (n = 0; x_content_types[n] != NULL; n++)
720 : 0 : g_print (" %s", x_content_types[n]);
721 : 0 : g_print ("\n");
722 : : }
723 : 0 : g_strfreev (x_content_types);
724 : :
725 : 0 : g_print ("%*scan_unmount=%d\n", indent + 2, "", g_mount_can_unmount (mount));
726 : 0 : g_print ("%*scan_eject=%d\n", indent + 2, "", g_mount_can_eject (mount));
727 : 0 : g_print ("%*sis_shadowed=%d\n", indent + 2, "", g_mount_is_shadowed (mount));
728 : 0 : sort_key = g_mount_get_sort_key (mount);
729 : 0 : if (sort_key != NULL)
730 : 0 : g_print ("%*ssort_key=%s\n", indent + 2, "", sort_key);
731 : 0 : g_free (uuid);
732 : : }
733 : :
734 : 0 : g_object_unref (root);
735 : 0 : g_free (name);
736 : 0 : g_free (uri);
737 : : }
738 : 0 : }
739 : :
740 : : static void
741 : 0 : list_volumes (GList *volumes,
742 : : int indent,
743 : : gboolean only_with_no_drive)
744 : : {
745 : : GList *l, *mounts;
746 : : int c, i;
747 : : GMount *mount;
748 : : GVolume *volume;
749 : : GDrive *drive;
750 : : char *name;
751 : : char *uuid;
752 : : GFile *activation_root;
753 : : char **ids;
754 : : GIcon *icon;
755 : : char *type_name;
756 : : const gchar *sort_key;
757 : :
758 : 0 : for (c = 0, l = volumes; l != NULL; l = l->next, c++)
759 : : {
760 : 0 : volume = (GVolume *) l->data;
761 : :
762 : 0 : if (only_with_no_drive)
763 : : {
764 : 0 : drive = g_volume_get_drive (volume);
765 : 0 : if (drive != NULL)
766 : : {
767 : 0 : g_object_unref (drive);
768 : 0 : continue;
769 : : }
770 : : }
771 : :
772 : 0 : name = g_volume_get_name (volume);
773 : :
774 : 0 : g_print ("%*sVolume(%d): %s\n", indent, "", c, name);
775 : 0 : g_free (name);
776 : :
777 : 0 : type_name = get_type_name (volume);
778 : 0 : g_print ("%*sType: %s\n", indent+2, "", type_name);
779 : 0 : g_free (type_name);
780 : :
781 : 0 : if (extra_detail)
782 : : {
783 : 0 : ids = g_volume_enumerate_identifiers (volume);
784 : 0 : if (ids && ids[0] != NULL)
785 : : {
786 : 0 : g_print ("%*sids:\n", indent+2, "");
787 : 0 : for (i = 0; ids[i] != NULL; i++)
788 : : {
789 : 0 : char *id = g_volume_get_identifier (volume,
790 : 0 : ids[i]);
791 : 0 : g_print ("%*s %s: '%s'\n", indent+2, "", ids[i], id);
792 : 0 : g_free (id);
793 : : }
794 : : }
795 : 0 : g_strfreev (ids);
796 : :
797 : 0 : uuid = g_volume_get_uuid (volume);
798 : 0 : if (uuid)
799 : 0 : g_print ("%*suuid=%s\n", indent + 2, "", uuid);
800 : 0 : activation_root = g_volume_get_activation_root (volume);
801 : 0 : if (activation_root)
802 : : {
803 : : char *uri;
804 : 0 : uri = g_file_get_uri (activation_root);
805 : 0 : g_print ("%*sactivation_root=%s\n", indent + 2, "", uri);
806 : 0 : g_free (uri);
807 : 0 : g_object_unref (activation_root);
808 : : }
809 : 0 : icon = g_volume_get_icon (volume);
810 : 0 : if (icon)
811 : : {
812 : 0 : if (G_IS_THEMED_ICON (icon))
813 : 0 : show_themed_icon_names (G_THEMED_ICON (icon), FALSE, indent + 2);
814 : :
815 : 0 : g_object_unref (icon);
816 : : }
817 : :
818 : 0 : icon = g_volume_get_symbolic_icon (volume);
819 : 0 : if (icon)
820 : : {
821 : 0 : if (G_IS_THEMED_ICON (icon))
822 : 0 : show_themed_icon_names (G_THEMED_ICON (icon), TRUE, indent + 2);
823 : :
824 : 0 : g_object_unref (icon);
825 : : }
826 : :
827 : 0 : g_print ("%*scan_mount=%d\n", indent + 2, "", g_volume_can_mount (volume));
828 : 0 : g_print ("%*scan_eject=%d\n", indent + 2, "", g_volume_can_eject (volume));
829 : 0 : g_print ("%*sshould_automount=%d\n", indent + 2, "", g_volume_should_automount (volume));
830 : 0 : sort_key = g_volume_get_sort_key (volume);
831 : 0 : if (sort_key != NULL)
832 : 0 : g_print ("%*ssort_key=%s\n", indent + 2, "", sort_key);
833 : 0 : g_free (uuid);
834 : : }
835 : :
836 : 0 : mount = g_volume_get_mount (volume);
837 : 0 : if (mount)
838 : : {
839 : 0 : mounts = g_list_prepend (NULL, mount);
840 : 0 : list_mounts (mounts, indent + 2, FALSE);
841 : 0 : g_list_free (mounts);
842 : 0 : g_object_unref (mount);
843 : : }
844 : : }
845 : 0 : }
846 : :
847 : : static void
848 : 0 : list_drives (GList *drives,
849 : : int indent)
850 : : {
851 : : GList *volumes, *l;
852 : : int c, i;
853 : : GDrive *drive;
854 : : char *name;
855 : : char **ids;
856 : : GIcon *icon;
857 : : char *type_name;
858 : : const gchar *sort_key;
859 : :
860 : 0 : for (c = 0, l = drives; l != NULL; l = l->next, c++)
861 : : {
862 : 0 : drive = (GDrive *) l->data;
863 : 0 : name = g_drive_get_name (drive);
864 : :
865 : 0 : g_print ("%*sDrive(%d): %s\n", indent, "", c, name);
866 : 0 : g_free (name);
867 : :
868 : 0 : type_name = get_type_name (drive);
869 : 0 : g_print ("%*sType: %s\n", indent+2, "", type_name);
870 : 0 : g_free (type_name);
871 : :
872 : 0 : if (extra_detail)
873 : : {
874 : : GEnumValue *enum_value;
875 : : gpointer klass;
876 : :
877 : 0 : ids = g_drive_enumerate_identifiers (drive);
878 : 0 : if (ids && ids[0] != NULL)
879 : : {
880 : 0 : g_print ("%*sids:\n", indent+2, "");
881 : 0 : for (i = 0; ids[i] != NULL; i++)
882 : : {
883 : 0 : char *id = g_drive_get_identifier (drive,
884 : 0 : ids[i]);
885 : 0 : g_print ("%*s %s: '%s'\n", indent+2, "", ids[i], id);
886 : 0 : g_free (id);
887 : : }
888 : : }
889 : 0 : g_strfreev (ids);
890 : :
891 : 0 : icon = g_drive_get_icon (drive);
892 : 0 : if (icon)
893 : : {
894 : 0 : if (G_IS_THEMED_ICON (icon))
895 : 0 : show_themed_icon_names (G_THEMED_ICON (icon), FALSE, indent + 2);
896 : 0 : g_object_unref (icon);
897 : : }
898 : :
899 : 0 : icon = g_drive_get_symbolic_icon (drive);
900 : 0 : if (icon)
901 : : {
902 : 0 : if (G_IS_THEMED_ICON (icon))
903 : 0 : show_themed_icon_names (G_THEMED_ICON (icon), TRUE, indent + 2);
904 : :
905 : 0 : g_object_unref (icon);
906 : : }
907 : :
908 : 0 : g_print ("%*sis_removable=%d\n", indent + 2, "", g_drive_is_removable (drive));
909 : 0 : g_print ("%*sis_media_removable=%d\n", indent + 2, "", g_drive_is_media_removable (drive));
910 : 0 : g_print ("%*shas_media=%d\n", indent + 2, "", g_drive_has_media (drive));
911 : 0 : g_print ("%*sis_media_check_automatic=%d\n", indent + 2, "", g_drive_is_media_check_automatic (drive));
912 : 0 : g_print ("%*scan_poll_for_media=%d\n", indent + 2, "", g_drive_can_poll_for_media (drive));
913 : 0 : g_print ("%*scan_eject=%d\n", indent + 2, "", g_drive_can_eject (drive));
914 : 0 : g_print ("%*scan_start=%d\n", indent + 2, "", g_drive_can_start (drive));
915 : 0 : g_print ("%*scan_stop=%d\n", indent + 2, "", g_drive_can_stop (drive));
916 : :
917 : 0 : enum_value = NULL;
918 : 0 : klass = g_type_class_ref (G_TYPE_DRIVE_START_STOP_TYPE);
919 : 0 : if (klass != NULL)
920 : : {
921 : 0 : enum_value = g_enum_get_value (klass, g_drive_get_start_stop_type (drive));
922 : 0 : g_print ("%*sstart_stop_type=%s\n", indent + 2, "",
923 : : enum_value != NULL ? enum_value->value_nick : "UNKNOWN");
924 : 0 : g_type_class_unref (klass);
925 : : }
926 : :
927 : 0 : sort_key = g_drive_get_sort_key (drive);
928 : 0 : if (sort_key != NULL)
929 : 0 : g_print ("%*ssort_key=%s\n", indent + 2, "", sort_key);
930 : : }
931 : 0 : volumes = g_drive_get_volumes (drive);
932 : 0 : list_volumes (volumes, indent + 2, FALSE);
933 : 0 : g_list_free_full (volumes, g_object_unref);
934 : : }
935 : 0 : }
936 : :
937 : :
938 : : static void
939 : 0 : list_monitor_items (void)
940 : : {
941 : : GList *drives, *volumes, *mounts;
942 : :
943 : : /* populate gvfs network mounts */
944 : 0 : iterate_gmain();
945 : :
946 : 0 : drives = g_volume_monitor_get_connected_drives (global_volume_monitor);
947 : 0 : list_drives (drives, 0);
948 : 0 : g_list_free_full (drives, g_object_unref);
949 : :
950 : 0 : volumes = g_volume_monitor_get_volumes (global_volume_monitor);
951 : 0 : list_volumes (volumes, 0, TRUE);
952 : 0 : g_list_free_full (volumes, g_object_unref);
953 : :
954 : 0 : mounts = g_volume_monitor_get_mounts (global_volume_monitor);
955 : 0 : list_mounts (mounts, 0, TRUE);
956 : 0 : g_list_free_full (mounts, g_object_unref);
957 : 0 : }
958 : :
959 : : static void
960 : 0 : unmount_all_with_scheme (const char *scheme)
961 : : {
962 : : GList *mounts;
963 : : GList *l;
964 : :
965 : : /* populate gvfs network mounts */
966 : 0 : iterate_gmain();
967 : :
968 : 0 : mounts = g_volume_monitor_get_mounts (global_volume_monitor);
969 : 0 : for (l = mounts; l != NULL; l = l->next) {
970 : 0 : GMount *mount = G_MOUNT (l->data);
971 : : GFile *root;
972 : :
973 : 0 : root = g_mount_get_root (mount);
974 : 0 : if (g_file_has_uri_scheme (root, scheme)) {
975 : 0 : unmount (root);
976 : : }
977 : 0 : g_object_unref (root);
978 : : }
979 : 0 : g_list_free_full (mounts, g_object_unref);
980 : 0 : }
981 : :
982 : : static void
983 : 0 : mount_with_device_file_cb (GObject *object,
984 : : GAsyncResult *res,
985 : : gpointer user_data)
986 : : {
987 : : GVolume *volume;
988 : : gboolean succeeded;
989 : 0 : GError *error = NULL;
990 : 0 : gchar *id = (gchar *)user_data;
991 : :
992 : 0 : volume = G_VOLUME (object);
993 : :
994 : 0 : succeeded = g_volume_mount_finish (volume, res, &error);
995 : :
996 : 0 : if (!succeeded)
997 : : {
998 : 0 : print_error ("%s: %s", id, error->message);
999 : 0 : g_error_free (error);
1000 : 0 : success = FALSE;
1001 : : }
1002 : :
1003 : 0 : g_free (id);
1004 : :
1005 : 0 : outstanding_mounts--;
1006 : :
1007 : 0 : if (outstanding_mounts == 0)
1008 : 0 : g_main_loop_quit (main_loop);
1009 : 0 : }
1010 : :
1011 : : static void
1012 : 0 : mount_with_id (const char *id)
1013 : : {
1014 : : GList *volumes;
1015 : : GList *l;
1016 : :
1017 : 0 : volumes = g_volume_monitor_get_volumes (global_volume_monitor);
1018 : 0 : for (l = volumes; l != NULL; l = l->next)
1019 : : {
1020 : 0 : GVolume *volume = G_VOLUME (l->data);
1021 : : gchar *device;
1022 : : gchar *uuid;
1023 : :
1024 : 0 : device = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
1025 : 0 : uuid = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UUID);
1026 : 0 : if (g_strcmp0 (device, id) == 0 || g_strcmp0 (uuid, id) == 0)
1027 : : {
1028 : : GMountOperation *op;
1029 : :
1030 : 0 : op = new_mount_op ();
1031 : :
1032 : 0 : g_volume_mount (volume,
1033 : : G_MOUNT_MOUNT_NONE,
1034 : : op,
1035 : : NULL,
1036 : : mount_with_device_file_cb,
1037 : 0 : g_strdup (id));
1038 : :
1039 : 0 : g_object_unref (op);
1040 : :
1041 : 0 : outstanding_mounts++;
1042 : : }
1043 : :
1044 : 0 : g_free (device);
1045 : 0 : g_free (uuid);
1046 : : }
1047 : 0 : g_list_free_full (volumes, g_object_unref);
1048 : :
1049 : 0 : if (outstanding_mounts == 0)
1050 : : {
1051 : 0 : print_error ("%s: %s", id, _("No volume for given ID"));
1052 : 0 : success = FALSE;
1053 : : }
1054 : 0 : }
1055 : :
1056 : : static void
1057 : 0 : monitor_print_mount (GMount *mount)
1058 : : {
1059 : 0 : if (extra_detail)
1060 : : {
1061 : : GList *l;
1062 : 0 : l = g_list_prepend (NULL, mount);
1063 : 0 : list_mounts (l, 2, FALSE);
1064 : 0 : g_list_free (l);
1065 : 0 : g_print ("\n");
1066 : : }
1067 : 0 : }
1068 : :
1069 : : static void
1070 : 0 : monitor_print_volume (GVolume *volume)
1071 : : {
1072 : 0 : if (extra_detail)
1073 : : {
1074 : : GList *l;
1075 : 0 : l = g_list_prepend (NULL, volume);
1076 : 0 : list_volumes (l, 2, FALSE);
1077 : 0 : g_list_free (l);
1078 : 0 : g_print ("\n");
1079 : : }
1080 : 0 : }
1081 : :
1082 : : static void
1083 : 0 : monitor_print_drive (GDrive *drive)
1084 : : {
1085 : 0 : if (extra_detail)
1086 : : {
1087 : : GList *l;
1088 : 0 : l = g_list_prepend (NULL, drive);
1089 : 0 : list_drives (l, 2);
1090 : 0 : g_list_free (l);
1091 : 0 : g_print ("\n");
1092 : : }
1093 : 0 : }
1094 : :
1095 : : static void
1096 : 0 : monitor_mount_added (GVolumeMonitor *volume_monitor, GMount *mount)
1097 : : {
1098 : : char *name;
1099 : 0 : name = g_mount_get_name (mount);
1100 : 0 : g_print ("Mount added: '%s'\n", name);
1101 : 0 : g_free (name);
1102 : 0 : monitor_print_mount (mount);
1103 : 0 : }
1104 : :
1105 : : static void
1106 : 0 : monitor_mount_removed (GVolumeMonitor *volume_monitor, GMount *mount)
1107 : : {
1108 : : char *name;
1109 : 0 : name = g_mount_get_name (mount);
1110 : 0 : g_print ("Mount removed: '%s'\n", name);
1111 : 0 : g_free (name);
1112 : 0 : monitor_print_mount (mount);
1113 : 0 : }
1114 : :
1115 : : static void
1116 : 0 : monitor_mount_changed (GVolumeMonitor *volume_monitor, GMount *mount)
1117 : : {
1118 : : char *name;
1119 : 0 : name = g_mount_get_name (mount);
1120 : 0 : g_print ("Mount changed: '%s'\n", name);
1121 : 0 : g_free (name);
1122 : 0 : monitor_print_mount (mount);
1123 : 0 : }
1124 : :
1125 : : static void
1126 : 0 : monitor_mount_pre_unmount (GVolumeMonitor *volume_monitor, GMount *mount)
1127 : : {
1128 : : char *name;
1129 : 0 : name = g_mount_get_name (mount);
1130 : 0 : g_print ("Mount pre-unmount: '%s'\n", name);
1131 : 0 : g_free (name);
1132 : 0 : monitor_print_mount (mount);
1133 : 0 : }
1134 : :
1135 : : static void
1136 : 0 : monitor_volume_added (GVolumeMonitor *volume_monitor, GVolume *volume)
1137 : : {
1138 : : char *name;
1139 : 0 : name = g_volume_get_name (volume);
1140 : 0 : g_print ("Volume added: '%s'\n", name);
1141 : 0 : g_free (name);
1142 : 0 : monitor_print_volume (volume);
1143 : 0 : }
1144 : :
1145 : : static void
1146 : 0 : monitor_volume_removed (GVolumeMonitor *volume_monitor, GVolume *volume)
1147 : : {
1148 : : char *name;
1149 : 0 : name = g_volume_get_name (volume);
1150 : 0 : g_print ("Volume removed: '%s'\n", name);
1151 : 0 : g_free (name);
1152 : 0 : monitor_print_volume (volume);
1153 : 0 : }
1154 : :
1155 : : static void
1156 : 0 : monitor_volume_changed (GVolumeMonitor *volume_monitor, GVolume *volume)
1157 : : {
1158 : : char *name;
1159 : 0 : name = g_volume_get_name (volume);
1160 : 0 : g_print ("Volume changed: '%s'\n", name);
1161 : 0 : g_free (name);
1162 : 0 : monitor_print_volume (volume);
1163 : 0 : }
1164 : :
1165 : : static void
1166 : 0 : monitor_drive_connected (GVolumeMonitor *volume_monitor, GDrive *drive)
1167 : : {
1168 : : char *name;
1169 : 0 : name = g_drive_get_name (drive);
1170 : 0 : g_print ("Drive connected: '%s'\n", name);
1171 : 0 : g_free (name);
1172 : 0 : monitor_print_drive (drive);
1173 : 0 : }
1174 : :
1175 : : static void
1176 : 0 : monitor_drive_disconnected (GVolumeMonitor *volume_monitor, GDrive *drive)
1177 : : {
1178 : : char *name;
1179 : 0 : name = g_drive_get_name (drive);
1180 : 0 : g_print ("Drive disconnected: '%s'\n", name);
1181 : 0 : g_free (name);
1182 : 0 : monitor_print_drive (drive);
1183 : 0 : }
1184 : :
1185 : : static void
1186 : 0 : monitor_drive_changed (GVolumeMonitor *volume_monitor, GDrive *drive)
1187 : : {
1188 : : char *name;
1189 : 0 : name = g_drive_get_name (drive);
1190 : 0 : g_print ("Drive changed: '%s'\n", name);
1191 : 0 : g_free (name);
1192 : 0 : monitor_print_drive (drive);
1193 : 0 : }
1194 : :
1195 : : static void
1196 : 0 : monitor_drive_eject_button (GVolumeMonitor *volume_monitor, GDrive *drive)
1197 : : {
1198 : : char *name;
1199 : 0 : name = g_drive_get_name (drive);
1200 : 0 : g_print ("Drive eject button: '%s'\n", name);
1201 : 0 : g_free (name);
1202 : 0 : }
1203 : :
1204 : : static void
1205 : 0 : monitor (void)
1206 : : {
1207 : 0 : g_signal_connect (global_volume_monitor, "mount-added", (GCallback) monitor_mount_added, NULL);
1208 : 0 : g_signal_connect (global_volume_monitor, "mount-removed", (GCallback) monitor_mount_removed, NULL);
1209 : 0 : g_signal_connect (global_volume_monitor, "mount-changed", (GCallback) monitor_mount_changed, NULL);
1210 : 0 : g_signal_connect (global_volume_monitor, "mount-pre-unmount", (GCallback) monitor_mount_pre_unmount, NULL);
1211 : 0 : g_signal_connect (global_volume_monitor, "volume-added", (GCallback) monitor_volume_added, NULL);
1212 : 0 : g_signal_connect (global_volume_monitor, "volume-removed", (GCallback) monitor_volume_removed, NULL);
1213 : 0 : g_signal_connect (global_volume_monitor, "volume-changed", (GCallback) monitor_volume_changed, NULL);
1214 : 0 : g_signal_connect (global_volume_monitor, "drive-connected", (GCallback) monitor_drive_connected, NULL);
1215 : 0 : g_signal_connect (global_volume_monitor, "drive-disconnected", (GCallback) monitor_drive_disconnected, NULL);
1216 : 0 : g_signal_connect (global_volume_monitor, "drive-changed", (GCallback) monitor_drive_changed, NULL);
1217 : 0 : g_signal_connect (global_volume_monitor, "drive-eject-button", (GCallback) monitor_drive_eject_button, NULL);
1218 : :
1219 : 0 : g_print ("Monitoring events. Press Ctrl+C to quit.\n");
1220 : :
1221 : 0 : g_main_loop_run (main_loop);
1222 : 0 : }
1223 : :
1224 : : int
1225 : 0 : handle_mount (int argc, char *argv[], gboolean do_help)
1226 : : {
1227 : : GOptionContext *context;
1228 : : gchar *param;
1229 : 0 : GError *error = NULL;
1230 : : GFile *file;
1231 : : int i;
1232 : :
1233 : 0 : g_set_prgname ("gio mount");
1234 : :
1235 : : /* Translators: commandline placeholder */
1236 : 0 : param = g_strdup_printf ("[%s…]", _("LOCATION"));
1237 : 0 : context = g_option_context_new (param);
1238 : 0 : g_free (param);
1239 : 0 : g_option_context_set_help_enabled (context, FALSE);
1240 : 0 : g_option_context_set_summary (context, _("Mount or unmount the locations."));
1241 : 0 : g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
1242 : :
1243 : 0 : if (do_help)
1244 : : {
1245 : 0 : show_help (context, NULL);
1246 : 0 : g_option_context_free (context);
1247 : 0 : return 0;
1248 : : }
1249 : :
1250 : 0 : if (!g_option_context_parse (context, &argc, &argv, &error))
1251 : : {
1252 : 0 : show_help (context, error->message);
1253 : 0 : g_error_free (error);
1254 : 0 : g_option_context_free (context);
1255 : 0 : return 1;
1256 : : }
1257 : :
1258 : 0 : main_loop = g_main_loop_new (NULL, FALSE);
1259 : 0 : global_volume_monitor = g_volume_monitor_get ();
1260 : :
1261 : 0 : if (mount_list)
1262 : 0 : list_monitor_items ();
1263 : 0 : else if (mount_id != NULL)
1264 : 0 : mount_with_id (mount_id);
1265 : 0 : else if (stop_device_file)
1266 : 0 : stop_with_device_file (stop_device_file);
1267 : 0 : else if (unmount_scheme != NULL)
1268 : 0 : unmount_all_with_scheme (unmount_scheme);
1269 : 0 : else if (mount_monitor)
1270 : 0 : monitor ();
1271 : 0 : else if (argc > 1)
1272 : : {
1273 : 0 : for (i = 1; i < argc; i++)
1274 : : {
1275 : 0 : file = g_file_new_for_commandline_arg (argv[i]);
1276 : 0 : if (mount_unmount)
1277 : 0 : unmount (file);
1278 : 0 : else if (mount_eject)
1279 : 0 : eject (file);
1280 : : else
1281 : 0 : mount (file);
1282 : 0 : g_object_unref (file);
1283 : : }
1284 : : }
1285 : : else
1286 : : {
1287 : 0 : show_help (context, _("No locations given"));
1288 : 0 : g_option_context_free (context);
1289 : 0 : g_object_unref (global_volume_monitor);
1290 : 0 : return 1;
1291 : : }
1292 : :
1293 : 0 : g_option_context_free (context);
1294 : :
1295 : 0 : if (outstanding_mounts > 0)
1296 : 0 : g_main_loop_run (main_loop);
1297 : :
1298 : 0 : g_object_unref (global_volume_monitor);
1299 : :
1300 : 0 : return success ? 0 : 2;
1301 : : }
|