1 /* mountlist.c -- return a list of mounted filesystems
2 Copyright (C) 1991, 1992, 1997 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 Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include <sys/types.h>
24 #include "mountlist.h"
31 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
45 #ifdef HAVE_SYS_PARAM_H
46 # include <sys/param.h>
49 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
50 # include <sys/mount.h>
51 # include <sys/fs_types.h>
52 #endif /* MOUNTED_GETFSSTAT */
54 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
56 # if !defined(MOUNTED)
57 # if defined(MNT_MNTTAB) /* HP-UX. */
58 # define MOUNTED MNT_MNTTAB
60 # if defined(MNTTABNAME) /* Dynix. */
61 # define MOUNTED MNTTABNAME
66 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
67 # include <sys/mount.h>
70 #ifdef MOUNTED_GETMNT /* Ultrix. */
71 # include <sys/mount.h>
72 # include <sys/fs_types.h>
75 #ifdef MOUNTED_FREAD /* SVR2. */
79 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
81 # include <sys/fstyp.h>
82 # include <sys/statfs.h>
85 #ifdef MOUNTED_LISTMNTENT
89 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
90 # include <sys/mnttab.h>
93 #ifdef MOUNTED_VMOUNT /* AIX. */
99 /* So special that it's not worth putting this in autoconf. */
100 # undef MOUNTED_FREAD_FSTYP
101 # define MOUNTED_GETMNTTBL
104 #ifdef HAVE_SYS_MNTENT_H
105 /* This is to get MNTOPT_IGNORE on e.g. SVR4. */
106 # include <sys/mntent.h>
109 #if defined (MNTOPT_IGNORE) && defined (HAVE_HASMNTOPT)
110 # define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE)
112 # define MNT_IGNORE(M) 0
115 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
116 /* Return the value of the hexadecimal number represented by CP.
117 No prefix (like '0x') or suffix (like 'h') is expected to be
129 if (*cp
>= 'a' && *cp
<= 'f')
130 val
= val
* 16 + *cp
- 'a' + 10;
131 else if (*cp
>= 'A' && *cp
<= 'F')
132 val
= val
* 16 + *cp
- 'A' + 10;
133 else if (*cp
>= '0' && *cp
<= '9')
134 val
= val
* 16 + *cp
- '0';
141 #endif /* MOUNTED_GETMNTENT1. */
143 #if defined (MOUNTED_GETMNTINFO) && !defined (__NetBSD__) && !defined (__OpenBSD__)
238 #endif /* MOUNTED_GETMNTINFO */
240 #ifdef MOUNTED_VMOUNT /* AIX. */
247 e
= getvfsbytype (t
);
248 if (!e
|| !e
->vfsent_name
)
251 return e
->vfsent_name
;
253 #endif /* MOUNTED_VMOUNT */
255 /* Return a list of the currently mounted filesystems, or NULL on error.
256 Add each entry to the tail of the list so that they stay in order.
257 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
258 the returned list are valid. Otherwise, they might not be.
259 If ALL_FS is zero, do not return entries for filesystems that
260 are automounter (dummy) entries. */
263 read_filesystem_list (need_fs_type
, all_fs
)
264 int need_fs_type
, all_fs
;
266 struct mount_entry
*mount_list
;
267 struct mount_entry
*me
;
268 struct mount_entry
*mtail
;
270 /* Start the list off with a dummy entry. */
271 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
273 mount_list
= mtail
= me
;
275 #ifdef MOUNTED_LISTMNTENT
277 struct tabmntent
*mntlist
, *p
;
279 struct mount_entry
*me
;
281 /* the third and fourth arguments could be used to filter mounts,
282 but Crays doesn't seem to have any mounts that we want to
283 remove. Specifically, automount create normal NFS mounts.
286 if(listmntent(&mntlist
, KMTAB
, NULL
, NULL
) < 0)
291 me
= (struct mount_entry
*) xmalloc(sizeof (struct mount_entry
));
292 me
->me_devname
= xstrdup(mnt
->mnt_fsname
);
293 me
->me_mountdir
= xstrdup(mnt
->mnt_dir
);
294 me
->me_type
= xstrdup(mnt
->mnt_type
);
301 freemntlist(mntlist
);
305 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
308 char *table
= MOUNTED
;
312 fp
= setmntent (table
, "r");
316 while ((mnt
= getmntent (fp
)))
318 if (!all_fs
&& (!strcmp (mnt
->mnt_type
, "ignore")
319 || !strcmp (mnt
->mnt_type
, "auto")))
322 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
323 me
->me_devname
= xstrdup (mnt
->mnt_fsname
);
324 me
->me_mountdir
= xstrdup (mnt
->mnt_dir
);
325 me
->me_type
= xstrdup (mnt
->mnt_type
);
326 devopt
= strstr (mnt
->mnt_opts
, "dev=");
329 if (devopt
[4] == '0' && (devopt
[5] == 'x' || devopt
[5] == 'X'))
330 me
->me_dev
= xatoi (devopt
+ 6);
332 me
->me_dev
= xatoi (devopt
+ 4);
335 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
338 /* Add to the linked list. */
343 if (endmntent (fp
) == 0)
346 #endif /* MOUNTED_GETMNTENT1. */
348 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
353 entries
= getmntinfo (&fsp
, MNT_NOWAIT
);
356 while (entries
-- > 0)
358 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
359 me
->me_devname
= xstrdup (fsp
->f_mntfromname
);
360 me
->me_mountdir
= xstrdup (fsp
->f_mntonname
);
361 # if defined (__NetBSD__) || defined (__OpenBSD__)
362 me
->me_type
= xstrdup (fsp
->f_fstypename
);
364 me
->me_type
= fstype_to_string (fsp
->f_type
);
366 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
369 /* Add to the linked list. */
375 #endif /* MOUNTED_GETMNTINFO */
377 #ifdef MOUNTED_GETMNT /* Ultrix. */
383 while ((val
= getmnt (&offset
, &fsd
, sizeof (fsd
), NOSTAT_MANY
,
386 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
387 me
->me_devname
= xstrdup (fsd
.fd_req
.devname
);
388 me
->me_mountdir
= xstrdup (fsd
.fd_req
.path
);
389 me
->me_type
= gt_names
[fsd
.fd_req
.fstype
];
390 me
->me_dev
= fsd
.fd_req
.dev
;
393 /* Add to the linked list. */
400 #endif /* MOUNTED_GETMNT. */
402 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
404 int numsys
, counter
, bufsize
;
405 struct statfs
*stats
;
407 numsys
= getfsstat ((struct statfs
*)0, 0L, MNT_WAIT
);
411 bufsize
= (1 + numsys
) * sizeof (struct statfs
);
412 stats
= (struct statfs
*)xmalloc (bufsize
);
413 numsys
= getfsstat (stats
, bufsize
, MNT_WAIT
);
421 for (counter
= 0; counter
< numsys
; counter
++)
423 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
424 me
->me_devname
= xstrdup (stats
[counter
].f_mntfromname
);
425 me
->me_mountdir
= xstrdup (stats
[counter
].f_mntonname
);
426 me
->me_type
= mnt_names
[stats
[counter
].f_type
];
427 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
430 /* Add to the linked list. */
437 #endif /* MOUNTED_GETFSSTAT */
439 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
442 char *table
= "/etc/mnttab";
445 fp
= fopen (table
, "r");
449 while (fread (&mnt
, sizeof mnt
, 1, fp
) > 0)
451 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
452 # ifdef GETFSTYP /* SVR3. */
453 me
->me_devname
= xstrdup (mnt
.mt_dev
);
455 me
->me_devname
= xmalloc (strlen (mnt
.mt_dev
) + 6);
456 strcpy (me
->me_devname
, "/dev/");
457 strcpy (me
->me_devname
+ 5, mnt
.mt_dev
);
459 me
->me_mountdir
= xstrdup (mnt
.mt_filsys
);
460 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
462 # ifdef GETFSTYP /* SVR3. */
466 char typebuf
[FSTYPSZ
];
468 if (statfs (me
->me_mountdir
, &fsd
, sizeof fsd
, 0) != -1
469 && sysfs (GETFSTYP
, fsd
.f_fstyp
, typebuf
) != -1)
470 me
->me_type
= xstrdup (typebuf
);
475 /* Add to the linked list. */
480 if (fclose (fp
) == EOF
)
483 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
485 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
487 struct mntent
**mnttbl
=getmnttbl(),**ent
;
488 for (ent
=mnttbl
;*ent
;ent
++)
490 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
491 me
->me_devname
= xstrdup ( (*ent
)->mt_resource
);
492 me
->me_mountdir
= xstrdup( (*ent
)->mt_directory
);
493 me
->me_type
= xstrdup ((*ent
)->mt_fstype
);
494 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
497 /* Add to the linked list. */
505 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
508 char *table
= MNTTAB
;
512 fp
= fopen (table
, "r");
516 while ((ret
= getmntent (fp
, &mnt
)) == 0)
518 /* Don't show automounted filesystems twice on e.g., Solaris. */
519 if (!all_fs
&& MNT_IGNORE (&mnt
))
522 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
523 me
->me_devname
= xstrdup (mnt
.mnt_special
);
524 me
->me_mountdir
= xstrdup (mnt
.mnt_mountp
);
525 me
->me_type
= xstrdup (mnt
.mnt_fstype
);
526 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
529 /* Add to the linked list. */
536 if (fclose (fp
) == EOF
)
539 #endif /* MOUNTED_GETMNTENT2. */
541 #ifdef MOUNTED_VMOUNT /* AIX. */
544 char *entries
, *thisent
;
547 /* Ask how many bytes to allocate for the mounted filesystem info. */
548 mntctl (MCTL_QUERY
, sizeof bufsize
, (struct vmount
*) &bufsize
);
549 entries
= xmalloc (bufsize
);
551 /* Get the list of mounted filesystems. */
552 mntctl (MCTL_QUERY
, bufsize
, (struct vmount
*) entries
);
554 for (thisent
= entries
; thisent
< entries
+ bufsize
;
555 thisent
+= vmp
->vmt_length
)
557 vmp
= (struct vmount
*) thisent
;
558 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
559 if (vmp
->vmt_flags
& MNT_REMOTE
)
563 /* Prepend the remote pathname. */
564 host
= thisent
+ vmp
->vmt_data
[VMT_HOSTNAME
].vmt_off
;
565 path
= thisent
+ vmp
->vmt_data
[VMT_OBJECT
].vmt_off
;
566 me
->me_devname
= xmalloc (strlen (host
) + strlen (path
) + 2);
567 strcpy (me
->me_devname
, host
);
568 strcat (me
->me_devname
, ":");
569 strcat (me
->me_devname
, path
);
573 me
->me_devname
= xstrdup (thisent
+
574 vmp
->vmt_data
[VMT_OBJECT
].vmt_off
);
576 me
->me_mountdir
= xstrdup (thisent
+ vmp
->vmt_data
[VMT_STUB
].vmt_off
);
577 me
->me_type
= xstrdup (fstype_to_string (vmp
->vmt_gfstype
));
578 me
->me_dev
= (dev_t
) -1; /* vmt_fsid might be the info we want. */
581 /* Add to the linked list. */
587 #endif /* MOUNTED_VMOUNT. */
589 /* Free the dummy head. */
591 mount_list
= mount_list
->me_next
;