/*
* Copyright 1994-1999, 2003 Matti Aarnio
* This is part of the ZMailer (2.99+), and available with
* the rules of the main program itself
*
* This yields available/used disk-space in KILOBYTES!
* This function maxes out at LONG_MAX for both the free,
* and the used space. (E.g. around 2 TB for 32 bit machines.)
*/
#include "hostenv.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>
#include <errno.h>
#ifdef HAVE_LIMIT_H
#include <limit.h>
#endif
#ifndef LONG_MAX
# define LONG_MAX 2147483647L /* For 32 bit machine! */
#endif
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif /* !HAVE_STATVFS */
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#include "libz.h"
long free_fd_statfs(fd)
int fd;
{
long bavail = 0;
long bsize = 0;
int rc;
/* Query the available space on the filesystem where the
currently open (int fd) file is located. This call
should be available on all systems, and given valid
parametrization, never fail... */
for (;;) {
#ifdef HAVE_STATVFS
struct statvfs statbuf; /* SysV and BSD definitions differ.. */
if ((rc = fstatvfs(fd, &statbuf)) == 0) {
/* Sidestep a problem at glibc 2.1.1 when running at Linux/i386 */
bavail = statbuf.f_bavail;
if (statbuf.f_frsize != 0)
bsize = statbuf.f_frsize;
else
bsize = statbuf.f_bsize;
}
#else
#ifdef STAT_STATFS3_OSF1
struct statfs statbuf;
if ((rc = fstatfs(fd, &statbuf, sizeof(statbuf))) == 0) {
bavail = statbuf.f_bavail;
bsize = statbuf.f_fsize;
}
#else
#ifdef STAT_STATFS2_BSIZE
struct statfs statbuf;
if ((rc = fstatfs(fd, &statbuf)) == 0) {
bavail = statbuf.f_bavail;
bsize = statbuf.f_bsize;
}
#else
#ifdef STAT_STATFS2_FSIZE
struct statfs statbuf;
if ((rc = fstatfs(fd, &statbuf)) == 0) {
bavail = statbuf.f_bavail;
bsize = statbuf.f_fsize;
}
#else
#ifdef STAT_STATFS2_FS_DATA /* Ultrix ? */
XX: XXX: XX: XXX:
#else /* none of the previous -- SVR3 stuff... */
struct statfs statbuf;
if ((rc = fstatfs(fd, &statbuf, sizeof statbuf, 0)) == 0) {
bavail = statbuf.f_bfree;
bsize = statbuf.f_bsize;
}
#endif
#endif
#endif
#endif
#endif
else {
if (errno == EINTR || errno == EAGAIN)
continue; /* restart the syscall! */
return -1; /* Don't know what! */
}
break; /* Out of for(;;) loop .. */
}
/* Convert the free space size to kilobytes ...
.. so that even 32 bit machines can handle
spools with more than 2 GB of free space
without using any sort of 64-bit gimmic codes... */
if (bsize < 1024) {
if (!bsize) bsize = 1024; /* Just code safety... */
bavail /= (1024 / bsize);
}
if (bsize > 1024) {
if (bavail <= (LONG_MAX / (long)(bsize / 1024)))
bavail *= (bsize / 1024);
else
bavail = LONG_MAX;
}
return bavail;
}
long used_fd_statfs(fd)
int fd;
{
long bused = 0;
long bsize = 0;
int rc;
/* Query the available space on the filesystem where the
currently open (int fd) file is located. This call
should be available on all systems, and given valid
parametrization, never fail... */
for (;;) {
#ifdef HAVE_STATVFS
struct statvfs statbuf; /* SysV and BSD definitions differ.. */
if ((rc = fstatvfs(fd, &statbuf)) == 0) {
/* Sidestep a problem at glibc 2.1.1 when running at Linux/i386 */
bused = statbuf.f_blocks - statbuf.f_bavail;
if (statbuf.f_frsize != 0)
bsize = statbuf.f_frsize;
else
bsize = statbuf.f_bsize;
}
#else
#ifdef STAT_STATFS3_OSF1
struct statfs statbuf;
if ((rc = fstatfs(fd, &statbuf, sizeof(statbuf))) == 0) {
/* UNSURE OF THIS WITHOUT MACHINE WHERE TO CHECK! */
bused = statbuf.f_blocks - statbuf.f_bavail;
bsize = statbuf.f_fsize;
}
#else
#ifdef STAT_STATFS2_BSIZE
struct statfs statbuf;
if ((rc = fstatfs(fd, &statbuf)) == 0) {
/* UNSURE OF THIS WITHOUT MACHINE WHERE TO CHECK! */
bused = statbuf.f_blocks - statbuf.f_bavail;
bsize = statbuf.f_bsize;
}
#else
#ifdef STAT_STATFS2_FSIZE
struct statfs statbuf;
if ((rc = fstatfs(fd, &statbuf)) == 0) {
/* UNSURE OF THIS WITHOUT MACHINE WHERE TO CHECK! */
bused = statbuf.f_blocks - statbuf.f_bavail;
bsize = statbuf.f_fsize;
}
#else
#ifdef STAT_STATFS2_FS_DATA /* Ultrix ? */
XX: XXX: XX: XXX:
#else /* none of the previous -- SVR3 stuff... */
struct statfs statbuf;
if ((rc = fstatfs(fd, &statbuf, sizeof statbuf, 0)) == 0) {
/* UNSURE OF THIS WITHOUT MACHINE WHERE TO CHECK! */
bused = statbuf.f_blocks - statbuf.f_bfree;
bsize = statbuf.f_bsize;
}
#endif
#endif
#endif
#endif
#endif
else {
if (errno == EINTR || errno == EAGAIN)
continue; /* restart the syscall! */
return -1; /* Don't know what! */
}
break; /* Out of for(;;) loop .. */
}
/* Convert the free space size to kilobytes ...
.. so that even 32 bit machines can handle
spools with more than 2 GB of used space
without using any sort of 64-bit gimmic codes... */
if (bsize < 1024) {
if (!bsize) bsize = 1024; /* Just code safety... */
bused /= (1024 / bsize);
}
if (bsize > 1024) {
if (bused <= (LONG_MAX / (long)(bsize / 1024)))
bused *= (bsize / 1024);
else
bused = LONG_MAX;
}
return bused;
}
syntax highlighted by Code2HTML, v. 0.9.1