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 996b71a1..30f42861 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 | } | ||
