summaryrefslogtreecommitdiffstats
path: root/gl/mountlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/mountlist.c')
-rw-r--r--gl/mountlist.c182
1 files changed, 142 insertions, 40 deletions
diff --git a/gl/mountlist.c b/gl/mountlist.c
index 996b71a..30f4286 100644
--- a/gl/mountlist.c
+++ b/gl/mountlist.c
@@ -1,6 +1,6 @@
1/* mountlist.c -- return a list of mounted file systems 1/* mountlist.c -- return a list of mounted file systems
2 2
3 Copyright (C) 1991-1992, 1997-2010 Free Software Foundation, Inc. 3 Copyright (C) 1991-1992, 1997-2013 Free Software Foundation, Inc.
4 4
5 This program is free software: you can redistribute it and/or modify 5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
@@ -112,6 +112,11 @@
112# include <sys/vfs.h> 112# include <sys/vfs.h>
113#endif 113#endif
114 114
115#ifdef MOUNTED_INTERIX_STATVFS /* Interix. */
116# include <sys/statvfs.h>
117# include <dirent.h>
118#endif
119
115#ifdef DOLPHIN 120#ifdef DOLPHIN
116/* So special that it's not worth putting this in autoconf. */ 121/* So special that it's not worth putting this in autoconf. */
117# undef MOUNTED_FREAD_FSTYP 122# undef MOUNTED_FREAD_FSTYP
@@ -123,8 +128,12 @@
123# include <sys/mntent.h> 128# include <sys/mntent.h>
124#endif 129#endif
125 130
131#ifndef HAVE_HASMNTOPT
132# define hasmntopt(mnt, opt) ((char *) 0)
133#endif
134
126#undef MNT_IGNORE 135#undef MNT_IGNORE
127#if defined MNTOPT_IGNORE && defined HAVE_HASMNTOPT 136#ifdef MNTOPT_IGNORE
128# define MNT_IGNORE(M) hasmntopt (M, MNTOPT_IGNORE) 137# define MNT_IGNORE(M) hasmntopt (M, MNTOPT_IGNORE)
129#else 138#else
130# define MNT_IGNORE(M) 0 139# define MNT_IGNORE(M) 0
@@ -144,21 +153,66 @@
144#undef opendir 153#undef opendir
145#undef closedir 154#undef closedir
146 155
147#ifndef ME_DUMMY 156#define ME_DUMMY_0(Fs_name, Fs_type) \
148# define ME_DUMMY(Fs_name, Fs_type) \ 157 (strcmp (Fs_type, "autofs") == 0 \
149 (strcmp (Fs_type, "autofs") == 0 \ 158 || strcmp (Fs_type, "proc") == 0 \
150 || strcmp (Fs_type, "none") == 0 \ 159 || strcmp (Fs_type, "subfs") == 0 \
151 || strcmp (Fs_type, "proc") == 0 \ 160 /* for Linux 2.6/3.x */ \
152 || strcmp (Fs_type, "subfs") == 0 \ 161 || strcmp (Fs_type, "debugfs") == 0 \
153 /* for NetBSD 3.0 */ \ 162 || strcmp (Fs_type, "devpts") == 0 \
154 || strcmp (Fs_type, "kernfs") == 0 \ 163 || strcmp (Fs_type, "fusectl") == 0 \
155 /* for Irix 6.5 */ \ 164 || strcmp (Fs_type, "mqueue") == 0 \
156 || strcmp (Fs_type, "ignore") == 0) 165 || strcmp (Fs_type, "rpc_pipefs") == 0 \
166 || strcmp (Fs_type, "sysfs") == 0 \
167 /* FreeBSD, Linux 2.4 */ \
168 || strcmp (Fs_type, "devfs") == 0 \
169 /* for NetBSD 3.0 */ \
170 || strcmp (Fs_type, "kernfs") == 0 \
171 /* for Irix 6.5 */ \
172 || strcmp (Fs_type, "ignore") == 0)
173
174/* Historically, we have marked as "dummy" any file system of type "none",
175 but now that programs like du need to know about bind-mounted directories,
176 we grant an exception to any with "bind" in its list of mount options.
177 I.e., those are *not* dummy entries. */
178#ifdef MOUNTED_GETMNTENT1
179# define ME_DUMMY(Fs_name, Fs_type, Fs_ent) \
180 (ME_DUMMY_0 (Fs_name, Fs_type) \
181 || (strcmp (Fs_type, "none") == 0 \
182 && !hasmntopt (Fs_ent, "bind")))
183#else
184# define ME_DUMMY(Fs_name, Fs_type) \
185 (ME_DUMMY_0 (Fs_name, Fs_type) || strcmp (Fs_type, "none") == 0)
186#endif
187
188#ifdef __CYGWIN__
189# include <windows.h>
190# define ME_REMOTE me_remote
191/* All cygwin mount points include ':' or start with '//'; so it
192 requires a native Windows call to determine remote disks. */
193static bool
194me_remote (char const *fs_name, char const *fs_type _GL_UNUSED)
195{
196 if (fs_name[0] && fs_name[1] == ':')
197 {
198 char drive[4];
199 sprintf (drive, "%c:\\", fs_name[0]);
200 switch (GetDriveType (drive))
201 {
202 case DRIVE_REMOVABLE:
203 case DRIVE_FIXED:
204 case DRIVE_CDROM:
205 case DRIVE_RAMDISK:
206 return false;
207 }
208 }
209 return true;
210}
157#endif 211#endif
158 212
159#ifndef ME_REMOTE 213#ifndef ME_REMOTE
160/* A file system is `remote' if its Fs_name contains a `:' 214/* A file system is "remote" if its Fs_name contains a ':'
161 or if (it is of type (smbfs or cifs) and its Fs_name starts with `//'). */ 215 or if (it is of type (smbfs or cifs) and its Fs_name starts with '//'). */
162# define ME_REMOTE(Fs_name, Fs_type) \ 216# define ME_REMOTE(Fs_name, Fs_type) \
163 (strchr (Fs_name, ':') != NULL \ 217 (strchr (Fs_name, ':') != NULL \
164 || ((Fs_name)[0] == '/' \ 218 || ((Fs_name)[0] == '/' \
@@ -354,19 +408,20 @@ read_file_system_list (bool need_fs_type)
354 408
355 if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0) 409 if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0)
356 return NULL; 410 return NULL;
357 for (p = mntlist; p; p = p->next) { 411 for (p = mntlist; p; p = p->next)
358 mnt = p->ment; 412 {
359 me = xmalloc (sizeof *me); 413 mnt = p->ment;
360 me->me_devname = xstrdup (mnt->mnt_fsname); 414 me = xmalloc (sizeof *me);
361 me->me_mountdir = xstrdup (mnt->mnt_dir); 415 me->me_devname = xstrdup (mnt->mnt_fsname);
362 me->me_type = xstrdup (mnt->mnt_type); 416 me->me_mountdir = xstrdup (mnt->mnt_dir);
363 me->me_type_malloced = 1; 417 me->me_type = xstrdup (mnt->mnt_type);
364 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 418 me->me_type_malloced = 1;
365 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 419 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
366 me->me_dev = -1; 420 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
367 *mtail = me; 421 me->me_dev = -1;
368 mtail = &me->me_next; 422 *mtail = me;
369 } 423 mtail = &me->me_next;
424 }
370 freemntlist (mntlist); 425 freemntlist (mntlist);
371 } 426 }
372#endif 427#endif
@@ -388,7 +443,7 @@ read_file_system_list (bool need_fs_type)
388 me->me_mountdir = xstrdup (mnt->mnt_dir); 443 me->me_mountdir = xstrdup (mnt->mnt_dir);
389 me->me_type = xstrdup (mnt->mnt_type); 444 me->me_type = xstrdup (mnt->mnt_type);
390 me->me_type_malloced = 1; 445 me->me_type_malloced = 1;
391 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 446 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt);
392 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 447 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
393 me->me_dev = dev_from_mount_options (mnt->mnt_opts); 448 me->me_dev = dev_from_mount_options (mnt->mnt_opts);
394 449
@@ -564,7 +619,8 @@ read_file_system_list (bool need_fs_type)
564 break; 619 break;
565 620
566 me = xmalloc (sizeof *me); 621 me = xmalloc (sizeof *me);
567 me->me_devname = xstrdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name); 622 me->me_devname = xstrdup (fi.device_name[0] != '\0'
623 ? fi.device_name : fi.fsh_name);
568 me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name); 624 me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name);
569 me->me_type = xstrdup (fi.fsh_name); 625 me->me_type = xstrdup (fi.fsh_name);
570 me->me_type_malloced = 1; 626 me->me_type_malloced = 1;
@@ -594,9 +650,9 @@ read_file_system_list (bool need_fs_type)
594 size_t bufsize; 650 size_t bufsize;
595 struct statfs *stats; 651 struct statfs *stats;
596 652
597 numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT); 653 numsys = getfsstat (NULL, 0L, MNT_NOWAIT);
598 if (numsys < 0) 654 if (numsys < 0)
599 return (NULL); 655 return NULL;
600 if (SIZE_MAX / sizeof *stats <= numsys) 656 if (SIZE_MAX / sizeof *stats <= numsys)
601 xalloc_die (); 657 xalloc_die ();
602 658
@@ -607,7 +663,7 @@ read_file_system_list (bool need_fs_type)
607 if (numsys < 0) 663 if (numsys < 0)
608 { 664 {
609 free (stats); 665 free (stats);
610 return (NULL); 666 return NULL;
611 } 667 }
612 668
613 for (counter = 0; counter < numsys; counter++) 669 for (counter = 0; counter < numsys; counter++)
@@ -693,11 +749,11 @@ read_file_system_list (bool need_fs_type)
693#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */ 749#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */
694 { 750 {
695 struct mntent **mnttbl = getmnttbl (), **ent; 751 struct mntent **mnttbl = getmnttbl (), **ent;
696 for (ent=mnttbl;*ent;ent++) 752 for (ent = mnttbl; *ent; ent++)
697 { 753 {
698 me = xmalloc (sizeof *me); 754 me = xmalloc (sizeof *me);
699 me->me_devname = xstrdup ( (*ent)->mt_resource); 755 me->me_devname = xstrdup ((*ent)->mt_resource);
700 me->me_mountdir = xstrdup ( (*ent)->mt_directory); 756 me->me_mountdir = xstrdup ((*ent)->mt_directory);
701 me->me_type = xstrdup ((*ent)->mt_fstype); 757 me->me_type = xstrdup ((*ent)->mt_fstype);
702 me->me_type_malloced = 1; 758 me->me_type_malloced = 1;
703 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 759 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
@@ -854,6 +910,45 @@ read_file_system_list (bool need_fs_type)
854 } 910 }
855#endif /* MOUNTED_VMOUNT. */ 911#endif /* MOUNTED_VMOUNT. */
856 912
913#ifdef MOUNTED_INTERIX_STATVFS
914 {
915 DIR *dirp = opendir ("/dev/fs");
916 char node[9 + NAME_MAX];
917
918 if (!dirp)
919 goto free_then_fail;
920
921 while (1)
922 {
923 struct statvfs dev;
924 struct dirent entry;
925 struct dirent *result;
926
927 if (readdir_r (dirp, &entry, &result) || result == NULL)
928 break;
929
930 strcpy (node, "/dev/fs/");
931 strcat (node, entry.d_name);
932
933 if (statvfs (node, &dev) == 0)
934 {
935 me = xmalloc (sizeof *me);
936 me->me_devname = xstrdup (dev.f_mntfromname);
937 me->me_mountdir = xstrdup (dev.f_mntonname);
938 me->me_type = xstrdup (dev.f_fstypename);
939 me->me_type_malloced = 1;
940 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
941 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
942 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
943
944 /* Add to the linked list. */
945 *mtail = me;
946 mtail = &me->me_next;
947 }
948 }
949 }
950#endif /* MOUNTED_INTERIX_STATVFS */
951
857 *mtail = NULL; 952 *mtail = NULL;
858 return mount_list; 953 return mount_list;
859 954
@@ -866,11 +961,7 @@ read_file_system_list (bool need_fs_type)
866 while (mount_list) 961 while (mount_list)
867 { 962 {
868 me = mount_list->me_next; 963 me = mount_list->me_next;
869 free (mount_list->me_devname); 964 free_mount_entry (mount_list);
870 free (mount_list->me_mountdir);
871 if (mount_list->me_type_malloced)
872 free (mount_list->me_type);
873 free (mount_list);
874 mount_list = me; 965 mount_list = me;
875 } 966 }
876 967
@@ -878,3 +969,14 @@ read_file_system_list (bool need_fs_type)
878 return NULL; 969 return NULL;
879 } 970 }
880} 971}
972
973/* Free a mount entry as returned from read_file_system_list (). */
974
975void free_mount_entry (struct mount_entry *me)
976{
977 free (me->me_devname);
978 free (me->me_mountdir);
979 if (me->me_type_malloced)
980 free (me->me_type);
981 free (me);
982}