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
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19 #include <sys/types.h>
20 #include "mountlist.h"
27 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
39 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
40 # include <sys/mount.h>
41 # include <sys/fs_types.h>
42 #endif /* MOUNTED_GETFSSTAT */
44 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
47 # if defined(MNT_MNTTAB) /* HP-UX. */
48 # define MOUNTED MNT_MNTTAB
50 # if defined(MNTTABNAME) /* Dynix. */
51 # define MOUNTED MNTTABNAME
56 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
57 #include <sys/mount.h>
60 #ifdef MOUNTED_GETMNT /* Ultrix. */
61 #include <sys/param.h>
62 #include <sys/mount.h>
63 #include <sys/fs_types.h>
66 #ifdef MOUNTED_FREAD /* SVR2. */
70 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
72 #include <sys/fstyp.h>
73 #include <sys/statfs.h>
76 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
77 #include <sys/mnttab.h>
80 #ifdef MOUNTED_VMOUNT /* AIX. */
85 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
86 /* Return the value of the hexadecimal number represented by CP.
87 No prefix (like '0x') or suffix (like 'h') is expected to be
99 if (*cp >= 'a' && *cp <= 'f')
100 val = val * 16 + *cp - 'a' + 10;
101 else if (*cp >= 'A' && *cp <= 'F')
102 val = val * 16 + *cp - 'A' + 10;
103 else if (*cp >= '0' && *cp <= '9')
104 val = val * 16 + *cp - '0';
111 #endif /* MOUNTED_GETMNTENT1. */
113 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
146 #endif /* MOUNTED_GETMNTINFO */
148 #ifdef MOUNTED_VMOUNT /* AIX. */
155 e = getvfsbytype (t);
156 if (!e || !e->vfsent_name)
159 return e->vfsent_name;
161 #endif /* MOUNTED_VMOUNT */
163 /* Return a list of the currently mounted filesystems, or NULL on error.
164 Add each entry to the tail of the list so that they stay in order.
165 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
166 the returned list are valid. Otherwise, they might not be.
167 If ALL_FS is zero, do not return entries for filesystems that
168 are automounter (dummy) entries. */
171 read_filesystem_list (need_fs_type, all_fs)
172 int need_fs_type, all_fs;
174 struct mount_entry *mount_list;
175 struct mount_entry *me;
176 struct mount_entry *mtail;
178 /* Start the list off with a dummy entry. */
179 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
181 mount_list = mtail = me;
183 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
186 char *table = MOUNTED;
190 fp = setmntent (table, "r");
194 while ((mnt = getmntent (fp)))
196 if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
197 || !strcmp (mnt->mnt_type, "auto")))
200 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
201 me->me_devname = xstrdup (mnt->mnt_fsname);
202 me->me_mountdir = xstrdup (mnt->mnt_dir);
203 me->me_type = xstrdup (mnt->mnt_type);
204 devopt = strstr (mnt->mnt_opts, "dev=");
207 if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
208 me->me_dev = xatoi (devopt + 6);
210 me->me_dev = xatoi (devopt + 4);
213 me->me_dev = -1; /* Magic; means not known yet. */
216 /* Add to the linked list. */
221 if (endmntent (fp) == 0)
224 #endif /* MOUNTED_GETMNTENT1. */
226 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
231 entries = getmntinfo (&fsp, MNT_NOWAIT);
234 while (entries-- > 0)
236 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
237 me->me_devname = xstrdup (fsp->f_mntfromname);
238 me->me_mountdir = xstrdup (fsp->f_mntonname);
239 me->me_type = fstype_to_string (fsp->f_type);
240 me->me_dev = -1; /* Magic; means not known yet. */
243 /* Add to the linked list. */
249 #endif /* MOUNTED_GETMNTINFO */
251 #ifdef MOUNTED_GETMNT /* Ultrix. */
257 while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
260 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
261 me->me_devname = xstrdup (fsd.fd_req.devname);
262 me->me_mountdir = xstrdup (fsd.fd_req.path);
263 me->me_type = gt_names[fsd.fd_req.fstype];
264 me->me_dev = fsd.fd_req.dev;
267 /* Add to the linked list. */
274 #endif /* MOUNTED_GETMNT. */
276 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
278 int numsys, counter, bufsize;
279 struct statfs *stats;
281 numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
285 bufsize = (1 + numsys) * sizeof (struct statfs);
286 stats = (struct statfs *)xmalloc (bufsize);
287 numsys = getfsstat (stats, bufsize, MNT_WAIT);
295 for (counter = 0; counter < numsys; counter++)
297 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
298 me->me_devname = xstrdup (stats[counter].f_mntfromname);
299 me->me_mountdir = xstrdup (stats[counter].f_mntonname);
300 me->me_type = mnt_names[stats[counter].f_type];
301 me->me_dev = -1; /* Magic; means not known yet. */
304 /* Add to the linked list. */
311 #endif /* MOUNTED_GETFSSTAT */
313 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
316 char *table = "/etc/mnttab";
319 fp = fopen (table, "r");
323 while (fread (&mnt, sizeof mnt, 1, fp) > 0)
325 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
326 #ifdef GETFSTYP /* SVR3. */
327 me->me_devname = xstrdup (mnt.mt_dev);
329 me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
330 strcpy (me->me_devname, "/dev/");
331 strcpy (me->me_devname + 5, mnt.mt_dev);
333 me->me_mountdir = xstrdup (mnt.mt_filsys);
334 me->me_dev = -1; /* Magic; means not known yet. */
336 #ifdef GETFSTYP /* SVR3. */
340 char typebuf[FSTYPSZ];
342 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
343 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
344 me->me_type = xstrdup (typebuf);
349 /* Add to the linked list. */
354 if (fclose (fp) == EOF)
357 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
359 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
362 char *table = MNTTAB;
366 fp = fopen (table, "r");
370 while ((ret = getmntent (fp, &mnt)) == 0)
372 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
373 me->me_devname = xstrdup (mnt.mnt_special);
374 me->me_mountdir = xstrdup (mnt.mnt_mountp);
375 me->me_type = xstrdup (mnt.mnt_fstype);
376 me->me_dev = -1; /* Magic; means not known yet. */
379 /* Add to the linked list. */
386 if (fclose (fp) == EOF)
389 #endif /* MOUNTED_GETMNTENT2. */
391 #ifdef MOUNTED_VMOUNT /* AIX. */
394 char *entries, *thisent;
397 /* Ask how many bytes to allocate for the mounted filesystem info. */
398 mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
399 entries = xmalloc (bufsize);
401 /* Get the list of mounted filesystems. */
402 mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
404 for (thisent = entries; thisent < entries + bufsize;
405 thisent += vmp->vmt_length)
407 vmp = (struct vmount *) thisent;
408 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
409 if (vmp->vmt_flags & MNT_REMOTE)
413 /* Prepend the remote pathname. */
414 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
415 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
416 me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
417 strcpy (me->me_devname, host);
418 strcat (me->me_devname, ":");
419 strcat (me->me_devname, path);
423 me->me_devname = xstrdup (thisent +
424 vmp->vmt_data[VMT_OBJECT].vmt_off);
426 me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
427 me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
428 me->me_dev = -1; /* vmt_fsid might be the info we want. */
431 /* Add to the linked list. */
437 #endif /* MOUNTED_VMOUNT. */
439 /* Free the dummy head. */
441 mount_list = mount_list->me_next;