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
146 fstype_to_string (short t)
239 /* __NetBSD__ || BSD_NET2 || __OpenBSD__ */
241 fsp_to_string (const struct statfs *fsp)
243 # if defined HAVE_F_FSTYPENAME_IN_STATFS
244 return xstrdup (fsp->f_fstypename);
246 return fstype_to_string (fsp->f_type);
250 #endif /* MOUNTED_GETMNTINFO */
252 #ifdef MOUNTED_VMOUNT /* AIX. */
259 e = getvfsbytype (t);
260 if (!e || !e->vfsent_name)
263 return e->vfsent_name;
265 #endif /* MOUNTED_VMOUNT */
267 /* Return a list of the currently mounted filesystems, or NULL on error.
268 Add each entry to the tail of the list so that they stay in order.
269 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
270 the returned list are valid. Otherwise, they might not be.
271 If ALL_FS is zero, do not return entries for filesystems that
272 are automounter (dummy) entries. */
275 read_filesystem_list (need_fs_type, all_fs)
276 int need_fs_type, all_fs;
278 struct mount_entry *mount_list;
279 struct mount_entry *me;
280 struct mount_entry *mtail;
282 /* Start the list off with a dummy entry. */
283 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
285 mount_list = mtail = me;
287 #ifdef MOUNTED_LISTMNTENT
289 struct tabmntent *mntlist, *p;
291 struct mount_entry *me;
293 /* the third and fourth arguments could be used to filter mounts,
294 but Crays doesn't seem to have any mounts that we want to
295 remove. Specifically, automount create normal NFS mounts.
298 if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0)
303 me = (struct mount_entry*) xmalloc(sizeof (struct mount_entry));
304 me->me_devname = xstrdup(mnt->mnt_fsname);
305 me->me_mountdir = xstrdup(mnt->mnt_dir);
306 me->me_type = xstrdup(mnt->mnt_type);
313 freemntlist(mntlist);
317 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
320 char *table = MOUNTED;
324 fp = setmntent (table, "r");
328 while ((mnt = getmntent (fp)))
330 if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
331 || !strcmp (mnt->mnt_type, "auto")))
334 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
335 me->me_devname = xstrdup (mnt->mnt_fsname);
336 me->me_mountdir = xstrdup (mnt->mnt_dir);
337 me->me_type = xstrdup (mnt->mnt_type);
338 devopt = strstr (mnt->mnt_opts, "dev=");
341 if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
342 me->me_dev = xatoi (devopt + 6);
344 me->me_dev = xatoi (devopt + 4);
347 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
350 /* Add to the linked list. */
355 if (endmntent (fp) == 0)
358 #endif /* MOUNTED_GETMNTENT1. */
360 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
365 entries = getmntinfo (&fsp, MNT_NOWAIT);
368 while (entries-- > 0)
370 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
371 me->me_devname = xstrdup (fsp->f_mntfromname);
372 me->me_mountdir = xstrdup (fsp->f_mntonname);
373 me->me_type = fsp_to_string (fsp);
374 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
377 /* Add to the linked list. */
383 #endif /* MOUNTED_GETMNTINFO */
385 #ifdef MOUNTED_GETMNT /* Ultrix. */
391 while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
394 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
395 me->me_devname = xstrdup (fsd.fd_req.devname);
396 me->me_mountdir = xstrdup (fsd.fd_req.path);
397 me->me_type = gt_names[fsd.fd_req.fstype];
398 me->me_dev = fsd.fd_req.dev;
401 /* Add to the linked list. */
408 #endif /* MOUNTED_GETMNT. */
410 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
412 int numsys, counter, bufsize;
413 struct statfs *stats;
415 numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
419 bufsize = (1 + numsys) * sizeof (struct statfs);
420 stats = (struct statfs *)xmalloc (bufsize);
421 numsys = getfsstat (stats, bufsize, MNT_WAIT);
429 for (counter = 0; counter < numsys; counter++)
431 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
432 me->me_devname = xstrdup (stats[counter].f_mntfromname);
433 me->me_mountdir = xstrdup (stats[counter].f_mntonname);
434 me->me_type = mnt_names[stats[counter].f_type];
435 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
438 /* Add to the linked list. */
445 #endif /* MOUNTED_GETFSSTAT */
447 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
450 char *table = "/etc/mnttab";
453 fp = fopen (table, "r");
457 while (fread (&mnt, sizeof mnt, 1, fp) > 0)
459 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
460 # ifdef GETFSTYP /* SVR3. */
461 me->me_devname = xstrdup (mnt.mt_dev);
463 me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
464 strcpy (me->me_devname, "/dev/");
465 strcpy (me->me_devname + 5, mnt.mt_dev);
467 me->me_mountdir = xstrdup (mnt.mt_filsys);
468 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
470 # ifdef GETFSTYP /* SVR3. */
474 char typebuf[FSTYPSZ];
476 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
477 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
478 me->me_type = xstrdup (typebuf);
483 /* Add to the linked list. */
488 if (fclose (fp) == EOF)
491 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
493 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
495 struct mntent **mnttbl=getmnttbl(),**ent;
496 for (ent=mnttbl;*ent;ent++)
498 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
499 me->me_devname = xstrdup ( (*ent)->mt_resource);
500 me->me_mountdir = xstrdup( (*ent)->mt_directory);
501 me->me_type = xstrdup ((*ent)->mt_fstype);
502 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
505 /* Add to the linked list. */
513 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
516 char *table = MNTTAB;
520 fp = fopen (table, "r");
524 while ((ret = getmntent (fp, &mnt)) == 0)
526 /* Don't show automounted filesystems twice on e.g., Solaris. */
527 if (!all_fs && MNT_IGNORE (&mnt))
530 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
531 me->me_devname = xstrdup (mnt.mnt_special);
532 me->me_mountdir = xstrdup (mnt.mnt_mountp);
533 me->me_type = xstrdup (mnt.mnt_fstype);
534 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
537 /* Add to the linked list. */
544 if (fclose (fp) == EOF)
547 #endif /* MOUNTED_GETMNTENT2. */
549 #ifdef MOUNTED_VMOUNT /* AIX. */
552 char *entries, *thisent;
555 /* Ask how many bytes to allocate for the mounted filesystem info. */
556 mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
557 entries = xmalloc (bufsize);
559 /* Get the list of mounted filesystems. */
560 mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
562 for (thisent = entries; thisent < entries + bufsize;
563 thisent += vmp->vmt_length)
565 vmp = (struct vmount *) thisent;
566 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
567 if (vmp->vmt_flags & MNT_REMOTE)
571 /* Prepend the remote pathname. */
572 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
573 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
574 me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
575 strcpy (me->me_devname, host);
576 strcat (me->me_devname, ":");
577 strcat (me->me_devname, path);
581 me->me_devname = xstrdup (thisent +
582 vmp->vmt_data[VMT_OBJECT].vmt_off);
584 me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
585 me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
586 me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */
589 /* Add to the linked list. */
595 #endif /* MOUNTED_VMOUNT. */
597 /* Free the dummy head. */
599 mount_list = mount_list->me_next;