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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19 * \brief Source: list of mounted filesystems
27 #include <sys/types.h>
29 /* This header needs to be included before sys/mount.h on *BSD */
30 #ifdef HAVE_SYS_PARAM_H
31 #include <sys/param.h>
34 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
35 #include <sys/mount.h>
36 #include <sys/fs_types.h>
37 #endif /* MOUNTED_GETFSSTAT */
39 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
42 #if defined(MNT_MNTTAB) /* HP-UX. */
43 #define MOUNTED MNT_MNTTAB
45 #if defined(MNTTABNAME) /* Dynix. */
46 #define MOUNTED MNTTABNAME
51 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
52 #include <sys/mount.h>
55 #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */
56 #include <sys/statvfs.h>
59 #ifdef MOUNTED_GETMNT /* Ultrix. */
60 #include <sys/mount.h>
61 #include <sys/fs_types.h>
64 #ifdef MOUNTED_FREAD /* SVR2. */
68 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
70 #include <sys/fstyp.h>
71 #include <sys/statfs.h>
74 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
75 #include <sys/mnttab.h>
78 #ifdef MOUNTED_VMOUNT /* AIX. */
83 #ifdef HAVE_SYS_STATFS_H
84 #include <sys/statfs.h>
87 #ifdef HAVE_INFOMOUNT_QNX
92 #ifdef HAVE_SYS_MOUNT_H
93 #include <sys/mount.h>
100 #ifdef HAVE_SYS_FILSYS_H
101 #include <sys/filsys.h> /* SVR2. */
104 #ifdef HAVE_DUSTAT_H /* AIX PS/2. */
105 #include <sys/dustat.h>
108 #ifdef HAVE_SYS_STATVFS_H /* SVR4. */
109 #include <sys/statvfs.h>
112 #include "lib/global.h"
113 #include "mountlist.h"
116 /* So special that it's not worth putting this in autoconf. */
117 #undef MOUNTED_FREAD_FSTYP
118 #define MOUNTED_GETMNTTBL
121 #if defined (__QNX__) && !defined(__QNXNTO__) && !defined (HAVE_INFOMOUNT_LIST)
122 # define HAVE_INFOMOUNT_QNX
125 #if defined(HAVE_INFOMOUNT_LIST) || defined(HAVE_INFOMOUNT_QNX)
126 # define HAVE_INFOMOUNT
129 /* A mount table entry. */
132 char *me_devname
; /* Device node pathname, including "/dev/". */
133 char *me_mountdir
; /* Mount point directory pathname. */
134 char *me_type
; /* "nfs", "4.2", etc. */
135 dev_t me_dev
; /* Device number of me_mountdir. */
136 struct mount_entry
*me_next
;
141 fsblkcnt_t fsu_blocks
; /* Total blocks. */
142 fsblkcnt_t fsu_bfree
; /* Free blocks available to superuser. */
143 fsblkcnt_t fsu_bavail
; /* Free blocks available to non-superuser. */
144 fsfilcnt_t fsu_files
; /* Total file nodes. */
145 fsfilcnt_t fsu_ffree
; /* Free file nodes. */
148 static int get_fs_usage (char *path
, struct fs_usage
*fsp
);
150 #ifdef HAVE_INFOMOUNT_LIST
152 static struct mount_entry
*mount_list
= NULL
;
155 free_mount_entry (struct mount_entry
*me
)
160 free (me
->me_devname
);
162 free (me
->me_mountdir
);
168 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
169 /* Return the value of the hexadecimal number represented by CP.
170 No prefix (like '0x') or suffix (like 'h') is expected to be
174 xatoi (const char *cp
)
181 if (*cp
>= 'a' && *cp
<= 'f')
182 val
= val
* 16 + *cp
- 'a' + 10;
183 else if (*cp
>= 'A' && *cp
<= 'F')
184 val
= val
* 16 + *cp
- 'A' + 10;
185 else if (*cp
>= '0' && *cp
<= '9')
186 val
= val
* 16 + *cp
- '0';
193 #endif /* MOUNTED_GETMNTENT1 */
195 #ifdef MOUNTED_GETMNTINFO
197 #ifndef HAVE_STRUCT_STATFS_F_FSTYPENAME
199 fstype_to_string (short t
)
291 #endif /* ! HAVE_STRUCT_STATFS_F_FSTYPENAME */
293 #endif /* MOUNTED_GETMNTINFO */
295 #ifdef MOUNTED_VMOUNT /* AIX. */
297 fstype_to_string (int t
)
301 e
= getvfsbytype (t
);
302 if (!e
|| !e
->vfsent_name
)
305 return e
->vfsent_name
;
307 #endif /* MOUNTED_VMOUNT */
309 /* Return a list of the currently mounted filesystems, or NULL on error.
310 Add each entry to the tail of the list so that they stay in order.
311 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
312 the returned list are valid. Otherwise, they might not be.
313 If ALL_FS is zero, do not return entries for filesystems that
314 are automounter (dummy) entries. */
316 static struct mount_entry
*
317 read_filesystem_list (int need_fs_type
, int all_fs
)
319 struct mount_entry
*mlist
;
320 struct mount_entry
*me
;
321 struct mount_entry
*mtail
;
326 /* Start the list off with a dummy entry. */
327 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
331 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
338 fp
= setmntent (MOUNTED
, "r");
342 while ((mnt
= getmntent (fp
)))
344 if (!all_fs
&& (!strcmp (mnt
->mnt_type
, "ignore") || !strcmp (mnt
->mnt_type
, "auto")))
347 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
348 me
->me_devname
= strdup (mnt
->mnt_fsname
);
349 me
->me_mountdir
= strdup (mnt
->mnt_dir
);
350 me
->me_type
= strdup (mnt
->mnt_type
);
351 devopt
= strstr (mnt
->mnt_opts
, "dev=");
354 if (devopt
[4] == '0' && (devopt
[5] == 'x' || devopt
[5] == 'X'))
355 me
->me_dev
= xatoi (devopt
+ 6);
357 me
->me_dev
= xatoi (devopt
+ 4);
360 me
->me_dev
= -1; /* Magic; means not known yet. */
363 /* Add to the linked list. */
368 if (endmntent (fp
) == 0)
372 #endif /* MOUNTED_GETMNTENT1 */
374 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
379 entries
= getmntinfo (&fsp
, MNT_NOWAIT
);
382 while (entries
-- > 0)
384 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
385 me
->me_devname
= strdup (fsp
->f_mntfromname
);
386 me
->me_mountdir
= strdup (fsp
->f_mntonname
);
387 #ifdef HAVE_STRUCT_STATFS_F_FSTYPENAME
388 me
->me_type
= strdup (fsp
->f_fstypename
);
390 me
->me_type
= fstype_to_string (fsp
->f_type
);
392 me
->me_dev
= -1; /* Magic; means not known yet. */
395 /* Add to the linked list. */
401 #endif /* MOUNTED_GETMNTINFO */
403 #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */
408 entries
= getmntinfo (&fsp
, MNT_NOWAIT
);
411 for (; entries
-- > 0; fsp
++)
413 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
414 me
->me_devname
= strdup (fsp
->f_mntfromname
);
415 me
->me_mountdir
= strdup (fsp
->f_mntonname
);
416 me
->me_type
= strdup (fsp
->f_fstypename
);
417 me
->me_dev
= (dev_t
) - 1; /* Magic; means not known yet. */
419 /* Add to the linked list. */
424 #endif /* MOUNTED_GETMNTINFO2 */
426 #ifdef MOUNTED_GETMNT /* Ultrix. */
432 while ((val
= getmnt (&offset
, &fsd
, sizeof (fsd
), NOSTAT_MANY
, NULL
)) > 0)
434 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
435 me
->me_devname
= strdup (fsd
.fd_req
.devname
);
436 me
->me_mountdir
= strdup (fsd
.fd_req
.path
);
437 me
->me_type
= gt_names
[fsd
.fd_req
.fstype
];
438 me
->me_dev
= fsd
.fd_req
.dev
;
441 /* Add to the linked list. */
448 #endif /* MOUNTED_GETMNT */
450 #ifdef MOUNTED_GETFSSTAT /* __alpha running OSF_1 */
452 int numsys
, counter
, bufsize
;
453 struct statfs
*stats
;
455 numsys
= getfsstat ((struct statfs
*) 0, 0L, MNT_WAIT
);
459 bufsize
= (1 + numsys
) * sizeof (struct statfs
);
460 stats
= (struct statfs
*) malloc (bufsize
);
461 numsys
= getfsstat (stats
, bufsize
, MNT_WAIT
);
468 for (counter
= 0; counter
< numsys
; counter
++)
470 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
471 me
->me_devname
= strdup (stats
[counter
].f_mntfromname
);
472 me
->me_mountdir
= strdup (stats
[counter
].f_mntonname
);
473 me
->me_type
= mnt_names
[stats
[counter
].f_type
];
474 me
->me_dev
= -1; /* Magic; means not known yet. */
477 /* Add to the linked list. */
484 #endif /* MOUNTED_GETFSSTAT */
486 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
489 char *table
= "/etc/mnttab";
492 fp
= fopen (table
, "r");
496 while (fread (&mnt
, sizeof mnt
, 1, fp
) > 0)
498 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
499 #ifdef GETFSTYP /* SVR3. */
500 me
->me_devname
= strdup (mnt
.mt_dev
);
502 me
->me_devname
= malloc (strlen (mnt
.mt_dev
) + 6);
503 strcpy (me
->me_devname
, "/dev/");
504 strcpy (me
->me_devname
+ 5, mnt
.mt_dev
);
506 me
->me_mountdir
= strdup (mnt
.mt_filsys
);
507 me
->me_dev
= -1; /* Magic; means not known yet. */
509 #ifdef GETFSTYP /* SVR3. */
513 char typebuf
[FSTYPSZ
];
515 if (statfs (me
->me_mountdir
, &fsd
, sizeof fsd
, 0) != -1
516 && sysfs (GETFSTYP
, fsd
.f_fstyp
, typebuf
) != -1)
517 me
->me_type
= strdup (typebuf
);
522 /* Add to the linked list. */
527 if (fclose (fp
) == EOF
)
530 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP */
532 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
534 struct mntent
**mnttbl
= getmnttbl (), **ent
;
535 for (ent
= mnttbl
; *ent
; ent
++)
537 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
538 me
->me_devname
= strdup ((*ent
)->mt_resource
);
539 me
->me_mountdir
= strdup ((*ent
)->mt_directory
);
540 me
->me_type
= strdup ((*ent
)->mt_fstype
);
541 me
->me_dev
= -1; /* Magic; means not known yet. */
544 /* Add to the linked list. */
550 #endif /* MOUNTED_GETMNTTBL */
552 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
555 char *table
= MNTTAB
;
559 fp
= fopen (table
, "r");
563 while ((ret
= getmntent (fp
, &mnt
)) == 0)
565 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
566 me
->me_devname
= strdup (mnt
.mnt_special
);
567 me
->me_mountdir
= strdup (mnt
.mnt_mountp
);
568 me
->me_type
= strdup (mnt
.mnt_fstype
);
569 me
->me_dev
= -1; /* Magic; means not known yet. */
571 /* Add to the linked list. */
578 if (fclose (fp
) == EOF
)
581 #endif /* MOUNTED_GETMNTENT2 */
583 #ifdef MOUNTED_VMOUNT /* AIX. */
586 char *entries
, *thisent
;
589 /* Ask how many bytes to allocate for the mounted filesystem info. */
590 mntctl (MCTL_QUERY
, sizeof bufsize
, (struct vmount
*) &bufsize
);
591 entries
= malloc (bufsize
);
593 /* Get the list of mounted filesystems. */
594 mntctl (MCTL_QUERY
, bufsize
, (struct vmount
*) entries
);
596 for (thisent
= entries
; thisent
< entries
+ bufsize
; thisent
+= vmp
->vmt_length
)
598 vmp
= (struct vmount
*) thisent
;
599 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
600 if (vmp
->vmt_flags
& MNT_REMOTE
)
604 /* Prepend the remote pathname. */
605 host
= thisent
+ vmp
->vmt_data
[VMT_HOSTNAME
].vmt_off
;
606 path
= thisent
+ vmp
->vmt_data
[VMT_OBJECT
].vmt_off
;
607 me
->me_devname
= malloc (strlen (host
) + strlen (path
) + 2);
608 strcpy (me
->me_devname
, host
);
609 strcat (me
->me_devname
, ":");
610 strcat (me
->me_devname
, path
);
614 me
->me_devname
= strdup (thisent
+ vmp
->vmt_data
[VMT_OBJECT
].vmt_off
);
616 me
->me_mountdir
= strdup (thisent
+ vmp
->vmt_data
[VMT_STUB
].vmt_off
);
617 me
->me_type
= strdup (fstype_to_string (vmp
->vmt_gfstype
));
618 me
->me_dev
= -1; /* vmt_fsid might be the info we want. */
621 /* Add to the linked list. */
627 #endif /* MOUNTED_VMOUNT */
629 /* Free the dummy head. */
631 mlist
= mlist
->me_next
;
635 #endif /* HAVE_INFOMOUNT_LIST */
637 #ifdef HAVE_INFOMOUNT_QNX
639 ** QNX has no [gs]etmnt*(), [gs]etfs*(), or /etc/mnttab, but can do
640 ** this via the following code.
641 ** Note that, as this is based on CWD, it only fills one mount_entry
642 ** structure. See my_statfs() in utilunix.c for the "other side" of
646 static struct mount_entry
*
647 read_filesystem_list (int need_fs_type
, int all_fs
)
649 struct _disk_entry de
;
652 char *tp
, dev
[_POSIX_NAME_MAX
], dir
[_POSIX_PATH_MAX
];
654 static struct mount_entry
*me
= NULL
;
659 free (me
->me_devname
);
661 free (me
->me_mountdir
);
666 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
668 if (!getcwd (dir
, _POSIX_PATH_MAX
))
671 if ((fd
= open (dir
, O_RDONLY
)) == -1)
674 i
= disk_get_entry (fd
, &de
);
681 switch (de
.disk_type
)
708 if (fsys_get_mount_dev (dir
, &dev
) == -1)
711 if (fsys_get_mount_pt (dev
, &dir
) == -1)
714 me
->me_devname
= strdup (dev
);
715 me
->me_mountdir
= strdup (dir
);
716 me
->me_type
= strdup (tp
);
717 me
->me_dev
= de
.disk_type
;
721 "disk_get_entry():\n\tdisk_type=%d (%s)\n\tdriver_name='%-*.*s'\n\tdisk_drv=%d\n",
722 de
.disk_type
, tp
, _DRIVER_NAME_LEN
, _DRIVER_NAME_LEN
, de
.driver_name
, de
.disk_drv
);
723 fprintf (stderr
, "fsys_get_mount_dev():\n\tdevice='%s'\n", dev
);
724 fprintf (stderr
, "fsys_get_mount_pt():\n\tmount point='%s'\n", dir
);
729 #endif /* HAVE_INFOMOUNT_QNX */
732 free_my_statfs (void)
734 #ifdef HAVE_INFOMOUNT_LIST
737 struct mount_entry
*next
= mount_list
->me_next
;
738 free_mount_entry (mount_list
);
742 #endif /* HAVE_INFOMOUNT_LIST */
747 init_my_statfs (void)
749 #ifdef HAVE_INFOMOUNT_LIST
751 mount_list
= read_filesystem_list (1, 1);
752 #endif /* HAVE_INFOMOUNT_LIST */
756 my_statfs (struct my_statfs
*myfs_stats
, const char *path
)
758 #ifdef HAVE_INFOMOUNT_LIST
760 struct mount_entry
*entry
= NULL
;
761 struct mount_entry
*temp
= mount_list
;
762 struct fs_usage fs_use
;
766 i
= strlen (temp
->me_mountdir
);
767 if (i
> len
&& (strncmp (path
, temp
->me_mountdir
, i
) == 0))
768 if (!entry
|| (path
[i
] == PATH_SEP
|| path
[i
] == 0))
773 temp
= temp
->me_next
;
778 memset (&fs_use
, 0, sizeof (struct fs_usage
));
779 get_fs_usage (entry
->me_mountdir
, &fs_use
);
781 myfs_stats
->type
= entry
->me_dev
;
782 myfs_stats
->typename
= entry
->me_type
;
783 myfs_stats
->mpoint
= entry
->me_mountdir
;
784 myfs_stats
->device
= entry
->me_devname
;
785 myfs_stats
->avail
= getuid ()? fs_use
.fsu_bavail
/ 2 : fs_use
.fsu_bfree
/ 2;
786 myfs_stats
->total
= fs_use
.fsu_blocks
/ 2;
787 myfs_stats
->nfree
= fs_use
.fsu_ffree
;
788 myfs_stats
->nodes
= fs_use
.fsu_files
;
791 #endif /* HAVE_INFOMOUNT_LIST */
793 #ifdef HAVE_INFOMOUNT_QNX
795 ** This is the "other side" of the hack to read_filesystem_list() in
797 ** It's not the most efficient approach, but consumes less memory. It
798 ** also accomodates QNX's ability to mount filesystems on the fly.
800 struct mount_entry
*entry
;
801 struct fs_usage fs_use
;
803 if ((entry
= read_filesystem_list (0, 0)) != NULL
)
805 get_fs_usage (entry
->me_mountdir
, &fs_use
);
807 myfs_stats
->type
= entry
->me_dev
;
808 myfs_stats
->typename
= entry
->me_type
;
809 myfs_stats
->mpoint
= entry
->me_mountdir
;
810 myfs_stats
->device
= entry
->me_devname
;
812 myfs_stats
->avail
= fs_use
.fsu_bfree
/ 2;
813 myfs_stats
->total
= fs_use
.fsu_blocks
/ 2;
814 myfs_stats
->nfree
= fs_use
.fsu_ffree
;
815 myfs_stats
->nodes
= fs_use
.fsu_files
;
818 #endif /* HAVE_INFOMOUNT_QNX */
820 myfs_stats
->type
= 0;
821 myfs_stats
->mpoint
= "unknown";
822 myfs_stats
->device
= "unknown";
823 myfs_stats
->avail
= 0;
824 myfs_stats
->total
= 0;
825 myfs_stats
->nfree
= 0;
826 myfs_stats
->nodes
= 0;
830 #ifdef HAVE_INFOMOUNT
832 /* Return the number of TOSIZE-byte blocks used by
833 BLOCKS FROMSIZE-byte blocks, rounding away from zero.
834 TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */
837 fs_adjust_blocks (fsblkcnt_t blocks
, int fromsize
, int tosize
)
844 if (fromsize
== tosize
) /* E.g., from 512 to 512. */
846 else if (fromsize
> tosize
) /* E.g., from 2048 to 512. */
847 return blocks
* (fromsize
/ tosize
);
848 else /* E.g., from 256 to 512. */
849 return blocks
/ (tosize
/ fromsize
);
852 #if defined(_AIX) && defined(_I386)
853 /* AIX PS/2 does not supply statfs. */
855 aix_statfs (char *path
, struct statfs
*fsb
)
860 if (stat (path
, &stats
))
862 if (dustat (stats
.st_dev
, 0, &fsd
, sizeof (fsd
)))
865 fsb
->f_bsize
= fsd
.du_bsize
;
866 fsb
->f_blocks
= fsd
.du_fsize
- fsd
.du_isize
;
867 fsb
->f_bfree
= fsd
.du_tfree
;
868 fsb
->f_bavail
= fsd
.du_tfree
;
869 fsb
->f_files
= (fsd
.du_isize
- 2) * fsd
.du_inopb
;
870 fsb
->f_ffree
= fsd
.du_tinode
;
871 fsb
->f_fsid
.val
[0] = fsd
.du_site
;
872 fsb
->f_fsid
.val
[1] = fsd
.du_pckno
;
876 #define statfs(path,fsb) aix_statfs(path,fsb)
877 #endif /* _AIX && _I386 */
879 /* Fill in the fields of FSP with information about space usage for
880 the filesystem on which PATH resides.
881 Return 0 if successful, -1 if not. */
884 get_fs_usage (char *path
, struct fs_usage
*fsp
)
886 #ifdef STAT_STATFS3_OSF1
889 if (statfs (path
, &fsd
, sizeof (struct statfs
)) != 0)
891 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), fsd.f_fsize, 512)
892 #endif /* STAT_STATFS3_OSF1 */
894 #ifdef STAT_STATFS2_FS_DATA /* Ultrix. */
897 if (statfs (path
, &fsd
) != 1)
899 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), 1024, 512)
900 fsp
->fsu_blocks
= CONVERT_BLOCKS (fsd
.fd_req
.btot
);
901 fsp
->fsu_bfree
= CONVERT_BLOCKS (fsd
.fd_req
.bfree
);
902 fsp
->fsu_bavail
= CONVERT_BLOCKS (fsd
.fd_req
.bfreen
);
903 fsp
->fsu_files
= fsd
.fd_req
.gtot
;
904 fsp
->fsu_ffree
= fsd
.fd_req
.gfree
;
907 #ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX. */
910 if (statfs (path
, &fsd
) < 0)
912 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), fsd.f_bsize, 512)
915 #ifdef STAT_STATFS2_FSIZE /* 4.4BSD. */
918 if (statfs (path
, &fsd
) < 0)
920 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), fsd.f_fsize, 512)
923 #ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX. */
926 if (statfs (path
, &fsd
, sizeof fsd
, 0) < 0)
928 /* Empirically, the block counts on most SVR3 and SVR3-derived
929 systems seem to always be in terms of 512-byte blocks,
930 no matter what value f_bsize has. */
932 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), fsd.f_bsize, 512)
934 #define CONVERT_BLOCKS(b) (b)
935 #ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx. */
936 #ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */
937 #define f_bavail f_bfree
943 #ifdef STAT_STATVFS /* SVR4. */
946 if (statvfs (path
, &fsd
) < 0)
948 /* f_frsize isn't guaranteed to be supported. */
949 #define CONVERT_BLOCKS(b) \
950 fs_adjust_blocks ((b), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512)
953 #if defined(CONVERT_BLOCKS) && !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ_FILSYS) /* !Ultrix && !SVR2. */
954 fsp
->fsu_blocks
= CONVERT_BLOCKS (fsd
.f_blocks
);
955 fsp
->fsu_bfree
= CONVERT_BLOCKS (fsd
.f_bfree
);
956 fsp
->fsu_bavail
= CONVERT_BLOCKS (fsd
.f_bavail
);
957 fsp
->fsu_files
= fsd
.f_files
;
958 fsp
->fsu_ffree
= fsd
.f_ffree
;
964 #endif /* HAVE_INFOMOUNT */