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__)
165 #endif /* MOUNTED_GETMNTINFO */
167 #ifdef MOUNTED_VMOUNT /* AIX. */
174 e = getvfsbytype (t);
175 if (!e || !e->vfsent_name)
178 return e->vfsent_name;
180 #endif /* MOUNTED_VMOUNT */
182 /* Return a list of the currently mounted filesystems, or NULL on error.
183 Add each entry to the tail of the list so that they stay in order.
184 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
185 the returned list are valid. Otherwise, they might not be.
186 If ALL_FS is zero, do not return entries for filesystems that
187 are automounter (dummy) entries. */
190 read_filesystem_list (need_fs_type, all_fs)
191 int need_fs_type, all_fs;
193 struct mount_entry *mount_list;
194 struct mount_entry *me;
195 struct mount_entry *mtail;
197 /* Start the list off with a dummy entry. */
198 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
200 mount_list = mtail = me;
202 #ifdef MOUNTED_LISTMNTENT
204 struct tabmntent *mntlist, *p;
206 struct mount_entry *me;
208 /* the third and fourth arguments could be used to filter mounts,
209 but Crays doesn't seem to have any mounts that we want to
210 remove. Specifically, automount create normal NFS mounts.
213 if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0)
218 me = (struct mount_entry*) xmalloc(sizeof (struct mount_entry));
219 me->me_devname = xstrdup(mnt->mnt_fsname);
220 me->me_mountdir = xstrdup(mnt->mnt_dir);
221 me->me_type = xstrdup(mnt->mnt_type);
228 freemntlist(mntlist);
232 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
235 char *table = MOUNTED;
239 fp = setmntent (table, "r");
243 while ((mnt = getmntent (fp)))
245 if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
246 || !strcmp (mnt->mnt_type, "auto")))
249 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
250 me->me_devname = xstrdup (mnt->mnt_fsname);
251 me->me_mountdir = xstrdup (mnt->mnt_dir);
252 me->me_type = xstrdup (mnt->mnt_type);
253 devopt = strstr (mnt->mnt_opts, "dev=");
256 if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
257 me->me_dev = xatoi (devopt + 6);
259 me->me_dev = xatoi (devopt + 4);
262 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
265 /* Add to the linked list. */
270 if (endmntent (fp) == 0)
273 #endif /* MOUNTED_GETMNTENT1. */
275 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
280 entries = getmntinfo (&fsp, MNT_NOWAIT);
283 while (entries-- > 0)
285 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
286 me->me_devname = xstrdup (fsp->f_mntfromname);
287 me->me_mountdir = xstrdup (fsp->f_mntonname);
289 me->me_type = xstrdup (fsp->f_fstypename);
291 me->me_type = fstype_to_string (fsp->f_type);
293 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
296 /* Add to the linked list. */
302 #endif /* MOUNTED_GETMNTINFO */
304 #ifdef MOUNTED_GETMNT /* Ultrix. */
310 while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
313 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
314 me->me_devname = xstrdup (fsd.fd_req.devname);
315 me->me_mountdir = xstrdup (fsd.fd_req.path);
316 me->me_type = gt_names[fsd.fd_req.fstype];
317 me->me_dev = fsd.fd_req.dev;
320 /* Add to the linked list. */
327 #endif /* MOUNTED_GETMNT. */
329 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
331 int numsys, counter, bufsize;
332 struct statfs *stats;
334 numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
338 bufsize = (1 + numsys) * sizeof (struct statfs);
339 stats = (struct statfs *)xmalloc (bufsize);
340 numsys = getfsstat (stats, bufsize, MNT_WAIT);
348 for (counter = 0; counter < numsys; counter++)
350 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
351 me->me_devname = xstrdup (stats[counter].f_mntfromname);
352 me->me_mountdir = xstrdup (stats[counter].f_mntonname);
353 me->me_type = mnt_names[stats[counter].f_type];
354 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
357 /* Add to the linked list. */
364 #endif /* MOUNTED_GETFSSTAT */
366 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
369 char *table = "/etc/mnttab";
372 fp = fopen (table, "r");
376 while (fread (&mnt, sizeof mnt, 1, fp) > 0)
378 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
379 #ifdef GETFSTYP /* SVR3. */
380 me->me_devname = xstrdup (mnt.mt_dev);
382 me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
383 strcpy (me->me_devname, "/dev/");
384 strcpy (me->me_devname + 5, mnt.mt_dev);
386 me->me_mountdir = xstrdup (mnt.mt_filsys);
387 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
389 #ifdef GETFSTYP /* SVR3. */
393 char typebuf[FSTYPSZ];
395 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
396 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
397 me->me_type = xstrdup (typebuf);
402 /* Add to the linked list. */
407 if (fclose (fp) == EOF)
410 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
412 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
414 struct mntent **mnttbl=getmnttbl(),**ent;
415 for (ent=mnttbl;*ent;ent++)
417 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
418 me->me_devname = xstrdup ( (*ent)->mt_resource);
419 me->me_mountdir = xstrdup( (*ent)->mt_directory);
420 me->me_type = xstrdup ((*ent)->mt_fstype);
421 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
424 /* Add to the linked list. */
432 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
435 char *table = MNTTAB;
439 fp = fopen (table, "r");
443 while ((ret = getmntent (fp, &mnt)) == 0)
445 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
446 me->me_devname = xstrdup (mnt.mnt_special);
447 me->me_mountdir = xstrdup (mnt.mnt_mountp);
448 me->me_type = xstrdup (mnt.mnt_fstype);
449 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
452 /* Add to the linked list. */
459 if (fclose (fp) == EOF)
462 #endif /* MOUNTED_GETMNTENT2. */
464 #ifdef MOUNTED_VMOUNT /* AIX. */
467 char *entries, *thisent;
470 /* Ask how many bytes to allocate for the mounted filesystem info. */
471 mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
472 entries = xmalloc (bufsize);
474 /* Get the list of mounted filesystems. */
475 mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
477 for (thisent = entries; thisent < entries + bufsize;
478 thisent += vmp->vmt_length)
480 vmp = (struct vmount *) thisent;
481 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
482 if (vmp->vmt_flags & MNT_REMOTE)
486 /* Prepend the remote pathname. */
487 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
488 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
489 me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
490 strcpy (me->me_devname, host);
491 strcat (me->me_devname, ":");
492 strcat (me->me_devname, path);
496 me->me_devname = xstrdup (thisent +
497 vmp->vmt_data[VMT_OBJECT].vmt_off);
499 me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
500 me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
501 me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */
504 /* Add to the linked list. */
510 #endif /* MOUNTED_VMOUNT. */
512 /* Free the dummy head. */
514 mount_list = mount_list->me_next;