#include "includes.h"
static SMB_BIG_UINT adjust_blocks(SMB_BIG_UINT blocks, SMB_BIG_UINT fromsize, SMB_BIG_UINT tosize)
{
if (fromsize == tosize) {
return blocks;
} else if (fromsize > tosize) {
return blocks * (fromsize / tosize);
} else {
if (fromsize == 0) {
fromsize = tosize;
}
return (blocks + 1) / (tosize / fromsize);
}
}
int sys_fsusage(const char *path, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
#ifdef STAT_STATFS3_OSF1
#define CONVERT_BLOCKS(B) adjust_blocks ((SMB_BIG_UINT)(B), (SMB_BIG_UINT)fsd.f_fsize, (SMB_BIG_UINT)512)
struct statfs fsd;
if (statfs (path, &fsd, sizeof (struct statfs)) != 0)
return -1;
#endif
#ifdef STAT_STATFS2_FS_DATA
#define CONVERT_BLOCKS(B) adjust_blocks ((SMB_BIG_UINT)(B), (SMB_BIG_UINT)1024, (SMB_BIG_UINT)512)
struct fs_data fsd;
if (statfs (path, &fsd) != 1)
return -1;
(*dsize) = CONVERT_BLOCKS (fsd.fd_req.btot);
(*dfree) = CONVERT_BLOCKS (fsd.fd_req.bfreen);
#endif
#ifdef STAT_STATFS2_BSIZE
#define CONVERT_BLOCKS(B) adjust_blocks ((SMB_BIG_UINT)(B), (SMB_BIG_UINT)fsd.f_bsize, (SMB_BIG_UINT)512)
struct statfs fsd;
if (statfs (path, &fsd) < 0)
return -1;
#ifdef STATFS_TRUNCATES_BLOCK_COUNTS
if (fsd.f_blocks == 0x1fffff && fsd.f_spare[0] > 0) {
fsd.f_blocks = fsd.f_spare[0];
fsd.f_bfree = fsd.f_spare[1];
fsd.f_bavail = fsd.f_spare[2];
}
#endif
#endif
#ifdef STAT_STATFS2_FSIZE
#define CONVERT_BLOCKS(B) adjust_blocks ((SMB_BIG_UINT)(B), (SMB_BIG_UINT)fsd.f_fsize, (SMB_BIG_UINT)512)
struct statfs fsd;
if (statfs (path, &fsd) < 0)
return -1;
#endif
#ifdef STAT_STATFS4
# if _AIX || defined(_CRAY)
# define CONVERT_BLOCKS(B) adjust_blocks ((SMB_BIG_UINT)(B), (SMB_BIG_UINT)fsd.f_bsize, (SMB_BIG_UINT)512)
# ifdef _CRAY
# define f_bavail f_bfree
# endif
# else
# define CONVERT_BLOCKS(B) ((SMB_BIG_UINT)B)
# ifndef _SEQUENT_
# ifndef DOLPHIN
# define f_bavail f_bfree
# endif
# endif
# endif
struct statfs fsd;
if (statfs (path, &fsd, sizeof fsd, 0) < 0)
return -1;
#endif
#if defined(STAT_STATVFS) || defined(STAT_STATVFS64)
# define CONVERT_BLOCKS(B) \
adjust_blocks ((SMB_BIG_UINT)(B), fsd.f_frsize ? (SMB_BIG_UINT)fsd.f_frsize : (SMB_BIG_UINT)fsd.f_bsize, (SMB_BIG_UINT)512)
#ifdef STAT_STATVFS64
struct statvfs64 fsd;
if (statvfs64(path, &fsd) < 0) return -1;
#else
struct statvfs fsd;
if (statvfs(path, &fsd) < 0) return -1;
#endif
#endif
#ifndef CONVERT_BLOCKS
return -1;
#else
#if !defined(STAT_STATFS2_FS_DATA)
(*dsize) = CONVERT_BLOCKS (fsd.f_blocks);
(*dfree) = CONVERT_BLOCKS (fsd.f_bavail);
#endif
#endif
return 0;
}