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. */
23 #include <sys/types.h>
25 /* This header needs to be included before sys/mount.h on *BSD */
26 #ifdef HAVE_SYS_PARAM_H
27 #include <sys/param.h>
30 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
31 #include <sys/mount.h>
32 #include <sys/fs_types.h>
33 #endif /* MOUNTED_GETFSSTAT */
35 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
38 #if defined(MNT_MNTTAB) /* HP-UX. */
39 #define MOUNTED MNT_MNTTAB
41 #if defined(MNTTABNAME) /* Dynix. */
42 #define MOUNTED MNTTABNAME
47 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
48 #include <sys/mount.h>
51 #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */
52 #include <sys/statvfs.h>
55 #ifdef MOUNTED_GETMNT /* Ultrix. */
56 #include <sys/mount.h>
57 #include <sys/fs_types.h>
60 #ifdef MOUNTED_FREAD /* SVR2. */
64 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
66 #include <sys/fstyp.h>
67 #include <sys/statfs.h>
70 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
71 #include <sys/mnttab.h>
74 #ifdef MOUNTED_VMOUNT /* AIX. */
79 #ifdef HAVE_SYS_STATFS_H
80 #include <sys/statfs.h>
83 #ifdef HAVE_INFOMOUNT_QNX
88 #ifdef HAVE_SYS_MOUNT_H
89 #include <sys/mount.h>
96 #ifdef HAVE_SYS_FILSYS_H
97 #include <sys/filsys.h> /* SVR2. */
100 #ifdef HAVE_DUSTAT_H /* AIX PS/2. */
101 #include <sys/dustat.h>
104 #ifdef HAVE_SYS_STATVFS_H /* SVR4. */
105 #include <sys/statvfs.h>
109 #include "mountlist.h"
113 /* So special that it's not worth putting this in autoconf. */
114 #undef MOUNTED_FREAD_FSTYP
115 #define MOUNTED_GETMNTTBL
118 #if defined (__QNX__) && !defined(__QNXNTO__) && !defined (HAVE_INFOMOUNT_LIST)
119 # define HAVE_INFOMOUNT_QNX
122 #if defined(HAVE_INFOMOUNT_LIST) || defined(HAVE_INFOMOUNT_QNX)
123 # define HAVE_INFOMOUNT
126 /* A mount table entry. */
129 char *me_devname
; /* Device node pathname, including "/dev/". */
130 char *me_mountdir
; /* Mount point directory pathname. */
131 char *me_type
; /* "nfs", "4.2", etc. */
132 dev_t me_dev
; /* Device number of me_mountdir. */
133 struct mount_entry
*me_next
;
138 long fsu_blocks
; /* Total blocks. */
139 long fsu_bfree
; /* Free blocks available to superuser. */
140 long fsu_bavail
; /* Free blocks available to non-superuser. */
141 long fsu_files
; /* Total file nodes. */
142 long fsu_ffree
; /* Free file nodes. */
145 static int get_fs_usage (char *path
, struct fs_usage
*fsp
);
147 #ifdef HAVE_INFOMOUNT_LIST
149 static struct mount_entry
*mount_list
= NULL
;
151 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
152 /* Return the value of the hexadecimal number represented by CP.
153 No prefix (like '0x') or suffix (like 'h') is expected to be
156 static int xatoi (const char *cp
)
162 if (*cp
>= 'a' && *cp
<= 'f')
163 val
= val
* 16 + *cp
- 'a' + 10;
164 else if (*cp
>= 'A' && *cp
<= 'F')
165 val
= val
* 16 + *cp
- 'A' + 10;
166 else if (*cp
>= '0' && *cp
<= '9')
167 val
= val
* 16 + *cp
- '0';
174 #endif /* MOUNTED_GETMNTENT1 */
176 #ifdef MOUNTED_GETMNTINFO
178 #ifndef HAVE_STRUCT_STATFS_F_FSTYPENAME
179 static char *fstype_to_string (short t
)
270 #endif /* ! HAVE_STRUCT_STATFS_F_FSTYPENAME */
272 #endif /* MOUNTED_GETMNTINFO */
274 #ifdef MOUNTED_VMOUNT /* AIX. */
276 fstype_to_string (int t
)
280 e
= getvfsbytype (t
);
281 if (!e
|| !e
->vfsent_name
)
284 return e
->vfsent_name
;
286 #endif /* MOUNTED_VMOUNT */
288 /* Return a list of the currently mounted filesystems, or NULL on error.
289 Add each entry to the tail of the list so that they stay in order.
290 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
291 the returned list are valid. Otherwise, they might not be.
292 If ALL_FS is zero, do not return entries for filesystems that
293 are automounter (dummy) entries. */
295 static struct mount_entry
*
296 read_filesystem_list (int need_fs_type
, int all_fs
)
298 struct mount_entry
*mlist
;
299 struct mount_entry
*me
;
300 struct mount_entry
*mtail
;
305 /* Start the list off with a dummy entry. */
306 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
310 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
317 fp
= setmntent (MOUNTED
, "r");
321 while ((mnt
= getmntent (fp
))) {
322 if (!all_fs
&& (!strcmp (mnt
->mnt_type
, "ignore")
323 || !strcmp (mnt
->mnt_type
, "auto")))
326 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
327 me
->me_devname
= strdup (mnt
->mnt_fsname
);
328 me
->me_mountdir
= strdup (mnt
->mnt_dir
);
329 me
->me_type
= strdup (mnt
->mnt_type
);
330 devopt
= strstr (mnt
->mnt_opts
, "dev=");
332 if (devopt
[4] == '0' && (devopt
[5] == 'x' || devopt
[5] == 'X'))
333 me
->me_dev
= xatoi (devopt
+ 6);
335 me
->me_dev
= xatoi (devopt
+ 4);
337 me
->me_dev
= -1; /* Magic; means not known yet. */
340 /* Add to the linked list. */
345 if (endmntent (fp
) == 0)
349 #endif /* MOUNTED_GETMNTENT1 */
351 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
356 entries
= getmntinfo (&fsp
, MNT_NOWAIT
);
359 while (entries
-- > 0) {
360 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
361 me
->me_devname
= strdup (fsp
->f_mntfromname
);
362 me
->me_mountdir
= strdup (fsp
->f_mntonname
);
363 #ifdef HAVE_STRUCT_STATFS_F_FSTYPENAME
364 me
->me_type
= strdup (fsp
->f_fstypename
);
366 me
->me_type
= fstype_to_string (fsp
->f_type
);
368 me
->me_dev
= -1; /* Magic; means not known yet. */
371 /* Add to the linked list. */
377 #endif /* MOUNTED_GETMNTINFO */
379 #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */
384 entries
= getmntinfo (&fsp
, MNT_NOWAIT
);
387 for (; entries
-- > 0; fsp
++) {
388 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
389 me
->me_devname
= strdup (fsp
->f_mntfromname
);
390 me
->me_mountdir
= strdup (fsp
->f_mntonname
);
391 me
->me_type
= strdup (fsp
->f_fstypename
);
392 me
->me_dev
= (dev_t
) -1; /* Magic; means not known yet. */
394 /* Add to the linked list. */
399 #endif /* MOUNTED_GETMNTINFO2 */
401 #ifdef MOUNTED_GETMNT /* Ultrix. */
407 while ((val
= getmnt (&offset
, &fsd
, sizeof (fsd
), NOSTAT_MANY
,
409 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
410 me
->me_devname
= strdup (fsd
.fd_req
.devname
);
411 me
->me_mountdir
= strdup (fsd
.fd_req
.path
);
412 me
->me_type
= gt_names
[fsd
.fd_req
.fstype
];
413 me
->me_dev
= fsd
.fd_req
.dev
;
416 /* Add to the linked list. */
423 #endif /* MOUNTED_GETMNT */
425 #ifdef MOUNTED_GETFSSTAT /* __alpha running OSF_1 */
427 int numsys
, counter
, bufsize
;
428 struct statfs
*stats
;
430 numsys
= getfsstat ((struct statfs
*) 0, 0L, MNT_WAIT
);
434 bufsize
= (1 + numsys
) * sizeof (struct statfs
);
435 stats
= (struct statfs
*) malloc (bufsize
);
436 numsys
= getfsstat (stats
, bufsize
, MNT_WAIT
);
442 for (counter
= 0; counter
< numsys
; counter
++) {
443 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
444 me
->me_devname
= strdup (stats
[counter
].f_mntfromname
);
445 me
->me_mountdir
= strdup (stats
[counter
].f_mntonname
);
446 me
->me_type
= mnt_names
[stats
[counter
].f_type
];
447 me
->me_dev
= -1; /* Magic; means not known yet. */
450 /* Add to the linked list. */
457 #endif /* MOUNTED_GETFSSTAT */
459 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
462 char *table
= "/etc/mnttab";
465 fp
= fopen (table
, "r");
469 while (fread (&mnt
, sizeof mnt
, 1, fp
) > 0) {
470 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
471 #ifdef GETFSTYP /* SVR3. */
472 me
->me_devname
= strdup (mnt
.mt_dev
);
474 me
->me_devname
= malloc (strlen (mnt
.mt_dev
) + 6);
475 strcpy (me
->me_devname
, "/dev/");
476 strcpy (me
->me_devname
+ 5, mnt
.mt_dev
);
478 me
->me_mountdir
= strdup (mnt
.mt_filsys
);
479 me
->me_dev
= -1; /* Magic; means not known yet. */
481 #ifdef GETFSTYP /* SVR3. */
484 char typebuf
[FSTYPSZ
];
486 if (statfs (me
->me_mountdir
, &fsd
, sizeof fsd
, 0) != -1
487 && sysfs (GETFSTYP
, fsd
.f_fstyp
, typebuf
) != -1)
488 me
->me_type
= strdup (typebuf
);
493 /* Add to the linked list. */
498 if (fclose (fp
) == EOF
)
501 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP */
503 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
505 struct mntent
**mnttbl
= getmnttbl (), **ent
;
506 for (ent
= mnttbl
; *ent
; ent
++) {
507 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
508 me
->me_devname
= strdup ((*ent
)->mt_resource
);
509 me
->me_mountdir
= strdup ((*ent
)->mt_directory
);
510 me
->me_type
= strdup ((*ent
)->mt_fstype
);
511 me
->me_dev
= -1; /* Magic; means not known yet. */
514 /* Add to the linked list. */
520 #endif /* MOUNTED_GETMNTTBL */
522 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
525 char *table
= MNTTAB
;
529 fp
= fopen (table
, "r");
533 while ((ret
= getmntent (fp
, &mnt
)) == 0) {
534 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
535 me
->me_devname
= strdup (mnt
.mnt_special
);
536 me
->me_mountdir
= strdup (mnt
.mnt_mountp
);
537 me
->me_type
= strdup (mnt
.mnt_fstype
);
538 me
->me_dev
= -1; /* Magic; means not known yet. */
540 /* Add to the linked list. */
547 if (fclose (fp
) == EOF
)
550 #endif /* MOUNTED_GETMNTENT2 */
552 #ifdef MOUNTED_VMOUNT /* AIX. */
555 char *entries
, *thisent
;
558 /* Ask how many bytes to allocate for the mounted filesystem info. */
559 mntctl (MCTL_QUERY
, sizeof bufsize
, (struct vmount
*) &bufsize
);
560 entries
= malloc (bufsize
);
562 /* Get the list of mounted filesystems. */
563 mntctl (MCTL_QUERY
, bufsize
, (struct vmount
*) entries
);
565 for (thisent
= entries
; thisent
< entries
+ bufsize
;
566 thisent
+= vmp
->vmt_length
) {
567 vmp
= (struct vmount
*) thisent
;
568 me
= (struct mount_entry
*) malloc (sizeof (struct mount_entry
));
569 if (vmp
->vmt_flags
& MNT_REMOTE
) {
572 /* Prepend the remote pathname. */
573 host
= thisent
+ vmp
->vmt_data
[VMT_HOSTNAME
].vmt_off
;
574 path
= thisent
+ vmp
->vmt_data
[VMT_OBJECT
].vmt_off
;
575 me
->me_devname
= malloc (strlen (host
) + strlen (path
) + 2);
576 strcpy (me
->me_devname
, host
);
577 strcat (me
->me_devname
, ":");
578 strcat (me
->me_devname
, path
);
580 me
->me_devname
= strdup (thisent
+
581 vmp
->vmt_data
[VMT_OBJECT
].vmt_off
);
583 me
->me_mountdir
= strdup (thisent
+ vmp
->vmt_data
[VMT_STUB
].vmt_off
);
584 me
->me_type
= strdup (fstype_to_string (vmp
->vmt_gfstype
));
585 me
->me_dev
= -1; /* vmt_fsid might be the info we want. */
588 /* Add to the linked list. */
594 #endif /* MOUNTED_VMOUNT */
596 /* Free the dummy head. */
598 mlist
= mlist
->me_next
;
602 #endif /* HAVE_INFOMOUNT_LIST */
604 #ifdef HAVE_INFOMOUNT_QNX
606 ** QNX has no [gs]etmnt*(), [gs]etfs*(), or /etc/mnttab, but can do
607 ** this via the following code.
608 ** Note that, as this is based on CWD, it only fills one mount_entry
609 ** structure. See my_statfs() in utilunix.c for the "other side" of
613 static struct mount_entry
*
614 read_filesystem_list(int need_fs_type
, int all_fs
)
616 struct _disk_entry de
;
619 char *tp
, dev
[_POSIX_NAME_MAX
], dir
[_POSIX_PATH_MAX
];
621 static struct mount_entry
*me
= NULL
;
625 if (me
->me_devname
) free(me
->me_devname
);
626 if (me
->me_mountdir
) free(me
->me_mountdir
);
627 if (me
->me_type
) free(me
->me_type
);
630 me
= (struct mount_entry
*)malloc(sizeof(struct mount_entry
));
632 if (!getcwd(dir
, _POSIX_PATH_MAX
)) return (NULL
);
634 if ((fd
= open(dir
, O_RDONLY
)) == -1) return (NULL
);
636 i
= disk_get_entry(fd
, &de
);
640 if (i
== -1) return (NULL
);
642 switch (de
.disk_type
)
644 case _UNMOUNTED
: tp
= "unmounted"; break;
645 case _FLOPPY
: tp
= "Floppy"; break;
646 case _HARD
: tp
= "Hard"; break;
647 case _RAMDISK
: tp
= "Ram"; break;
648 case _REMOVABLE
: tp
= "Removable"; break;
649 case _TAPE
: tp
= "Tape"; break;
650 case _CDROM
: tp
= "CDROM"; break;
651 default: tp
= "unknown";
654 if (fsys_get_mount_dev(dir
, &dev
) == -1) return (NULL
);
656 if (fsys_get_mount_pt(dev
, &dir
) == -1) return (NULL
);
658 me
->me_devname
= strdup(dev
);
659 me
->me_mountdir
= strdup(dir
);
660 me
->me_type
= strdup(tp
);
661 me
->me_dev
= de
.disk_type
;
664 fprintf(stderr
, "disk_get_entry():\n\tdisk_type=%d (%s)\n\tdriver_name='%-*.*s'\n\tdisk_drv=%d\n",
665 de
.disk_type
, tp
, _DRIVER_NAME_LEN
, _DRIVER_NAME_LEN
, de
.driver_name
, de
.disk_drv
);
666 fprintf(stderr
, "fsys_get_mount_dev():\n\tdevice='%s'\n", dev
);
667 fprintf(stderr
, "fsys_get_mount_pt():\n\tmount point='%s'\n", dir
);
672 #endif /* HAVE_INFOMOUNT_QNX */
675 init_my_statfs (void)
677 #ifdef HAVE_INFOMOUNT_LIST
678 mount_list
= read_filesystem_list (1, 1);
679 #endif /* HAVE_INFOMOUNT_LIST */
683 my_statfs (struct my_statfs
*myfs_stats
, const char *path
)
685 #ifdef HAVE_INFOMOUNT_LIST
687 struct mount_entry
*entry
= NULL
;
688 struct mount_entry
*temp
= mount_list
;
689 struct fs_usage fs_use
;
692 i
= strlen (temp
->me_mountdir
);
693 if (i
> len
&& (strncmp (path
, temp
->me_mountdir
, i
) == 0))
694 if (!entry
|| (path
[i
] == PATH_SEP
|| path
[i
] == 0)){
698 temp
= temp
->me_next
;
702 memset (&fs_use
, 0, sizeof (struct fs_usage
));
703 get_fs_usage (entry
->me_mountdir
, &fs_use
);
705 myfs_stats
->type
= entry
->me_dev
;
706 myfs_stats
->typename
= entry
->me_type
;
707 myfs_stats
->mpoint
= entry
->me_mountdir
;
708 myfs_stats
->device
= entry
->me_devname
;
709 myfs_stats
->avail
= getuid () ? fs_use
.fsu_bavail
/2 : fs_use
.fsu_bfree
/2;
710 myfs_stats
->total
= fs_use
.fsu_blocks
/2;
711 myfs_stats
->nfree
= fs_use
.fsu_ffree
;
712 myfs_stats
->nodes
= fs_use
.fsu_files
;
714 #endif /* HAVE_INFOMOUNT_LIST */
716 #ifdef HAVE_INFOMOUNT_QNX
718 ** This is the "other side" of the hack to read_filesystem_list() in
720 ** It's not the most efficient approach, but consumes less memory. It
721 ** also accomodates QNX's ability to mount filesystems on the fly.
723 struct mount_entry
*entry
;
724 struct fs_usage fs_use
;
726 if ((entry
= read_filesystem_list(0, 0)) != NULL
)
728 get_fs_usage(entry
->me_mountdir
, &fs_use
);
730 myfs_stats
->type
= entry
->me_dev
;
731 myfs_stats
->typename
= entry
->me_type
;
732 myfs_stats
->mpoint
= entry
->me_mountdir
;
733 myfs_stats
->device
= entry
->me_devname
;
735 myfs_stats
->avail
= fs_use
.fsu_bfree
/ 2;
736 myfs_stats
->total
= fs_use
.fsu_blocks
/ 2;
737 myfs_stats
->nfree
= fs_use
.fsu_ffree
;
738 myfs_stats
->nodes
= fs_use
.fsu_files
;
741 #endif /* HAVE_INFOMOUNT_QNX */
743 myfs_stats
->type
= 0;
744 myfs_stats
->mpoint
= "unknown";
745 myfs_stats
->device
= "unknown";
746 myfs_stats
->avail
= 0;
747 myfs_stats
->total
= 0;
748 myfs_stats
->nfree
= 0;
749 myfs_stats
->nodes
= 0;
753 #ifdef HAVE_INFOMOUNT
755 /* Return the number of TOSIZE-byte blocks used by
756 BLOCKS FROMSIZE-byte blocks, rounding away from zero.
757 TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */
760 fs_adjust_blocks (long blocks
, int fromsize
, int tosize
)
767 if (fromsize
== tosize
) /* E.g., from 512 to 512. */
769 else if (fromsize
> tosize
) /* E.g., from 2048 to 512. */
770 return blocks
* (fromsize
/ tosize
);
771 else /* E.g., from 256 to 512. */
772 return (blocks
+ (blocks
< 0 ? -1 : 1)) / (tosize
/ fromsize
);
775 #if defined(_AIX) && defined(_I386)
776 /* AIX PS/2 does not supply statfs. */
777 static int aix_statfs (char *path
, struct statfs
*fsb
)
782 if (stat (path
, &stats
))
784 if (dustat (stats
.st_dev
, 0, &fsd
, sizeof (fsd
)))
787 fsb
->f_bsize
= fsd
.du_bsize
;
788 fsb
->f_blocks
= fsd
.du_fsize
- fsd
.du_isize
;
789 fsb
->f_bfree
= fsd
.du_tfree
;
790 fsb
->f_bavail
= fsd
.du_tfree
;
791 fsb
->f_files
= (fsd
.du_isize
- 2) * fsd
.du_inopb
;
792 fsb
->f_ffree
= fsd
.du_tinode
;
793 fsb
->f_fsid
.val
[0] = fsd
.du_site
;
794 fsb
->f_fsid
.val
[1] = fsd
.du_pckno
;
797 #define statfs(path,fsb) aix_statfs(path,fsb)
798 #endif /* _AIX && _I386 */
800 /* Fill in the fields of FSP with information about space usage for
801 the filesystem on which PATH resides.
802 Return 0 if successful, -1 if not. */
805 get_fs_usage (char *path
, struct fs_usage
*fsp
)
807 #ifdef STAT_STATFS3_OSF1
810 if (statfs (path
, &fsd
, sizeof (struct statfs
)) != 0)
812 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), fsd.f_fsize, 512)
813 #endif /* STAT_STATFS3_OSF1 */
815 #ifdef STAT_STATFS2_FS_DATA /* Ultrix. */
818 if (statfs (path
, &fsd
) != 1)
820 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), 1024, 512)
821 fsp
->fsu_blocks
= CONVERT_BLOCKS (fsd
.fd_req
.btot
);
822 fsp
->fsu_bfree
= CONVERT_BLOCKS (fsd
.fd_req
.bfree
);
823 fsp
->fsu_bavail
= CONVERT_BLOCKS (fsd
.fd_req
.bfreen
);
824 fsp
->fsu_files
= fsd
.fd_req
.gtot
;
825 fsp
->fsu_ffree
= fsd
.fd_req
.gfree
;
828 #ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX. */
831 if (statfs (path
, &fsd
) < 0)
833 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), fsd.f_bsize, 512)
836 #ifdef STAT_STATFS2_FSIZE /* 4.4BSD. */
839 if (statfs (path
, &fsd
) < 0)
841 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), fsd.f_fsize, 512)
844 #ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX. */
847 if (statfs (path
, &fsd
, sizeof fsd
, 0) < 0)
849 /* Empirically, the block counts on most SVR3 and SVR3-derived
850 systems seem to always be in terms of 512-byte blocks,
851 no matter what value f_bsize has. */
853 #define CONVERT_BLOCKS(b) fs_adjust_blocks ((b), fsd.f_bsize, 512)
855 #define CONVERT_BLOCKS(b) (b)
856 #ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx. */
857 #ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */
858 #define f_bavail f_bfree
864 #ifdef STAT_STATVFS /* SVR4. */
867 if (statvfs (path
, &fsd
) < 0)
869 /* f_frsize isn't guaranteed to be supported. */
870 #define CONVERT_BLOCKS(b) \
871 fs_adjust_blocks ((b), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512)
874 #if defined(CONVERT_BLOCKS) && !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ_FILSYS) /* !Ultrix && !SVR2. */
875 fsp
->fsu_blocks
= CONVERT_BLOCKS (fsd
.f_blocks
);
876 fsp
->fsu_bfree
= CONVERT_BLOCKS (fsd
.f_bfree
);
877 fsp
->fsu_bavail
= CONVERT_BLOCKS (fsd
.f_bavail
);
878 fsp
->fsu_files
= fsd
.f_files
;
879 fsp
->fsu_ffree
= fsd
.f_ffree
;
885 #endif /* HAVE_INFOMOUNT */