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"
74 # define _(Text) gettext (Text)
79 # define N_(String) gettext_noop (String)
81 /* See locate.c for explanation as to why not use (String) */
82 # define N_(String) String
85 static char *filesystem_type_uncached
PARAMS((const struct stat
*statp
, const char *path
));
88 /* Get MNTTYPE_IGNORE if it is available. */
94 # include <sys/mnttab.h>
102 free_file_system_list(struct mount_entry
*p
)
106 struct mount_entry
*pnext
= p
->me_next
;
109 free(p
->me_mountdir
);
111 if(p
->me_type_malloced
)
123 #include <netinet/in.h>
124 #include <afs/venus.h>
126 /* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */
128 #define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
131 /* AFS on Solaris 2.3 doesn't get this definition. */
132 #include <sys/ioccom.h>
138 static char space
[2048];
142 vi
.out_size
= sizeof (space
);
145 if (pioctl (path
, VIOC_FILE_CELL_NAME
, &vi
, 1)
146 && (errno
== EINVAL
|| errno
== ENOENT
))
152 /* Nonzero if the current filesystem's type is known. */
153 static int fstype_known
= 0;
155 /* Return a static string naming the type of filesystem that the file PATH,
156 described by STATP, is on.
157 RELPATH is the file name relative to the current directory.
158 Return "unknown" if its filesystem type is unknown. */
161 filesystem_type (const struct stat
*statp
, const char *path
)
163 static char *current_fstype
= NULL
;
164 static dev_t current_dev
;
166 if (current_fstype
!= NULL
)
168 if (fstype_known
&& statp
->st_dev
== current_dev
)
169 return current_fstype
; /* Cached value. */
170 free (current_fstype
);
172 current_dev
= statp
->st_dev
;
173 current_fstype
= filesystem_type_uncached (statp
, path
);
174 return current_fstype
;
178 set_fstype_devno(struct mount_entry
*p
)
182 if (p
->me_dev
== (dev_t
)-1)
184 set_stat_placeholders(&stbuf
);
185 if (0 == (options
.xstat
)(p
->me_mountdir
, &stbuf
))
187 p
->me_dev
= stbuf
.st_dev
;
195 return 0; /* not needed */
198 static struct mount_entry
*
199 must_read_fs_list(bool need_fs_type
)
201 struct mount_entry
*entries
= read_file_system_list(need_fs_type
);
204 /* We cannot determine for sure which file we were trying to
205 * use because gnulib has extracted all that stuff away.
206 * Hence we cannot issue a specific error message here.
208 error(1, 0, "Cannot read mounted filesystem list");
215 /* Return a newly allocated string naming the type of filesystem that the
216 file PATH, described by STATP, is on.
217 RELPATH is the file name relative to the current directory.
218 Return "unknown" if its filesystem type is unknown. */
221 filesystem_type_uncached (const struct stat
*statp
, const char *path
)
223 struct mount_entry
*entries
, *entry
;
232 return xstrdup("afs");
236 entries
= must_read_fs_list(true);
237 for (type
=NULL
, entry
=entries
; entry
; entry
=entry
->me_next
)
239 #ifdef MNTTYPE_IGNORE
240 if (!strcmp (entry
->me_type
, MNTTYPE_IGNORE
))
243 set_fstype_devno(entry
);
244 if (entry
->me_dev
== statp
->st_dev
)
246 type
= xstrdup(entry
->me_type
);
250 free_file_system_list(entries
);
252 /* Don't cache unknown values. */
253 fstype_known
= (type
!= NULL
);
255 return type
? type
: xstrdup(_("unknown"));
260 get_mounted_filesystems (void)
263 size_t alloc_size
= 0u;
265 struct mount_entry
*entries
, *entry
;
267 entries
= must_read_fs_list(false);
268 for (entry
=entries
; entry
; entry
=entry
->me_next
)
272 #ifdef MNTTYPE_IGNORE
273 if (!strcmp (entry
->me_type
, MNTTYPE_IGNORE
))
276 set_fstype_devno(entry
);
278 len
= strlen(entry
->me_mountdir
) + 1;
279 result
= extendbuf(result
, used
+len
, &alloc_size
);
280 strcpy(&result
[used
], entry
->me_mountdir
);
281 used
+= len
; /* len already includes one for the \0 */
284 free_file_system_list(entries
);
290 get_mounted_devices (size_t *n
)
292 size_t alloc_size
= 0u;
294 struct mount_entry
*entries
, *entry
;
295 dev_t
*result
= NULL
;
297 /* Use read_file_system_list() rather than must_read_fs_list()
298 * because on some system this is always called at startup,
299 * and find should only exit fatally if it needs to use the
300 * result of this operation. If we can't get the fs list
301 * but we never need the information, there is no need to fail.
303 for (entry
= entries
= read_file_system_list(false);
305 entry
= entry
->me_next
)
307 result
= extendbuf(result
, sizeof(dev_t
)*(used
+1), &alloc_size
);
308 set_fstype_devno(entry
);
309 result
[used
] = entry
->me_dev
;
312 free_file_system_list(entries
);