summaryrefslogtreecommitdiff
path: root/lib/mountlist.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1992-10-31 20:42:48 +0000
committerJim Meyering <jim@meyering.net>1992-10-31 20:42:48 +0000
commit14fd34b78818660e05806b6eda178e3f846c5c21 (patch)
treeb40038aa2684b5cd95ae2d5fcef564bcf8e05cc3 /lib/mountlist.c
downloadcoreutils-14fd34b78818660e05806b6eda178e3f846c5c21.tar.xz
Initial revision
Diffstat (limited to 'lib/mountlist.c')
-rw-r--r--lib/mountlist.c402
1 files changed, 402 insertions, 0 deletions
diff --git a/lib/mountlist.c b/lib/mountlist.c
new file mode 100644
index 000000000..78955f709
--- /dev/null
+++ b/lib/mountlist.c
@@ -0,0 +1,402 @@
+/* mountlist.c -- return a list of mounted filesystems
+ Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "mountlist.h"
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+void free ();
+#endif
+#if defined(USG) || defined(STDC_HEADERS)
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+char *strstr ();
+char *xmalloc ();
+char *xrealloc ();
+char *xstrdup ();
+void error ();
+
+#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
+#include <mntent.h>
+#if !defined(MOUNTED)
+# if defined(MNT_MNTTAB) /* HP-UX. */
+# define MOUNTED MNT_MNTTAB
+# endif
+# if defined(MNTTABNAME) /* Dynix. */
+# define MOUNTED MNTTABNAME
+# endif
+#endif
+#endif
+
+#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
+#include <sys/mount.h>
+#endif
+
+#ifdef MOUNTED_GETMNT /* Ultrix. */
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/fs_types.h>
+#endif
+
+#ifdef MOUNTED_FREAD /* SVR2. */
+#include <mnttab.h>
+#endif
+
+#ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
+#include <mnttab.h>
+#include <sys/fstyp.h>
+#include <sys/statfs.h>
+#endif
+
+#ifdef MOUNTED_GETMNTENT2 /* SVR4. */
+#include <sys/mnttab.h>
+#endif
+
+#ifdef MOUNTED_VMOUNT /* AIX. */
+#include <fshelp.h>
+#include <sys/vfs.h>
+#endif
+
+#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
+/* Return the value of the hexadecimal number represented by CP.
+ No prefix (like '0x') or suffix (like 'h') is expected to be
+ part of CP. */
+
+static int
+xatoi (cp)
+ char *cp;
+{
+ int val;
+
+ val = 0;
+ while (*cp)
+ {
+ if (*cp >= 'a' && *cp <= 'f')
+ val = val * 16 + *cp - 'a' + 10;
+ else if (*cp >= 'A' && *cp <= 'F')
+ val = val * 16 + *cp - 'A' + 10;
+ else if (*cp >= '0' && *cp <= '9')
+ val = val * 16 + *cp - '0';
+ else
+ break;
+ cp++;
+ }
+ return val;
+}
+#endif /* MOUNTED_GETMNTENT1. */
+
+#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
+static char *
+fstype_to_string (t)
+ short t;
+{
+ switch (t)
+ {
+ case MOUNT_UFS:
+ return "ufs";
+ case MOUNT_NFS:
+ return "nfs";
+ case MOUNT_PC:
+ return "pc";
+#ifdef MOUNT_MFS
+ case MOUNT_MFS:
+ return "mfs";
+#endif
+#ifdef MOUNT_LO
+ case MOUNT_LO:
+ return "lo";
+#endif
+#ifdef MOUNT_TFS
+ case MOUNT_TFS:
+ return "tfs";
+#endif
+#ifdef MOUNT_TMP
+ case MOUNT_TMP:
+ return "tmp";
+#endif
+ default:
+ return "?";
+ }
+}
+#endif /* MOUNTED_GETMNTINFO */
+
+#ifdef MOUNTED_VMOUNT /* AIX. */
+static char *
+fstype_to_string (t)
+ int t;
+{
+ struct vfs_ent *e;
+
+ e = getvfsbytype (t);
+ if (!e || !e->vfsent_name)
+ return "none";
+ else
+ return e->vfsent_name;
+}
+#endif /* MOUNTED_VMOUNT */
+
+/* Return a list of the currently mounted filesystems, or NULL on error.
+ Add each entry to the tail of the list so that they stay in order.
+ If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
+ the returned list are valid. Otherwise, they might not be.
+ If ALL_FS is zero, do not return entries for filesystems that
+ are automounter (dummy) entries. */
+
+struct mount_entry *
+read_filesystem_list (need_fs_type, all_fs)
+ int need_fs_type, all_fs;
+{
+ struct mount_entry *mount_list;
+ struct mount_entry *me;
+ struct mount_entry *mtail;
+
+ /* Start the list off with a dummy entry. */
+ me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
+ me->me_next = NULL;
+ mount_list = mtail = me;
+
+#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
+ {
+ struct mntent *mnt;
+ char *table = MOUNTED;
+ FILE *fp;
+ char *devopt;
+
+ fp = setmntent (table, "r");
+ if (fp == NULL)
+ return NULL;
+
+ while ((mnt = getmntent (fp)))
+ {
+ if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
+ || !strcmp (mnt->mnt_type, "auto")))
+ continue;
+
+ me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
+ me->me_devname = xstrdup (mnt->mnt_fsname);
+ me->me_mountdir = xstrdup (mnt->mnt_dir);
+ me->me_type = xstrdup (mnt->mnt_type);
+ devopt = strstr (mnt->mnt_opts, "dev=");
+ if (devopt)
+ {
+ if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
+ me->me_dev = xatoi (devopt + 6);
+ else
+ me->me_dev = xatoi (devopt + 4);
+ }
+ else
+ me->me_dev = -1; /* Magic; means not known yet. */
+ me->me_next = NULL;
+
+ /* Add to the linked list. */
+ mtail->me_next = me;
+ mtail = me;
+ }
+
+ if (endmntent (fp) == 0)
+ return NULL;
+ }
+#endif /* MOUNTED_GETMNTENT1. */
+
+#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
+ {
+ struct statfs *fsp;
+ int entries;
+
+ entries = getmntinfo (&fsp, MNT_NOWAIT);
+ if (entries < 0)
+ return NULL;
+ while (entries-- > 0)
+ {
+ me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
+ me->me_devname = xstrdup (fsp->f_mntfromname);
+ me->me_mountdir = xstrdup (fsp->f_mntonname);
+ me->me_type = fstype_to_string (fsp->f_type);
+ me->me_dev = -1; /* Magic; means not known yet. */
+ me->me_next = NULL;
+
+ /* Add to the linked list. */
+ mtail->me_next = me;
+ mtail = me;
+ fsp++;
+ }
+ }
+#endif /* MOUNTED_GETMNTINFO */
+
+#ifdef MOUNTED_GETMNT /* Ultrix. */
+ {
+ int offset = 0;
+ int val;
+ struct fs_data fsd;
+
+ while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
+ (char *) 0)) > 0)
+ {
+ me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
+ me->me_devname = xstrdup (fsd.fd_req.devname);
+ me->me_mountdir = xstrdup (fsd.fd_req.path);
+ me->me_type = gt_names[fsd.fd_req.fstype];
+ me->me_dev = fsd.fd_req.dev;
+ me->me_next = NULL;
+
+ /* Add to the linked list. */
+ mtail->me_next = me;
+ mtail = me;
+ }
+ if (val < 0)
+ return NULL;
+ }
+#endif /* MOUNTED_GETMNT. */
+
+#if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
+ {
+ struct mnttab mnt;
+ char *table = "/etc/mnttab";
+ FILE *fp;
+
+ fp = fopen (table, "r");
+ if (fp == NULL)
+ return NULL;
+
+ while (fread (&mnt, sizeof mnt, 1, fp) > 0)
+ {
+ me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
+#ifdef GETFSTYP /* SVR3. */
+ me->me_devname = xstrdup (mnt.mt_dev);
+#else
+ me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
+ strcpy (me->me_devname, "/dev/");
+ strcpy (me->me_devname + 5, mnt.mt_dev);
+#endif
+ me->me_mountdir = xstrdup (mnt.mt_filsys);
+ me->me_dev = -1; /* Magic; means not known yet. */
+ me->me_type = "";
+#ifdef GETFSTYP /* SVR3. */
+ if (need_fs_type)
+ {
+ struct statfs fsd;
+ char typebuf[FSTYPSZ];
+
+ if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
+ && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
+ me->me_type = xstrdup (typebuf);
+ }
+#endif
+ me->me_next = NULL;
+
+ /* Add to the linked list. */
+ mtail->me_next = me;
+ mtail = me;
+ }
+
+ if (fclose (fp) == EOF)
+ return NULL;
+ }
+#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
+
+#ifdef MOUNTED_GETMNTENT2 /* SVR4. */
+ {
+ struct mnttab mnt;
+ char *table = MNTTAB;
+ FILE *fp;
+ int ret;
+
+ fp = fopen (table, "r");
+ if (fp == NULL)
+ return NULL;
+
+ while ((ret = getmntent (fp, &mnt)) == 0)
+ {
+ me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
+ me->me_devname = xstrdup (mnt.mnt_special);
+ me->me_mountdir = xstrdup (mnt.mnt_mountp);
+ me->me_type = xstrdup (mnt.mnt_fstype);
+ me->me_dev = -1; /* Magic; means not known yet. */
+ me->me_next = NULL;
+
+ /* Add to the linked list. */
+ mtail->me_next = me;
+ mtail = me;
+ }
+
+ if (ret > 0)
+ return NULL;
+ if (fclose (fp) == EOF)
+ return NULL;
+ }
+#endif /* MOUNTED_GETMNTENT2. */
+
+#ifdef MOUNTED_VMOUNT /* AIX. */
+ {
+ int bufsize;
+ char *entries, *thisent;
+ struct vmount *vmp;
+
+ /* Ask how many bytes to allocate for the mounted filesystem info. */
+ mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
+ entries = xmalloc (bufsize);
+
+ /* Get the list of mounted filesystems. */
+ mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
+
+ for (thisent = entries; thisent < entries + bufsize;
+ thisent += vmp->vmt_length)
+ {
+ vmp = (struct vmount *) thisent;
+ me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
+ if (vmp->vmt_flags & MNT_REMOTE)
+ {
+ char *host, *path;
+
+ /* Prepend the remote pathname. */
+ host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
+ path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
+ me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
+ strcpy (me->me_devname, host);
+ strcat (me->me_devname, ":");
+ strcat (me->me_devname, path);
+ }
+ else
+ {
+ me->me_devname = xstrdup (thisent +
+ vmp->vmt_data[VMT_OBJECT].vmt_off);
+ }
+ me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
+ me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
+ me->me_dev = -1; /* vmt_fsid might be the info we want. */
+ me->me_next = NULL;
+
+ /* Add to the linked list. */
+ mtail->me_next = me;
+ mtail = me;
+ }
+ free (entries);
+ }
+#endif /* MOUNTED_VMOUNT. */
+
+ /* Free the dummy head. */
+ me = mount_list;
+ mount_list = mount_list->me_next;
+ free (me);
+ return mount_list;
+}