1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: Alexander Larsson <alexl@redhat.com>
25 #include <sys/types.h>
28 #ifndef HAVE_SYSCTLBYNAME
29 #ifdef HAVE_SYS_PARAM_H
30 #include <sys/param.h>
32 #ifdef HAVE_SYS_POLL_H
46 #include "gunixmounts.h"
48 #include "gfilemonitor.h"
53 char *filesystem_type;
54 gboolean is_read_only;
55 gboolean is_system_internal;
58 struct _GUnixMountPoint {
61 char *filesystem_type;
62 gboolean is_read_only;
63 gboolean is_user_mountable;
73 static guint signals[LAST_SIGNAL];
75 struct _GUnixMountMonitor {
78 GFileMonitor *fstab_monitor;
79 GFileMonitor *mtab_monitor;
82 struct _GUnixMountMonitorClass {
83 GObjectClass parent_class;
86 static GUnixMountMonitor *the_mount_monitor = NULL;
88 static GList *_g_get_unix_mounts (void);
89 static GList *_g_get_unix_mount_points (void);
91 G_DEFINE_TYPE (GUnixMountMonitor, g_unix_mount_monitor, G_TYPE_OBJECT);
93 #define MOUNT_POLL_INTERVAL 4000
95 #ifdef HAVE_SYS_MNTTAB_H
96 #define MNTOPT_RO "ro"
101 #elif defined (HAVE_SYS_MNTTAB_H)
102 #include <sys/mnttab.h>
105 #ifdef HAVE_SYS_VFSTAB_H
106 #include <sys/vfstab.h>
109 #if defined(HAVE_SYS_MNTCTL_H) && defined(HAVE_SYS_VMOUNT_H) && defined(HAVE_SYS_VFS_H)
110 #include <sys/mntctl.h>
112 #include <sys/vmount.h>
116 #if defined(HAVE_GETMNTINFO) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
117 #include <sys/ucred.h>
118 #include <sys/mount.h>
120 #ifdef HAVE_SYS_SYSCTL_H
121 #include <sys/sysctl.h>
125 #ifndef HAVE_SETMNTENT
126 #define setmntent(f,m) fopen(f,m)
128 #ifndef HAVE_ENDMNTENT
129 #define endmntent(f) fclose(f)
133 is_in (const char *value, const char *set[])
136 for (i = 0; set[i] != NULL; i++)
138 if (strcmp (set[i], value) == 0)
145 guess_system_internal (const char *mountpoint,
149 const char *ignore_fs[] = {
167 const char *ignore_devices[] = {
176 const char *ignore_mountpoints[] = {
177 /* Includes all FHS 2.3 toplevel dirs */
200 if (is_in (fs, ignore_fs))
203 if (is_in (device, ignore_devices))
206 if (is_in (mountpoint, ignore_mountpoints))
209 if (g_str_has_prefix (mountpoint, "/dev") ||
210 g_str_has_prefix (mountpoint, "/proc") ||
211 g_str_has_prefix (mountpoint, "/sys"))
214 if (strstr (mountpoint, "/.gvfs") != NULL)
223 get_mtab_read_file (void)
227 return "/proc/mounts";
229 return _PATH_MOUNTED;
237 get_mtab_monitor_file (void)
240 return _PATH_MOUNTED;
246 G_LOCK_DEFINE_STATIC(getmntent);
249 _g_get_unix_mounts ()
251 struct mntent *mntent;
254 GUnixMount *mount_entry;
255 GHashTable *mounts_hash;
258 read_file = get_mtab_read_file ();
260 file = setmntent (read_file, "r");
266 mounts_hash = g_hash_table_new (g_str_hash, g_str_equal);
269 while ((mntent = getmntent (file)) != NULL)
271 /* ignore any mnt_fsname that is repeated and begins with a '/'
273 * We do this to avoid being fooled by --bind mounts, since
274 * these have the same device as the location they bind to.
275 * Its not an ideal solution to the problem, but its likely that
276 * the most important mountpoint is first and the --bind ones after
277 * that aren't as important. So it should work.
279 * The '/' is to handle procfs, tmpfs and other no device mounts.
281 if (mntent->mnt_fsname != NULL &&
282 mntent->mnt_fsname[0] == '/' &&
283 g_hash_table_lookup (mounts_hash, mntent->mnt_fsname))
286 mount_entry = g_new0 (GUnixMount, 1);
287 mount_entry->mount_path = g_strdup (mntent->mnt_dir);
288 mount_entry->device_path = g_strdup (mntent->mnt_fsname);
289 mount_entry->filesystem_type = g_strdup (mntent->mnt_type);
291 #if defined (HAVE_HASMNTOPT)
292 if (hasmntopt (mntent, MNTOPT_RO) != NULL)
293 mount_entry->is_read_only = TRUE;
296 mount_entry->is_system_internal =
297 guess_system_internal (mount_entry->mount_path,
298 mount_entry->filesystem_type,
299 mount_entry->device_path);
301 g_hash_table_insert (mounts_hash,
302 mount_entry->device_path,
303 mount_entry->device_path);
305 return_list = g_list_prepend (return_list, mount_entry);
307 g_hash_table_destroy (mounts_hash);
311 G_UNLOCK (getmntent);
313 return g_list_reverse (return_list);
316 #elif defined (HAVE_SYS_MNTTAB_H)
318 G_LOCK_DEFINE_STATIC(getmntent);
321 get_mtab_read_file (void)
324 return _PATH_MOUNTED;
326 return "/etc/mnttab";
331 get_mtab_monitor_file (void)
333 return get_mtab_read_file ();
337 _g_get_unix_mounts (void)
339 struct mnttab mntent;
342 GUnixMount *mount_entry;
345 read_file = get_mtab_read_file ();
347 file = setmntent (read_file, "r");
354 while (! getmntent (file, &mntent))
356 mount_entry = g_new0 (GUnixMount, 1);
358 mount_entry->mount_path = g_strdup (mntent.mnt_mountp);
359 mount_entry->device_path = g_strdup (mntent.mnt_special);
360 mount_entry->filesystem_type = g_strdup (mntent.mnt_fstype);
362 #if defined (HAVE_HASMNTOPT)
363 if (hasmntopt (&mntent, MNTOPT_RO) != NULL)
364 mount_entry->is_read_only = TRUE;
367 mount_entry->is_system_internal =
368 guess_system_internal (mount_entry->mount_path,
369 mount_entry->filesystem_type,
370 mount_entry->device_path);
372 return_list = g_list_prepend (return_list, mount_entry);
377 G_UNLOCK (getmntent);
379 return g_list_reverse (return_list);
382 #elif defined(HAVE_SYS_MNTCTL_H) && defined(HAVE_SYS_VMOUNT_H) && defined(HAVE_SYS_VFS_H)
385 get_mtab_monitor_file (void)
391 _g_get_unix_mounts (void)
393 struct vfs_ent *fs_info;
394 struct vmount *vmount_info;
396 unsigned int vmount_size;
400 if (mntctl (MCTL_QUERY, sizeof (vmount_size), &vmount_size) != 0)
402 g_warning ("Unable to know the number of mounted volumes\n");
407 vmount_info = (struct vmount*)g_malloc (vmount_size);
409 vmount_number = mntctl (MCTL_QUERY, vmount_size, vmount_info);
411 if (vmount_info->vmt_revision != VMT_REVISION)
412 g_warning ("Bad vmount structure revision number, want %d, got %d\n", VMT_REVISION, vmount_info->vmt_revision);
414 if (vmount_number < 0)
416 g_warning ("Unable to recover mounted volumes information\n");
418 g_free (vmount_info);
423 while (vmount_number > 0)
425 mount_entry = g_new0 (GUnixMount, 1);
427 mount_entry->device_path = g_strdup (vmt2dataptr (vmount_info, VMT_OBJECT));
428 mount_entry->mount_path = g_strdup (vmt2dataptr (vmount_info, VMT_STUB));
429 /* is_removable = (vmount_info->vmt_flags & MNT_REMOVABLE) ? 1 : 0; */
430 mount_entry->is_read_only = (vmount_info->vmt_flags & MNT_READONLY) ? 1 : 0;
432 fs_info = getvfsbytype (vmount_info->vmt_gfstype);
435 mount_entry->filesystem_type = g_strdup ("unknown");
437 mount_entry->filesystem_type = g_strdup (fs_info->vfsent_name);
439 mount_entry->is_system_internal =
440 guess_system_internal (mount_entry->mount_path,
441 mount_entry->filesystem_type,
442 mount_entry->device_path);
444 return_list = g_list_prepend (return_list, mount_entry);
446 vmount_info = (struct vmount *)( (char*)vmount_info
447 + vmount_info->vmt_length);
452 g_free (vmount_info);
454 return g_list_reverse (return_list);
457 #elif defined(HAVE_GETMNTINFO) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
460 get_mtab_monitor_file (void)
466 _g_get_unix_mounts (void)
468 struct statfs *mntent = NULL;
470 GUnixMount *mount_entry;
473 /* Pass MNT_NOWAIT to avoid blocking trying to update NFS mounts. */
474 if ((num_mounts = getmntinfo (&mntent, MNT_NOWAIT)) == 0)
479 for (i = 0; i < num_mounts; i++)
481 mount_entry = g_new0 (GUnixMount, 1);
483 mount_entry->mount_path = g_strdup (mntent[i].f_mntonname);
484 mount_entry->device_path = g_strdup (mntent[i].f_mntfromname);
485 mount_entry->filesystem_type = g_strdup (mntent[i].f_fstypename);
486 if (mntent[i].f_flags & MNT_RDONLY)
487 mount_entry->is_read_only = TRUE;
489 mount_entry->is_system_internal =
490 guess_system_internal (mount_entry->mount_path,
491 mount_entry->filesystem_type,
492 mount_entry->device_path);
494 return_list = g_list_prepend (return_list, mount_entry);
497 return g_list_reverse (return_list);
500 #error No _g_get_unix_mounts() implementation for system
503 /* _g_get_unix_mount_points():
505 * don't return swap and ignore mounts.
509 get_fstab_file (void)
511 #if defined(HAVE_SYS_MNTCTL_H) && defined(HAVE_SYS_VMOUNT_H) && defined(HAVE_SYS_VFS_H)
513 return "/etc/filesystems";
514 #elif defined(_PATH_MNTTAB)
516 #elif defined(VFSTAB)
525 _g_get_unix_mount_points (void)
527 struct mntent *mntent;
530 GUnixMountPoint *mount_entry;
533 read_file = get_fstab_file ();
535 file = setmntent (read_file, "r");
542 while ((mntent = getmntent (file)) != NULL)
544 if ((strcmp (mntent->mnt_dir, "ignore") == 0) ||
545 (strcmp (mntent->mnt_dir, "swap") == 0))
548 mount_entry = g_new0 (GUnixMountPoint, 1);
549 mount_entry->mount_path = g_strdup (mntent->mnt_dir);
550 mount_entry->device_path = g_strdup (mntent->mnt_fsname);
551 mount_entry->filesystem_type = g_strdup (mntent->mnt_type);
553 #ifdef HAVE_HASMNTOPT
554 if (hasmntopt (mntent, MNTOPT_RO) != NULL)
555 mount_entry->is_read_only = TRUE;
557 if (hasmntopt (mntent, "loop") != NULL)
558 mount_entry->is_loopback = TRUE;
562 if ((mntent->mnt_type != NULL && strcmp ("supermount", mntent->mnt_type) == 0)
563 #ifdef HAVE_HASMNTOPT
564 || (hasmntopt (mntent, "user") != NULL
565 && hasmntopt (mntent, "user") != hasmntopt (mntent, "user_xattr"))
566 || hasmntopt (mntent, "pamconsole") != NULL
567 || hasmntopt (mntent, "users") != NULL
568 || hasmntopt (mntent, "owner") != NULL
571 mount_entry->is_user_mountable = TRUE;
573 return_list = g_list_prepend (return_list, mount_entry);
577 G_UNLOCK (getmntent);
579 return g_list_reverse (return_list);
582 #elif defined (HAVE_SYS_MNTTAB_H)
585 _g_get_unix_mount_points (void)
587 struct mnttab mntent;
590 GUnixMountPoint *mount_entry;
593 read_file = get_fstab_file ();
595 file = setmntent (read_file, "r");
602 while (! getmntent (file, &mntent))
604 if ((strcmp (mntent.mnt_mountp, "ignore") == 0) ||
605 (strcmp (mntent.mnt_mountp, "swap") == 0))
608 mount_entry = g_new0 (GUnixMountPoint, 1);
610 mount_entry->mount_path = g_strdup (mntent.mnt_mountp);
611 mount_entry->device_path = g_strdup (mntent.mnt_special);
612 mount_entry->filesystem_type = g_strdup (mntent.mnt_fstype);
614 #ifdef HAVE_HASMNTOPT
615 if (hasmntopt (&mntent, MNTOPT_RO) != NULL)
616 mount_entry->is_read_only = TRUE;
618 if (hasmntopt (&mntent, "lofs") != NULL)
619 mount_entry->is_loopback = TRUE;
622 if ((mntent.mnt_fstype != NULL)
623 #ifdef HAVE_HASMNTOPT
624 || (hasmntopt (&mntent, "user") != NULL
625 && hasmntopt (&mntent, "user") != hasmntopt (&mntent, "user_xattr"))
626 || hasmntopt (&mntent, "pamconsole") != NULL
627 || hasmntopt (&mntent, "users") != NULL
628 || hasmntopt (&mntent, "owner") != NULL
631 mount_entry->is_user_mountable = TRUE;
634 return_list = g_list_prepend (return_list, mount_entry);
638 G_UNLOCK (getmntent);
640 return g_list_reverse (return_list);
642 #elif defined(HAVE_SYS_MNTCTL_H) && defined(HAVE_SYS_VMOUNT_H) && defined(HAVE_SYS_VFS_H)
644 /* functions to parse /etc/filesystems on aix */
646 /* read character, ignoring comments (begin with '*', end with '\n' */
648 aix_fs_getc (FILE *fd)
652 while ((c = getc (fd)) == '*')
654 while (((c = getc (fd)) != '\n') && (c != EOF))
659 /* eat all continuous spaces in a file */
661 aix_fs_ignorespace (FILE *fd)
665 while ((c = aix_fs_getc (fd)) != EOF)
667 if (!g_ascii_isspace (c))
677 /* read one word from file */
679 aix_fs_getword (FILE *fd, char *word)
683 aix_fs_ignorespace (fd);
685 while (((c = aix_fs_getc (fd)) != EOF) && !g_ascii_isspace (c))
689 while (((c = aix_fs_getc (fd)) != EOF) && (c != '"'))
701 char mnt_mount[PATH_MAX];
702 char mnt_special[PATH_MAX];
704 char mnt_options[128];
705 } AixMountTableEntry;
707 /* read mount points properties */
709 aix_fs_get (FILE *fd, AixMountTableEntry *prop)
711 static char word[PATH_MAX] = { 0 };
712 char value[PATH_MAX];
717 if (aix_fs_getword (fd, word) == EOF)
721 word[strlen(word) - 1] = 0;
722 strcpy (prop->mnt_mount, word);
724 /* read attributes and value */
726 while (aix_fs_getword (fd, word) != EOF)
728 /* test if is attribute or new stanza */
729 if (word[strlen(word) - 1] == ':')
733 aix_fs_getword (fd, value);
736 aix_fs_getword (fd, value);
738 if (strcmp (word, "dev") == 0)
739 strcpy (prop->mnt_special, value);
740 else if (strcmp (word, "vfs") == 0)
741 strcpy (prop->mnt_fstype, value);
742 else if (strcmp (word, "options") == 0)
743 strcpy(prop->mnt_options, value);
750 _g_get_unix_mount_points (void)
752 struct mntent *mntent;
755 GUnixMountPoint *mount_entry;
756 AixMountTableEntry mntent;
759 read_file = get_fstab_file ();
761 file = setmntent (read_file, "r");
767 while (!aix_fs_get (file, &mntent))
769 if (strcmp ("cdrfs", mntent.mnt_fstype) == 0)
771 mount_entry = g_new0 (GUnixMountPoint, 1);
774 mount_entry->mount_path = g_strdup (mntent.mnt_mount);
775 mount_entry->device_path = g_strdup (mntent.mnt_special);
776 mount_entry->filesystem_type = g_strdup (mntent.mnt_fstype);
777 mount_entry->is_read_only = TRUE;
778 mount_entry->is_user_mountable = TRUE;
780 return_list = g_list_prepend (return_list, mount_entry);
786 return g_list_reverse (return_list);
789 #elif defined(HAVE_GETMNTINFO) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
792 _g_get_unix_mount_points (void)
794 struct fstab *fstab = NULL;
795 GUnixMountPoint *mount_entry;
797 #ifdef HAVE_SYS_SYSCTL_H
799 size_t len = sizeof(usermnt);
808 #ifdef HAVE_SYS_SYSCTL_H
809 #if defined(HAVE_SYSCTLBYNAME)
810 sysctlbyname ("vfs.usermount", &usermnt, &len, NULL, 0);
811 #elif defined(CTL_VFS) && defined(VFS_USERMOUNT)
816 mib[1] = VFS_USERMOUNT;
817 sysctl (mib, 2, &usermnt, &len, NULL, 0);
819 #elif defined(CTL_KERN) && defined(KERN_USERMOUNT)
824 mib[1] = KERN_USERMOUNT;
825 sysctl (mib, 2, &usermnt, &len, NULL, 0);
830 while ((fstab = getfsent ()) != NULL)
832 if (strcmp (fstab->fs_vfstype, "swap") == 0)
835 mount_entry = g_new0 (GUnixMountPoint, 1);
837 mount_entry->mount_path = g_strdup (fstab->fs_file);
838 mount_entry->device_path = g_strdup (fstab->fs_spec);
839 mount_entry->filesystem_type = g_strdup (fstab->fs_vfstype);
841 if (strcmp (fstab->fs_type, "ro") == 0)
842 mount_entry->is_read_only = TRUE;
844 #ifdef HAVE_SYS_SYSCTL_H
847 uid_t uid = getuid ();
848 if (stat (fstab->fs_file, &sb) == 0)
850 if (uid == 0 || sb.st_uid == uid)
851 mount_entry->is_user_mountable = TRUE;
856 return_list = g_list_prepend (return_list, mount_entry);
861 return g_list_reverse (return_list);
864 #error No g_get_mount_table() implementation for system
868 get_mounts_timestamp (void)
870 const char *monitor_file;
873 monitor_file = get_mtab_monitor_file ();
876 if (stat (monitor_file, &buf) == 0)
877 return (guint64)buf.st_mtime;
883 get_mount_points_timestamp (void)
885 const char *monitor_file;
888 monitor_file = get_fstab_file ();
891 if (stat (monitor_file, &buf) == 0)
892 return (guint64)buf.st_mtime;
899 * @time_read: guint64 to contain a timestamp.
901 * Returns a #GList of the UNIX mounts. If @time_read
902 * is set, it will be filled with the mount timestamp.
905 g_get_unix_mounts (guint64 *time_read)
908 *time_read = get_mounts_timestamp ();
910 return _g_get_unix_mounts ();
914 * g_get_unix_mount_at:
915 * @mount_path: path to mount.
916 * @time_read: guint64 to contain a timestamp.
918 * Returns a #GUnixMount. If @time_read
919 * is set, it will be filled with the mount timestamp.
922 g_get_unix_mount_at (const char *mount_path,
926 GUnixMount *mount_entry, *found;
928 mounts = g_get_unix_mounts (time_read);
931 for (l = mounts; l != NULL; l = l->next)
933 mount_entry = l->data;
935 if (strcmp (mount_path, mount_entry->mount_path) == 0)
938 g_unix_mount_free (mount_entry);
941 g_list_free (mounts);
947 * g_get_unix_mount_points:
948 * @time_read: guint64 to contain a timestamp.
950 * Returns a #GList of the UNIX mountpoints. If @time_read
951 * is set, it will be filled with the mount timestamp.
954 g_get_unix_mount_points (guint64 *time_read)
957 *time_read = get_mount_points_timestamp ();
959 return _g_get_unix_mount_points ();
963 * g_unix_mounts_change_since:
964 * @time: guint64 to contain a timestamp.
966 * Returns %TRUE if the mounts have changed since @time.
969 g_unix_mounts_changed_since (guint64 time)
971 return get_mounts_timestamp () != time;
975 * g_unix_mount_points_change_since:
976 * @time: guint64 to contain a timestamp.
978 * Returns %TRUE if the mount points have changed since @time.
981 g_unix_mount_points_changed_since (guint64 time)
983 return get_mount_points_timestamp () != time;
987 g_unix_mount_monitor_finalize (GObject *object)
989 GUnixMountMonitor *monitor;
991 monitor = G_UNIX_MOUNT_MONITOR (object);
993 if (monitor->fstab_monitor)
995 g_file_monitor_cancel (monitor->fstab_monitor);
996 g_object_unref (monitor->fstab_monitor);
999 if (monitor->mtab_monitor)
1001 g_file_monitor_cancel (monitor->mtab_monitor);
1002 g_object_unref (monitor->mtab_monitor);
1005 the_mount_monitor = NULL;
1007 if (G_OBJECT_CLASS (g_unix_mount_monitor_parent_class)->finalize)
1008 (*G_OBJECT_CLASS (g_unix_mount_monitor_parent_class)->finalize) (object);
1013 g_unix_mount_monitor_class_init (GUnixMountMonitorClass *klass)
1015 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1017 gobject_class->finalize = g_unix_mount_monitor_finalize;
1019 signals[MOUNTS_CHANGED] =
1020 g_signal_new ("mounts_changed",
1021 G_TYPE_FROM_CLASS (klass),
1025 g_cclosure_marshal_VOID__VOID,
1028 signals[MOUNTPOINTS_CHANGED] =
1029 g_signal_new ("mountpoints_changed",
1030 G_TYPE_FROM_CLASS (klass),
1034 g_cclosure_marshal_VOID__VOID,
1039 fstab_file_changed (GFileMonitor* monitor,
1042 GFileMonitorEvent event_type,
1045 GUnixMountMonitor *mount_monitor;
1047 if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
1048 event_type != G_FILE_MONITOR_EVENT_CREATED &&
1049 event_type != G_FILE_MONITOR_EVENT_DELETED)
1052 mount_monitor = user_data;
1053 g_signal_emit (mount_monitor, signals[MOUNTPOINTS_CHANGED], 0);
1057 mtab_file_changed (GFileMonitor* monitor,
1060 GFileMonitorEvent event_type,
1063 GUnixMountMonitor *mount_monitor;
1065 if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
1066 event_type != G_FILE_MONITOR_EVENT_CREATED &&
1067 event_type != G_FILE_MONITOR_EVENT_DELETED)
1070 mount_monitor = user_data;
1071 g_signal_emit (mount_monitor, signals[MOUNTS_CHANGED], 0);
1075 g_unix_mount_monitor_init (GUnixMountMonitor *monitor)
1079 if (get_fstab_file () != NULL)
1081 file = g_file_new_for_path (get_fstab_file ());
1082 monitor->fstab_monitor = g_file_monitor_file (file, 0, NULL);
1083 g_object_unref (file);
1085 g_signal_connect (monitor->fstab_monitor, "changed", (GCallback)fstab_file_changed, monitor);
1088 if (get_mtab_monitor_file () != NULL)
1090 file = g_file_new_for_path (get_mtab_monitor_file ());
1091 monitor->mtab_monitor = g_file_monitor_file (file, 0, NULL);
1092 g_object_unref (file);
1094 g_signal_connect (monitor->mtab_monitor, "changed", (GCallback)mtab_file_changed, monitor);
1099 * g_unix_mount_monitor_new:
1101 * Returns a new #GUnixMountMonitor.
1104 g_unix_mount_monitor_new (void)
1106 if (the_mount_monitor == NULL)
1108 the_mount_monitor = g_object_new (G_TYPE_UNIX_MOUNT_MONITOR, NULL);
1109 return the_mount_monitor;
1112 return g_object_ref (the_mount_monitor);
1116 * g_unix_mount_free:
1117 * @mount_entry: a #GUnixMount.
1121 g_unix_mount_free (GUnixMount *mount_entry)
1123 g_return_if_fail (mount_entry != NULL);
1125 g_free (mount_entry->mount_path);
1126 g_free (mount_entry->device_path);
1127 g_free (mount_entry->filesystem_type);
1128 g_free (mount_entry);
1132 * g_unix_mount_point_free:
1137 g_unix_mount_point_free (GUnixMountPoint *mount_point)
1139 g_return_if_fail (mount_point != NULL);
1141 g_free (mount_point->mount_path);
1142 g_free (mount_point->device_path);
1143 g_free (mount_point->filesystem_type);
1144 g_free (mount_point);
1148 strcmp_null (const char *str1,
1153 if (str1 == NULL && str2 != NULL)
1155 if (str1 != NULL && str2 == NULL)
1157 return strcmp (str1, str2);
1161 * g_unix_mount_compare:
1162 * @mount1: first #GUnixMount to compare.
1163 * @mount2: second #GUnixMount to compare.
1165 * Returns 1, 0 or -1 if @mount1 is greater than, equal to,
1166 * or less than @mount2, respectively.
1169 g_unix_mount_compare (GUnixMount *mount1,
1174 g_return_val_if_fail (mount1 != NULL && mount2 != NULL, 0);
1176 res = strcmp_null (mount1->mount_path, mount2->mount_path);
1180 res = strcmp_null (mount1->device_path, mount2->device_path);
1184 res = strcmp_null (mount1->filesystem_type, mount2->filesystem_type);
1188 res = mount1->is_read_only - mount2->is_read_only;
1196 * g_unix_mount_get_mount_path:
1197 * @mount_entry: input #GUnixMount to get the mount path for.
1199 * Returns the mount path for @mount_entry.
1203 g_unix_mount_get_mount_path (GUnixMount *mount_entry)
1205 g_return_val_if_fail (mount_entry != NULL, NULL);
1207 return mount_entry->mount_path;
1211 * g_unix_mount_get_device_path:
1212 * @mount_entry: a #GUnixMount.
1216 g_unix_mount_get_device_path (GUnixMount *mount_entry)
1218 g_return_val_if_fail (mount_entry != NULL, NULL);
1220 return mount_entry->device_path;
1224 * g_unix_mount_get_fs_type:
1225 * @mount_entry: a #GUnixMount.
1229 g_unix_mount_get_fs_type (GUnixMount *mount_entry)
1231 g_return_val_if_fail (mount_entry != NULL, NULL);
1233 return mount_entry->filesystem_type;
1237 * g_unix_mount_is_readonly:
1238 * @mount_entry: a #GUnixMount.
1240 * Returns %TRUE if @mount_entry is read only.
1244 g_unix_mount_is_readonly (GUnixMount *mount_entry)
1246 g_return_val_if_fail (mount_entry != NULL, FALSE);
1248 return mount_entry->is_read_only;
1252 * g_unix_mount_is_system_internal:
1253 * @mount_entry: a #GUnixMount.
1257 g_unix_mount_is_system_internal (GUnixMount *mount_entry)
1259 g_return_val_if_fail (mount_entry != NULL, FALSE);
1261 return mount_entry->is_system_internal;
1265 * g_unix_mount_point_compare:
1266 * @mount1: a #GUnixMount.
1267 * @mount2: a #GUnixMount.
1269 * Returns 1, 0 or -1 if @mount1 is greater than, equal to,
1270 * or less than @mount2, respectively.
1273 g_unix_mount_point_compare (GUnixMountPoint *mount1,
1274 GUnixMountPoint *mount2)
1278 g_return_val_if_fail (mount1 != NULL && mount2 != NULL, 0);
1280 res = strcmp_null (mount1->mount_path, mount2->mount_path);
1284 res = strcmp_null (mount1->device_path, mount2->device_path);
1288 res = strcmp_null (mount1->filesystem_type, mount2->filesystem_type);
1292 res = mount1->is_read_only - mount2->is_read_only;
1296 res = mount1->is_user_mountable - mount2->is_user_mountable;
1300 res = mount1->is_loopback - mount2->is_loopback;
1308 * g_unix_mount_point_get_mount_path:
1309 * @mount_point: a #GUnixMount.
1313 g_unix_mount_point_get_mount_path (GUnixMountPoint *mount_point)
1315 g_return_val_if_fail (mount_point != NULL, NULL);
1317 return mount_point->mount_path;
1321 * g_unix_mount_point_get_device_path:
1322 * @mount_point: a #GUnixMount.
1326 g_unix_mount_point_get_device_path (GUnixMountPoint *mount_point)
1328 g_return_val_if_fail (mount_point != NULL, NULL);
1330 return mount_point->device_path;
1334 * g_unix_mount_point_get_fs_type:
1335 * @mount_point: a #GUnixMount.
1339 g_unix_mount_point_get_fs_type (GUnixMountPoint *mount_point)
1341 g_return_val_if_fail (mount_point != NULL, NULL);
1343 return mount_point->filesystem_type;
1347 * g_unix_mount_point_is_readonly:
1348 * @mount_point: a #GUnixMount.
1352 g_unix_mount_point_is_readonly (GUnixMountPoint *mount_point)
1354 g_return_val_if_fail (mount_point != NULL, FALSE);
1356 return mount_point->is_read_only;
1360 * g_unix_mount_point_is_user_mountable:
1361 * @mount_point: a #GUnixMount.
1365 g_unix_mount_point_is_user_mountable (GUnixMountPoint *mount_point)
1367 g_return_val_if_fail (mount_point != NULL, FALSE);
1369 return mount_point->is_user_mountable;
1373 * g_unix_mount_point_is_loopback:
1374 * @mount_point: a #GUnixMount.
1378 g_unix_mount_point_is_loopback (GUnixMountPoint *mount_point)
1380 g_return_val_if_fail (mount_point != NULL, FALSE);
1382 return mount_point->is_loopback;
1385 static GUnixMountType
1386 guess_mount_type (const char *mount_path,
1387 const char *device_path,
1388 const char *filesystem_type)
1390 GUnixMountType type;
1393 type = G_UNIX_MOUNT_TYPE_UNKNOWN;
1395 if ((strcmp (filesystem_type, "udf") == 0) ||
1396 (strcmp (filesystem_type, "iso9660") == 0) ||
1397 (strcmp (filesystem_type, "cd9660") == 0))
1398 type = G_UNIX_MOUNT_TYPE_CDROM;
1399 else if (strcmp (filesystem_type, "nfs") == 0)
1400 type = G_UNIX_MOUNT_TYPE_NFS;
1401 else if (g_str_has_prefix (device_path, "/vol/dev/diskette/") ||
1402 g_str_has_prefix (device_path, "/dev/fd") ||
1403 g_str_has_prefix (device_path, "/dev/floppy"))
1404 type = G_UNIX_MOUNT_TYPE_FLOPPY;
1405 else if (g_str_has_prefix (device_path, "/dev/cdrom") ||
1406 g_str_has_prefix (device_path, "/dev/acd") ||
1407 g_str_has_prefix (device_path, "/dev/cd"))
1408 type = G_UNIX_MOUNT_TYPE_CDROM;
1409 else if (g_str_has_prefix (device_path, "/vol/"))
1411 const char *name = mount_path + strlen ("/");
1413 if (g_str_has_prefix (name, "cdrom"))
1414 type = G_UNIX_MOUNT_TYPE_CDROM;
1415 else if (g_str_has_prefix (name, "floppy") ||
1416 g_str_has_prefix (device_path, "/vol/dev/diskette/"))
1417 type = G_UNIX_MOUNT_TYPE_FLOPPY;
1418 else if (g_str_has_prefix (name, "rmdisk"))
1419 type = G_UNIX_MOUNT_TYPE_ZIP;
1420 else if (g_str_has_prefix (name, "jaz"))
1421 type = G_UNIX_MOUNT_TYPE_JAZ;
1422 else if (g_str_has_prefix (name, "memstick"))
1423 type = G_UNIX_MOUNT_TYPE_MEMSTICK;
1427 basename = g_path_get_basename (mount_path);
1429 if (g_str_has_prefix (basename, "cdrom") ||
1430 g_str_has_prefix (basename, "cdwriter") ||
1431 g_str_has_prefix (basename, "burn") ||
1432 g_str_has_prefix (basename, "cdr") ||
1433 g_str_has_prefix (basename, "cdrw") ||
1434 g_str_has_prefix (basename, "dvdrom") ||
1435 g_str_has_prefix (basename, "dvdram") ||
1436 g_str_has_prefix (basename, "dvdr") ||
1437 g_str_has_prefix (basename, "dvdrw") ||
1438 g_str_has_prefix (basename, "cdrom_dvdrom") ||
1439 g_str_has_prefix (basename, "cdrom_dvdram") ||
1440 g_str_has_prefix (basename, "cdrom_dvdr") ||
1441 g_str_has_prefix (basename, "cdrom_dvdrw") ||
1442 g_str_has_prefix (basename, "cdr_dvdrom") ||
1443 g_str_has_prefix (basename, "cdr_dvdram") ||
1444 g_str_has_prefix (basename, "cdr_dvdr") ||
1445 g_str_has_prefix (basename, "cdr_dvdrw") ||
1446 g_str_has_prefix (basename, "cdrw_dvdrom") ||
1447 g_str_has_prefix (basename, "cdrw_dvdram") ||
1448 g_str_has_prefix (basename, "cdrw_dvdr") ||
1449 g_str_has_prefix (basename, "cdrw_dvdrw"))
1450 type = G_UNIX_MOUNT_TYPE_CDROM;
1451 else if (g_str_has_prefix (basename, "floppy"))
1452 type = G_UNIX_MOUNT_TYPE_FLOPPY;
1453 else if (g_str_has_prefix (basename, "zip"))
1454 type = G_UNIX_MOUNT_TYPE_ZIP;
1455 else if (g_str_has_prefix (basename, "jaz"))
1456 type = G_UNIX_MOUNT_TYPE_JAZ;
1457 else if (g_str_has_prefix (basename, "camera"))
1458 type = G_UNIX_MOUNT_TYPE_CAMERA;
1459 else if (g_str_has_prefix (basename, "memstick") ||
1460 g_str_has_prefix (basename, "memory_stick") ||
1461 g_str_has_prefix (basename, "ram"))
1462 type = G_UNIX_MOUNT_TYPE_MEMSTICK;
1463 else if (g_str_has_prefix (basename, "compact_flash"))
1464 type = G_UNIX_MOUNT_TYPE_CF;
1465 else if (g_str_has_prefix (basename, "smart_media"))
1466 type = G_UNIX_MOUNT_TYPE_SM;
1467 else if (g_str_has_prefix (basename, "sd_mmc"))
1468 type = G_UNIX_MOUNT_TYPE_SDMMC;
1469 else if (g_str_has_prefix (basename, "ipod"))
1470 type = G_UNIX_MOUNT_TYPE_IPOD;
1475 if (type == G_UNIX_MOUNT_TYPE_UNKNOWN)
1476 type = G_UNIX_MOUNT_TYPE_HD;
1482 * g_unix_mount_guess_type:
1483 * @mount_entry: a #GUnixMount.
1487 g_unix_mount_guess_type (GUnixMount *mount_entry)
1489 g_return_val_if_fail (mount_entry != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
1490 g_return_val_if_fail (mount_entry->mount_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
1491 g_return_val_if_fail (mount_entry->device_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
1492 g_return_val_if_fail (mount_entry->filesystem_type != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
1494 return guess_mount_type (mount_entry->mount_path,
1495 mount_entry->device_path,
1496 mount_entry->filesystem_type);
1500 * g_unix_mount_point_guess_type:
1501 * @mount_point: a #GUnixMount.
1505 g_unix_mount_point_guess_type (GUnixMountPoint *mount_point)
1507 g_return_val_if_fail (mount_point != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
1508 g_return_val_if_fail (mount_point->mount_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
1509 g_return_val_if_fail (mount_point->device_path != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
1510 g_return_val_if_fail (mount_point->filesystem_type != NULL, G_UNIX_MOUNT_TYPE_UNKNOWN);
1512 return guess_mount_type (mount_point->mount_path,
1513 mount_point->device_path,
1514 mount_point->filesystem_type);