1 /* mountlist.c -- return a list of mounted filesystems
2 Copyright (C) 1991, 1992, 1997, 1998 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)
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 #if 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 MOUNTED_GETMNTINFO
145 # if ! HAVE_F_FSTYPENAME_IN_STATFS
147 fstype_to_string (short t)
239 # endif /* ! HAVE_F_FSTYPENAME_IN_STATFS */
241 /* __NetBSD__ || BSD_NET2 || __OpenBSD__ */
243 fsp_to_string (const struct statfs *fsp)
245 # if defined HAVE_F_FSTYPENAME_IN_STATFS
246 return xstrdup (fsp->f_fstypename);
248 return fstype_to_string (fsp->f_type);
252 #endif /* MOUNTED_GETMNTINFO */
254 #ifdef MOUNTED_VMOUNT /* AIX. */
261 e = getvfsbytype (t);
262 if (!e || !e->vfsent_name)
265 return e->vfsent_name;
267 #endif /* MOUNTED_VMOUNT */
269 /* Return a list of the currently mounted filesystems, or NULL on error.
270 Add each entry to the tail of the list so that they stay in order.
271 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
272 the returned list are valid. Otherwise, they might not be.
273 If ALL_FS is zero, do not return entries for filesystems that
274 are automounter (dummy) entries. */
277 read_filesystem_list (need_fs_type, all_fs)
278 int need_fs_type, all_fs;
280 struct mount_entry *mount_list;
281 struct mount_entry *me;
282 struct mount_entry *mtail;
284 /* Start the list off with a dummy entry. */
285 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
287 mount_list = mtail = me;
289 #ifdef MOUNTED_LISTMNTENT
291 struct tabmntent *mntlist, *p;
293 struct mount_entry *me;
295 /* the third and fourth arguments could be used to filter mounts,
296 but Crays doesn't seem to have any mounts that we want to
297 remove. Specifically, automount create normal NFS mounts.
300 if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0)
305 me = (struct mount_entry*) xmalloc(sizeof (struct mount_entry));
306 me->me_devname = xstrdup(mnt->mnt_fsname);
307 me->me_mountdir = xstrdup(mnt->mnt_dir);
308 me->me_type = xstrdup(mnt->mnt_type);
315 freemntlist(mntlist);
319 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
322 char *table = MOUNTED;
326 fp = setmntent (table, "r");
330 while ((mnt = getmntent (fp)))
332 if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
333 || !strcmp (mnt->mnt_type, "auto")))
336 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
337 me->me_devname = xstrdup (mnt->mnt_fsname);
338 me->me_mountdir = xstrdup (mnt->mnt_dir);
339 me->me_type = xstrdup (mnt->mnt_type);
340 devopt = strstr (mnt->mnt_opts, "dev=");
343 if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
344 me->me_dev = xatoi (devopt + 6);
346 me->me_dev = xatoi (devopt + 4);
349 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
352 /* Add to the linked list. */
357 if (endmntent (fp) == 0)
360 #endif /* MOUNTED_GETMNTENT1. */
362 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
367 entries = getmntinfo (&fsp, MNT_NOWAIT);
370 while (entries-- > 0)
372 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
373 me->me_devname = xstrdup (fsp->f_mntfromname);
374 me->me_mountdir = xstrdup (fsp->f_mntonname);
375 me->me_type = fsp_to_string (fsp);
376 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
379 /* Add to the linked list. */
385 #endif /* MOUNTED_GETMNTINFO */
387 #ifdef MOUNTED_GETMNT /* Ultrix. */
393 while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
396 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
397 me->me_devname = xstrdup (fsd.fd_req.devname);
398 me->me_mountdir = xstrdup (fsd.fd_req.path);
399 me->me_type = gt_names[fsd.fd_req.fstype];
400 me->me_dev = fsd.fd_req.dev;
403 /* Add to the linked list. */
410 #endif /* MOUNTED_GETMNT. */
412 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
414 int numsys, counter, bufsize;
415 struct statfs *stats;
417 numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
421 bufsize = (1 + numsys) * sizeof (struct statfs);
422 stats = (struct statfs *)xmalloc (bufsize);
423 numsys = getfsstat (stats, bufsize, MNT_WAIT);
431 for (counter = 0; counter < numsys; counter++)
433 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
434 me->me_devname = xstrdup (stats[counter].f_mntfromname);
435 me->me_mountdir = xstrdup (stats[counter].f_mntonname);
436 me->me_type = mnt_names[stats[counter].f_type];
437 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
440 /* Add to the linked list. */
447 #endif /* MOUNTED_GETFSSTAT */
449 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
452 char *table = "/etc/mnttab";
455 fp = fopen (table, "r");
459 while (fread (&mnt, sizeof mnt, 1, fp) > 0)
461 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
462 # ifdef GETFSTYP /* SVR3. */
463 me->me_devname = xstrdup (mnt.mt_dev);
465 me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
466 strcpy (me->me_devname, "/dev/");
467 strcpy (me->me_devname + 5, mnt.mt_dev);
469 me->me_mountdir = xstrdup (mnt.mt_filsys);
470 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
472 # ifdef GETFSTYP /* SVR3. */
476 char typebuf[FSTYPSZ];
478 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
479 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
480 me->me_type = xstrdup (typebuf);
485 /* Add to the linked list. */
490 if (fclose (fp) == EOF)
493 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
495 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
497 struct mntent **mnttbl=getmnttbl(),**ent;
498 for (ent=mnttbl;*ent;ent++)
500 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
501 me->me_devname = xstrdup ( (*ent)->mt_resource);
502 me->me_mountdir = xstrdup( (*ent)->mt_directory);
503 me->me_type = xstrdup ((*ent)->mt_fstype);
504 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
507 /* Add to the linked list. */
515 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
518 char *table = MNTTAB;
522 fp = fopen (table, "r");
526 while ((ret = getmntent (fp, &mnt)) == 0)
528 /* Don't show automounted filesystems twice on e.g., Solaris. */
529 if (!all_fs && MNT_IGNORE (&mnt))
532 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
533 me->me_devname = xstrdup (mnt.mnt_special);
534 me->me_mountdir = xstrdup (mnt.mnt_mountp);
535 me->me_type = xstrdup (mnt.mnt_fstype);
536 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
539 /* Add to the linked list. */
546 if (fclose (fp) == EOF)
549 #endif /* MOUNTED_GETMNTENT2. */
551 #ifdef MOUNTED_VMOUNT /* AIX. */
554 char *entries, *thisent;
557 /* Ask how many bytes to allocate for the mounted filesystem info. */
558 mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
559 entries = xmalloc (bufsize);
561 /* Get the list of mounted filesystems. */
562 mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
564 for (thisent = entries; thisent < entries + bufsize;
565 thisent += vmp->vmt_length)
567 vmp = (struct vmount *) thisent;
568 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
569 if (vmp->vmt_flags & MNT_REMOTE)
573 /* Prepend the remote pathname. */
574 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
575 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
576 me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
577 strcpy (me->me_devname, host);
578 strcat (me->me_devname, ":");
579 strcat (me->me_devname, path);
583 me->me_devname = xstrdup (thisent +
584 vmp->vmt_data[VMT_OBJECT].vmt_off);
586 me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
587 me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
588 me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */
591 /* Add to the linked list. */
597 #endif /* MOUNTED_VMOUNT. */
599 /* Free the dummy head. */
601 mount_list = mount_list->me_next;