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 */ | ||