1 /* mountlist.c -- return a list of mounted filesystems
2 Copyright (C) 1991, 1992, 1997 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. */
54 # if !defined(MOUNTED)
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 HAVE_SYS_MNTENT_H
103 /* This is to get MNTOPT_IGNORE on e.g. SVR4. */
104 # include <sys/mntent.h>
107 #if defined (MNTOPT_IGNORE) && defined (HAVE_HASMNTOPT)
108 # define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE)
110 # define MNT_IGNORE(M) 0
113 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
114 /* Return the value of the hexadecimal number represented by CP.
115 No prefix (like '0x') or suffix (like 'h') is expected to be
127 if (*cp
>= 'a' && *cp
<= 'f')
128 val
= val
* 16 + *cp
- 'a' + 10;
129 else if (*cp
>= 'A' && *cp
<= 'F')
130 val
= val
* 16 + *cp
- 'A' + 10;
131 else if (*cp
>= '0' && *cp
<= '9')
132 val
= val
* 16 + *cp
- '0';
139 #endif /* MOUNTED_GETMNTENT1. */
141 #if defined (MOUNTED_GETMNTINFO) && !defined (__NetBSD__) && !defined (__OpenBSD__)
236 #endif /* MOUNTED_GETMNTINFO */
238 #ifdef MOUNTED_VMOUNT /* AIX. */
245 e
= getvfsbytype (t
);
246 if (!e
|| !e
->vfsent_name
)
249 return e
->vfsent_name
;
251 #endif /* MOUNTED_VMOUNT */
253 /* Return a list of the currently mounted filesystems, or NULL on error.
254 Add each entry to the tail of the list so that they stay in order.
255 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
256 the returned list are valid. Otherwise, they might not be.
257 If ALL_FS is zero, do not return entries for filesystems that
258 are automounter (dummy) entries. */
261 read_filesystem_list (need_fs_type
, all_fs
)
262 int need_fs_type
, all_fs
;
264 struct mount_entry
*mount_list
;
265 struct mount_entry
*me
;
266 struct mount_entry
*mtail
;
268 /* Start the list off with a dummy entry. */
269 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
271 mount_list
= mtail
= me
;
273 #ifdef MOUNTED_LISTMNTENT
275 struct tabmntent
*mntlist
, *p
;
277 struct mount_entry
*me
;
279 /* the third and fourth arguments could be used to filter mounts,
280 but Crays doesn't seem to have any mounts that we want to
281 remove. Specifically, automount create normal NFS mounts.
284 if(listmntent(&mntlist
, KMTAB
, NULL
, NULL
) < 0)
289 me
= (struct mount_entry
*) xmalloc(sizeof (struct mount_entry
));
290 me
->me_devname
= xstrdup(mnt
->mnt_fsname
);
291 me
->me_mountdir
= xstrdup(mnt
->mnt_dir
);
292 me
->me_type
= xstrdup(mnt
->mnt_type
);
299 freemntlist(mntlist
);
303 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
306 char *table
= MOUNTED
;
310 fp
= setmntent (table
, "r");
314 while ((mnt
= getmntent (fp
)))
316 if (!all_fs
&& (!strcmp (mnt
->mnt_type
, "ignore")
317 || !strcmp (mnt
->mnt_type
, "auto")))
320 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
321 me
->me_devname
= xstrdup (mnt
->mnt_fsname
);
322 me
->me_mountdir
= xstrdup (mnt
->mnt_dir
);
323 me
->me_type
= xstrdup (mnt
->mnt_type
);
324 devopt
= strstr (mnt
->mnt_opts
, "dev=");
327 if (devopt
[4] == '0' && (devopt
[5] == 'x' || devopt
[5] == 'X'))
328 me
->me_dev
= xatoi (devopt
+ 6);
330 me
->me_dev
= xatoi (devopt
+ 4);
333 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
336 /* Add to the linked list. */
341 if (endmntent (fp
) == 0)
344 #endif /* MOUNTED_GETMNTENT1. */
346 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
351 entries
= getmntinfo (&fsp
, MNT_NOWAIT
);
354 while (entries
-- > 0)
356 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
357 me
->me_devname
= xstrdup (fsp
->f_mntfromname
);
358 me
->me_mountdir
= xstrdup (fsp
->f_mntonname
);
359 # if defined (__NetBSD__) || defined (__OpenBSD__)
360 me
->me_type
= xstrdup (fsp
->f_fstypename
);
362 me
->me_type
= fstype_to_string (fsp
->f_type
);
364 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
367 /* Add to the linked list. */
373 #endif /* MOUNTED_GETMNTINFO */
375 #ifdef MOUNTED_GETMNT /* Ultrix. */
381 while ((val
= getmnt (&offset
, &fsd
, sizeof (fsd
), NOSTAT_MANY
,
384 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
385 me
->me_devname
= xstrdup (fsd
.fd_req
.devname
);
386 me
->me_mountdir
= xstrdup (fsd
.fd_req
.path
);
387 me
->me_type
= gt_names
[fsd
.fd_req
.fstype
];
388 me
->me_dev
= fsd
.fd_req
.dev
;
391 /* Add to the linked list. */
398 #endif /* MOUNTED_GETMNT. */
400 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
402 int numsys
, counter
, bufsize
;
403 struct statfs
*stats
;
405 numsys
= getfsstat ((struct statfs
*)0, 0L, MNT_WAIT
);
409 bufsize
= (1 + numsys
) * sizeof (struct statfs
);
410 stats
= (struct statfs
*)xmalloc (bufsize
);
411 numsys
= getfsstat (stats
, bufsize
, MNT_WAIT
);
419 for (counter
= 0; counter
< numsys
; counter
++)
421 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
422 me
->me_devname
= xstrdup (stats
[counter
].f_mntfromname
);
423 me
->me_mountdir
= xstrdup (stats
[counter
].f_mntonname
);
424 me
->me_type
= mnt_names
[stats
[counter
].f_type
];
425 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
428 /* Add to the linked list. */
435 #endif /* MOUNTED_GETFSSTAT */
437 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
440 char *table
= "/etc/mnttab";
443 fp
= fopen (table
, "r");
447 while (fread (&mnt
, sizeof mnt
, 1, fp
) > 0)
449 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
450 # ifdef GETFSTYP /* SVR3. */
451 me
->me_devname
= xstrdup (mnt
.mt_dev
);
453 me
->me_devname
= xmalloc (strlen (mnt
.mt_dev
) + 6);
454 strcpy (me
->me_devname
, "/dev/");
455 strcpy (me
->me_devname
+ 5, mnt
.mt_dev
);
457 me
->me_mountdir
= xstrdup (mnt
.mt_filsys
);
458 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
460 # ifdef GETFSTYP /* SVR3. */
464 char typebuf
[FSTYPSZ
];
466 if (statfs (me
->me_mountdir
, &fsd
, sizeof fsd
, 0) != -1
467 && sysfs (GETFSTYP
, fsd
.f_fstyp
, typebuf
) != -1)
468 me
->me_type
= xstrdup (typebuf
);
473 /* Add to the linked list. */
478 if (fclose (fp
) == EOF
)
481 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
483 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
485 struct mntent
**mnttbl
=getmnttbl(),**ent
;
486 for (ent
=mnttbl
;*ent
;ent
++)
488 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
489 me
->me_devname
= xstrdup ( (*ent
)->mt_resource
);
490 me
->me_mountdir
= xstrdup( (*ent
)->mt_directory
);
491 me
->me_type
= xstrdup ((*ent
)->mt_fstype
);
492 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
495 /* Add to the linked list. */
503 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
506 char *table
= MNTTAB
;
510 fp
= fopen (table
, "r");
514 while ((ret
= getmntent (fp
, &mnt
)) == 0)
516 /* Don't show automounted filesystems twice on e.g., Solaris. */
517 if (!all_fs
&& MNT_IGNORE (&mnt
))
520 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
521 me
->me_devname
= xstrdup (mnt
.mnt_special
);
522 me
->me_mountdir
= xstrdup (mnt
.mnt_mountp
);
523 me
->me_type
= xstrdup (mnt
.mnt_fstype
);
524 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
527 /* Add to the linked list. */
534 if (fclose (fp
) == EOF
)
537 #endif /* MOUNTED_GETMNTENT2. */
539 #ifdef MOUNTED_VMOUNT /* AIX. */
542 char *entries
, *thisent
;
545 /* Ask how many bytes to allocate for the mounted filesystem info. */
546 mntctl (MCTL_QUERY
, sizeof bufsize
, (struct vmount
*) &bufsize
);
547 entries
= xmalloc (bufsize
);
549 /* Get the list of mounted filesystems. */
550 mntctl (MCTL_QUERY
, bufsize
, (struct vmount
*) entries
);
552 for (thisent
= entries
; thisent
< entries
+ bufsize
;
553 thisent
+= vmp
->vmt_length
)
555 vmp
= (struct vmount
*) thisent
;
556 me
= (struct mount_entry
*) xmalloc (sizeof (struct mount_entry
));
557 if (vmp
->vmt_flags
& MNT_REMOTE
)
561 /* Prepend the remote pathname. */
562 host
= thisent
+ vmp
->vmt_data
[VMT_HOSTNAME
].vmt_off
;
563 path
= thisent
+ vmp
->vmt_data
[VMT_OBJECT
].vmt_off
;
564 me
->me_devname
= xmalloc (strlen (host
) + strlen (path
) + 2);
565 strcpy (me
->me_devname
, host
);
566 strcat (me
->me_devname
, ":");
567 strcat (me
->me_devname
, path
);
571 me
->me_devname
= xstrdup (thisent
+
572 vmp
->vmt_data
[VMT_OBJECT
].vmt_off
);
574 me
->me_mountdir
= xstrdup (thisent
+ vmp
->vmt_data
[VMT_STUB
].vmt_off
);
575 me
->me_type
= xstrdup (fstype_to_string (vmp
->vmt_gfstype
));
576 me
->me_dev
= (dev_t
) -1; /* vmt_fsid might be the info we want. */
579 /* Add to the linked list. */
585 #endif /* MOUNTED_VMOUNT. */
587 /* Free the dummy head. */
589 mount_list
= mount_list
->me_next
;