diff options
Diffstat (limited to 'gl/mountlist.c')
-rw-r--r-- | gl/mountlist.c | 182 |
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. */ | ||
193 | static bool | ||
194 | me_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 | |||
975 | void 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 | } | ||