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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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).
32 #ifdef HAVE_SYS_TYPES_H
33 #include <sys/types.h>
40 #ifdef HAVE_SYS_MNTIO_H
44 #include <sys/mntio.h>
46 #ifdef HAVE_SYS_MKDEV_H
47 #include <sys/mkdev.h>
57 #include "../gnulib/lib/dirname.h"
61 /* Need declaration of function `xstrtoumax' */
62 #include "../gnulib/lib/xstrtol.h"
64 #include "extendbuf.h"
65 #include "mountlist.h"
71 # define _(Text) gettext (Text)
76 # define N_(String) gettext_noop (String)
78 /* See locate.c for explanation as to why not use (String) */
79 # define N_(String) String
82 static char *filesystem_type_uncached
PARAMS((const struct stat
*statp
));
85 /* Get MNTTYPE_IGNORE if it is available. */
91 # include <sys/mnttab.h>
99 free_file_system_list(struct mount_entry
*p
)
103 struct mount_entry
*pnext
= p
->me_next
;
106 free(p
->me_mountdir
);
108 if(p
->me_type_malloced
)
120 #include <netinet/in.h>
121 #include <afs/venus.h>
123 /* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */
125 #define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
128 /* AFS on Solaris 2.3 doesn't get this definition. */
129 #include <sys/ioccom.h>
135 static char space
[2048];
139 vi
.out_size
= sizeof (space
);
142 if (pioctl (path
, VIOC_FILE_CELL_NAME
, &vi
, 1)
143 && (errno
== EINVAL
|| errno
== ENOENT
))
149 /* Nonzero if the current filesystem's type is known. */
150 static int fstype_known
= 0;
152 /* Return a static string naming the type of filesystem that the file PATH,
153 described by STATP, is on.
154 RELPATH is the file name relative to the current directory.
155 Return "unknown" if its filesystem type is unknown. */
158 filesystem_type (const struct stat
*statp
)
160 static char *current_fstype
= NULL
;
161 static dev_t current_dev
;
163 if (current_fstype
!= NULL
)
165 if (fstype_known
&& statp
->st_dev
== current_dev
)
166 return current_fstype
; /* Cached value. */
167 free (current_fstype
);
169 current_dev
= statp
->st_dev
;
170 current_fstype
= filesystem_type_uncached (statp
);
171 return current_fstype
;
175 set_fstype_devno(struct mount_entry
*p
)
179 if (p
->me_dev
== (dev_t
)-1)
181 if (0 == (options
.xstat
)(p
->me_mountdir
, &stbuf
))
183 p
->me_dev
= stbuf
.st_dev
;
191 return 0; /* not needed */
195 /* Return a newly allocated string naming the type of filesystem that the
196 file PATH, described by STATP, is on.
197 RELPATH is the file name relative to the current directory.
198 Return "unknown" if its filesystem type is unknown. */
201 filesystem_type_uncached (const struct stat
*statp
)
203 struct mount_entry
*entries
, *entry
;
210 return xstrdup("afs");
214 entries
= read_file_system_list(true);
215 for (type
=NULL
, entry
=entries
; entry
; entry
=entry
->me_next
)
217 #ifdef MNTTYPE_IGNORE
218 if (!strcmp (entry
->me_type
, MNTTYPE_IGNORE
))
221 set_fstype_devno(entry
);
222 if (entry
->me_dev
== statp
->st_dev
)
223 type
= xstrdup(entry
->me_type
);
225 free_file_system_list(entries
);
227 /* Don't cache unknown values. */
228 fstype_known
= (type
!= NULL
);
230 return type
? type
: xstrdup(_("unknown"));
235 get_mounted_filesystems (void)
238 size_t alloc_size
= 0u;
240 struct mount_entry
*entries
, *entry
;
242 entries
= read_file_system_list(false);
243 for (entry
=entries
; entry
; entry
=entry
->me_next
)
247 #ifdef MNTTYPE_IGNORE
248 if (!strcmp (entry
->me_type
, MNTTYPE_IGNORE
))
251 set_fstype_devno(entry
);
253 len
= strlen(entry
->me_mountdir
) + 1;
254 result
= extendbuf(result
, used
+len
, &alloc_size
);
255 strcpy(&result
[used
], entry
->me_mountdir
);
256 used
+= len
; /* len already includes one for the \0 */
259 free_file_system_list(entries
);
265 get_mounted_devices (size_t *n
)
267 size_t alloc_size
= 0u;
269 struct mount_entry
*entries
, *entry
;
270 dev_t
*result
= NULL
;
272 for (entry
= entries
= read_file_system_list(false);
274 entry
= entry
->me_next
)
276 result
= extendbuf(result
, sizeof(dev_t
)*(used
+1), &alloc_size
);
277 set_fstype_devno(entry
);
278 result
[used
] = entry
->me_dev
;
281 free_file_system_list(entries
);