1 /* mountlist.c -- return a list of mounted filesystems
2 Copyright (C) 1991, 1992 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)
43 #ifdef HAVE_SYS_PARAM_H
44 #include <sys/param.h>
47 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
48 # include <sys/mount.h>
49 # include <sys/fs_types.h>
50 #endif /* MOUNTED_GETFSSTAT */
52 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
55 # if defined(MNT_MNTTAB) /* HP-UX. */
56 # define MOUNTED MNT_MNTTAB
58 # if defined(MNTTABNAME) /* Dynix. */
59 # define MOUNTED MNTTABNAME
64 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
65 #include <sys/mount.h>
68 #ifdef MOUNTED_GETMNT /* Ultrix. */
69 #include <sys/mount.h>
70 #include <sys/fs_types.h>
73 #ifdef MOUNTED_FREAD /* SVR2. */
77 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
79 #include <sys/fstyp.h>
80 #include <sys/statfs.h>
83 #ifdef MOUNTED_LISTMNTENT
87 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
88 #include <sys/mnttab.h>
91 #ifdef MOUNTED_VMOUNT /* AIX. */
97 /* So special that it's not worth putting this in autoconf. */
98 #undef MOUNTED_FREAD_FSTYP
99 #define MOUNTED_GETMNTTBL
102 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
103 /* Return the value of the hexadecimal number represented by CP.
104 No prefix (like '0x') or suffix (like 'h') is expected to be
116 if (*cp >= 'a' && *cp <= 'f')
117 val = val * 16 + *cp - 'a' + 10;
118 else if (*cp >= 'A' && *cp <= 'F')
119 val = val * 16 + *cp - 'A' + 10;
120 else if (*cp >= '0' && *cp <= '9')
121 val = val * 16 + *cp - '0';
128 #endif /* MOUNTED_GETMNTENT1. */
130 #if defined (MOUNTED_GETMNTINFO) && !defined (__NetBSD__)
225 #endif /* MOUNTED_GETMNTINFO */
227 #ifdef MOUNTED_VMOUNT /* AIX. */
234 e = getvfsbytype (t);
235 if (!e || !e->vfsent_name)
238 return e->vfsent_name;
240 #endif /* MOUNTED_VMOUNT */
242 /* Return a list of the currently mounted filesystems, or NULL on error.
243 Add each entry to the tail of the list so that they stay in order.
244 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
245 the returned list are valid. Otherwise, they might not be.
246 If ALL_FS is zero, do not return entries for filesystems that
247 are automounter (dummy) entries. */
250 read_filesystem_list (need_fs_type, all_fs)
251 int need_fs_type, all_fs;
253 struct mount_entry *mount_list;
254 struct mount_entry *me;
255 struct mount_entry *mtail;
257 /* Start the list off with a dummy entry. */
258 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
260 mount_list = mtail = me;
262 #ifdef MOUNTED_LISTMNTENT
264 struct tabmntent *mntlist, *p;
266 struct mount_entry *me;
268 /* the third and fourth arguments could be used to filter mounts,
269 but Crays doesn't seem to have any mounts that we want to
270 remove. Specifically, automount create normal NFS mounts.
273 if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0)
278 me = (struct mount_entry*) xmalloc(sizeof (struct mount_entry));
279 me->me_devname = xstrdup(mnt->mnt_fsname);
280 me->me_mountdir = xstrdup(mnt->mnt_dir);
281 me->me_type = xstrdup(mnt->mnt_type);
288 freemntlist(mntlist);
292 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
295 char *table = MOUNTED;
299 fp = setmntent (table, "r");
303 while ((mnt = getmntent (fp)))
305 if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
306 || !strcmp (mnt->mnt_type, "auto")))
309 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
310 me->me_devname = xstrdup (mnt->mnt_fsname);
311 me->me_mountdir = xstrdup (mnt->mnt_dir);
312 me->me_type = xstrdup (mnt->mnt_type);
313 devopt = strstr (mnt->mnt_opts, "dev=");
316 if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
317 me->me_dev = xatoi (devopt + 6);
319 me->me_dev = xatoi (devopt + 4);
322 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
325 /* Add to the linked list. */
330 if (endmntent (fp) == 0)
333 #endif /* MOUNTED_GETMNTENT1. */
335 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
340 entries = getmntinfo (&fsp, MNT_NOWAIT);
343 while (entries-- > 0)
345 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
346 me->me_devname = xstrdup (fsp->f_mntfromname);
347 me->me_mountdir = xstrdup (fsp->f_mntonname);
349 me->me_type = xstrdup (fsp->f_fstypename);
351 me->me_type = fstype_to_string (fsp->f_type);
353 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
356 /* Add to the linked list. */
362 #endif /* MOUNTED_GETMNTINFO */
364 #ifdef MOUNTED_GETMNT /* Ultrix. */
370 while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
373 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
374 me->me_devname = xstrdup (fsd.fd_req.devname);
375 me->me_mountdir = xstrdup (fsd.fd_req.path);
376 me->me_type = gt_names[fsd.fd_req.fstype];
377 me->me_dev = fsd.fd_req.dev;
380 /* Add to the linked list. */
387 #endif /* MOUNTED_GETMNT. */
389 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
391 int numsys, counter, bufsize;
392 struct statfs *stats;
394 numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
398 bufsize = (1 + numsys) * sizeof (struct statfs);
399 stats = (struct statfs *)xmalloc (bufsize);
400 numsys = getfsstat (stats, bufsize, MNT_WAIT);
408 for (counter = 0; counter < numsys; counter++)
410 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
411 me->me_devname = xstrdup (stats[counter].f_mntfromname);
412 me->me_mountdir = xstrdup (stats[counter].f_mntonname);
413 me->me_type = mnt_names[stats[counter].f_type];
414 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
417 /* Add to the linked list. */
424 #endif /* MOUNTED_GETFSSTAT */
426 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
429 char *table = "/etc/mnttab";
432 fp = fopen (table, "r");
436 while (fread (&mnt, sizeof mnt, 1, fp) > 0)
438 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
439 #ifdef GETFSTYP /* SVR3. */
440 me->me_devname = xstrdup (mnt.mt_dev);
442 me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
443 strcpy (me->me_devname, "/dev/");
444 strcpy (me->me_devname + 5, mnt.mt_dev);
446 me->me_mountdir = xstrdup (mnt.mt_filsys);
447 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
449 #ifdef GETFSTYP /* SVR3. */
453 char typebuf[FSTYPSZ];
455 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
456 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
457 me->me_type = xstrdup (typebuf);
462 /* Add to the linked list. */
467 if (fclose (fp) == EOF)
470 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
472 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
474 struct mntent **mnttbl=getmnttbl(),**ent;
475 for (ent=mnttbl;*ent;ent++)
477 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
478 me->me_devname = xstrdup ( (*ent)->mt_resource);
479 me->me_mountdir = xstrdup( (*ent)->mt_directory);
480 me->me_type = xstrdup ((*ent)->mt_fstype);
481 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
484 /* Add to the linked list. */
492 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
495 char *table = MNTTAB;
499 fp = fopen (table, "r");
503 while ((ret = getmntent (fp, &mnt)) == 0)
505 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
506 me->me_devname = xstrdup (mnt.mnt_special);
507 me->me_mountdir = xstrdup (mnt.mnt_mountp);
508 me->me_type = xstrdup (mnt.mnt_fstype);
509 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
512 /* Add to the linked list. */
519 if (fclose (fp) == EOF)
522 #endif /* MOUNTED_GETMNTENT2. */
524 #ifdef MOUNTED_VMOUNT /* AIX. */
527 char *entries, *thisent;
530 /* Ask how many bytes to allocate for the mounted filesystem info. */
531 mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
532 entries = xmalloc (bufsize);
534 /* Get the list of mounted filesystems. */
535 mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
537 for (thisent = entries; thisent < entries + bufsize;
538 thisent += vmp->vmt_length)
540 vmp = (struct vmount *) thisent;
541 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
542 if (vmp->vmt_flags & MNT_REMOTE)
546 /* Prepend the remote pathname. */
547 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
548 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
549 me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
550 strcpy (me->me_devname, host);
551 strcat (me->me_devname, ":");
552 strcat (me->me_devname, path);
556 me->me_devname = xstrdup (thisent +
557 vmp->vmt_data[VMT_OBJECT].vmt_off);
559 me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
560 me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
561 me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */
564 /* Add to the linked list. */
570 #endif /* MOUNTED_VMOUNT. */
572 /* Free the dummy head. */
574 mount_list = mount_list->me_next;