gunixvolumemonitor.c revision feb5258cf9ca9c3b3d9a58a98b1c6c75c822855a
13ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
23ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen
33781343738de4abddf56982325a77bd70a98cd26Alexander Larsson/* GIO - GLib Input, Output and Streaming Library
43781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *
53781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * Copyright (C) 2006-2007 Red Hat, Inc.
63781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *
73781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * This library is free software; you can redistribute it and/or
83781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * modify it under the terms of the GNU Lesser General Public
93781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * License as published by the Free Software Foundation; either
103781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * version 2 of the License, or (at your option) any later version.
113781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *
123781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * This library is distributed in the hope that it will be useful,
133781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * but WITHOUT ANY WARRANTY; without even the implied warranty of
143781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
153781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * Lesser General Public License for more details.
163781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *
173781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * You should have received a copy of the GNU Lesser General
183781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * Public License along with this library; if not, write to the
193781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
203781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * Boston, MA 02111-1307, USA.
213781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *
223781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * Author: Alexander Larsson <alexl@redhat.com>
233ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen *         David Zeuthen <davidz@redhat.com>
243781343738de4abddf56982325a77bd70a98cd26Alexander Larsson */
253781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
263781343738de4abddf56982325a77bd70a98cd26Alexander Larsson#include <config.h>
273781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
283781343738de4abddf56982325a77bd70a98cd26Alexander Larsson#include <string.h>
293781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
303781343738de4abddf56982325a77bd70a98cd26Alexander Larsson#include <glib.h>
313781343738de4abddf56982325a77bd70a98cd26Alexander Larsson#include "gunixvolumemonitor.h"
323781343738de4abddf56982325a77bd70a98cd26Alexander Larsson#include "gunixmounts.h"
333ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen#include "gunixmount.h"
343781343738de4abddf56982325a77bd70a98cd26Alexander Larsson#include "gunixvolume.h"
353ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen#include "gmountprivate.h"
363781343738de4abddf56982325a77bd70a98cd26Alexander Larsson#include "glibintl.h"
373781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
387f3280230bc9448a5750fc17a6eabef691ba25f4Alexander Larsson#include "gioalias.h"
397f3280230bc9448a5750fc17a6eabef691ba25f4Alexander Larsson
403781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstruct _GUnixVolumeMonitor {
413781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GNativeVolumeMonitor parent;
423781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
433781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixMountMonitor *mount_monitor;
443781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
453781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *last_mountpoints;
463781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *last_mounts;
473781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
483781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *volumes;
493ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  GList *mounts;
503781343738de4abddf56982325a77bd70a98cd26Alexander Larsson};
513781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
523ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic void mountpoints_changed      (GUnixMountMonitor  *mount_monitor,
533ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen                                      gpointer            user_data);
543ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic void mounts_changed           (GUnixMountMonitor  *mount_monitor,
553ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen                                      gpointer            user_data);
563ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic void update_volumes           (GUnixVolumeMonitor *monitor);
573ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic void update_mounts            (GUnixVolumeMonitor *monitor);
583781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
59d9594f5709313d6e7a8a4f3e5f3b23fc72017417Alexander Larsson#define g_unix_volume_monitor_get_type _g_unix_volume_monitor_get_type
603781343738de4abddf56982325a77bd70a98cd26Alexander LarssonG_DEFINE_TYPE (GUnixVolumeMonitor, g_unix_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR);
613781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
623781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void
633781343738de4abddf56982325a77bd70a98cd26Alexander Larssong_unix_volume_monitor_finalize (GObject *object)
643781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
653781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixVolumeMonitor *monitor;
663781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
673781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  monitor = G_UNIX_VOLUME_MONITOR (object);
683781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
693781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mountpoints_changed, monitor);
703781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mounts_changed, monitor);
713781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
723781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_object_unref (monitor->mount_monitor);
733781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
743ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  g_list_foreach (monitor->last_mountpoints, (GFunc)g_unix_mount_point_free, NULL);
753ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  g_list_free (monitor->last_mountpoints);
763781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_foreach (monitor->last_mounts, (GFunc)g_unix_mount_free, NULL);
773781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_free (monitor->last_mounts);
783781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
793781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_foreach (monitor->volumes, (GFunc)g_object_unref, NULL);
803781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_free (monitor->volumes);
813ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  g_list_foreach (monitor->mounts, (GFunc)g_object_unref, NULL);
823ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  g_list_free (monitor->mounts);
833781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
843781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  if (G_OBJECT_CLASS (g_unix_volume_monitor_parent_class)->finalize)
853781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    (*G_OBJECT_CLASS (g_unix_volume_monitor_parent_class)->finalize) (object);
863781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
873781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
883781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic GList *
893ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenget_mounts (GVolumeMonitor *volume_monitor)
903781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
913781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixVolumeMonitor *monitor;
923781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *l;
933781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
943781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  monitor = G_UNIX_VOLUME_MONITOR (volume_monitor);
953781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
963ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  l = g_list_copy (monitor->mounts);
973781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_foreach (l, (GFunc)g_object_ref, NULL);
983781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
993781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  return l;
1003781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
1013781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1023781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic GList *
1033ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenget_volumes (GVolumeMonitor *volume_monitor)
1043781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
1053781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixVolumeMonitor *monitor;
1063781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *l;
1073781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1083781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  monitor = G_UNIX_VOLUME_MONITOR (volume_monitor);
1093781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1103ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  l = g_list_copy (monitor->volumes);
1113781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_foreach (l, (GFunc)g_object_ref, NULL);
1123781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1133781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  return l;
1143781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
1153781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1163ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic GList *
1173ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenget_connected_drives (GVolumeMonitor *volume_monitor)
1183781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
1193ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  return NULL;
1203ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen}
1213ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen
122f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthenstatic GVolume *
123f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthenget_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
124f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen{
125f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen  return NULL;
126f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen}
127f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen
128f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthenstatic GMount *
129f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthenget_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
130f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen{
131f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen  return NULL;
132f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen}
133f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen
1343ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic GMount *
1353ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenget_mount_for_mount_path (const char *mount_path)
1363ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen{
1373ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  GUnixMountEntry *mount_entry;
1383781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixMount *mount;
1393781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
140feb5258cf9ca9c3b3d9a58a98b1c6c75c822855aMatthias Clasen  mount_entry = g_unix_mount_at (mount_path, NULL);
1413781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1423ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  /* TODO: Set mountable volume? */
1433ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  mount = _g_unix_mount_new (NULL, mount_entry, NULL);
1443781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1453ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  return G_MOUNT (mount);
1463781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
1473781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1483781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void
1493781343738de4abddf56982325a77bd70a98cd26Alexander Larssong_unix_volume_monitor_class_init (GUnixVolumeMonitorClass *klass)
1503781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
1513781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1523781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass);
1533781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GNativeVolumeMonitorClass *native_class = G_NATIVE_VOLUME_MONITOR_CLASS (klass);
1543781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1553781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  gobject_class->finalize = g_unix_volume_monitor_finalize;
1563781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1573ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  monitor_class->get_mounts = get_mounts;
1583ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  monitor_class->get_volumes = get_volumes;
1593781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  monitor_class->get_connected_drives = get_connected_drives;
160f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen  monitor_class->get_volume_for_uuid = get_volume_for_uuid;
161f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen  monitor_class->get_mount_for_uuid = get_mount_for_uuid;
1623781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1633781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  native_class->priority = 0;
1643ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  native_class->get_mount_for_mount_path = get_mount_for_mount_path;
1653781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
1663781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1673781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void
1683781343738de4abddf56982325a77bd70a98cd26Alexander Larssonmountpoints_changed (GUnixMountMonitor *mount_monitor,
169a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen		     gpointer           user_data)
1703781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
1713781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixVolumeMonitor *unix_monitor = user_data;
1723781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1733ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  /* Update both to make sure volumes are created before mounts */
1743781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  update_volumes (unix_monitor);
1753ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  update_mounts (unix_monitor);
1763781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
1773781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1783781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void
1793781343738de4abddf56982325a77bd70a98cd26Alexander Larssonmounts_changed (GUnixMountMonitor *mount_monitor,
180a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen		gpointer           user_data)
1813781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
1823781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixVolumeMonitor *unix_monitor = user_data;
1833781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1843ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  /* Update both to make sure volumes are created before mounts */
1853781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  update_volumes (unix_monitor);
1863ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  update_mounts (unix_monitor);
1873781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
1883781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1893781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void
1903781343738de4abddf56982325a77bd70a98cd26Alexander Larssong_unix_volume_monitor_init (GUnixVolumeMonitor *unix_monitor)
1913781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
1923781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1933781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  unix_monitor->mount_monitor = g_unix_mount_monitor_new ();
1943781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1953781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_signal_connect (unix_monitor->mount_monitor,
1963781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		    "mounts_changed", G_CALLBACK (mounts_changed),
1973781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		    unix_monitor);
1983781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
1993781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_signal_connect (unix_monitor->mount_monitor,
2003781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		    "mountpoints_changed", G_CALLBACK (mountpoints_changed),
2013781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		    unix_monitor);
2023781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2033781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  update_volumes (unix_monitor);
2043ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  update_mounts (unix_monitor);
2053781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
2063781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2073781343738de4abddf56982325a77bd70a98cd26Alexander Larsson/**
2083781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * g_unix_volume_monitor_new:
2093781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *
2103781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * Returns:  a new #GVolumeMonitor.
2113781343738de4abddf56982325a77bd70a98cd26Alexander Larsson **/
2123781343738de4abddf56982325a77bd70a98cd26Alexander LarssonGVolumeMonitor *
213d9594f5709313d6e7a8a4f3e5f3b23fc72017417Alexander Larsson_g_unix_volume_monitor_new (void)
2143781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
2153781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixVolumeMonitor *monitor;
2163781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2173781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  monitor = g_object_new (G_TYPE_UNIX_VOLUME_MONITOR, NULL);
2183781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2193781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  return G_VOLUME_MONITOR (monitor);
2203781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
2213781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2223781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void
223a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasendiff_sorted_lists (GList         *list1,
224a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen                   GList         *list2,
225a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen                   GCompareFunc   compare,
226a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen		   GList        **added,
227a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen                   GList        **removed)
2283781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
2293781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  int order;
2303781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2313781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  *added = *removed = NULL;
2323781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2333781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  while (list1 != NULL &&
2343781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	 list2 != NULL)
2353781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
2363781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      order = (*compare) (list1->data, list2->data);
2373781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      if (order < 0)
2383781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	{
2393781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	  *removed = g_list_prepend (*removed, list1->data);
2403781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	  list1 = list1->next;
2413781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	}
2423781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      else if (order > 0)
2433781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	{
2443781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	  *added = g_list_prepend (*added, list2->data);
2453781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	  list2 = list2->next;
2463781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	}
2473781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      else
2483781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	{ /* same item */
2493781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	  list1 = list1->next;
2503781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	  list2 = list2->next;
2513781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	}
2523781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
2533781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2543781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  while (list1 != NULL)
2553781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
2563781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      *removed = g_list_prepend (*removed, list1->data);
2573781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      list1 = list1->next;
2583781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
2593781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  while (list2 != NULL)
2603781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
2613781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      *added = g_list_prepend (*added, list2->data);
2623781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      list2 = list2->next;
2633781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
2643781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
2653781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2663781343738de4abddf56982325a77bd70a98cd26Alexander Larsson/**
2673ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen * _g_unix_volume_monitor_lookup_volume_for_mount_path:
2683781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * @monitor:
2693ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen * @mount_path:
2703781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *
2713ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen * Returns:  #GUnixVolume for the given @mount_path.
2723781343738de4abddf56982325a77bd70a98cd26Alexander Larsson **/
2733ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid ZeuthenGUnixVolume *
2743ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen_g_unix_volume_monitor_lookup_volume_for_mount_path (GUnixVolumeMonitor *monitor,
2753ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen                                                     const char         *mount_path)
2763781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
2773781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *l;
2783781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2793ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  for (l = monitor->volumes; l != NULL; l = l->next)
2803781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
2813ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      GUnixVolume *volume = l->data;
2823781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2833ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      if (_g_unix_volume_has_mount_path (volume, mount_path))
2843ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	return volume;
2853781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
2863781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2873781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  return NULL;
2883781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
2893781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2903ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic GUnixMount *
2913ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenfind_mount_by_mountpath (GUnixVolumeMonitor *monitor,
2923ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen                         const char *mount_path)
2933781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
2943781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *l;
2953781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
2963ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  for (l = monitor->mounts; l != NULL; l = l->next)
2973781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
2983ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      GUnixMount *mount = l->data;
2993781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3003ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      if (_g_unix_mount_has_mount_path (mount, mount_path))
3013ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	return mount;
3023781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
3033781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3043781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  return NULL;
3053781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
3063781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3073781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void
3083ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenupdate_volumes (GUnixVolumeMonitor *monitor)
3093781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
3103781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *new_mountpoints;
3113781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *removed, *added;
3123781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *l;
3133ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  GUnixVolume *volume;
3143781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
315feb5258cf9ca9c3b3d9a58a98b1c6c75c822855aMatthias Clasen  new_mountpoints = g_unix_mount_points_get (NULL);
3163781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3173781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  new_mountpoints = g_list_sort (new_mountpoints, (GCompareFunc) g_unix_mount_point_compare);
3183781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3193781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  diff_sorted_lists (monitor->last_mountpoints,
3203781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		     new_mountpoints, (GCompareFunc) g_unix_mount_point_compare,
3213781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		     &added, &removed);
3223781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3233781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  for (l = removed; l != NULL; l = l->next)
3243781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
3253781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      GUnixMountPoint *mountpoint = l->data;
3263781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3273ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor,
3283ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen                                                                    g_unix_mount_point_get_mount_path (mountpoint));
3293ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      if (volume)
3303781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	{
3313ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  _g_unix_volume_disconnected (volume);
3323ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  monitor->volumes = g_list_remove (monitor->volumes, volume);
3333ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  g_signal_emit_by_name (monitor, "volume_removed", volume);
3343ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  g_object_unref (volume);
3353781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	}
3363781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
3373781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3383781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  for (l = added; l != NULL; l = l->next)
3393781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
3403781343738de4abddf56982325a77bd70a98cd26Alexander Larsson      GUnixMountPoint *mountpoint = l->data;
3413781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3423ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      volume = _g_unix_volume_new (G_VOLUME_MONITOR (monitor), mountpoint);
3433ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      if (volume)
3443781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	{
3453ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  monitor->volumes = g_list_prepend (monitor->volumes, volume);
3463ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  g_signal_emit_by_name (monitor, "volume_added", volume);
3473781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	}
3483781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
3493781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3503781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_free (added);
3513781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_free (removed);
3523781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_foreach (monitor->last_mountpoints,
3533781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		  (GFunc)g_unix_mount_point_free, NULL);
3543781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_free (monitor->last_mountpoints);
3553781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  monitor->last_mountpoints = new_mountpoints;
3563781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
3573781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3583781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void
3593ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenupdate_mounts (GUnixVolumeMonitor *monitor)
3603781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{
3613781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *new_mounts;
3623781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *removed, *added;
3633781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GList *l;
3643ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen  GUnixMount *mount;
3653781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  GUnixVolume *volume;
3663781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  const char *mount_path;
3673781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
368feb5258cf9ca9c3b3d9a58a98b1c6c75c822855aMatthias Clasen  new_mounts = g_unix_mounts_get (NULL);
3693781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3703781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  new_mounts = g_list_sort (new_mounts, (GCompareFunc) g_unix_mount_compare);
3713781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3723781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  diff_sorted_lists (monitor->last_mounts,
3733781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		     new_mounts, (GCompareFunc) g_unix_mount_compare,
3743781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		     &added, &removed);
3753781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3763781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  for (l = removed; l != NULL; l = l->next)
3773781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
3783ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      GUnixMountEntry *mount_entry = l->data;
3793781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3803ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      mount = find_mount_by_mountpath (monitor, g_unix_mount_get_mount_path (mount_entry));
3813ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      if (mount)
3823781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	{
3833ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  _g_unix_mount_unmounted (mount);
3843ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  monitor->mounts = g_list_remove (monitor->mounts, mount);
3853ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  g_signal_emit_by_name (monitor, "mount_removed", mount);
3863ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  g_object_unref (mount);
3873781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	}
3883781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
3893781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3903781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  for (l = added; l != NULL; l = l->next)
3913781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    {
3923ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      GUnixMountEntry *mount_entry = l->data;
3933781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3943ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      mount_path = g_unix_mount_get_mount_path (mount_entry);
3953781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
3963ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, mount_path);
3973ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      mount = _g_unix_mount_new (G_VOLUME_MONITOR (monitor), mount_entry, volume);
3983ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen      if (mount)
3993781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	{
4003ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  monitor->mounts = g_list_prepend (monitor->mounts, mount);
4013ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen	  g_signal_emit_by_name (monitor, "mount_added", mount);
4023781343738de4abddf56982325a77bd70a98cd26Alexander Larsson	}
4033781343738de4abddf56982325a77bd70a98cd26Alexander Larsson    }
4043781343738de4abddf56982325a77bd70a98cd26Alexander Larsson
4053781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_free (added);
4063781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_free (removed);
4073781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_foreach (monitor->last_mounts,
4083781343738de4abddf56982325a77bd70a98cd26Alexander Larsson		  (GFunc)g_unix_mount_free, NULL);
4093781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  g_list_free (monitor->last_mounts);
4103781343738de4abddf56982325a77bd70a98cd26Alexander Larsson  monitor->last_mounts = new_mounts;
4113781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}
412