LCOV - code coverage report
Current view: top level - gio - gio-tool-mount.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 0.0 % 629 0
Test Date: 2024-11-26 05:23:01 Functions: 0.0 % 41 0
Branches: - 0 0

             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                 :             : }
        

Generated by: LCOV version 2.0-1