diff options
-rw-r--r-- | lib/afs.m4 | 12 | ||||
-rw-r--r-- | lib/fstypename.m4 | 32 | ||||
-rw-r--r-- | lib/fsusage.c | 281 | ||||
-rw-r--r-- | lib/fsusage.h | 45 | ||||
-rw-r--r-- | lib/fsusage.m4 | 194 | ||||
-rw-r--r-- | lib/ls-mntd-fs.m4 | 243 | ||||
-rw-r--r-- | lib/mountlist.c | 788 | ||||
-rw-r--r-- | lib/mountlist.h | 50 |
8 files changed, 1645 insertions, 0 deletions
diff --git a/lib/afs.m4 b/lib/afs.m4 new file mode 100644 index 00000000..13f3bc96 --- /dev/null +++ b/lib/afs.m4 | |||
@@ -0,0 +1,12 @@ | |||
1 | #serial 3 | ||
2 | |||
3 | AC_DEFUN(jm_AFS, | ||
4 | AC_MSG_CHECKING(for AFS) | ||
5 | if test -d /afs; then | ||
6 | AC_DEFINE(AFS, 1, [Define if you have the Andrew File System.]) | ||
7 | ac_result=yes | ||
8 | else | ||
9 | ac_result=no | ||
10 | fi | ||
11 | AC_MSG_RESULT($ac_result) | ||
12 | ) | ||
diff --git a/lib/fstypename.m4 b/lib/fstypename.m4 new file mode 100644 index 00000000..70abc12b --- /dev/null +++ b/lib/fstypename.m4 | |||
@@ -0,0 +1,32 @@ | |||
1 | #serial 2 | ||
2 | |||
3 | dnl From Jim Meyering. | ||
4 | dnl | ||
5 | dnl See if struct statfs has the f_fstypename member. | ||
6 | dnl If so, define HAVE_F_FSTYPENAME_IN_STATFS. | ||
7 | dnl | ||
8 | |||
9 | AC_DEFUN(jm_FSTYPENAME, | ||
10 | [ | ||
11 | AC_CACHE_CHECK([for f_fstypename in struct statfs], | ||
12 | fu_cv_sys_f_fstypename_in_statfs, | ||
13 | [ | ||
14 | AC_TRY_COMPILE( | ||
15 | [ | ||
16 | #include <sys/param.h> | ||
17 | #include <sys/types.h> | ||
18 | #include <sys/mount.h> | ||
19 | ], | ||
20 | [struct statfs s; int i = sizeof s.f_fstypename;], | ||
21 | fu_cv_sys_f_fstypename_in_statfs=yes, | ||
22 | fu_cv_sys_f_fstypename_in_statfs=no | ||
23 | ) | ||
24 | ] | ||
25 | ) | ||
26 | |||
27 | if test $fu_cv_sys_f_fstypename_in_statfs = yes; then | ||
28 | AC_DEFINE_UNQUOTED(HAVE_F_FSTYPENAME_IN_STATFS, 1, | ||
29 | [Define if struct statfs has the f_fstypename member.]) | ||
30 | fi | ||
31 | ] | ||
32 | ) | ||
diff --git a/lib/fsusage.c b/lib/fsusage.c new file mode 100644 index 00000000..5a864bf2 --- /dev/null +++ b/lib/fsusage.c | |||
@@ -0,0 +1,281 @@ | |||
1 | /* fsusage.c -- return space usage of mounted filesystems | ||
2 | Copyright (C) 1991, 1992, 1996, 1998, 1999 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software Foundation, | ||
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
17 | |||
18 | #include "../plugins/config.h" | ||
19 | |||
20 | #if HAVE_INTTYPES_H | ||
21 | # include <inttypes.h> | ||
22 | #endif | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include "fsusage.h" | ||
26 | |||
27 | #if HAVE_LIMITS_H | ||
28 | # include <limits.h> | ||
29 | #endif | ||
30 | #ifndef CHAR_BIT | ||
31 | # define CHAR_BIT 8 | ||
32 | #endif | ||
33 | |||
34 | int statfs (); | ||
35 | |||
36 | #if HAVE_SYS_PARAM_H | ||
37 | # include <sys/param.h> | ||
38 | #endif | ||
39 | |||
40 | #if HAVE_SYS_MOUNT_H | ||
41 | # include <sys/mount.h> | ||
42 | #endif | ||
43 | |||
44 | #if HAVE_SYS_VFS_H | ||
45 | # include <sys/vfs.h> | ||
46 | #endif | ||
47 | |||
48 | #if HAVE_SYS_FS_S5PARAM_H /* Fujitsu UXP/V */ | ||
49 | # include <sys/fs/s5param.h> | ||
50 | #endif | ||
51 | |||
52 | #if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) | ||
53 | # include <sys/filsys.h> /* SVR2 */ | ||
54 | #endif | ||
55 | |||
56 | #if HAVE_FCNTL_H | ||
57 | # include <fcntl.h> | ||
58 | #endif | ||
59 | |||
60 | #if HAVE_SYS_STATFS_H | ||
61 | # include <sys/statfs.h> | ||
62 | #endif | ||
63 | |||
64 | #if HAVE_DUSTAT_H /* AIX PS/2 */ | ||
65 | # include <sys/dustat.h> | ||
66 | #endif | ||
67 | |||
68 | #if HAVE_SYS_STATVFS_H /* SVR4 */ | ||
69 | # include <sys/statvfs.h> | ||
70 | int statvfs (); | ||
71 | #endif | ||
72 | |||
73 | /* Many space usage primitives use all 1 bits to denote a value that is | ||
74 | not applicable or unknown. Propagate this information by returning | ||
75 | a uintmax_t value that is all 1 bits if the argument is all 1 bits, | ||
76 | even if the argument is unsigned and smaller than uintmax_t. */ | ||
77 | #define PROPAGATE_ALL_ONES(x) ((x) == -1 ? (uintmax_t) -1 : (uintmax_t) (x)) | ||
78 | |||
79 | /* Extract the top bit of X as an uintmax_t value. */ | ||
80 | #define EXTRACT_TOP_BIT(x) ((x) \ | ||
81 | & ((uintmax_t) 1 << (sizeof (x) * CHAR_BIT - 1))) | ||
82 | |||
83 | /* If a value is negative, many space usage primitives store it into an | ||
84 | integer variable by assignment, even if the variable's type is unsigned. | ||
85 | So, if a space usage variable X's top bit is set, convert X to the | ||
86 | uintmax_t value V such that (- (uintmax_t) V) is the negative of | ||
87 | the original value. If X's top bit is clear, just yield X. | ||
88 | Use PROPAGATE_TOP_BIT if the original value might be negative; | ||
89 | otherwise, use PROPAGATE_ALL_ONES. */ | ||
90 | #define PROPAGATE_TOP_BIT(x) ((x) | ~ (EXTRACT_TOP_BIT (x) - 1)) | ||
91 | |||
92 | int safe_read (); | ||
93 | |||
94 | /* Fill in the fields of FSP with information about space usage for | ||
95 | the filesystem on which PATH resides. | ||
96 | DISK is the device on which PATH is mounted, for space-getting | ||
97 | methods that need to know it. | ||
98 | Return 0 if successful, -1 if not. When returning -1, ensure that | ||
99 | ERRNO is either a system error value, or zero if DISK is NULL | ||
100 | on a system that requires a non-NULL value. */ | ||
101 | int | ||
102 | get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp) | ||
103 | { | ||
104 | #ifdef STAT_STATFS3_OSF1 | ||
105 | |||
106 | struct statfs fsd; | ||
107 | |||
108 | if (statfs (path, &fsd, sizeof (struct statfs)) != 0) | ||
109 | return -1; | ||
110 | |||
111 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize); | ||
112 | |||
113 | #endif /* STAT_STATFS3_OSF1 */ | ||
114 | |||
115 | #ifdef STAT_STATFS2_FS_DATA /* Ultrix */ | ||
116 | |||
117 | struct fs_data fsd; | ||
118 | |||
119 | if (statfs (path, &fsd) != 1) | ||
120 | return -1; | ||
121 | |||
122 | fsp->fsu_blocksize = 1024; | ||
123 | fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.fd_req.btot); | ||
124 | fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.fd_req.bfree); | ||
125 | fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.fd_req.bfreen); | ||
126 | fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.fd_req.bfreen) != 0; | ||
127 | fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.fd_req.gtot); | ||
128 | fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.fd_req.gfree); | ||
129 | |||
130 | #endif /* STAT_STATFS2_FS_DATA */ | ||
131 | |||
132 | #ifdef STAT_READ_FILSYS /* SVR2 */ | ||
133 | # ifndef SUPERBOFF | ||
134 | # define SUPERBOFF (SUPERB * 512) | ||
135 | # endif | ||
136 | |||
137 | struct filsys fsd; | ||
138 | int fd; | ||
139 | |||
140 | if (! disk) | ||
141 | { | ||
142 | errno = 0; | ||
143 | return -1; | ||
144 | } | ||
145 | |||
146 | fd = open (disk, O_RDONLY); | ||
147 | if (fd < 0) | ||
148 | return -1; | ||
149 | lseek (fd, (off_t) SUPERBOFF, 0); | ||
150 | if (safe_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd) | ||
151 | { | ||
152 | close (fd); | ||
153 | return -1; | ||
154 | } | ||
155 | close (fd); | ||
156 | |||
157 | fsp->fsu_blocksize = (fsd.s_type == Fs2b ? 1024 : 512); | ||
158 | fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.s_fsize); | ||
159 | fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.s_tfree); | ||
160 | fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.s_tfree); | ||
161 | fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.s_tfree) != 0; | ||
162 | fsp->fsu_files = (fsd.s_isize == -1 | ||
163 | ? (uintmax_t) -1 | ||
164 | : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1)); | ||
165 | fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode); | ||
166 | |||
167 | #endif /* STAT_READ_FILSYS */ | ||
168 | |||
169 | #ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX */ | ||
170 | |||
171 | struct statfs fsd; | ||
172 | |||
173 | if (statfs (path, &fsd) < 0) | ||
174 | return -1; | ||
175 | |||
176 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize); | ||
177 | |||
178 | # ifdef STATFS_TRUNCATES_BLOCK_COUNTS | ||
179 | |||
180 | /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the | ||
181 | struct statfs are truncated to 2GB. These conditions detect that | ||
182 | truncation, presumably without botching the 4.1.1 case, in which | ||
183 | the values are not truncated. The correct counts are stored in | ||
184 | undocumented spare fields. */ | ||
185 | if (fsd.f_blocks == 0x7fffffff / fsd.f_bsize && fsd.f_spare[0] > 0) | ||
186 | { | ||
187 | fsd.f_blocks = fsd.f_spare[0]; | ||
188 | fsd.f_bfree = fsd.f_spare[1]; | ||
189 | fsd.f_bavail = fsd.f_spare[2]; | ||
190 | } | ||
191 | # endif /* STATFS_TRUNCATES_BLOCK_COUNTS */ | ||
192 | |||
193 | #endif /* STAT_STATFS2_BSIZE */ | ||
194 | |||
195 | #ifdef STAT_STATFS2_FSIZE /* 4.4BSD */ | ||
196 | |||
197 | struct statfs fsd; | ||
198 | |||
199 | if (statfs (path, &fsd) < 0) | ||
200 | return -1; | ||
201 | |||
202 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize); | ||
203 | |||
204 | #endif /* STAT_STATFS2_FSIZE */ | ||
205 | |||
206 | #ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX */ | ||
207 | |||
208 | # if !_AIX && !defined _SEQUENT_ && !defined DOLPHIN | ||
209 | # define f_bavail f_bfree | ||
210 | # endif | ||
211 | |||
212 | struct statfs fsd; | ||
213 | |||
214 | if (statfs (path, &fsd, sizeof fsd, 0) < 0) | ||
215 | return -1; | ||
216 | |||
217 | /* Empirically, the block counts on most SVR3 and SVR3-derived | ||
218 | systems seem to always be in terms of 512-byte blocks, | ||
219 | no matter what value f_bsize has. */ | ||
220 | # if _AIX || defined(_CRAY) | ||
221 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize); | ||
222 | # else | ||
223 | fsp->fsu_blocksize = 512; | ||
224 | # endif | ||
225 | |||
226 | #endif /* STAT_STATFS4 */ | ||
227 | |||
228 | #ifdef STAT_STATVFS /* SVR4 */ | ||
229 | |||
230 | struct statvfs fsd; | ||
231 | |||
232 | if (statvfs (path, &fsd) < 0) | ||
233 | return -1; | ||
234 | |||
235 | /* f_frsize isn't guaranteed to be supported. */ | ||
236 | fsp->fsu_blocksize = | ||
237 | PROPAGATE_ALL_ONES (fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize); | ||
238 | |||
239 | #endif /* STAT_STATVFS */ | ||
240 | |||
241 | #if !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ_FILSYS) | ||
242 | /* !Ultrix && !SVR2 */ | ||
243 | |||
244 | fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks); | ||
245 | fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree); | ||
246 | fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.f_bavail); | ||
247 | fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.f_bavail) != 0; | ||
248 | fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files); | ||
249 | fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree); | ||
250 | |||
251 | #endif /* not STAT_STATFS2_FS_DATA && not STAT_READ_FILSYS */ | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | #if defined(_AIX) && defined(_I386) | ||
257 | /* AIX PS/2 does not supply statfs. */ | ||
258 | |||
259 | int | ||
260 | statfs (char *path, struct statfs *fsb) | ||
261 | { | ||
262 | struct stat stats; | ||
263 | struct dustat fsd; | ||
264 | |||
265 | if (stat (path, &stats)) | ||
266 | return -1; | ||
267 | if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd))) | ||
268 | return -1; | ||
269 | fsb->f_type = 0; | ||
270 | fsb->f_bsize = fsd.du_bsize; | ||
271 | fsb->f_blocks = fsd.du_fsize - fsd.du_isize; | ||
272 | fsb->f_bfree = fsd.du_tfree; | ||
273 | fsb->f_bavail = fsd.du_tfree; | ||
274 | fsb->f_files = (fsd.du_isize - 2) * fsd.du_inopb; | ||
275 | fsb->f_ffree = fsd.du_tinode; | ||
276 | fsb->f_fsid.val[0] = fsd.du_site; | ||
277 | fsb->f_fsid.val[1] = fsd.du_pckno; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | #endif /* _AIX && _I386 */ | ||
diff --git a/lib/fsusage.h b/lib/fsusage.h new file mode 100644 index 00000000..e0c0db58 --- /dev/null +++ b/lib/fsusage.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* fsusage.h -- declarations for filesystem space usage info | ||
2 | Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software Foundation, | ||
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
17 | |||
18 | /* Space usage statistics for a filesystem. Blocks are 512-byte. */ | ||
19 | |||
20 | #if !defined FSUSAGE_H_ | ||
21 | # define FSUSAGE_H_ | ||
22 | |||
23 | struct fs_usage | ||
24 | { | ||
25 | int fsu_blocksize; /* Size of a block. */ | ||
26 | uintmax_t fsu_blocks; /* Total blocks. */ | ||
27 | uintmax_t fsu_bfree; /* Free blocks available to superuser. */ | ||
28 | uintmax_t fsu_bavail; /* Free blocks available to non-superuser. */ | ||
29 | int fsu_bavail_top_bit_set; /* 1 if fsu_bavail represents a value < 0. */ | ||
30 | uintmax_t fsu_files; /* Total file nodes. */ | ||
31 | uintmax_t fsu_ffree; /* Free file nodes. */ | ||
32 | }; | ||
33 | |||
34 | # ifndef PARAMS | ||
35 | # if defined PROTOTYPES || (defined __STDC__ && __STDC__) | ||
36 | # define PARAMS(Args) Args | ||
37 | # else | ||
38 | # define PARAMS(Args) () | ||
39 | # endif | ||
40 | # endif | ||
41 | |||
42 | int get_fs_usage PARAMS ((const char *path, const char *disk, | ||
43 | struct fs_usage *fsp)); | ||
44 | |||
45 | #endif | ||
diff --git a/lib/fsusage.m4 b/lib/fsusage.m4 new file mode 100644 index 00000000..d5c646f4 --- /dev/null +++ b/lib/fsusage.m4 | |||
@@ -0,0 +1,194 @@ | |||
1 | #serial 7 | ||
2 | |||
3 | # From fileutils/configure.in | ||
4 | |||
5 | # Try to determine how a program can obtain filesystem usage information. | ||
6 | # If successful, define the appropriate symbol (see fsusage.c) and | ||
7 | # execute ACTION-IF-FOUND. Otherwise, execute ACTION-IF-NOT-FOUND. | ||
8 | # | ||
9 | # jm_FILE_SYSTEM_USAGE([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) | ||
10 | |||
11 | AC_DEFUN(jm_FILE_SYSTEM_USAGE, | ||
12 | [ | ||
13 | |||
14 | echo "checking how to get filesystem space usage..." | ||
15 | ac_fsusage_space=no | ||
16 | |||
17 | # Perform only the link test since it seems there are no variants of the | ||
18 | # statvfs function. This check is more than just AC_CHECK_FUNCS(statvfs) | ||
19 | # because that got a false positive on SCO OSR5. Adding the declaration | ||
20 | # of a `struct statvfs' causes this test to fail (as it should) on such | ||
21 | # systems. That system is reported to work fine with STAT_STATFS4 which | ||
22 | # is what it gets when this test fails. | ||
23 | if test $ac_fsusage_space = no; then | ||
24 | # SVR4 | ||
25 | AC_CACHE_CHECK([for statvfs function (SVR4)], fu_cv_sys_stat_statvfs, | ||
26 | [AC_TRY_LINK([#include <sys/types.h> | ||
27 | #include <sys/statvfs.h>], | ||
28 | [struct statvfs fsd; statvfs (0, &fsd);], | ||
29 | fu_cv_sys_stat_statvfs=yes, | ||
30 | fu_cv_sys_stat_statvfs=no)]) | ||
31 | if test $fu_cv_sys_stat_statvfs = yes; then | ||
32 | ac_fsusage_space=yes | ||
33 | AC_DEFINE_UNQUOTED(STAT_STATVFS, 1, | ||
34 | [ Define if there is a function named statvfs. (SVR4)]) | ||
35 | fi | ||
36 | fi | ||
37 | |||
38 | if test $ac_fsusage_space = no; then | ||
39 | # DEC Alpha running OSF/1 | ||
40 | AC_MSG_CHECKING([for 3-argument statfs function (DEC OSF/1)]) | ||
41 | AC_CACHE_VAL(fu_cv_sys_stat_statfs3_osf1, | ||
42 | [AC_TRY_RUN([ | ||
43 | #include <sys/param.h> | ||
44 | #include <sys/types.h> | ||
45 | #include <sys/mount.h> | ||
46 | main () | ||
47 | { | ||
48 | struct statfs fsd; | ||
49 | fsd.f_fsize = 0; | ||
50 | exit (statfs (".", &fsd, sizeof (struct statfs))); | ||
51 | }], | ||
52 | fu_cv_sys_stat_statfs3_osf1=yes, | ||
53 | fu_cv_sys_stat_statfs3_osf1=no, | ||
54 | fu_cv_sys_stat_statfs3_osf1=no)]) | ||
55 | AC_MSG_RESULT($fu_cv_sys_stat_statfs3_osf1) | ||
56 | if test $fu_cv_sys_stat_statfs3_osf1 = yes; then | ||
57 | ac_fsusage_space=yes | ||
58 | AC_DEFINE_UNQUOTED(STAT_STATFS3_OSF1, 1, | ||
59 | [ Define if statfs takes 3 args. (DEC Alpha running OSF/1)]) | ||
60 | fi | ||
61 | fi | ||
62 | |||
63 | if test $ac_fsusage_space = no; then | ||
64 | # AIX | ||
65 | AC_MSG_CHECKING([for two-argument statfs with statfs.bsize dnl | ||
66 | member (AIX, 4.3BSD)]) | ||
67 | AC_CACHE_VAL(fu_cv_sys_stat_statfs2_bsize, | ||
68 | [AC_TRY_RUN([ | ||
69 | #ifdef HAVE_SYS_PARAM_H | ||
70 | #include <sys/param.h> | ||
71 | #endif | ||
72 | #ifdef HAVE_SYS_MOUNT_H | ||
73 | #include <sys/mount.h> | ||
74 | #endif | ||
75 | #ifdef HAVE_SYS_VFS_H | ||
76 | #include <sys/vfs.h> | ||
77 | #endif | ||
78 | main () | ||
79 | { | ||
80 | struct statfs fsd; | ||
81 | fsd.f_bsize = 0; | ||
82 | exit (statfs (".", &fsd)); | ||
83 | }], | ||
84 | fu_cv_sys_stat_statfs2_bsize=yes, | ||
85 | fu_cv_sys_stat_statfs2_bsize=no, | ||
86 | fu_cv_sys_stat_statfs2_bsize=no)]) | ||
87 | AC_MSG_RESULT($fu_cv_sys_stat_statfs2_bsize) | ||
88 | if test $fu_cv_sys_stat_statfs2_bsize = yes; then | ||
89 | ac_fsusage_space=yes | ||
90 | AC_DEFINE_UNQUOTED(STAT_STATFS2_BSIZE, 1, | ||
91 | [ Define if statfs takes 2 args and struct statfs has a field named f_bsize. | ||
92 | (4.3BSD, SunOS 4, HP-UX, AIX PS/2)]) | ||
93 | fi | ||
94 | fi | ||
95 | |||
96 | if test $ac_fsusage_space = no; then | ||
97 | # SVR3 | ||
98 | AC_MSG_CHECKING([for four-argument statfs (AIX-3.2.5, SVR3)]) | ||
99 | AC_CACHE_VAL(fu_cv_sys_stat_statfs4, | ||
100 | [AC_TRY_RUN([#include <sys/types.h> | ||
101 | #include <sys/statfs.h> | ||
102 | main () | ||
103 | { | ||
104 | struct statfs fsd; | ||
105 | exit (statfs (".", &fsd, sizeof fsd, 0)); | ||
106 | }], | ||
107 | fu_cv_sys_stat_statfs4=yes, | ||
108 | fu_cv_sys_stat_statfs4=no, | ||
109 | fu_cv_sys_stat_statfs4=no)]) | ||
110 | AC_MSG_RESULT($fu_cv_sys_stat_statfs4) | ||
111 | if test $fu_cv_sys_stat_statfs4 = yes; then | ||
112 | ac_fsusage_space=yes | ||
113 | AC_DEFINE_UNQUOTED(STAT_STATFS4, 1, | ||
114 | [ Define if statfs takes 4 args. (SVR3, Dynix, Irix, Dolphin)]) | ||
115 | fi | ||
116 | fi | ||
117 | |||
118 | if test $ac_fsusage_space = no; then | ||
119 | # 4.4BSD and NetBSD | ||
120 | AC_MSG_CHECKING([for two-argument statfs with statfs.fsize dnl | ||
121 | member (4.4BSD and NetBSD)]) | ||
122 | AC_CACHE_VAL(fu_cv_sys_stat_statfs2_fsize, | ||
123 | [AC_TRY_RUN([#include <sys/types.h> | ||
124 | #ifdef HAVE_SYS_PARAM_H | ||
125 | #include <sys/param.h> | ||
126 | #endif | ||
127 | #ifdef HAVE_SYS_MOUNT_H | ||
128 | #include <sys/mount.h> | ||
129 | #endif | ||
130 | main () | ||
131 | { | ||
132 | struct statfs fsd; | ||
133 | fsd.f_fsize = 0; | ||
134 | exit (statfs (".", &fsd)); | ||
135 | }], | ||
136 | fu_cv_sys_stat_statfs2_fsize=yes, | ||
137 | fu_cv_sys_stat_statfs2_fsize=no, | ||
138 | fu_cv_sys_stat_statfs2_fsize=no)]) | ||
139 | AC_MSG_RESULT($fu_cv_sys_stat_statfs2_fsize) | ||
140 | if test $fu_cv_sys_stat_statfs2_fsize = yes; then | ||
141 | ac_fsusage_space=yes | ||
142 | AC_DEFINE_UNQUOTED(STAT_STATFS2_FSIZE, 1, | ||
143 | [ Define if statfs takes 2 args and struct statfs has a field named f_fsize. | ||
144 | (4.4BSD, NetBSD)]) | ||
145 | fi | ||
146 | fi | ||
147 | |||
148 | if test $ac_fsusage_space = no; then | ||
149 | # Ultrix | ||
150 | AC_MSG_CHECKING([for two-argument statfs with struct fs_data (Ultrix)]) | ||
151 | AC_CACHE_VAL(fu_cv_sys_stat_fs_data, | ||
152 | [AC_TRY_RUN([#include <sys/types.h> | ||
153 | #ifdef HAVE_SYS_PARAM_H | ||
154 | #include <sys/param.h> | ||
155 | #endif | ||
156 | #ifdef HAVE_SYS_MOUNT_H | ||
157 | #include <sys/mount.h> | ||
158 | #endif | ||
159 | #ifdef HAVE_SYS_FS_TYPES_H | ||
160 | #include <sys/fs_types.h> | ||
161 | #endif | ||
162 | main () | ||
163 | { | ||
164 | struct fs_data fsd; | ||
165 | /* Ultrix's statfs returns 1 for success, | ||
166 | 0 for not mounted, -1 for failure. */ | ||
167 | exit (statfs (".", &fsd) != 1); | ||
168 | }], | ||
169 | fu_cv_sys_stat_fs_data=yes, | ||
170 | fu_cv_sys_stat_fs_data=no, | ||
171 | fu_cv_sys_stat_fs_data=no)]) | ||
172 | AC_MSG_RESULT($fu_cv_sys_stat_fs_data) | ||
173 | if test $fu_cv_sys_stat_fs_data = yes; then | ||
174 | ac_fsusage_space=yes | ||
175 | AC_DEFINE_UNQUOTED(STAT_STATFS2_FS_DATA, 1, | ||
176 | [ Define if statfs takes 2 args and the second argument has | ||
177 | type struct fs_data. (Ultrix)]) | ||
178 | fi | ||
179 | fi | ||
180 | |||
181 | if test $ac_fsusage_space = no; then | ||
182 | # SVR2 | ||
183 | AC_TRY_CPP([#include <sys/filsys.h> | ||
184 | ], | ||
185 | AC_DEFINE_UNQUOTED(STAT_READ_FILSYS, 1, | ||
186 | [Define if there is no specific function for reading filesystems usage | ||
187 | information and you have the <sys/filsys.h> header file. (SVR2)]) | ||
188 | ac_fsusage_space=yes) | ||
189 | fi | ||
190 | |||
191 | dnl AS_IF([test $ac_fsusage_space = yes], [$1], [$2]) | ||
192 | if test $ac_fsusage_space = yes ; then [$1] ; else [$2] ; fi | ||
193 | |||
194 | ]) | ||
diff --git a/lib/ls-mntd-fs.m4 b/lib/ls-mntd-fs.m4 new file mode 100644 index 00000000..695b3ba6 --- /dev/null +++ b/lib/ls-mntd-fs.m4 | |||
@@ -0,0 +1,243 @@ | |||
1 | #serial 10 | ||
2 | |||
3 | dnl From Jim Meyering. | ||
4 | dnl | ||
5 | dnl This is not pretty. I've just taken the autoconf code and wrapped | ||
6 | dnl it in an AC_DEFUN. | ||
7 | dnl | ||
8 | |||
9 | # jm_LIST_MOUNTED_FILESYSTEMS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) | ||
10 | AC_DEFUN(jm_LIST_MOUNTED_FILESYSTEMS, | ||
11 | [ | ||
12 | AC_CHECK_FUNCS(listmntent getmntinfo) | ||
13 | AC_CHECK_HEADERS(mntent.h) | ||
14 | |||
15 | # Determine how to get the list of mounted filesystems. | ||
16 | ac_list_mounted_fs= | ||
17 | |||
18 | # If the getmntent function is available but not in the standard library, | ||
19 | # make sure LIBS contains -lsun (on Irix4) or -lseq (on PTX). | ||
20 | AC_FUNC_GETMNTENT | ||
21 | |||
22 | # This test must precede the ones for getmntent because Unicos-9 is | ||
23 | # reported to have the getmntent function, but its support is incompatible | ||
24 | # with other getmntent implementations. | ||
25 | |||
26 | # NOTE: Normally, I wouldn't use a check for system type as I've done for | ||
27 | # `CRAY' below since that goes against the whole autoconf philosophy. But | ||
28 | # I think there is too great a chance that some non-Cray system has a | ||
29 | # function named listmntent to risk the false positive. | ||
30 | |||
31 | if test -z "$ac_list_mounted_fs"; then | ||
32 | # Cray UNICOS 9 | ||
33 | AC_MSG_CHECKING([for listmntent of Cray/Unicos-9]) | ||
34 | AC_CACHE_VAL(fu_cv_sys_mounted_cray_listmntent, | ||
35 | [fu_cv_sys_mounted_cray_listmntent=no | ||
36 | AC_EGREP_CPP(yes, | ||
37 | [#ifdef _CRAY | ||
38 | yes | ||
39 | #endif | ||
40 | ], [test $ac_cv_func_listmntent = yes \ | ||
41 | && fu_cv_sys_mounted_cray_listmntent=yes] | ||
42 | ) | ||
43 | ] | ||
44 | ) | ||
45 | AC_MSG_RESULT($fu_cv_sys_mounted_cray_listmntent) | ||
46 | if test $fu_cv_sys_mounted_cray_listmntent = yes; then | ||
47 | ac_list_mounted_fs=found | ||
48 | AC_DEFINE(MOUNTED_LISTMNTENT, 1, | ||
49 | [Define if there is a function named listmntent that can be used to | ||
50 | list all mounted filesystems. (UNICOS)]) | ||
51 | fi | ||
52 | fi | ||
53 | |||
54 | if test $ac_cv_func_getmntent = yes; then | ||
55 | |||
56 | # This system has the getmntent function. | ||
57 | # Determine whether it's the one-argument variant or the two-argument one. | ||
58 | |||
59 | if test -z "$ac_list_mounted_fs"; then | ||
60 | # 4.3BSD, SunOS, HP-UX, Dynix, Irix | ||
61 | AC_MSG_CHECKING([for one-argument getmntent function]) | ||
62 | AC_CACHE_VAL(fu_cv_sys_mounted_getmntent1, | ||
63 | [test $ac_cv_header_mntent_h = yes \ | ||
64 | && fu_cv_sys_mounted_getmntent1=yes \ | ||
65 | || fu_cv_sys_mounted_getmntent1=no]) | ||
66 | AC_MSG_RESULT($fu_cv_sys_mounted_getmntent1) | ||
67 | if test $fu_cv_sys_mounted_getmntent1 = yes; then | ||
68 | ac_list_mounted_fs=found | ||
69 | AC_DEFINE(MOUNTED_GETMNTENT1, 1, | ||
70 | [Define if there is a function named getmntent for reading the list | ||
71 | of mounted filesystems, and that function takes a single argument. | ||
72 | (4.3BSD, SunOS, HP-UX, Dynix, Irix)]) | ||
73 | fi | ||
74 | fi | ||
75 | |||
76 | if test -z "$ac_list_mounted_fs"; then | ||
77 | # SVR4 | ||
78 | AC_MSG_CHECKING([for two-argument getmntent function]) | ||
79 | AC_CACHE_VAL(fu_cv_sys_mounted_getmntent2, | ||
80 | [AC_EGREP_HEADER(getmntent, sys/mnttab.h, | ||
81 | fu_cv_sys_mounted_getmntent2=yes, | ||
82 | fu_cv_sys_mounted_getmntent2=no)]) | ||
83 | AC_MSG_RESULT($fu_cv_sys_mounted_getmntent2) | ||
84 | if test $fu_cv_sys_mounted_getmntent2 = yes; then | ||
85 | ac_list_mounted_fs=found | ||
86 | AC_DEFINE(MOUNTED_GETMNTENT2, 1, | ||
87 | [Define if there is a function named getmntent for reading the list of | ||
88 | mounted filesystems, and that function takes two arguments. (SVR4)]) | ||
89 | fi | ||
90 | fi | ||
91 | |||
92 | if test -z "$ac_list_mounted_fs"; then | ||
93 | AC_MSG_ERROR([could not determine how to read list of mounted filesystems]) | ||
94 | fi | ||
95 | |||
96 | fi | ||
97 | |||
98 | if test -z "$ac_list_mounted_fs"; then | ||
99 | # DEC Alpha running OSF/1. | ||
100 | AC_MSG_CHECKING([for getfsstat function]) | ||
101 | AC_CACHE_VAL(fu_cv_sys_mounted_getsstat, | ||
102 | [AC_TRY_LINK([ | ||
103 | #include <sys/types.h> | ||
104 | #include <sys/mount.h> | ||
105 | #include <sys/fs_types.h>], | ||
106 | [struct statfs *stats; | ||
107 | int numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT); ], | ||
108 | fu_cv_sys_mounted_getsstat=yes, | ||
109 | fu_cv_sys_mounted_getsstat=no)]) | ||
110 | AC_MSG_RESULT($fu_cv_sys_mounted_getsstat) | ||
111 | if test $fu_cv_sys_mounted_getsstat = yes; then | ||
112 | ac_list_mounted_fs=found | ||
113 | AC_DEFINE(MOUNTED_GETFSSTAT, 1, | ||
114 | [Define if there is a function named getfsstat for reading the | ||
115 | list of mounted filesystems. (DEC Alpha running OSF/1)]) | ||
116 | fi | ||
117 | fi | ||
118 | |||
119 | if test -z "$ac_list_mounted_fs"; then | ||
120 | # AIX. | ||
121 | AC_MSG_CHECKING([for mntctl function and struct vmount]) | ||
122 | AC_CACHE_VAL(fu_cv_sys_mounted_vmount, | ||
123 | [AC_TRY_CPP([#include <fshelp.h>], | ||
124 | fu_cv_sys_mounted_vmount=yes, | ||
125 | fu_cv_sys_mounted_vmount=no)]) | ||
126 | AC_MSG_RESULT($fu_cv_sys_mounted_vmount) | ||
127 | if test $fu_cv_sys_mounted_vmount = yes; then | ||
128 | ac_list_mounted_fs=found | ||
129 | AC_DEFINE(MOUNTED_VMOUNT, 1, | ||
130 | [Define if there is a function named mntctl that can be used to read | ||
131 | the list of mounted filesystems, and there is a system header file | ||
132 | that declares `struct vmount.' (AIX)]) | ||
133 | fi | ||
134 | fi | ||
135 | |||
136 | if test -z "$ac_list_mounted_fs"; then | ||
137 | # SVR3 | ||
138 | AC_MSG_CHECKING([for FIXME existence of three headers]) | ||
139 | AC_CACHE_VAL(fu_cv_sys_mounted_fread_fstyp, | ||
140 | [AC_TRY_CPP([ | ||
141 | #include <sys/statfs.h> | ||
142 | #include <sys/fstyp.h> | ||
143 | #include <mnttab.h>], | ||
144 | fu_cv_sys_mounted_fread_fstyp=yes, | ||
145 | fu_cv_sys_mounted_fread_fstyp=no)]) | ||
146 | AC_MSG_RESULT($fu_cv_sys_mounted_fread_fstyp) | ||
147 | if test $fu_cv_sys_mounted_fread_fstyp = yes; then | ||
148 | ac_list_mounted_fs=found | ||
149 | AC_DEFINE(MOUNTED_FREAD_FSTYP, 1, | ||
150 | [Define if (like SVR2) there is no specific function for reading the | ||
151 | list of mounted filesystems, and your system has these header files: | ||
152 | <sys/fstyp.h> and <sys/statfs.h>. (SVR3)]) | ||
153 | fi | ||
154 | fi | ||
155 | |||
156 | if test -z "$ac_list_mounted_fs"; then | ||
157 | # 4.4BSD and DEC OSF/1. | ||
158 | AC_MSG_CHECKING([for getmntinfo function]) | ||
159 | AC_CACHE_VAL(fu_cv_sys_mounted_getmntinfo, | ||
160 | [ | ||
161 | ok= | ||
162 | if test $ac_cv_func_getmntinfo = yes; then | ||
163 | AC_EGREP_HEADER(f_type;, sys/mount.h, | ||
164 | ok=yes) | ||
165 | fi | ||
166 | test -n "$ok" \ | ||
167 | && fu_cv_sys_mounted_getmntinfo=yes \ | ||
168 | || fu_cv_sys_mounted_getmntinfo=no | ||
169 | ]) | ||
170 | AC_MSG_RESULT($fu_cv_sys_mounted_getmntinfo) | ||
171 | if test $fu_cv_sys_mounted_getmntinfo = yes; then | ||
172 | ac_list_mounted_fs=found | ||
173 | AC_DEFINE(MOUNTED_GETMNTINFO, 1, | ||
174 | [Define if there is a function named getmntinfo for reading the | ||
175 | list of mounted filesystems. (4.4BSD)]) | ||
176 | fi | ||
177 | fi | ||
178 | |||
179 | if test -z "$ac_list_mounted_fs"; then | ||
180 | # Ultrix | ||
181 | AC_MSG_CHECKING([for getmnt function]) | ||
182 | AC_CACHE_VAL(fu_cv_sys_mounted_getmnt, | ||
183 | [AC_TRY_CPP([ | ||
184 | #include <sys/fs_types.h> | ||
185 | #include <sys/mount.h>], | ||
186 | fu_cv_sys_mounted_getmnt=yes, | ||
187 | fu_cv_sys_mounted_getmnt=no)]) | ||
188 | AC_MSG_RESULT($fu_cv_sys_mounted_getmnt) | ||
189 | if test $fu_cv_sys_mounted_getmnt = yes; then | ||
190 | ac_list_mounted_fs=found | ||
191 | AC_DEFINE(MOUNTED_GETMNT, 1, | ||
192 | [Define if there is a function named getmnt for reading the list of | ||
193 | mounted filesystems. (Ultrix)]) | ||
194 | fi | ||
195 | fi | ||
196 | |||
197 | if test -z "$ac_list_mounted_fs"; then | ||
198 | # BeOS | ||
199 | AC_CHECK_FUNCS(next_dev fs_stat_dev) | ||
200 | AC_CHECK_HEADERS(fs_info.h) | ||
201 | AC_MSG_CHECKING([for BEOS mounted file system support functions]) | ||
202 | if test $ac_cv_header_fs_info_h = yes \ | ||
203 | && test $ac_cv_func_next_dev = yes \ | ||
204 | && test $ac_cv_func_fs_stat_dev = yes; then | ||
205 | fu_result=yes | ||
206 | else | ||
207 | fu_result=no | ||
208 | fi | ||
209 | AC_MSG_RESULT($fu_result) | ||
210 | if test $fu_result = yes; then | ||
211 | ac_list_mounted_fs=found | ||
212 | AC_DEFINE(MOUNTED_FS_STAT_DEV, 1, | ||
213 | [Define if there are functions named next_dev and fs_stat_dev for | ||
214 | reading the list of mounted filesystems. (BeOS)]) | ||
215 | fi | ||
216 | fi | ||
217 | |||
218 | if test -z "$ac_list_mounted_fs"; then | ||
219 | # SVR2 | ||
220 | AC_MSG_CHECKING([whether it is possible to resort to fread on /etc/mnttab]) | ||
221 | AC_CACHE_VAL(fu_cv_sys_mounted_fread, | ||
222 | [AC_TRY_CPP([#include <mnttab.h>], | ||
223 | fu_cv_sys_mounted_fread=yes, | ||
224 | fu_cv_sys_mounted_fread=no)]) | ||
225 | AC_MSG_RESULT($fu_cv_sys_mounted_fread) | ||
226 | if test $fu_cv_sys_mounted_fread = yes; then | ||
227 | ac_list_mounted_fs=found | ||
228 | AC_DEFINE(MOUNTED_FREAD, 1, | ||
229 | [Define if there is no specific function for reading the list of | ||
230 | mounted filesystems. fread will be used to read /etc/mnttab. (SVR2) ]) | ||
231 | fi | ||
232 | fi | ||
233 | |||
234 | if test -z "$ac_list_mounted_fs"; then | ||
235 | AC_MSG_ERROR([could not determine how to read list of mounted filesystems]) | ||
236 | # FIXME -- no need to abort building the whole package | ||
237 | # Can't build mountlist.c or anything that needs its functions | ||
238 | fi | ||
239 | |||
240 | dnl AS_IF([test $ac_list_mounted_fs = found], [$1], [$2]) | ||
241 | if test $ac_list_mounted_fs = found ; then [$1] ; else [$2] ; fi | ||
242 | |||
243 | ]) | ||
diff --git a/lib/mountlist.c b/lib/mountlist.c new file mode 100644 index 00000000..b667c443 --- /dev/null +++ b/lib/mountlist.c | |||
@@ -0,0 +1,788 @@ | |||
1 | /* mountlist.c -- return a list of mounted filesystems | ||
2 | Copyright (C) 1991, 1992, 1997-2000 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software Foundation, | ||
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
17 | |||
18 | #include "../plugins/config.h" | ||
19 | |||
20 | #include <stdio.h> | ||
21 | #include <sys/types.h> | ||
22 | #include "mountlist.h" | ||
23 | |||
24 | #ifdef STDC_HEADERS | ||
25 | # include <stdlib.h> | ||
26 | #else | ||
27 | void free (); | ||
28 | #endif | ||
29 | #if defined(STDC_HEADERS) || defined(HAVE_STRING_H) | ||
30 | # include <string.h> | ||
31 | #else | ||
32 | # include <strings.h> | ||
33 | #endif | ||
34 | |||
35 | #ifndef strstr | ||
36 | char *strstr (); | ||
37 | #endif | ||
38 | char *xmalloc (); | ||
39 | char *xrealloc (); | ||
40 | char *xstrdup (); | ||
41 | |||
42 | #include <errno.h> | ||
43 | #ifndef errno | ||
44 | extern int errno; | ||
45 | #endif | ||
46 | |||
47 | #ifdef HAVE_FCNTL_H | ||
48 | # include <fcntl.h> | ||
49 | #endif | ||
50 | |||
51 | #ifdef HAVE_UNISTD_H | ||
52 | # include <unistd.h> | ||
53 | #endif | ||
54 | |||
55 | #if HAVE_SYS_PARAM_H | ||
56 | # include <sys/param.h> | ||
57 | #endif | ||
58 | |||
59 | #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */ | ||
60 | # include <sys/mount.h> | ||
61 | # include <sys/fs_types.h> | ||
62 | #endif /* MOUNTED_GETFSSTAT */ | ||
63 | |||
64 | #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ | ||
65 | # include <mntent.h> | ||
66 | # if !defined(MOUNTED) | ||
67 | # if defined(MNT_MNTTAB) /* HP-UX. */ | ||
68 | # define MOUNTED MNT_MNTTAB | ||
69 | # endif | ||
70 | # if defined(MNTTABNAME) /* Dynix. */ | ||
71 | # define MOUNTED MNTTABNAME | ||
72 | # endif | ||
73 | # endif | ||
74 | #endif | ||
75 | |||
76 | #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ | ||
77 | # include <sys/mount.h> | ||
78 | #endif | ||
79 | |||
80 | #ifdef MOUNTED_GETMNT /* Ultrix. */ | ||
81 | # include <sys/mount.h> | ||
82 | # include <sys/fs_types.h> | ||
83 | #endif | ||
84 | |||
85 | #ifdef MOUNTED_FS_STAT_DEV /* BeOS. */ | ||
86 | # include <fs_info.h> | ||
87 | # include <dirent.h> | ||
88 | #endif | ||
89 | |||
90 | #ifdef MOUNTED_FREAD /* SVR2. */ | ||
91 | # include <mnttab.h> | ||
92 | #endif | ||
93 | |||
94 | #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */ | ||
95 | # include <mnttab.h> | ||
96 | # include <sys/fstyp.h> | ||
97 | # include <sys/statfs.h> | ||
98 | #endif | ||
99 | |||
100 | #ifdef MOUNTED_LISTMNTENT | ||
101 | # include <mntent.h> | ||
102 | #endif | ||
103 | |||
104 | #ifdef MOUNTED_GETMNTENT2 /* SVR4. */ | ||
105 | # include <sys/mnttab.h> | ||
106 | #endif | ||
107 | |||
108 | #ifdef MOUNTED_VMOUNT /* AIX. */ | ||
109 | # include <fshelp.h> | ||
110 | # include <sys/vfs.h> | ||
111 | #endif | ||
112 | |||
113 | #ifdef DOLPHIN | ||
114 | /* So special that it's not worth putting this in autoconf. */ | ||
115 | # undef MOUNTED_FREAD_FSTYP | ||
116 | # define MOUNTED_GETMNTTBL | ||
117 | #endif | ||
118 | |||
119 | #if HAVE_SYS_MNTENT_H | ||
120 | /* This is to get MNTOPT_IGNORE on e.g. SVR4. */ | ||
121 | # include <sys/mntent.h> | ||
122 | #endif | ||
123 | |||
124 | #if defined (MNTOPT_IGNORE) && defined (HAVE_HASMNTOPT) | ||
125 | # define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE) | ||
126 | #else | ||
127 | # define MNT_IGNORE(M) 0 | ||
128 | #endif | ||
129 | |||
130 | #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ | ||
131 | /* Return the value of the hexadecimal number represented by CP. | ||
132 | No prefix (like '0x') or suffix (like 'h') is expected to be | ||
133 | part of CP. */ | ||
134 | /* FIXME: this can overflow */ | ||
135 | |||
136 | static int | ||
137 | xatoi (char *cp) | ||
138 | { | ||
139 | int val; | ||
140 | |||
141 | val = 0; | ||
142 | while (*cp) | ||
143 | { | ||
144 | if (*cp >= 'a' && *cp <= 'f') | ||
145 | val = val * 16 + *cp - 'a' + 10; | ||
146 | else if (*cp >= 'A' && *cp <= 'F') | ||
147 | val = val * 16 + *cp - 'A' + 10; | ||
148 | else if (*cp >= '0' && *cp <= '9') | ||
149 | val = val * 16 + *cp - '0'; | ||
150 | else | ||
151 | break; | ||
152 | cp++; | ||
153 | } | ||
154 | return val; | ||
155 | } | ||
156 | #endif /* MOUNTED_GETMNTENT1. */ | ||
157 | |||
158 | #if MOUNTED_GETMNTINFO | ||
159 | |||
160 | # if ! HAVE_F_FSTYPENAME_IN_STATFS | ||
161 | static char * | ||
162 | fstype_to_string (short t) | ||
163 | { | ||
164 | switch (t) | ||
165 | { | ||
166 | # ifdef MOUNT_PC | ||
167 | case MOUNT_PC: | ||
168 | return "pc"; | ||
169 | # endif | ||
170 | # ifdef MOUNT_MFS | ||
171 | case MOUNT_MFS: | ||
172 | return "mfs"; | ||
173 | # endif | ||
174 | # ifdef MOUNT_LO | ||
175 | case MOUNT_LO: | ||
176 | return "lo"; | ||
177 | # endif | ||
178 | # ifdef MOUNT_TFS | ||
179 | case MOUNT_TFS: | ||
180 | return "tfs"; | ||
181 | # endif | ||
182 | # ifdef MOUNT_TMP | ||
183 | case MOUNT_TMP: | ||
184 | return "tmp"; | ||
185 | # endif | ||
186 | # ifdef MOUNT_UFS | ||
187 | case MOUNT_UFS: | ||
188 | return "ufs" ; | ||
189 | # endif | ||
190 | # ifdef MOUNT_NFS | ||
191 | case MOUNT_NFS: | ||
192 | return "nfs" ; | ||
193 | # endif | ||
194 | # ifdef MOUNT_MSDOS | ||
195 | case MOUNT_MSDOS: | ||
196 | return "msdos" ; | ||
197 | # endif | ||
198 | # ifdef MOUNT_LFS | ||
199 | case MOUNT_LFS: | ||
200 | return "lfs" ; | ||
201 | # endif | ||
202 | # ifdef MOUNT_LOFS | ||
203 | case MOUNT_LOFS: | ||
204 | return "lofs" ; | ||
205 | # endif | ||
206 | # ifdef MOUNT_FDESC | ||
207 | case MOUNT_FDESC: | ||
208 | return "fdesc" ; | ||
209 | # endif | ||
210 | # ifdef MOUNT_PORTAL | ||
211 | case MOUNT_PORTAL: | ||
212 | return "portal" ; | ||
213 | # endif | ||
214 | # ifdef MOUNT_NULL | ||
215 | case MOUNT_NULL: | ||
216 | return "null" ; | ||
217 | # endif | ||
218 | # ifdef MOUNT_UMAP | ||
219 | case MOUNT_UMAP: | ||
220 | return "umap" ; | ||
221 | # endif | ||
222 | # ifdef MOUNT_KERNFS | ||
223 | case MOUNT_KERNFS: | ||
224 | return "kernfs" ; | ||
225 | # endif | ||
226 | # ifdef MOUNT_PROCFS | ||
227 | case MOUNT_PROCFS: | ||
228 | return "procfs" ; | ||
229 | # endif | ||
230 | # ifdef MOUNT_AFS | ||
231 | case MOUNT_AFS: | ||
232 | return "afs" ; | ||
233 | # endif | ||
234 | # ifdef MOUNT_CD9660 | ||
235 | case MOUNT_CD9660: | ||
236 | return "cd9660" ; | ||
237 | # endif | ||
238 | # ifdef MOUNT_UNION | ||
239 | case MOUNT_UNION: | ||
240 | return "union" ; | ||
241 | # endif | ||
242 | # ifdef MOUNT_DEVFS | ||
243 | case MOUNT_DEVFS: | ||
244 | return "devfs" ; | ||
245 | # endif | ||
246 | # ifdef MOUNT_EXT2FS | ||
247 | case MOUNT_EXT2FS: | ||
248 | return "ext2fs" ; | ||
249 | # endif | ||
250 | default: | ||
251 | return "?"; | ||
252 | } | ||
253 | } | ||
254 | # endif /* ! HAVE_F_FSTYPENAME_IN_STATFS */ | ||
255 | |||
256 | /* __NetBSD__ || BSD_NET2 || __OpenBSD__ */ | ||
257 | static char * | ||
258 | fsp_to_string (const struct statfs *fsp) | ||
259 | { | ||
260 | # if defined HAVE_F_FSTYPENAME_IN_STATFS | ||
261 | return (char *) (fsp->f_fstypename); | ||
262 | # else | ||
263 | return fstype_to_string (fsp->f_type); | ||
264 | # endif | ||
265 | } | ||
266 | |||
267 | #endif /* MOUNTED_GETMNTINFO */ | ||
268 | |||
269 | #ifdef MOUNTED_VMOUNT /* AIX. */ | ||
270 | static char * | ||
271 | fstype_to_string (int t) | ||
272 | { | ||
273 | struct vfs_ent *e; | ||
274 | |||
275 | e = getvfsbytype (t); | ||
276 | if (!e || !e->vfsent_name) | ||
277 | return "none"; | ||
278 | else | ||
279 | return e->vfsent_name; | ||
280 | } | ||
281 | #endif /* MOUNTED_VMOUNT */ | ||
282 | |||
283 | /* Return a list of the currently mounted filesystems, or NULL on error. | ||
284 | Add each entry to the tail of the list so that they stay in order. | ||
285 | If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in | ||
286 | the returned list are valid. Otherwise, they might not be. */ | ||
287 | |||
288 | struct mount_entry * | ||
289 | read_filesystem_list (int need_fs_type) | ||
290 | { | ||
291 | struct mount_entry *mount_list; | ||
292 | struct mount_entry *me; | ||
293 | struct mount_entry **mtail = &mount_list; | ||
294 | |||
295 | #ifdef MOUNTED_LISTMNTENT | ||
296 | { | ||
297 | struct tabmntent *mntlist, *p; | ||
298 | struct mntent *mnt; | ||
299 | struct mount_entry *me; | ||
300 | |||
301 | /* the third and fourth arguments could be used to filter mounts, | ||
302 | but Crays doesn't seem to have any mounts that we want to | ||
303 | remove. Specifically, automount create normal NFS mounts. | ||
304 | */ | ||
305 | |||
306 | if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) | ||
307 | return NULL; | ||
308 | for (p = mntlist; p; p = p->next) { | ||
309 | mnt = p->ment; | ||
310 | me = (struct mount_entry*) xmalloc(sizeof (struct mount_entry)); | ||
311 | me->me_devname = xstrdup(mnt->mnt_fsname); | ||
312 | me->me_mountdir = xstrdup(mnt->mnt_dir); | ||
313 | me->me_type = xstrdup(mnt->mnt_type); | ||
314 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
315 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
316 | me->me_dev = -1; | ||
317 | *mtail = me; | ||
318 | mtail = &me->me_next; | ||
319 | } | ||
320 | freemntlist(mntlist); | ||
321 | } | ||
322 | #endif | ||
323 | |||
324 | #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ | ||
325 | { | ||
326 | struct mntent *mnt; | ||
327 | char *table = MOUNTED; | ||
328 | FILE *fp; | ||
329 | char *devopt; | ||
330 | |||
331 | fp = setmntent (table, "r"); | ||
332 | if (fp == NULL) | ||
333 | return NULL; | ||
334 | |||
335 | while ((mnt = getmntent (fp))) | ||
336 | { | ||
337 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
338 | me->me_devname = xstrdup (mnt->mnt_fsname); | ||
339 | me->me_mountdir = xstrdup (mnt->mnt_dir); | ||
340 | me->me_type = xstrdup (mnt->mnt_type); | ||
341 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
342 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
343 | devopt = strstr (mnt->mnt_opts, "dev="); | ||
344 | if (devopt) | ||
345 | { | ||
346 | if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X')) | ||
347 | me->me_dev = xatoi (devopt + 6); | ||
348 | else | ||
349 | me->me_dev = xatoi (devopt + 4); | ||
350 | } | ||
351 | else | ||
352 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ | ||
353 | |||
354 | /* Add to the linked list. */ | ||
355 | *mtail = me; | ||
356 | mtail = &me->me_next; | ||
357 | } | ||
358 | |||
359 | if (endmntent (fp) == 0) | ||
360 | goto free_then_fail; | ||
361 | } | ||
362 | #endif /* MOUNTED_GETMNTENT1. */ | ||
363 | |||
364 | #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ | ||
365 | { | ||
366 | struct statfs *fsp; | ||
367 | int entries; | ||
368 | |||
369 | entries = getmntinfo (&fsp, MNT_NOWAIT); | ||
370 | if (entries < 0) | ||
371 | return NULL; | ||
372 | for (; entries-- > 0; fsp++) | ||
373 | { | ||
374 | char *fs_type = fsp_to_string (fsp); | ||
375 | |||
376 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
377 | me->me_devname = xstrdup (fsp->f_mntfromname); | ||
378 | me->me_mountdir = xstrdup (fsp->f_mntonname); | ||
379 | me->me_type = fs_type; | ||
380 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
381 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
382 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ | ||
383 | |||
384 | /* Add to the linked list. */ | ||
385 | *mtail = me; | ||
386 | mtail = &me->me_next; | ||
387 | } | ||
388 | } | ||
389 | #endif /* MOUNTED_GETMNTINFO */ | ||
390 | |||
391 | #ifdef MOUNTED_GETMNT /* Ultrix. */ | ||
392 | { | ||
393 | int offset = 0; | ||
394 | int val; | ||
395 | struct fs_data fsd; | ||
396 | |||
397 | while (errno = 0, | ||
398 | 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, | ||
399 | (char *) 0))) | ||
400 | { | ||
401 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
402 | me->me_devname = xstrdup (fsd.fd_req.devname); | ||
403 | me->me_mountdir = xstrdup (fsd.fd_req.path); | ||
404 | me->me_type = gt_names[fsd.fd_req.fstype]; | ||
405 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
406 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
407 | me->me_dev = fsd.fd_req.dev; | ||
408 | |||
409 | /* Add to the linked list. */ | ||
410 | *mtail = me; | ||
411 | mtail = &me->me_next; | ||
412 | } | ||
413 | if (val < 0) | ||
414 | goto free_then_fail; | ||
415 | } | ||
416 | #endif /* MOUNTED_GETMNT. */ | ||
417 | |||
418 | #if defined (MOUNTED_FS_STAT_DEV) /* BeOS */ | ||
419 | { | ||
420 | /* The next_dev() and fs_stat_dev() system calls give the list of | ||
421 | all filesystems, including the information returned by statvfs() | ||
422 | (fs type, total blocks, free blocks etc.), but without the mount | ||
423 | point. But on BeOS all filesystems except / are mounted in the | ||
424 | rootfs, directly under /. | ||
425 | The directory name of the mount point is often, but not always, | ||
426 | identical to the volume name of the device. | ||
427 | We therefore get the list of subdirectories of /, and the list | ||
428 | of all filesystems, and match the two lists. */ | ||
429 | |||
430 | DIR *dirp; | ||
431 | struct rootdir_entry | ||
432 | { | ||
433 | char *name; | ||
434 | dev_t dev; | ||
435 | ino_t ino; | ||
436 | struct rootdir_entry *next; | ||
437 | }; | ||
438 | struct rootdir_entry *rootdir_list; | ||
439 | struct rootdir_entry **rootdir_tail; | ||
440 | int32 pos; | ||
441 | dev_t dev; | ||
442 | fs_info fi; | ||
443 | |||
444 | /* All volumes are mounted in the rootfs, directly under /. */ | ||
445 | rootdir_list = NULL; | ||
446 | rootdir_tail = &rootdir_list; | ||
447 | dirp = opendir ("/"); | ||
448 | if (dirp) | ||
449 | { | ||
450 | struct dirent *d; | ||
451 | |||
452 | while ((d = readdir (dirp)) != NULL) | ||
453 | { | ||
454 | char *name; | ||
455 | struct stat statbuf; | ||
456 | |||
457 | if (strcmp (d->d_name, "..") == 0) | ||
458 | continue; | ||
459 | |||
460 | if (strcmp (d->d_name, ".") == 0) | ||
461 | name = xstrdup ("/"); | ||
462 | else | ||
463 | { | ||
464 | name = xmalloc (1 + strlen (d->d_name) + 1); | ||
465 | name[0] = '/'; | ||
466 | strcpy (name + 1, d->d_name); | ||
467 | } | ||
468 | |||
469 | if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) | ||
470 | { | ||
471 | struct rootdir_entry *re; | ||
472 | |||
473 | re = (struct rootdir_entry *) xmalloc (sizeof (struct rootdir_entry)); | ||
474 | re->name = name; | ||
475 | re->dev = statbuf.st_dev; | ||
476 | re->ino = statbuf.st_ino; | ||
477 | |||
478 | /* Add to the linked list. */ | ||
479 | *rootdir_tail = re; | ||
480 | rootdir_tail = &re->next; | ||
481 | } | ||
482 | else | ||
483 | free (name); | ||
484 | } | ||
485 | closedir (dirp); | ||
486 | } | ||
487 | *rootdir_tail = NULL; | ||
488 | |||
489 | for (pos = 0; (dev = next_dev (&pos)) >= 0; ) | ||
490 | if (fs_stat_dev (dev, &fi) >= 0) | ||
491 | { | ||
492 | /* Note: fi.dev == dev. */ | ||
493 | struct rootdir_entry *re; | ||
494 | |||
495 | for (re = rootdir_list; re; re = re->next) | ||
496 | if (re->dev == fi.dev && re->ino == fi.root) | ||
497 | break; | ||
498 | |||
499 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
500 | me->me_devname = xstrdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name); | ||
501 | me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name); | ||
502 | me->me_type = xstrdup (fi.fsh_name); | ||
503 | me->me_dev = fi.dev; | ||
504 | me->me_dummy = 0; | ||
505 | me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0; | ||
506 | |||
507 | /* Add to the linked list. */ | ||
508 | *mtail = me; | ||
509 | mtail = &me->me_next; | ||
510 | } | ||
511 | *mtail = NULL; | ||
512 | |||
513 | while (rootdir_list != NULL) | ||
514 | { | ||
515 | struct rootdir_entry *re = rootdir_list; | ||
516 | rootdir_list = re->next; | ||
517 | free (re->name); | ||
518 | free (re); | ||
519 | } | ||
520 | } | ||
521 | #endif /* MOUNTED_FS_STAT_DEV */ | ||
522 | |||
523 | #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */ | ||
524 | { | ||
525 | int numsys, counter, bufsize; | ||
526 | struct statfs *stats; | ||
527 | |||
528 | numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT); | ||
529 | if (numsys < 0) | ||
530 | return (NULL); | ||
531 | |||
532 | bufsize = (1 + numsys) * sizeof (struct statfs); | ||
533 | stats = (struct statfs *)xmalloc (bufsize); | ||
534 | numsys = getfsstat (stats, bufsize, MNT_WAIT); | ||
535 | |||
536 | if (numsys < 0) | ||
537 | { | ||
538 | free (stats); | ||
539 | return (NULL); | ||
540 | } | ||
541 | |||
542 | for (counter = 0; counter < numsys; counter++) | ||
543 | { | ||
544 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
545 | me->me_devname = xstrdup (stats[counter].f_mntfromname); | ||
546 | me->me_mountdir = xstrdup (stats[counter].f_mntonname); | ||
547 | me->me_type = mnt_names[stats[counter].f_type]; | ||
548 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
549 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
550 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ | ||
551 | |||
552 | /* Add to the linked list. */ | ||
553 | *mtail = me; | ||
554 | mtail = &me->me_next; | ||
555 | } | ||
556 | |||
557 | free (stats); | ||
558 | } | ||
559 | #endif /* MOUNTED_GETFSSTAT */ | ||
560 | |||
561 | #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */ | ||
562 | { | ||
563 | struct mnttab mnt; | ||
564 | char *table = "/etc/mnttab"; | ||
565 | FILE *fp; | ||
566 | |||
567 | fp = fopen (table, "r"); | ||
568 | if (fp == NULL) | ||
569 | return NULL; | ||
570 | |||
571 | while (fread (&mnt, sizeof mnt, 1, fp) > 0) | ||
572 | { | ||
573 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
574 | # ifdef GETFSTYP /* SVR3. */ | ||
575 | me->me_devname = xstrdup (mnt.mt_dev); | ||
576 | # else | ||
577 | me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6); | ||
578 | strcpy (me->me_devname, "/dev/"); | ||
579 | strcpy (me->me_devname + 5, mnt.mt_dev); | ||
580 | # endif | ||
581 | me->me_mountdir = xstrdup (mnt.mt_filsys); | ||
582 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ | ||
583 | me->me_type = ""; | ||
584 | # ifdef GETFSTYP /* SVR3. */ | ||
585 | if (need_fs_type) | ||
586 | { | ||
587 | struct statfs fsd; | ||
588 | char typebuf[FSTYPSZ]; | ||
589 | |||
590 | if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1 | ||
591 | && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) | ||
592 | me->me_type = xstrdup (typebuf); | ||
593 | } | ||
594 | # endif | ||
595 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
596 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
597 | |||
598 | /* Add to the linked list. */ | ||
599 | *mtail = me; | ||
600 | mtail = &me->me_next; | ||
601 | } | ||
602 | |||
603 | if (ferror (fp)) | ||
604 | { | ||
605 | int saved_errno = errno; | ||
606 | fclose (fp); | ||
607 | errno = saved_errno; | ||
608 | goto free_then_fail; | ||
609 | } | ||
610 | |||
611 | if (fclose (fp) == EOF) | ||
612 | goto free_then_fail; | ||
613 | } | ||
614 | #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */ | ||
615 | |||
616 | #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */ | ||
617 | { | ||
618 | struct mntent **mnttbl=getmnttbl(),**ent; | ||
619 | for (ent=mnttbl;*ent;ent++) | ||
620 | { | ||
621 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
622 | me->me_devname = xstrdup ( (*ent)->mt_resource); | ||
623 | me->me_mountdir = xstrdup( (*ent)->mt_directory); | ||
624 | me->me_type = xstrdup ((*ent)->mt_fstype); | ||
625 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
626 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
627 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ | ||
628 | |||
629 | /* Add to the linked list. */ | ||
630 | *mtail = me; | ||
631 | mtail = &me->me_next; | ||
632 | } | ||
633 | endmnttbl(); | ||
634 | } | ||
635 | #endif | ||
636 | |||
637 | #ifdef MOUNTED_GETMNTENT2 /* SVR4. */ | ||
638 | { | ||
639 | struct mnttab mnt; | ||
640 | char *table = MNTTAB; | ||
641 | FILE *fp; | ||
642 | int ret; | ||
643 | int lockfd = -1; | ||
644 | |||
645 | # if defined F_RDLCK && defined F_SETLKW | ||
646 | /* MNTTAB_LOCK is a macro name of our own invention; it's not present in | ||
647 | e.g. Solaris 2.6. If the SVR4 folks ever define a macro | ||
648 | for this file name, we should use their macro name instead. | ||
649 | (Why not just lock MNTTAB directly? We don't know.) */ | ||
650 | # ifndef MNTTAB_LOCK | ||
651 | # define MNTTAB_LOCK "/etc/.mnttab.lock" | ||
652 | # endif | ||
653 | lockfd = open (MNTTAB_LOCK, O_RDONLY); | ||
654 | if (0 <= lockfd) | ||
655 | { | ||
656 | struct flock flock; | ||
657 | flock.l_type = F_RDLCK; | ||
658 | flock.l_whence = SEEK_SET; | ||
659 | flock.l_start = 0; | ||
660 | flock.l_len = 0; | ||
661 | while (fcntl (lockfd, F_SETLKW, &flock) == -1) | ||
662 | if (errno != EINTR) | ||
663 | { | ||
664 | int saved_errno = errno; | ||
665 | close (lockfd); | ||
666 | errno = saved_errno; | ||
667 | return NULL; | ||
668 | } | ||
669 | } | ||
670 | else if (errno != ENOENT) | ||
671 | return NULL; | ||
672 | # endif | ||
673 | |||
674 | errno = 0; | ||
675 | fp = fopen (table, "r"); | ||
676 | if (fp == NULL) | ||
677 | ret = errno; | ||
678 | else | ||
679 | { | ||
680 | while ((ret = getmntent (fp, &mnt)) == 0) | ||
681 | { | ||
682 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
683 | me->me_devname = xstrdup (mnt.mnt_special); | ||
684 | me->me_mountdir = xstrdup (mnt.mnt_mountp); | ||
685 | me->me_type = xstrdup (mnt.mnt_fstype); | ||
686 | me->me_dummy = MNT_IGNORE (&mnt) != 0; | ||
687 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
688 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ | ||
689 | |||
690 | /* Add to the linked list. */ | ||
691 | *mtail = me; | ||
692 | mtail = &me->me_next; | ||
693 | } | ||
694 | |||
695 | ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; | ||
696 | } | ||
697 | |||
698 | if (0 <= lockfd && close (lockfd) != 0) | ||
699 | ret = errno; | ||
700 | |||
701 | if (0 <= ret) | ||
702 | { | ||
703 | errno = ret; | ||
704 | goto free_then_fail; | ||
705 | } | ||
706 | } | ||
707 | #endif /* MOUNTED_GETMNTENT2. */ | ||
708 | |||
709 | #ifdef MOUNTED_VMOUNT /* AIX. */ | ||
710 | { | ||
711 | int bufsize; | ||
712 | char *entries, *thisent; | ||
713 | struct vmount *vmp; | ||
714 | |||
715 | /* Ask how many bytes to allocate for the mounted filesystem info. */ | ||
716 | mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize); | ||
717 | entries = xmalloc (bufsize); | ||
718 | |||
719 | /* Get the list of mounted filesystems. */ | ||
720 | mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries); | ||
721 | |||
722 | for (thisent = entries; thisent < entries + bufsize; | ||
723 | thisent += vmp->vmt_length) | ||
724 | { | ||
725 | char *options, *ignore; | ||
726 | |||
727 | vmp = (struct vmount *) thisent; | ||
728 | me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); | ||
729 | if (vmp->vmt_flags & MNT_REMOTE) | ||
730 | { | ||
731 | char *host, *path; | ||
732 | |||
733 | me->me_remote = 1; | ||
734 | /* Prepend the remote pathname. */ | ||
735 | host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off; | ||
736 | path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off; | ||
737 | me->me_devname = xmalloc (strlen (host) + strlen (path) + 2); | ||
738 | strcpy (me->me_devname, host); | ||
739 | strcat (me->me_devname, ":"); | ||
740 | strcat (me->me_devname, path); | ||
741 | } | ||
742 | else | ||
743 | { | ||
744 | me->me_remote = 0; | ||
745 | me->me_devname = xstrdup (thisent + | ||
746 | vmp->vmt_data[VMT_OBJECT].vmt_off); | ||
747 | } | ||
748 | me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); | ||
749 | me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype)); | ||
750 | options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; | ||
751 | ignore = strstr (options, "ignore"); | ||
752 | me->me_dummy = (ignore | ||
753 | && (ignore == options || ignore[-1] == ',') | ||
754 | && (ignore[sizeof "ignore" - 1] == ',' | ||
755 | || ignore[sizeof "ignore" - 1] == '\0')); | ||
756 | me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */ | ||
757 | |||
758 | /* Add to the linked list. */ | ||
759 | *mtail = me; | ||
760 | mtail = &me->me_next; | ||
761 | } | ||
762 | free (entries); | ||
763 | } | ||
764 | #endif /* MOUNTED_VMOUNT. */ | ||
765 | |||
766 | *mtail = NULL; | ||
767 | return mount_list; | ||
768 | |||
769 | |||
770 | free_then_fail: | ||
771 | { | ||
772 | int saved_errno = errno; | ||
773 | *mtail = NULL; | ||
774 | |||
775 | while (mount_list) | ||
776 | { | ||
777 | me = mount_list->me_next; | ||
778 | free (mount_list->me_devname); | ||
779 | free (mount_list->me_mountdir); | ||
780 | /* FIXME: me_type is not always malloced. */ | ||
781 | free (mount_list); | ||
782 | mount_list = me; | ||
783 | } | ||
784 | |||
785 | errno = saved_errno; | ||
786 | return NULL; | ||
787 | } | ||
788 | } | ||
diff --git a/lib/mountlist.h b/lib/mountlist.h new file mode 100644 index 00000000..c41490c9 --- /dev/null +++ b/lib/mountlist.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* mountlist.h -- declarations for list of mounted filesystems | ||
2 | Copyright (C) 1991, 1992, 1998, 2000 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software Foundation, | ||
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
17 | |||
18 | /* A mount table entry. */ | ||
19 | struct mount_entry | ||
20 | { | ||
21 | char *me_devname; /* Device node pathname, including "/dev/". */ | ||
22 | char *me_mountdir; /* Mount point directory pathname. */ | ||
23 | char *me_type; /* "nfs", "4.2", etc. */ | ||
24 | dev_t me_dev; /* Device number of me_mountdir. */ | ||
25 | unsigned int me_dummy : 1; /* Nonzero for dummy filesystems. */ | ||
26 | unsigned int me_remote : 1; /* Nonzero for remote fileystems. */ | ||
27 | struct mount_entry *me_next; | ||
28 | }; | ||
29 | |||
30 | #ifndef PARAMS | ||
31 | # if defined PROTOTYPES || (defined __STDC__ && __STDC__) | ||
32 | # define PARAMS(Args) Args | ||
33 | # else | ||
34 | # define PARAMS(Args) () | ||
35 | # endif | ||
36 | #endif | ||
37 | |||
38 | struct mount_entry *read_filesystem_list PARAMS ((int need_fs_type)); | ||
39 | |||
40 | #ifndef ME_DUMMY | ||
41 | # define ME_DUMMY(fs_name, fs_type) \ | ||
42 | (!strcmp (fs_type, "auto") \ | ||
43 | || !strcmp (fs_type, "autofs") \ | ||
44 | /* for Irix 6.5 */ \ | ||
45 | || !strcmp (fs_type, "ignore")) | ||
46 | #endif | ||
47 | |||
48 | #ifndef ME_REMOTE | ||
49 | # define ME_REMOTE(fs_name, fs_type) (strchr (fs_name, ':') != 0) | ||
50 | #endif | ||