diff options
Diffstat (limited to 'lib/fsusage.c')
| -rw-r--r-- | lib/fsusage.c | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/lib/fsusage.c b/lib/fsusage.c deleted file mode 100644 index b1377907..00000000 --- a/lib/fsusage.c +++ /dev/null | |||
| @@ -1,289 +0,0 @@ | |||
| 1 | /* fsusage.c -- return space usage of mounted file systems | ||
| 2 | |||
| 3 | Copyright (C) 1991, 1992, 1996, 1998, 1999, 2002, 2003, 2004, 2005 | ||
| 4 | Free Software Foundation, Inc. | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software Foundation, | ||
| 18 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
| 19 | |||
| 20 | #ifdef HAVE_CONFIG_H | ||
| 21 | # include <config.h> | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #if HAVE_INTTYPES_H | ||
| 25 | # include <inttypes.h> | ||
| 26 | #endif | ||
| 27 | #if HAVE_STDINT_H | ||
| 28 | # include <stdint.h> | ||
| 29 | #endif | ||
| 30 | #include <unistd.h> | ||
| 31 | #ifndef UINTMAX_MAX | ||
| 32 | # define UINTMAX_MAX ((uintmax_t) -1) | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #include <sys/types.h> | ||
| 36 | #include <sys/stat.h> | ||
| 37 | #include "fsusage.h" | ||
| 38 | |||
| 39 | #include <limits.h> | ||
| 40 | |||
| 41 | #if HAVE_SYS_PARAM_H | ||
| 42 | # include <sys/param.h> | ||
| 43 | #endif | ||
| 44 | |||
| 45 | #if HAVE_SYS_MOUNT_H | ||
| 46 | # include <sys/mount.h> | ||
| 47 | #endif | ||
| 48 | |||
| 49 | #if HAVE_SYS_VFS_H | ||
| 50 | # include <sys/vfs.h> | ||
| 51 | #endif | ||
| 52 | |||
| 53 | #if HAVE_SYS_FS_S5PARAM_H /* Fujitsu UXP/V */ | ||
| 54 | # include <sys/fs/s5param.h> | ||
| 55 | #endif | ||
| 56 | |||
| 57 | #if defined HAVE_SYS_FILSYS_H && !defined _CRAY | ||
| 58 | # include <sys/filsys.h> /* SVR2 */ | ||
| 59 | #endif | ||
| 60 | |||
| 61 | #include <fcntl.h> | ||
| 62 | |||
| 63 | #if HAVE_SYS_STATFS_H | ||
| 64 | # include <sys/statfs.h> | ||
| 65 | #endif | ||
| 66 | |||
| 67 | #if HAVE_DUSTAT_H /* AIX PS/2 */ | ||
| 68 | # include <sys/dustat.h> | ||
| 69 | #endif | ||
| 70 | |||
| 71 | #if HAVE_SYS_STATVFS_H /* SVR4 */ | ||
| 72 | # include <sys/statvfs.h> | ||
| 73 | #endif | ||
| 74 | |||
| 75 | #include "full-read.h" | ||
| 76 | |||
| 77 | /* Many space usage primitives use all 1 bits to denote a value that is | ||
| 78 | not applicable or unknown. Propagate this information by returning | ||
| 79 | a uintmax_t value that is all 1 bits if X is all 1 bits, even if X | ||
| 80 | is unsigned and narrower than uintmax_t. */ | ||
| 81 | #define PROPAGATE_ALL_ONES(x) \ | ||
| 82 | ((sizeof (x) < sizeof (uintmax_t) \ | ||
| 83 | && (~ (x) == (sizeof (x) < sizeof (int) \ | ||
| 84 | ? - (1 << (sizeof (x) * CHAR_BIT)) \ | ||
| 85 | : 0))) \ | ||
| 86 | ? UINTMAX_MAX : (x)) | ||
| 87 | |||
| 88 | /* Extract the top bit of X as an uintmax_t value. */ | ||
| 89 | #define EXTRACT_TOP_BIT(x) ((x) \ | ||
| 90 | & ((uintmax_t) 1 << (sizeof (x) * CHAR_BIT - 1))) | ||
| 91 | |||
| 92 | /* If a value is negative, many space usage primitives store it into an | ||
| 93 | integer variable by assignment, even if the variable's type is unsigned. | ||
| 94 | So, if a space usage variable X's top bit is set, convert X to the | ||
| 95 | uintmax_t value V such that (- (uintmax_t) V) is the negative of | ||
| 96 | the original value. If X's top bit is clear, just yield X. | ||
| 97 | Use PROPAGATE_TOP_BIT if the original value might be negative; | ||
| 98 | otherwise, use PROPAGATE_ALL_ONES. */ | ||
| 99 | #define PROPAGATE_TOP_BIT(x) ((x) | ~ (EXTRACT_TOP_BIT (x) - 1)) | ||
| 100 | |||
| 101 | /* Fill in the fields of FSP with information about space usage for | ||
| 102 | the file system on which FILE resides. | ||
| 103 | DISK is the device on which FILE is mounted, for space-getting | ||
| 104 | methods that need to know it. | ||
| 105 | Return 0 if successful, -1 if not. When returning -1, ensure that | ||
| 106 | ERRNO is either a system error value, or zero if DISK is NULL | ||
| 107 | on a system that requires a non-NULL value. */ | ||
| 108 | int | ||
| 109 | get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) | ||
| 110 | { | ||
| 111 | #ifdef STAT_STATFS3_OSF1 | ||
| 112 | |||
| 113 | struct statfs fsd; | ||
| 114 | |||
| 115 | if (statfs (file, &fsd, sizeof (struct statfs)) != 0) | ||
| 116 | return -1; | ||
| 117 | |||
| 118 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize); | ||
| 119 | |||
| 120 | #endif /* STAT_STATFS3_OSF1 */ | ||
| 121 | |||
| 122 | #ifdef STAT_STATFS2_FS_DATA /* Ultrix */ | ||
| 123 | |||
| 124 | struct fs_data fsd; | ||
| 125 | |||
| 126 | if (statfs (file, &fsd) != 1) | ||
| 127 | return -1; | ||
| 128 | |||
| 129 | fsp->fsu_blocksize = 1024; | ||
| 130 | fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.fd_req.btot); | ||
| 131 | fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.fd_req.bfree); | ||
| 132 | fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.fd_req.bfreen); | ||
| 133 | fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.fd_req.bfreen) != 0; | ||
| 134 | fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.fd_req.gtot); | ||
| 135 | fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.fd_req.gfree); | ||
| 136 | |||
| 137 | #endif /* STAT_STATFS2_FS_DATA */ | ||
| 138 | |||
| 139 | #ifdef STAT_READ_FILSYS /* SVR2 */ | ||
| 140 | # ifndef SUPERBOFF | ||
| 141 | # define SUPERBOFF (SUPERB * 512) | ||
| 142 | # endif | ||
| 143 | |||
| 144 | struct filsys fsd; | ||
| 145 | int fd; | ||
| 146 | |||
| 147 | if (! disk) | ||
| 148 | { | ||
| 149 | errno = 0; | ||
| 150 | return -1; | ||
| 151 | } | ||
| 152 | |||
| 153 | fd = open (disk, O_RDONLY); | ||
| 154 | if (fd < 0) | ||
| 155 | return -1; | ||
| 156 | lseek (fd, (off_t) SUPERBOFF, 0); | ||
| 157 | if (full_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd) | ||
| 158 | { | ||
| 159 | close (fd); | ||
| 160 | return -1; | ||
| 161 | } | ||
| 162 | close (fd); | ||
| 163 | |||
| 164 | fsp->fsu_blocksize = (fsd.s_type == Fs2b ? 1024 : 512); | ||
| 165 | fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.s_fsize); | ||
| 166 | fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.s_tfree); | ||
| 167 | fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.s_tfree); | ||
| 168 | fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.s_tfree) != 0; | ||
| 169 | fsp->fsu_files = (fsd.s_isize == -1 | ||
| 170 | ? UINTMAX_MAX | ||
| 171 | : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1)); | ||
| 172 | fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode); | ||
| 173 | |||
| 174 | #endif /* STAT_READ_FILSYS */ | ||
| 175 | |||
| 176 | #ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX */ | ||
| 177 | |||
| 178 | struct statfs fsd; | ||
| 179 | |||
| 180 | if (statfs (file, &fsd) < 0) | ||
| 181 | return -1; | ||
| 182 | |||
| 183 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize); | ||
| 184 | |||
| 185 | # ifdef STATFS_TRUNCATES_BLOCK_COUNTS | ||
| 186 | |||
| 187 | /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the | ||
| 188 | struct statfs are truncated to 2GB. These conditions detect that | ||
| 189 | truncation, presumably without botching the 4.1.1 case, in which | ||
| 190 | the values are not truncated. The correct counts are stored in | ||
| 191 | undocumented spare fields. */ | ||
| 192 | if (fsd.f_blocks == 0x7fffffff / fsd.f_bsize && fsd.f_spare[0] > 0) | ||
| 193 | { | ||
| 194 | fsd.f_blocks = fsd.f_spare[0]; | ||
| 195 | fsd.f_bfree = fsd.f_spare[1]; | ||
| 196 | fsd.f_bavail = fsd.f_spare[2]; | ||
| 197 | } | ||
| 198 | # endif /* STATFS_TRUNCATES_BLOCK_COUNTS */ | ||
| 199 | |||
| 200 | #endif /* STAT_STATFS2_BSIZE */ | ||
| 201 | |||
| 202 | #ifdef STAT_STATFS2_FSIZE /* 4.4BSD */ | ||
| 203 | |||
| 204 | struct statfs fsd; | ||
| 205 | |||
| 206 | if (statfs (file, &fsd) < 0) | ||
| 207 | return -1; | ||
| 208 | |||
| 209 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize); | ||
| 210 | |||
| 211 | #endif /* STAT_STATFS2_FSIZE */ | ||
| 212 | |||
| 213 | #ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX */ | ||
| 214 | |||
| 215 | # if !_AIX && !defined _SEQUENT_ && !defined DOLPHIN | ||
| 216 | # define f_bavail f_bfree | ||
| 217 | # endif | ||
| 218 | |||
| 219 | struct statfs fsd; | ||
| 220 | |||
| 221 | if (statfs (file, &fsd, sizeof fsd, 0) < 0) | ||
| 222 | return -1; | ||
| 223 | |||
| 224 | /* Empirically, the block counts on most SVR3 and SVR3-derived | ||
| 225 | systems seem to always be in terms of 512-byte blocks, | ||
| 226 | no matter what value f_bsize has. */ | ||
| 227 | # if _AIX || defined _CRAY | ||
| 228 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize); | ||
| 229 | # else | ||
| 230 | fsp->fsu_blocksize = 512; | ||
| 231 | # endif | ||
| 232 | |||
| 233 | #endif /* STAT_STATFS4 */ | ||
| 234 | |||
| 235 | #ifdef STAT_STATVFS /* SVR4 */ | ||
| 236 | |||
| 237 | struct statvfs fsd; | ||
| 238 | |||
| 239 | if (statvfs (file, &fsd) < 0) | ||
| 240 | return -1; | ||
| 241 | |||
| 242 | /* f_frsize isn't guaranteed to be supported. */ | ||
| 243 | fsp->fsu_blocksize = (fsd.f_frsize | ||
| 244 | ? PROPAGATE_ALL_ONES (fsd.f_frsize) | ||
| 245 | : PROPAGATE_ALL_ONES (fsd.f_bsize)); | ||
| 246 | |||
| 247 | #endif /* STAT_STATVFS */ | ||
| 248 | |||
| 249 | #if !defined STAT_STATFS2_FS_DATA && !defined STAT_READ_FILSYS | ||
| 250 | /* !Ultrix && !SVR2 */ | ||
| 251 | |||
| 252 | fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks); | ||
| 253 | fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree); | ||
| 254 | fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.f_bavail); | ||
| 255 | fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.f_bavail) != 0; | ||
| 256 | fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files); | ||
| 257 | fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree); | ||
| 258 | |||
| 259 | #endif /* not STAT_STATFS2_FS_DATA && not STAT_READ_FILSYS */ | ||
| 260 | |||
| 261 | return 0; | ||
| 262 | } | ||
| 263 | |||
| 264 | #if defined _AIX && defined _I386 | ||
| 265 | /* AIX PS/2 does not supply statfs. */ | ||
| 266 | |||
| 267 | int | ||
| 268 | statfs (char *file, struct statfs *fsb) | ||
| 269 | { | ||
| 270 | struct stat stats; | ||
| 271 | struct dustat fsd; | ||
| 272 | |||
| 273 | if (stat (file, &stats) != 0) | ||
| 274 | return -1; | ||
| 275 | if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd))) | ||
| 276 | return -1; | ||
| 277 | fsb->f_type = 0; | ||
| 278 | fsb->f_bsize = fsd.du_bsize; | ||
| 279 | fsb->f_blocks = fsd.du_fsize - fsd.du_isize; | ||
| 280 | fsb->f_bfree = fsd.du_tfree; | ||
| 281 | fsb->f_bavail = fsd.du_tfree; | ||
| 282 | fsb->f_files = (fsd.du_isize - 2) * fsd.du_inopb; | ||
| 283 | fsb->f_ffree = fsd.du_tinode; | ||
| 284 | fsb->f_fsid.val[0] = fsd.du_site; | ||
| 285 | fsb->f_fsid.val[1] = fsd.du_pckno; | ||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 289 | #endif /* _AIX && _I386 */ | ||
