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 26761424465aaad736916b029383483b6ac419d831Johan Dahlin#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" 353d93bf6968884d75dd2706ef85e2014305eb92f2Cody Russell#include "gmount.h" 363ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen#include "gmountprivate.h" 373d93bf6968884d75dd2706ef85e2014305eb92f2Cody Russell#include "giomodule.h" 383781343738de4abddf56982325a77bd70a98cd26Alexander Larsson#include "glibintl.h" 393781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 407f3280230bc9448a5750fc17a6eabef691ba25f4Alexander Larsson#include "gioalias.h" 417f3280230bc9448a5750fc17a6eabef691ba25f4Alexander Larsson 423781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstruct _GUnixVolumeMonitor { 433781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GNativeVolumeMonitor parent; 443781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 453781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixMountMonitor *mount_monitor; 463781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 473781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *last_mountpoints; 483781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *last_mounts; 493781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 503781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *volumes; 513ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen GList *mounts; 523781343738de4abddf56982325a77bd70a98cd26Alexander Larsson}; 533781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 543ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic void mountpoints_changed (GUnixMountMonitor *mount_monitor, 553ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen gpointer user_data); 563ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic void mounts_changed (GUnixMountMonitor *mount_monitor, 573ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen gpointer user_data); 583ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic void update_volumes (GUnixVolumeMonitor *monitor); 593ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic void update_mounts (GUnixVolumeMonitor *monitor); 603781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 61d9594f5709313d6e7a8a4f3e5f3b23fc72017417Alexander Larsson#define g_unix_volume_monitor_get_type _g_unix_volume_monitor_get_type 62bff9ecedbbea1a794827f569638365db40c442e6Alexander LarssonG_DEFINE_TYPE_WITH_CODE (GUnixVolumeMonitor, g_unix_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR, 63bff9ecedbbea1a794827f569638365db40c442e6Alexander Larsson g_io_extension_point_implement (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME, 64bff9ecedbbea1a794827f569638365db40c442e6Alexander Larsson g_define_type_id, 65bff9ecedbbea1a794827f569638365db40c442e6Alexander Larsson "unix", 66bff9ecedbbea1a794827f569638365db40c442e6Alexander Larsson 0)); 673781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 683781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void 693781343738de4abddf56982325a77bd70a98cd26Alexander Larssong_unix_volume_monitor_finalize (GObject *object) 703781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 713781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixVolumeMonitor *monitor; 723781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 733781343738de4abddf56982325a77bd70a98cd26Alexander Larsson monitor = G_UNIX_VOLUME_MONITOR (object); 743781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 753781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mountpoints_changed, monitor); 763781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_signal_handlers_disconnect_by_func (monitor->mount_monitor, mounts_changed, monitor); 773781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 783781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_object_unref (monitor->mount_monitor); 793781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 803ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen g_list_foreach (monitor->last_mountpoints, (GFunc)g_unix_mount_point_free, NULL); 813ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen g_list_free (monitor->last_mountpoints); 823781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_foreach (monitor->last_mounts, (GFunc)g_unix_mount_free, NULL); 833781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_free (monitor->last_mounts); 843781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 853781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_foreach (monitor->volumes, (GFunc)g_object_unref, NULL); 863781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_free (monitor->volumes); 873ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen g_list_foreach (monitor->mounts, (GFunc)g_object_unref, NULL); 883ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen g_list_free (monitor->mounts); 89a4427bfff5d31499dc0b46fa3f734bc92f7d0dd5Michael Natterer 90a4427bfff5d31499dc0b46fa3f734bc92f7d0dd5Michael Natterer G_OBJECT_CLASS (g_unix_volume_monitor_parent_class)->finalize (object); 913781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 923781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 9373477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larssonstatic void 9473477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larssong_unix_volume_monitor_dispose (GObject *object) 9573477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson{ 9673477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson GUnixVolumeMonitor *monitor; 9773477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson 9873477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson monitor = G_UNIX_VOLUME_MONITOR (object); 9973477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson g_list_foreach (monitor->volumes, (GFunc)g_object_unref, NULL); 10073477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson g_list_free (monitor->volumes); 10173477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson monitor->volumes = NULL; 10273477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson 10373477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson g_list_foreach (monitor->mounts, (GFunc)g_object_unref, NULL); 10473477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson g_list_free (monitor->mounts); 10573477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson monitor->mounts = NULL; 10673477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson 10773477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson G_OBJECT_CLASS (g_unix_volume_monitor_parent_class)->dispose (object); 10873477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson} 10973477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson 1103781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic GList * 1113ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenget_mounts (GVolumeMonitor *volume_monitor) 1123781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 1133781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixVolumeMonitor *monitor; 1143781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *l; 1153781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1163781343738de4abddf56982325a77bd70a98cd26Alexander Larsson monitor = G_UNIX_VOLUME_MONITOR (volume_monitor); 1173781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1183ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen l = g_list_copy (monitor->mounts); 1193781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_foreach (l, (GFunc)g_object_ref, NULL); 1203781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1213781343738de4abddf56982325a77bd70a98cd26Alexander Larsson return l; 1223781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 1233781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1243781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic GList * 1253ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenget_volumes (GVolumeMonitor *volume_monitor) 1263781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 1273781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixVolumeMonitor *monitor; 1283781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *l; 1293781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1303781343738de4abddf56982325a77bd70a98cd26Alexander Larsson monitor = G_UNIX_VOLUME_MONITOR (volume_monitor); 1313781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1323ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen l = g_list_copy (monitor->volumes); 1333781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_foreach (l, (GFunc)g_object_ref, NULL); 1343781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1353781343738de4abddf56982325a77bd70a98cd26Alexander Larsson return l; 1363781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 1373781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1383ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic GList * 1393ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenget_connected_drives (GVolumeMonitor *volume_monitor) 1403781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 1413ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen return NULL; 1423ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen} 1433ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen 144f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthenstatic GVolume * 145f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthenget_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) 146f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen{ 147f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen return NULL; 148f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen} 149f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen 150f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthenstatic GMount * 151f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthenget_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) 152f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen{ 153f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen return NULL; 154f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen} 155f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen 156c4e3cfbf4070d9bf255d08e23591e8a8dc476d72Alexander Larssonstatic gboolean 157c4e3cfbf4070d9bf255d08e23591e8a8dc476d72Alexander Larssonis_supported (void) 158c4e3cfbf4070d9bf255d08e23591e8a8dc476d72Alexander Larsson{ 159c4e3cfbf4070d9bf255d08e23591e8a8dc476d72Alexander Larsson return TRUE; 160c4e3cfbf4070d9bf255d08e23591e8a8dc476d72Alexander Larsson} 161c4e3cfbf4070d9bf255d08e23591e8a8dc476d72Alexander Larsson 1623ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic GMount * 163c4e3cfbf4070d9bf255d08e23591e8a8dc476d72Alexander Larssonget_mount_for_mount_path (const char *mount_path, 164c4e3cfbf4070d9bf255d08e23591e8a8dc476d72Alexander Larsson GCancellable *cancellable) 1653ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen{ 1663ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen GUnixMountEntry *mount_entry; 1673781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixMount *mount; 1683781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 169feb5258cf9ca9c3b3d9a58a98b1c6c75c822855aMatthias Clasen mount_entry = g_unix_mount_at (mount_path, NULL); 1704d23d2647a324c33de1e8bfbbf1d5720ec8bb728Matthias Clasen 1714d23d2647a324c33de1e8bfbbf1d5720ec8bb728Matthias Clasen if (!mount_entry) 1724d23d2647a324c33de1e8bfbbf1d5720ec8bb728Matthias Clasen return NULL; 1734d23d2647a324c33de1e8bfbbf1d5720ec8bb728Matthias Clasen 1743ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen /* TODO: Set mountable volume? */ 1753ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen mount = _g_unix_mount_new (NULL, mount_entry, NULL); 1763781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1776dba7df4b12852623a9b893301b22af028184793Matthias Clasen g_unix_mount_free (mount_entry); 1786dba7df4b12852623a9b893301b22af028184793Matthias Clasen 1793ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen return G_MOUNT (mount); 1803781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 1813781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1823781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void 1833781343738de4abddf56982325a77bd70a98cd26Alexander Larssong_unix_volume_monitor_class_init (GUnixVolumeMonitorClass *klass) 1843781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 1853781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 1863781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass); 1873781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GNativeVolumeMonitorClass *native_class = G_NATIVE_VOLUME_MONITOR_CLASS (klass); 1883781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1893781343738de4abddf56982325a77bd70a98cd26Alexander Larsson gobject_class->finalize = g_unix_volume_monitor_finalize; 19073477419e89e73c4af49c3f2d88493af4f57ce90Alexander Larsson gobject_class->dispose = g_unix_volume_monitor_dispose; 1913781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1923ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen monitor_class->get_mounts = get_mounts; 1933ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen monitor_class->get_volumes = get_volumes; 1943781343738de4abddf56982325a77bd70a98cd26Alexander Larsson monitor_class->get_connected_drives = get_connected_drives; 195f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen monitor_class->get_volume_for_uuid = get_volume_for_uuid; 196f4add8f0faf4a8c2ca1cdb4f99f5f3d0d66aaff8David Zeuthen monitor_class->get_mount_for_uuid = get_mount_for_uuid; 19728d1c8e0ad86253c84de1ee948a338eec98ae701Alexander Larsson monitor_class->is_supported = is_supported; 1983781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 1993ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen native_class->get_mount_for_mount_path = get_mount_for_mount_path; 2003781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 2013781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2023781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void 2033781343738de4abddf56982325a77bd70a98cd26Alexander Larssonmountpoints_changed (GUnixMountMonitor *mount_monitor, 204a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen gpointer user_data) 2053781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 2063781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixVolumeMonitor *unix_monitor = user_data; 2073781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2083ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen /* Update both to make sure volumes are created before mounts */ 2093781343738de4abddf56982325a77bd70a98cd26Alexander Larsson update_volumes (unix_monitor); 2103ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen update_mounts (unix_monitor); 2113781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 2123781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2133781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void 2143781343738de4abddf56982325a77bd70a98cd26Alexander Larssonmounts_changed (GUnixMountMonitor *mount_monitor, 215a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen gpointer user_data) 2163781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 2173781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixVolumeMonitor *unix_monitor = user_data; 2183781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2193ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen /* Update both to make sure volumes are created before mounts */ 2203781343738de4abddf56982325a77bd70a98cd26Alexander Larsson update_volumes (unix_monitor); 2213ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen update_mounts (unix_monitor); 2223781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 2233781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2243781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void 2253781343738de4abddf56982325a77bd70a98cd26Alexander Larssong_unix_volume_monitor_init (GUnixVolumeMonitor *unix_monitor) 2263781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 2273781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2283781343738de4abddf56982325a77bd70a98cd26Alexander Larsson unix_monitor->mount_monitor = g_unix_mount_monitor_new (); 2293781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2303781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_signal_connect (unix_monitor->mount_monitor, 2318d37a7964d3b41de330aa581b61eda374b093e71Sven Neumann "mounts-changed", G_CALLBACK (mounts_changed), 2323781343738de4abddf56982325a77bd70a98cd26Alexander Larsson unix_monitor); 2333781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2343781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_signal_connect (unix_monitor->mount_monitor, 2358d37a7964d3b41de330aa581b61eda374b093e71Sven Neumann "mountpoints-changed", G_CALLBACK (mountpoints_changed), 2363781343738de4abddf56982325a77bd70a98cd26Alexander Larsson unix_monitor); 2373781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2383781343738de4abddf56982325a77bd70a98cd26Alexander Larsson update_volumes (unix_monitor); 2393ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen update_mounts (unix_monitor); 2403781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 2413781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2423781343738de4abddf56982325a77bd70a98cd26Alexander Larsson/** 2433781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * g_unix_volume_monitor_new: 2443781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * 2453781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * Returns: a new #GVolumeMonitor. 2463781343738de4abddf56982325a77bd70a98cd26Alexander Larsson **/ 2473781343738de4abddf56982325a77bd70a98cd26Alexander LarssonGVolumeMonitor * 248d9594f5709313d6e7a8a4f3e5f3b23fc72017417Alexander Larsson_g_unix_volume_monitor_new (void) 2493781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 2503781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixVolumeMonitor *monitor; 2513781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2523781343738de4abddf56982325a77bd70a98cd26Alexander Larsson monitor = g_object_new (G_TYPE_UNIX_VOLUME_MONITOR, NULL); 2533781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2543781343738de4abddf56982325a77bd70a98cd26Alexander Larsson return G_VOLUME_MONITOR (monitor); 2553781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 2563781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2573781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void 258a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasendiff_sorted_lists (GList *list1, 259a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen GList *list2, 260a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen GCompareFunc compare, 261a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen GList **added, 262a2ca589703273fca80cb126430a8b058aba3eb52Matthias Clasen GList **removed) 2633781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 2643781343738de4abddf56982325a77bd70a98cd26Alexander Larsson int order; 2653781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2663781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *added = *removed = NULL; 2673781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2683781343738de4abddf56982325a77bd70a98cd26Alexander Larsson while (list1 != NULL && 2693781343738de4abddf56982325a77bd70a98cd26Alexander Larsson list2 != NULL) 2703781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 2713781343738de4abddf56982325a77bd70a98cd26Alexander Larsson order = (*compare) (list1->data, list2->data); 2723781343738de4abddf56982325a77bd70a98cd26Alexander Larsson if (order < 0) 2733781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 2743781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *removed = g_list_prepend (*removed, list1->data); 2753781343738de4abddf56982325a77bd70a98cd26Alexander Larsson list1 = list1->next; 2763781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 2773781343738de4abddf56982325a77bd70a98cd26Alexander Larsson else if (order > 0) 2783781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 2793781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *added = g_list_prepend (*added, list2->data); 2803781343738de4abddf56982325a77bd70a98cd26Alexander Larsson list2 = list2->next; 2813781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 2823781343738de4abddf56982325a77bd70a98cd26Alexander Larsson else 2833781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { /* same item */ 2843781343738de4abddf56982325a77bd70a98cd26Alexander Larsson list1 = list1->next; 2853781343738de4abddf56982325a77bd70a98cd26Alexander Larsson list2 = list2->next; 2863781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 2873781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 2883781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 2893781343738de4abddf56982325a77bd70a98cd26Alexander Larsson while (list1 != NULL) 2903781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 2913781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *removed = g_list_prepend (*removed, list1->data); 2923781343738de4abddf56982325a77bd70a98cd26Alexander Larsson list1 = list1->next; 2933781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 2943781343738de4abddf56982325a77bd70a98cd26Alexander Larsson while (list2 != NULL) 2953781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 2963781343738de4abddf56982325a77bd70a98cd26Alexander Larsson *added = g_list_prepend (*added, list2->data); 2973781343738de4abddf56982325a77bd70a98cd26Alexander Larsson list2 = list2->next; 2983781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 2993781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 3003781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3013781343738de4abddf56982325a77bd70a98cd26Alexander Larsson/** 3023ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen * _g_unix_volume_monitor_lookup_volume_for_mount_path: 3033781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * @monitor: 3043ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen * @mount_path: 3053781343738de4abddf56982325a77bd70a98cd26Alexander Larsson * 3063ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen * Returns: #GUnixVolume for the given @mount_path. 3073781343738de4abddf56982325a77bd70a98cd26Alexander Larsson **/ 3083ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid ZeuthenGUnixVolume * 3093ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen_g_unix_volume_monitor_lookup_volume_for_mount_path (GUnixVolumeMonitor *monitor, 3103ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen const char *mount_path) 3113781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 3123781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *l; 3133781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3143ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen for (l = monitor->volumes; l != NULL; l = l->next) 3153781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 3163ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen GUnixVolume *volume = l->data; 3173781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3183ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen if (_g_unix_volume_has_mount_path (volume, mount_path)) 3193ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen return volume; 3203781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 3213781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3223781343738de4abddf56982325a77bd70a98cd26Alexander Larsson return NULL; 3233781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 3243781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3253ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenstatic GUnixMount * 3263ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenfind_mount_by_mountpath (GUnixVolumeMonitor *monitor, 3273ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen const char *mount_path) 3283781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 3293781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *l; 3303781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3313ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen for (l = monitor->mounts; l != NULL; l = l->next) 3323781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 3333ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen GUnixMount *mount = l->data; 3343781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3353ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen if (_g_unix_mount_has_mount_path (mount, mount_path)) 3363ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen return mount; 3373781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 3383781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3393781343738de4abddf56982325a77bd70a98cd26Alexander Larsson return NULL; 3403781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 3413781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3423781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void 3433ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenupdate_volumes (GUnixVolumeMonitor *monitor) 3443781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 3453781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *new_mountpoints; 3463781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *removed, *added; 3473781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *l; 3483ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen GUnixVolume *volume; 3493781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 350feb5258cf9ca9c3b3d9a58a98b1c6c75c822855aMatthias Clasen new_mountpoints = g_unix_mount_points_get (NULL); 3513781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3523781343738de4abddf56982325a77bd70a98cd26Alexander Larsson new_mountpoints = g_list_sort (new_mountpoints, (GCompareFunc) g_unix_mount_point_compare); 3533781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3543781343738de4abddf56982325a77bd70a98cd26Alexander Larsson diff_sorted_lists (monitor->last_mountpoints, 3553781343738de4abddf56982325a77bd70a98cd26Alexander Larsson new_mountpoints, (GCompareFunc) g_unix_mount_point_compare, 3563781343738de4abddf56982325a77bd70a98cd26Alexander Larsson &added, &removed); 3573781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3583781343738de4abddf56982325a77bd70a98cd26Alexander Larsson for (l = removed; l != NULL; l = l->next) 3593781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 3603781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixMountPoint *mountpoint = l->data; 3613781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3623ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, 3633ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen g_unix_mount_point_get_mount_path (mountpoint)); 3643ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen if (volume) 3653781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 3663ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen _g_unix_volume_disconnected (volume); 3673ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen monitor->volumes = g_list_remove (monitor->volumes, volume); 3688d37a7964d3b41de330aa581b61eda374b093e71Sven Neumann g_signal_emit_by_name (monitor, "volume-removed", volume); 36988679aba98d30ba069edfffb46257ef77451d641David Zeuthen g_signal_emit_by_name (volume, "removed"); 3703ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen g_object_unref (volume); 3713781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 3723781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 3733781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3743781343738de4abddf56982325a77bd70a98cd26Alexander Larsson for (l = added; l != NULL; l = l->next) 3753781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 3763781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixMountPoint *mountpoint = l->data; 3773781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3783ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen volume = _g_unix_volume_new (G_VOLUME_MONITOR (monitor), mountpoint); 3793ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen if (volume) 3803781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 3813ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen monitor->volumes = g_list_prepend (monitor->volumes, volume); 3828d37a7964d3b41de330aa581b61eda374b093e71Sven Neumann g_signal_emit_by_name (monitor, "volume-added", volume); 3833781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 3843781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 3853781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3863781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_free (added); 3873781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_free (removed); 3883781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_foreach (monitor->last_mountpoints, 3893781343738de4abddf56982325a77bd70a98cd26Alexander Larsson (GFunc)g_unix_mount_point_free, NULL); 3903781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_free (monitor->last_mountpoints); 3913781343738de4abddf56982325a77bd70a98cd26Alexander Larsson monitor->last_mountpoints = new_mountpoints; 3923781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 3933781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 3943781343738de4abddf56982325a77bd70a98cd26Alexander Larssonstatic void 3953ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthenupdate_mounts (GUnixVolumeMonitor *monitor) 3963781343738de4abddf56982325a77bd70a98cd26Alexander Larsson{ 3973781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *new_mounts; 3983781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *removed, *added; 3993781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GList *l; 4003ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen GUnixMount *mount; 4013781343738de4abddf56982325a77bd70a98cd26Alexander Larsson GUnixVolume *volume; 4023781343738de4abddf56982325a77bd70a98cd26Alexander Larsson const char *mount_path; 4033781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 404feb5258cf9ca9c3b3d9a58a98b1c6c75c822855aMatthias Clasen new_mounts = g_unix_mounts_get (NULL); 4053781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 4063781343738de4abddf56982325a77bd70a98cd26Alexander Larsson new_mounts = g_list_sort (new_mounts, (GCompareFunc) g_unix_mount_compare); 4073781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 4083781343738de4abddf56982325a77bd70a98cd26Alexander Larsson diff_sorted_lists (monitor->last_mounts, 4093781343738de4abddf56982325a77bd70a98cd26Alexander Larsson new_mounts, (GCompareFunc) g_unix_mount_compare, 4103781343738de4abddf56982325a77bd70a98cd26Alexander Larsson &added, &removed); 4113781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 4123781343738de4abddf56982325a77bd70a98cd26Alexander Larsson for (l = removed; l != NULL; l = l->next) 4133781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 4143ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen GUnixMountEntry *mount_entry = l->data; 4153781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 4163ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen mount = find_mount_by_mountpath (monitor, g_unix_mount_get_mount_path (mount_entry)); 4173ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen if (mount) 4183781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 4193ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen _g_unix_mount_unmounted (mount); 4203ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen monitor->mounts = g_list_remove (monitor->mounts, mount); 4218d37a7964d3b41de330aa581b61eda374b093e71Sven Neumann g_signal_emit_by_name (monitor, "mount-removed", mount); 42288679aba98d30ba069edfffb46257ef77451d641David Zeuthen g_signal_emit_by_name (mount, "unmounted"); 4233ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen g_object_unref (mount); 4243781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 4253781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 4263781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 4273781343738de4abddf56982325a77bd70a98cd26Alexander Larsson for (l = added; l != NULL; l = l->next) 4283781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 4293ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen GUnixMountEntry *mount_entry = l->data; 4303781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 4313ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen mount_path = g_unix_mount_get_mount_path (mount_entry); 4323781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 4333ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen volume = _g_unix_volume_monitor_lookup_volume_for_mount_path (monitor, mount_path); 4343ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen mount = _g_unix_mount_new (G_VOLUME_MONITOR (monitor), mount_entry, volume); 4353ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen if (mount) 4363781343738de4abddf56982325a77bd70a98cd26Alexander Larsson { 4373ca9fd4dbb134088bf70f2f6584f14a559e6820aDavid Zeuthen monitor->mounts = g_list_prepend (monitor->mounts, mount); 4388d37a7964d3b41de330aa581b61eda374b093e71Sven Neumann g_signal_emit_by_name (monitor, "mount-added", mount); 4393781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 4403781343738de4abddf56982325a77bd70a98cd26Alexander Larsson } 4413781343738de4abddf56982325a77bd70a98cd26Alexander Larsson 4423781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_free (added); 4433781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_free (removed); 4443781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_foreach (monitor->last_mounts, 4453781343738de4abddf56982325a77bd70a98cd26Alexander Larsson (GFunc)g_unix_mount_free, NULL); 4463781343738de4abddf56982325a77bd70a98cd26Alexander Larsson g_list_free (monitor->last_mounts); 4473781343738de4abddf56982325a77bd70a98cd26Alexander Larsson monitor->last_mounts = new_mounts; 4483781343738de4abddf56982325a77bd70a98cd26Alexander Larsson} 449