summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/afs.m412
-rw-r--r--lib/fstypename.m432
-rw-r--r--lib/fsusage.c281
-rw-r--r--lib/fsusage.h45
-rw-r--r--lib/fsusage.m4194
-rw-r--r--lib/ls-mntd-fs.m4243
-rw-r--r--lib/mountlist.c788
-rw-r--r--lib/mountlist.h50
8 files changed, 1645 insertions, 0 deletions
diff --git a/lib/afs.m4 b/lib/afs.m4
new file mode 100644
index 0000000..13f3bc9
--- /dev/null
+++ b/lib/afs.m4
@@ -0,0 +1,12 @@
1#serial 3
2
3AC_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 0000000..70abc12
--- /dev/null
+++ b/lib/fstypename.m4
@@ -0,0 +1,32 @@
1#serial 2
2
3dnl From Jim Meyering.
4dnl
5dnl See if struct statfs has the f_fstypename member.
6dnl If so, define HAVE_F_FSTYPENAME_IN_STATFS.
7dnl
8
9AC_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 0000000..5a864bf
--- /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
34int 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>
70int 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
92int 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. */
101int
102get_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
259int
260statfs (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 0000000..e0c0db5
--- /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
23struct 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
42int 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 0000000..d5c646f
--- /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
11AC_DEFUN(jm_FILE_SYSTEM_USAGE,
12[
13
14echo "checking how to get filesystem space usage..."
15ac_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.
23if 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
36fi
37
38if 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
61fi
62
63if test $ac_fsusage_space = no; then
64# AIX
65 AC_MSG_CHECKING([for two-argument statfs with statfs.bsize dnl
66member (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
94fi
95
96if 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
116fi
117
118if test $ac_fsusage_space = no; then
119# 4.4BSD and NetBSD
120 AC_MSG_CHECKING([for two-argument statfs with statfs.fsize dnl
121member (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
146fi
147
148if 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
179fi
180
181if 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)
189fi
190
191dnl AS_IF([test $ac_fsusage_space = yes], [$1], [$2])
192if 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 0000000..695b3ba
--- /dev/null
+++ b/lib/ls-mntd-fs.m4
@@ -0,0 +1,243 @@
1#serial 10
2
3dnl From Jim Meyering.
4dnl
5dnl This is not pretty. I've just taken the autoconf code and wrapped
6dnl it in an AC_DEFUN.
7dnl
8
9# jm_LIST_MOUNTED_FILESYSTEMS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
10AC_DEFUN(jm_LIST_MOUNTED_FILESYSTEMS,
11 [
12AC_CHECK_FUNCS(listmntent getmntinfo)
13AC_CHECK_HEADERS(mntent.h)
14
15# Determine how to get the list of mounted filesystems.
16ac_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).
20AC_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
31if 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
38yes
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
52fi
53
54if 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
96fi
97
98if 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
117fi
118
119if 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
134fi
135
136if 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
154fi
155
156if 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
177fi
178
179if 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
195fi
196
197if 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
216fi
217
218if 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
232fi
233
234if 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
238fi
239
240dnl AS_IF([test $ac_list_mounted_fs = found], [$1], [$2])
241if 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 0000000..b667c44
--- /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
27void 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
36char *strstr ();
37#endif
38char *xmalloc ();
39char *xrealloc ();
40char *xstrdup ();
41
42#include <errno.h>
43#ifndef errno
44extern 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
136static int
137xatoi (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
161static char *
162fstype_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__ */
257static char *
258fsp_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. */
270static char *
271fstype_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
288struct mount_entry *
289read_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 0000000..c41490c
--- /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. */
19struct 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
38struct 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