/* * Copyright (C) 1996-2023 The Squid Software Foundation and contributors * * Squid software is distributed under GPLv2+ license and includes * contributions from numerous individuals and organizations. * Please see the COPYING and CONTRIBUTORS files for details. */ #include "squid.h" #include "compat/statvfs.h" #if !HAVE_STATVFS // struct statfs has some member differences between OS versions #if HAVE_F_FRSIZE_IN_STATFS #define STATFS_FRSIZE(x) (x).f_frsize #else #define STATFS_FRSIZE(x) (x).f_bsize #endif int xstatvfs(const char *path, struct statvfs *sfs) { #if !HAVE_STATFS && _SQUID_WINDOWS_ char drive[4]; DWORD spc, bps, freec, totalc; DWORD vsn, maxlen, flags; if (!sfs) { errno = EINVAL; return -1; } strncpy(drive, path, 2); drive[2] = '\0'; strcat(drive, "\\"); if (!GetDiskFreeSpace(drive, &spc, &bps, &freec, &totalc)) { errno = ENOENT; return -1; } if (!GetVolumeInformation(drive, nullptr, 0, &vsn, &maxlen, &flags, nullptr, 0)) { errno = ENOENT; return -1; } memset(sfs, 0, sizeof(*sfs)); sfs->f_bsize = sfs->f_frsize = spc * bps; /* file system block size, fragment size */ sfs->f_blocks = totalc; /* size of fs in f_frsize units */ sfs->f_bfree = sfs->f_bavail = freec; /* # free blocks total, and available for unprivileged users */ sfs->f_files = sfs->f_ffree = sfs->f_favail = -1; /* # inodes total, free, and available for unprivileged users */ sfs->f_fsid = vsn; /* file system ID */ sfs->f_namemax = maxlen; /* maximum filename length */ return 0; #elif HAVE_STATFS // use statfs() and map results from struct statfs to struct statvfs struct statfs tmpSfs; if (int x = statfs(path, &tmpSfs)) return x; memset(sfs, 0, sizeof(*sfs)); sfs->f_bsize = tmpSfs.f_bsize; /* file system block size */ sfs->f_frsize = STATFS_FRSIZE(tmpSfs); /* fragment size */ sfs->f_blocks = tmpSfs.f_blocks; /* size of fs in f_frsize units */ sfs->f_bfree = tmpSfs.f_bfree; /* # free blocks */ sfs->f_bavail = tmpSfs.f_bavail; /* # free blocks for unprivileged users */ sfs->f_files = tmpSfs.f_files; /* # inodes */ sfs->f_ffree = tmpSfs.f_ffree; /* # free inodes */ sfs->f_favail = tmpSfs.f_ffree; /* # free inodes for unprivileged users */ sfs->f_fsid = tmpSfs.f_fsid; /* file system ID */ sfs->f_namemax = tmpSfs.f_namelen; /* maximum filename length */ #else #error Both statvfs() and statfs() system calls are missing. errno = ENOSYS; return -1; #endif } #endif /* HAVE_STATVFS */