5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 /* mountlist.c -- return a list of mounted file systems
23 Copyright (C) 1991, 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
24 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
26 This program is free software; you can redistribute it and/or modify
27 it under the terms of the GNU General Public License as published by
28 the Free Software Foundation; either version 2, or (at your option)
31 This program is distributed in the hope that it will be useful,
32 but WITHOUT ANY WARRANTY; without even the implied warranty of
33 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 GNU General Public License for more details.
36 You should have received a copy of the GNU General Public License
37 along with this program; if not, see <http://www.gnu.org/licenses/>.
40 // This file is not used on some platforms, so don't do anything for them
41 #if(!(defined(WIN32) || !defined __GNUC__)&&(!defined(__amigaos4__))&&(!defined(__AROS__))&&(!defined(__MORPHOS__))&&(!defined(__amigaos__)))
43 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) // MacOS X is POSIX compliant
44 #define MOUNTED_GETMNTINFO
45 #if defined(__APPLE__)
46 #include <sys/types.h>
48 #if defined(__OpenBSD__)
49 #define HAVE_STRUCT_STATFS_F_FSTYPENAME 1
50 #include <sys/param.h> /* types.h needs this */
51 #include <sys/types.h>
53 #elif defined(__NetBSD__)
54 #define MOUNTED_GETMNTINFO2
55 #elif defined(__BEOS__) || defined(__HAIKU__)
56 #define MOUNTED_FS_STAT_DEV
57 #elif defined(__TRU64__)
58 #define MOUNTED_GETFSSTAT 1
59 #define HAVE_SYS_MOUNT_H 1
60 #include <sys/types.h>
62 #define MOUNTED_GETMNTENT1
65 #include "mountlist.h"
78 # include <sys/param.h>
81 #if defined MOUNTED_GETFSSTAT /* OSF_1 and Darwin1.3.x */
83 # include <grp.h> /* needed on OSF V4.0 for definition of NGROUPS,
84 NGROUPS is used as an array dimension in ucred.h */
85 # include <sys/ucred.h> /* needed by powerpc-apple-darwin1.3.7 */
88 # include <sys/mount.h>
90 # if HAVE_SYS_FS_TYPES_H
91 # include <sys/fs_types.h> /* needed by powerpc-apple-darwin1.3.7 */
93 # if HAVE_STRUCT_FSSTAT_F_FSTYPENAME
94 # define FS_TYPE(Ent) ((Ent).f_fstypename)
96 # define FS_TYPE(Ent) mnt_names[(Ent).f_type]
98 #endif /* MOUNTED_GETFSSTAT */
100 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
102 # if !defined MOUNTED
103 # if defined _PATH_MOUNTED /* GNU libc */
104 # define MOUNTED _PATH_MOUNTED
106 # if defined MNT_MNTTAB /* HP-UX. */
107 # define MOUNTED MNT_MNTTAB
109 # if defined MNTTABNAME /* Dynix. */
110 # define MOUNTED MNTTABNAME
115 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
116 # include <sys/mount.h>
119 #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */
120 # include <sys/statvfs.h>
123 #ifdef MOUNTED_GETMNT /* Ultrix. */
124 # include <sys/mount.h>
125 # include <sys/fs_types.h>
128 #ifdef MOUNTED_FS_STAT_DEV /* BeOS. */
129 # include <fs_info.h>
133 #ifdef MOUNTED_FREAD /* SVR2. */
137 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
139 # include <sys/fstyp.h>
140 # include <sys/statfs.h>
143 #ifdef MOUNTED_LISTMNTENT
147 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
148 # include <sys/mnttab.h>
151 #ifdef MOUNTED_VMOUNT /* AIX. */
153 # include <sys/vfs.h>
157 /* So special that it's not worth putting this in autoconf. */
158 # undef MOUNTED_FREAD_FSTYP
159 # define MOUNTED_GETMNTTBL
162 #if HAVE_SYS_MNTENT_H
163 /* This is to get MNTOPT_IGNORE on e.g. SVR4. */
164 # include <sys/mntent.h>
168 #if defined MNTOPT_IGNORE && defined HAVE_HASMNTOPT
169 # define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE)
171 # define MNT_IGNORE(M) 0
175 # include "unlocked-io.h"
179 # define SIZE_MAX ((size_t) -1)
182 /* The results of open() in this file are not used with fchdir,
183 therefore save some unnecessary work in fchdir.c. */
187 /* The results of opendir() in this file are not used with dirfd and fchdir,
188 therefore save some unnecessary work in fchdir.c. */
192 // gcc2 under haiku and beos don't like these macros for some reason.
193 // As they are not used there anyways, we remove them and everyone is happy.
194 #if !defined(__HAIKU__) && !defined(__BEOS__)
196 # define ME_DUMMY(Fs_name, Fs_type) \
197 (strcmp (Fs_type, "autofs") == 0 \
198 || strcmp (Fs_type, "none") == 0 \
199 || strcmp (Fs_type, "proc") == 0 \
200 || strcmp (Fs_type, "subfs") == 0 \
201 || strcmp (Fs_type, "sysfs") == 0 \
202 || strcmp (Fs_type, "usbfs") == 0 \
203 || strcmp (Fs_type, "devpts") == 0 \
204 || strcmp (Fs_type, "tmpfs") == 0 \
205 /* for NetBSD 3.0 */ \
206 || strcmp (Fs_type, "kernfs") == 0 \
208 || strcmp (Fs_type, "ignore") == 0 \
210 || strcmp (Fs_type, "devfs") == 0 \
211 || strcmp (Fs_type, "fdesc") == 0 \
212 || strcmp (Fs_type, "nfs") == 0 \
213 || strcmp (Fs_type, "volfs") == 0)
217 /* A file system is `remote' if its Fs_name contains a `:'
218 or if (it is of type (smbfs or cifs) and its Fs_name starts with `//'). */
219 # define ME_REMOTE(Fs_name, Fs_type) \
220 (strchr (Fs_name, ':') != NULL \
221 || ((Fs_name)[0] == '/' \
222 && (Fs_name)[1] == '/' \
223 && (strcmp (Fs_type, "smbfs") == 0 \
224 || strcmp (Fs_type, "cifs") == 0)))
226 #endif // HAIKU / BEOS
228 #ifdef MOUNTED_GETMNTINFO
230 # if ! HAVE_STRUCT_STATFS_F_FSTYPENAME && !defined(__clang__)
232 fstype_to_string (short int t
)
326 #if !defined(__clang__)
328 fsp_to_string (const struct statfs
*fsp
)
330 # if HAVE_STRUCT_STATFS_F_FSTYPENAME
331 return (char *) (fsp
->f_fstypename
);
333 return fstype_to_string (fsp
->f_type
);
338 #endif /* MOUNTED_GETMNTINFO */
340 #ifdef MOUNTED_VMOUNT /* AIX. */
342 fstype_to_string (int t
)
346 e
= getvfsbytype (t
);
347 if (!e
|| !e
->vfsent_name
)
350 return e
->vfsent_name
;
352 #endif /* MOUNTED_VMOUNT */
354 #if defined MOUNTED_GETMNTENT1 || defined MOUNTED_GETMNTENT2
356 /* Return the device number from MOUNT_OPTIONS, if possible.
357 Otherwise return (dev_t) -1. */
360 dev_from_mount_options (char const *mount_options
)
362 /* GNU/Linux allows file system implementations to define their own
363 meaning for "dev=" mount options, so don't trust the meaning
366 static char const dev_pattern
[] = ",dev=";
367 char const *devopt
= strstr (mount_options
, dev_pattern
);
371 char const *optval
= devopt
+ sizeof dev_pattern
- 1;
373 unsigned long int dev
;
375 dev
= strtoul (optval
, &optvalend
, 16);
376 if (optval
!= optvalend
377 && (*optvalend
== '\0' || *optvalend
== ',')
378 && ! (dev
== ULONG_MAX
&& errno
== ERANGE
)
379 && dev
== (dev_t
) dev
)
383 (void)mount_options
; // unused
391 /* Return a list of the currently mounted file systems, or NULL on error.
392 Add each entry to the tail of the list so that they stay in order.
393 If NEED_FS_TYPE is true, ensure that the file system type fields in
394 the returned list are valid. Otherwise, they might not be. */
397 read_file_system_list (bool need_fs_type
)
399 struct mount_entry
*mount_list
;
400 struct mount_entry
*me
;
401 struct mount_entry
**mtail
= &mount_list
;
402 (void)need_fs_type
; // may be unused
404 #ifdef MOUNTED_LISTMNTENT
406 struct tabmntent
*mntlist
, *p
;
408 struct mount_entry
*me
;
410 /* the third and fourth arguments could be used to filter mounts,
411 but Crays doesn't seem to have any mounts that we want to
412 remove. Specifically, automount create normal NFS mounts.
415 if (listmntent (&mntlist
, KMTAB
, NULL
, NULL
) < 0)
417 for (p
= mntlist
; p
; p
= p
->next
) {
419 me
= xmalloc (sizeof *me
);
420 me
->me_devname
= xstrdup (mnt
->mnt_fsname
);
421 me
->me_mountdir
= xstrdup (mnt
->mnt_dir
);
422 me
->me_type
= xstrdup (mnt
->mnt_type
);
423 me
->me_type_malloced
= 1;
424 me
->me_dummy
= ME_DUMMY (me
->me_devname
, me
->me_type
);
425 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
428 mtail
= &me
->me_next
;
430 freemntlist (mntlist
);
434 #ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
437 const char *table
= MOUNTED
;
440 fp
= setmntent (table
, "r");
444 while ((mnt
= getmntent (fp
)))
446 me
= (mount_entry
*) malloc (sizeof *me
);
447 me
->me_devname
= strdup (mnt
->mnt_fsname
);
448 me
->me_mountdir
= strdup (mnt
->mnt_dir
);
449 me
->me_type
= strdup (mnt
->mnt_type
);
450 me
->me_type_malloced
= 1;
451 me
->me_dummy
= ME_DUMMY (me
->me_devname
, me
->me_type
);
452 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
453 me
->me_dev
= dev_from_mount_options (mnt
->mnt_opts
);
455 /* Add to the linked list. */
457 mtail
= &me
->me_next
;
460 if (endmntent (fp
) == 0)
463 #endif /* MOUNTED_GETMNTENT1. */
465 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
470 entries
= getmntinfo (&fsp
, MNT_NOWAIT
);
473 for (; entries
-- > 0; fsp
++)
475 me
= (mount_entry
*) malloc (sizeof *me
);
476 me
->me_devname
= strdup (fsp
->f_mntfromname
);
477 me
->me_mountdir
= strdup (fsp
->f_mntonname
);
478 #if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__)
479 me
->me_type
= fsp
->f_fstypename
;
481 me
->me_type
= fsp
->fs_typename
;
483 me
->me_type_malloced
= 0;
484 me
->me_dummy
= ME_DUMMY (me
->me_devname
, me
->me_type
);
485 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
486 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
488 /* Add to the linked list. */
490 mtail
= &me
->me_next
;
493 #endif /* MOUNTED_GETMNTINFO */
495 #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */
500 entries
= getmntinfo (&fsp
, MNT_NOWAIT
);
503 for (; entries
-- > 0; fsp
++)
505 me
= malloc (sizeof *me
);
506 me
->me_devname
= strdup (fsp
->f_mntfromname
);
507 me
->me_mountdir
= strdup (fsp
->f_mntonname
);
508 me
->me_type
= strdup (fsp
->f_fstypename
);
509 me
->me_type_malloced
= 1;
510 me
->me_dummy
= ME_DUMMY (me
->me_devname
, me
->me_type
);
511 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
512 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
514 /* Add to the linked list. */
516 mtail
= &me
->me_next
;
519 #endif /* MOUNTED_GETMNTINFO2 */
521 #ifdef MOUNTED_GETMNT /* Ultrix. */
528 0 < (val
= getmnt (&offset
, &fsd
, sizeof (fsd
), NOSTAT_MANY
,
531 me
= xmalloc (sizeof *me
);
532 me
->me_devname
= xstrdup (fsd
.fd_req
.devname
);
533 me
->me_mountdir
= xstrdup (fsd
.fd_req
.path
);
534 me
->me_type
= gt_names
[fsd
.fd_req
.fstype
];
535 me
->me_type_malloced
= 0;
536 me
->me_dummy
= ME_DUMMY (me
->me_devname
, me
->me_type
);
537 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
538 me
->me_dev
= fsd
.fd_req
.dev
;
540 /* Add to the linked list. */
542 mtail
= &me
->me_next
;
547 #endif /* MOUNTED_GETMNT. */
549 #if defined MOUNTED_FS_STAT_DEV /* BeOS */
551 /* The next_dev() and fs_stat_dev() system calls give the list of
552 all file systems, including the information returned by statvfs()
553 (fs type, total blocks, free blocks etc.), but without the mount
554 point. But on BeOS all file systems except / are mounted in the
555 rootfs, directly under /.
556 The directory name of the mount point is often, but not always,
557 identical to the volume name of the device.
558 We therefore get the list of subdirectories of /, and the list
559 of all file systems, and match the two lists. */
567 struct rootdir_entry
*next
;
569 struct rootdir_entry
*rootdir_list
;
570 struct rootdir_entry
**rootdir_tail
;
575 /* All volumes are mounted in the rootfs, directly under /. */
577 rootdir_tail
= &rootdir_list
;
578 dirp
= opendir ("/");
583 while ((d
= readdir (dirp
)) != NULL
)
588 if (strcmp (d
->d_name
, "..") == 0)
591 if (strcmp (d
->d_name
, ".") == 0)
595 name
= malloc (1 + strlen (d
->d_name
) + 1);
597 strcpy (name
+ 1, d
->d_name
);
600 if (lstat (name
, &statbuf
) >= 0 && S_ISDIR (statbuf
.st_mode
))
602 struct rootdir_entry
*re
= malloc (sizeof *re
);
604 re
->dev
= statbuf
.st_dev
;
605 re
->ino
= statbuf
.st_ino
;
607 /* Add to the linked list. */
609 rootdir_tail
= &re
->next
;
616 *rootdir_tail
= NULL
;
618 for (pos
= 0; (dev
= next_dev (&pos
)) >= 0; )
619 if (fs_stat_dev (dev
, &fi
) >= 0)
621 /* Note: fi.dev == dev. */
622 struct rootdir_entry
*re
;
624 for (re
= rootdir_list
; re
; re
= re
->next
)
625 if (re
->dev
== fi
.dev
&& re
->ino
== fi
.root
)
628 me
= malloc (sizeof *me
);
629 me
->me_devname
= strdup (fi
.device_name
[0] != '\0' ? fi
.device_name
: fi
.fsh_name
);
630 me
->me_mountdir
= strdup (re
!= NULL
? re
->name
: fi
.fsh_name
);
631 me
->me_type
= strdup (fi
.fsh_name
);
632 me
->me_type_malloced
= 1;
635 me
->me_remote
= (fi
.flags
& B_FS_IS_SHARED
) != 0;
637 /* Add to the linked list. */
639 mtail
= &me
->me_next
;
643 while (rootdir_list
!= NULL
)
645 struct rootdir_entry
*re
= rootdir_list
;
646 rootdir_list
= re
->next
;
651 #endif /* MOUNTED_FS_STAT_DEV */
653 #if defined MOUNTED_GETFSSTAT /* __alpha running OSF_1 */
657 struct statfs
*stats
;
659 numsys
= getfsstat ((struct statfs
*)0, 0L, MNT_NOWAIT
);
663 if (SIZE_MAX / sizeof *stats <= numsys)
666 bufsize
= (1 + numsys
) * sizeof *stats
;
667 stats
= malloc (bufsize
);
668 numsys
= getfsstat (stats
, bufsize
, MNT_NOWAIT
);
676 for (counter
= 0; counter
< numsys
; counter
++)
678 me
= malloc (sizeof *me
);
679 me
->me_devname
= strdup (stats
[counter
].f_mntfromname
);
680 me
->me_mountdir
= strdup (stats
[counter
].f_mntonname
);
681 //me->me_type = strdup (FS_TYPE (stats[counter]));
682 me
->me_type_malloced
= 1;
683 me
->me_dummy
= ME_DUMMY (me
->me_devname
, me
->me_type
);
684 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
685 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
687 /* Add to the linked list. */
689 mtail
= &me
->me_next
;
694 #endif /* MOUNTED_GETFSSTAT */
696 #if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23]. */
699 char *table
= "/etc/mnttab";
702 fp
= fopen (table
, "r");
706 while (fread (&mnt
, sizeof mnt
, 1, fp
) > 0)
708 me
= xmalloc (sizeof *me
);
709 # ifdef GETFSTYP /* SVR3. */
710 me
->me_devname
= xstrdup (mnt
.mt_dev
);
712 me
->me_devname
= xmalloc (strlen (mnt
.mt_dev
) + 6);
713 strcpy (me
->me_devname
, "/dev/");
714 strcpy (me
->me_devname
+ 5, mnt
.mt_dev
);
716 me
->me_mountdir
= xstrdup (mnt
.mt_filsys
);
717 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
719 me
->me_type_malloced
= 0;
720 # ifdef GETFSTYP /* SVR3. */
724 char typebuf
[FSTYPSZ
];
726 if (statfs (me
->me_mountdir
, &fsd
, sizeof fsd
, 0) != -1
727 && sysfs (GETFSTYP
, fsd
.f_fstyp
, typebuf
) != -1)
729 me
->me_type
= xstrdup (typebuf
);
730 me
->me_type_malloced
= 1;
734 me
->me_dummy
= ME_DUMMY (me
->me_devname
, me
->me_type
);
735 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
737 /* Add to the linked list. */
739 mtail
= &me
->me_next
;
744 /* The last fread() call must have failed. */
745 int saved_errno
= errno
;
751 if (fclose (fp
) == EOF
)
754 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
756 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */
758 struct mntent
**mnttbl
= getmnttbl (), **ent
;
759 for (ent
=mnttbl
;*ent
;ent
++)
761 me
= xmalloc (sizeof *me
);
762 me
->me_devname
= xstrdup ( (*ent
)->mt_resource
);
763 me
->me_mountdir
= xstrdup ( (*ent
)->mt_directory
);
764 me
->me_type
= xstrdup ((*ent
)->mt_fstype
);
765 me
->me_type_malloced
= 1;
766 me
->me_dummy
= ME_DUMMY (me
->me_devname
, me
->me_type
);
767 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
768 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
770 /* Add to the linked list. */
772 mtail
= &me
->me_next
;
778 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
781 char *table
= MNTTAB
;
786 # if defined F_RDLCK && defined F_SETLKW
787 /* MNTTAB_LOCK is a macro name of our own invention; it's not present in
788 e.g. Solaris 2.6. If the SVR4 folks ever define a macro
789 for this file name, we should use their macro name instead.
790 (Why not just lock MNTTAB directly? We don't know.) */
792 # define MNTTAB_LOCK "/etc/.mnttab.lock"
794 lockfd
= open (MNTTAB_LOCK
, O_RDONLY
);
798 flock
.l_type
= F_RDLCK
;
799 flock
.l_whence
= SEEK_SET
;
802 while (fcntl (lockfd
, F_SETLKW
, &flock
) == -1)
805 int saved_errno
= errno
;
811 else if (errno
!= ENOENT
)
816 fp
= fopen (table
, "r");
821 while ((ret
= getmntent (fp
, &mnt
)) == 0)
823 me
= xmalloc (sizeof *me
);
824 me
->me_devname
= xstrdup (mnt
.mnt_special
);
825 me
->me_mountdir
= xstrdup (mnt
.mnt_mountp
);
826 me
->me_type
= xstrdup (mnt
.mnt_fstype
);
827 me
->me_type_malloced
= 1;
828 me
->me_dummy
= MNT_IGNORE (&mnt
) != 0;
829 me
->me_remote
= ME_REMOTE (me
->me_devname
, me
->me_type
);
830 me
->me_dev
= dev_from_mount_options (mnt
.mnt_mntopts
);
832 /* Add to the linked list. */
834 mtail
= &me
->me_next
;
837 ret
= fclose (fp
) == EOF
? errno
: 0 < ret
? 0 : -1;
840 if (0 <= lockfd
&& close (lockfd
) != 0)
849 #endif /* MOUNTED_GETMNTENT2. */
851 #ifdef MOUNTED_VMOUNT /* AIX. */
854 char *entries
, *thisent
;
859 /* Ask how many bytes to allocate for the mounted file system info. */
860 if (mntctl (MCTL_QUERY
, sizeof bufsize
, (struct vmount
*) &bufsize
) != 0)
862 entries
= xmalloc (bufsize
);
864 /* Get the list of mounted file systems. */
865 n_entries
= mntctl (MCTL_QUERY
, bufsize
, (struct vmount
*) entries
);
868 int saved_errno
= errno
;
874 for (i
= 0, thisent
= entries
;
876 i
++, thisent
+= vmp
->vmt_length
)
878 char *options
, *ignore
;
880 vmp
= (struct vmount
*) thisent
;
881 me
= xmalloc (sizeof *me
);
882 if (vmp
->vmt_flags
& MNT_REMOTE
)
887 /* Prepend the remote dirname. */
888 host
= thisent
+ vmp
->vmt_data
[VMT_HOSTNAME
].vmt_off
;
889 dir
= thisent
+ vmp
->vmt_data
[VMT_OBJECT
].vmt_off
;
890 me
->me_devname
= xmalloc (strlen (host
) + strlen (dir
) + 2);
891 strcpy (me
->me_devname
, host
);
892 strcat (me
->me_devname
, ":");
893 strcat (me
->me_devname
, dir
);
898 me
->me_devname
= xstrdup (thisent
+
899 vmp
->vmt_data
[VMT_OBJECT
].vmt_off
);
901 me
->me_mountdir
= xstrdup (thisent
+ vmp
->vmt_data
[VMT_STUB
].vmt_off
);
902 me
->me_type
= xstrdup (fstype_to_string (vmp
->vmt_gfstype
));
903 me
->me_type_malloced
= 1;
904 options
= thisent
+ vmp
->vmt_data
[VMT_ARGS
].vmt_off
;
905 ignore
= strstr (options
, "ignore");
906 me
->me_dummy
= (ignore
907 && (ignore
== options
|| ignore
[-1] == ',')
908 && (ignore
[sizeof "ignore" - 1] == ','
909 || ignore
[sizeof "ignore" - 1] == '\0'));
910 me
->me_dev
= (dev_t
) -1; /* vmt_fsid might be the info we want. */
912 /* Add to the linked list. */
914 mtail
= &me
->me_next
;
918 #endif /* MOUNTED_VMOUNT. */
923 #if defined(MOUNTED_GETMNTENT1) || defined(MOUNTED_GETMNTENT2) || defined(MOUNTED_GETMNT) || defined(MOUNTED_FREAD) || defined(MOUNTED_FREAD_FSTYP)
926 int saved_errno
= errno
;
931 me
= mount_list
->me_next
;
932 free (mount_list
->me_devname
);
933 free (mount_list
->me_mountdir
);
934 if (mount_list
->me_type_malloced
)
935 free (mount_list
->me_type
);
946 void free_file_system_list(struct mount_entry
* mount_list
)
948 struct mount_entry
* me
;
951 me
= mount_list
->me_next
;
952 free (mount_list
->me_devname
);
953 free (mount_list
->me_mountdir
);
954 if (mount_list
->me_type_malloced
)
955 free (mount_list
->me_type
);