1 /* fstype.c -- determine type of file systems that files are on
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2004 Free Software Foundation, Inc.
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 /* Written by David MacKenzie <djm@gnu.org>.
19 * Converted to use gnulib's read_file_system_list()
20 * by James Youngman <jay@gnu.org> (which saves a lot
21 * of manual hacking of configure.in).
29 #ifdef HAVE_SYS_TYPES_H
30 #include <sys/types.h>
34 /* The presence of unistd.h is assumed by gnulib these days, so we
35 * might as well assume it too.
40 #ifdef HAVE_SYS_MNTIO_H
41 #include <sys/mntio.h>
43 #ifdef HAVE_SYS_MKDEV_H
44 #include <sys/mkdev.h>
54 #include "../gnulib/lib/dirname.h"
58 /* Need declaration of function `xstrtoumax' */
59 #include "../gnulib/lib/xstrtol.h"
61 #include "extendbuf.h"
62 #include "mountlist.h"
69 # define _(Text) gettext (Text)
74 # define N_(String) gettext_noop (String)
76 /* See locate.c for explanation as to why not use (String) */
77 # define N_(String) String
80 static char *file_system_type_uncached
PARAMS((const struct stat
*statp
, const char *path
));
83 /* Get MNTTYPE_IGNORE if it is available. */
89 # include <sys/mnttab.h>
97 free_file_system_list(struct mount_entry
*p
)
101 struct mount_entry
*pnext
= p
->me_next
;
104 free(p
->me_mountdir
);
106 if(p
->me_type_malloced
)
118 #include <netinet/in.h>
119 #include <afs/venus.h>
121 /* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */
123 #define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
126 /* AFS on Solaris 2.3 doesn't get this definition. */
127 #include <sys/ioccom.h>
133 static char space
[2048];
137 vi
.out_size
= sizeof (space
);
140 if (pioctl (path
, VIOC_FILE_CELL_NAME
, &vi
, 1)
141 && (errno
== EINVAL
|| errno
== ENOENT
))
147 /* Nonzero if the current file system's type is known. */
148 static int fstype_known
= 0;
150 /* Return a static string naming the type of file system that the file PATH,
151 described by STATP, is on.
152 RELPATH is the file name relative to the current directory.
153 Return "unknown" if its file system type is unknown. */
156 filesystem_type (const struct stat
*statp
, const char *path
)
158 static char *current_fstype
= NULL
;
159 static dev_t current_dev
;
161 if (current_fstype
!= NULL
)
163 if (fstype_known
&& statp
->st_dev
== current_dev
)
164 return current_fstype
; /* Cached value. */
165 free (current_fstype
);
167 current_dev
= statp
->st_dev
;
168 current_fstype
= file_system_type_uncached (statp
, path
);
169 return current_fstype
;
173 set_fstype_devno(struct mount_entry
*p
)
177 if (p
->me_dev
== (dev_t
)-1)
179 set_stat_placeholders(&stbuf
);
180 if (0 == (options
.xstat
)(p
->me_mountdir
, &stbuf
))
182 p
->me_dev
= stbuf
.st_dev
;
190 return 0; /* not needed */
193 static struct mount_entry
*
194 must_read_fs_list(bool need_fs_type
)
196 struct mount_entry
*entries
= read_file_system_list(need_fs_type
);
199 /* We cannot determine for sure which file we were trying to
200 * use because gnulib has extracted all that stuff away.
201 * Hence we cannot issue a specific error message here.
203 error(1, 0, "Cannot read mounted file system list");
210 /* Return a newly allocated string naming the type of file system that the
211 file PATH, described by STATP, is on.
212 RELPATH is the file name relative to the current directory.
213 Return "unknown" if its file system type is unknown. */
216 file_system_type_uncached (const struct stat
*statp
, const char *path
)
218 struct mount_entry
*entries
, *entry
;
227 return xstrdup("afs");
231 entries
= must_read_fs_list(true);
232 for (type
=NULL
, entry
=entries
; entry
; entry
=entry
->me_next
)
234 #ifdef MNTTYPE_IGNORE
235 if (!strcmp (entry
->me_type
, MNTTYPE_IGNORE
))
238 set_fstype_devno(entry
);
239 if (entry
->me_dev
== statp
->st_dev
)
241 type
= xstrdup(entry
->me_type
);
245 free_file_system_list(entries
);
247 /* Don't cache unknown values. */
248 fstype_known
= (type
!= NULL
);
252 return xstrdup(_("unknown"
253 /* TRANSLATORS: this is essentially an abbreviation
254 for "unknown file system type" */));
259 get_mounted_filesystems (void)
262 size_t alloc_size
= 0u;
264 struct mount_entry
*entries
, *entry
;
266 entries
= must_read_fs_list(false);
267 for (entry
=entries
; entry
; entry
=entry
->me_next
)
271 #ifdef MNTTYPE_IGNORE
272 if (!strcmp (entry
->me_type
, MNTTYPE_IGNORE
))
275 set_fstype_devno(entry
);
277 len
= strlen(entry
->me_mountdir
) + 1;
278 result
= extendbuf(result
, used
+len
, &alloc_size
);
279 strcpy(&result
[used
], entry
->me_mountdir
);
280 used
+= len
; /* len already includes one for the \0 */
283 free_file_system_list(entries
);
289 get_mounted_devices (size_t *n
)
291 size_t alloc_size
= 0u;
293 struct mount_entry
*entries
, *entry
;
294 dev_t
*result
= NULL
;
296 /* Use read_file_system_list() rather than must_read_fs_list()
297 * because on some system this is always called at startup,
298 * and find should only exit fatally if it needs to use the
299 * result of this operation. If we can't get the fs list
300 * but we never need the information, there is no need to fail.
302 for (entry
= entries
= read_file_system_list(false);
304 entry
= entry
->me_next
)
306 result
= extendbuf(result
, sizeof(dev_t
)*(used
+1), &alloc_size
);
307 set_fstype_devno(entry
);
308 result
[used
] = entry
->me_dev
;
311 free_file_system_list(entries
);