1 /* fstype.c -- determine type of filesystems that files are on
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2004 Free Software Foundation, Inc.
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)
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.
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
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 /* Written by David MacKenzie <djm@gnu.org>.
22 * Converted to use gnulib's read_file_system_list()
23 * by James Youngman <jay@gnu.org> (which saves a lot
24 * of manual hacking of configure.in).
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
37 /* The presence of unistd.h is assumed by gnulib these days, so we
38 * might as well assume it too.
42 #ifdef HAVE_SYS_MNTIO_H
46 #include <sys/mntio.h>
48 #ifdef HAVE_SYS_MKDEV_H
49 #include <sys/mkdev.h>
59 #include "../gnulib/lib/dirname.h"
63 /* Need declaration of function `xstrtoumax' */
64 #include "../gnulib/lib/xstrtol.h"
66 #include "extendbuf.h"
67 #include "mountlist.h"
73 # define _(Text) gettext (Text)
78 # define N_(String) gettext_noop (String)
80 /* See locate.c for explanation as to why not use (String) */
81 # define N_(String) String
84 static char *filesystem_type_uncached
PARAMS((const struct stat
*statp
, const char *path
));
87 /* Get MNTTYPE_IGNORE if it is available. */
93 # include <sys/mnttab.h>
101 free_file_system_list(struct mount_entry
*p
)
105 struct mount_entry
*pnext
= p
->me_next
;
108 free(p
->me_mountdir
);
110 if(p
->me_type_malloced
)
122 #include <netinet/in.h>
123 #include <afs/venus.h>
125 /* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */
127 #define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
130 /* AFS on Solaris 2.3 doesn't get this definition. */
131 #include <sys/ioccom.h>
137 static char space
[2048];
141 vi
.out_size
= sizeof (space
);
144 if (pioctl (path
, VIOC_FILE_CELL_NAME
, &vi
, 1)
145 && (errno
== EINVAL
|| errno
== ENOENT
))
151 /* Nonzero if the current filesystem's type is known. */
152 static int fstype_known
= 0;
154 /* Return a static string naming the type of filesystem that the file PATH,
155 described by STATP, is on.
156 RELPATH is the file name relative to the current directory.
157 Return "unknown" if its filesystem type is unknown. */
160 filesystem_type (const struct stat
*statp
, const char *path
)
162 static char *current_fstype
= NULL
;
163 static dev_t current_dev
;
165 if (current_fstype
!= NULL
)
167 if (fstype_known
&& statp
->st_dev
== current_dev
)
168 return current_fstype
; /* Cached value. */
169 free (current_fstype
);
171 current_dev
= statp
->st_dev
;
172 current_fstype
= filesystem_type_uncached (statp
, path
);
173 return current_fstype
;
177 set_fstype_devno(struct mount_entry
*p
)
181 if (p
->me_dev
== (dev_t
)-1)
183 if (0 == (options
.xstat
)(p
->me_mountdir
, &stbuf
))
185 p
->me_dev
= stbuf
.st_dev
;
193 return 0; /* not needed */
196 static struct mount_entry
*
197 must_read_fs_list(bool need_fs_type
)
199 struct mount_entry
*entries
= read_file_system_list(need_fs_type
);
202 /* We cannot determine for sure which file we were trying to
203 * use because gnulib has extracted all that stuff away.
204 * Hence we cannot issue a specific error message here.
206 error(1, 0, "Cannot read mounted filesystem list");
213 /* Return a newly allocated string naming the type of filesystem that the
214 file PATH, described by STATP, is on.
215 RELPATH is the file name relative to the current directory.
216 Return "unknown" if its filesystem type is unknown. */
219 filesystem_type_uncached (const struct stat
*statp
, const char *path
)
221 struct mount_entry
*entries
, *entry
;
230 return xstrdup("afs");
234 entries
= must_read_fs_list(true);
235 for (type
=NULL
, entry
=entries
; entry
; entry
=entry
->me_next
)
237 #ifdef MNTTYPE_IGNORE
238 if (!strcmp (entry
->me_type
, MNTTYPE_IGNORE
))
241 set_fstype_devno(entry
);
242 if (entry
->me_dev
== statp
->st_dev
)
244 type
= xstrdup(entry
->me_type
);
248 free_file_system_list(entries
);
250 /* Don't cache unknown values. */
251 fstype_known
= (type
!= NULL
);
253 return type
? type
: xstrdup(_("unknown"));
258 get_mounted_filesystems (void)
261 size_t alloc_size
= 0u;
263 struct mount_entry
*entries
, *entry
;
265 entries
= must_read_fs_list(false);
266 for (entry
=entries
; entry
; entry
=entry
->me_next
)
270 #ifdef MNTTYPE_IGNORE
271 if (!strcmp (entry
->me_type
, MNTTYPE_IGNORE
))
274 set_fstype_devno(entry
);
276 len
= strlen(entry
->me_mountdir
) + 1;
277 result
= extendbuf(result
, used
+len
, &alloc_size
);
278 strcpy(&result
[used
], entry
->me_mountdir
);
279 used
+= len
; /* len already includes one for the \0 */
282 free_file_system_list(entries
);
288 get_mounted_devices (size_t *n
)
290 size_t alloc_size
= 0u;
292 struct mount_entry
*entries
, *entry
;
293 dev_t
*result
= NULL
;
295 /* Use read_file_system_list() rather than must_read_fs_list()
296 * because on some system this is always called at startup,
297 * and find should only exit fatally if it needs to use the
298 * result of this operation. If we can't get the fs list
299 * but we never need the information, there is no need to fail.
301 for (entry
= entries
= read_file_system_list(false);
303 entry
= entry
->me_next
)
305 result
= extendbuf(result
, sizeof(dev_t
)*(used
+1), &alloc_size
);
306 set_fstype_devno(entry
);
307 result
[used
] = entry
->me_dev
;
310 free_file_system_list(entries
);