5
|
1 /* fsusage.c -- return space usage of mounted filesystems |
|
2 Copyright (C) 1991, 1992 Free Software Foundation, Inc. |
|
3 |
|
4 This program is free software; you can redistribute it and/or modify |
|
5 it under the terms of the GNU General Public License as published by |
|
6 the Free Software Foundation; either version 2, or (at your option) |
|
7 any later version. |
|
8 |
|
9 This program is distributed in the hope that it will be useful, |
|
10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 GNU General Public License for more details. |
|
13 |
|
14 You should have received a copy of the GNU General Public License |
|
15 along with this program; if not, write to the Free Software |
|
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
17 |
|
18 #include <sys/types.h> |
|
19 #include "fsusage.h" |
|
20 |
|
21 int statfs (); |
|
22 |
76
|
23 #if defined (STATFS_OSF1) /* DEC Alpha running OSF/1 */ |
|
24 # include <sys/mount.h> |
|
25 #endif |
|
26 |
5
|
27 #if defined(STAT_STATFS2_BSIZE) && !defined(_IBMR2) /* 4.3BSD, SunOS 4, HP-UX, AIX PS/2. */ |
|
28 #include <sys/vfs.h> |
|
29 #endif |
|
30 |
|
31 #ifdef STAT_STATFS2_FSIZE /* 4.4BSD. */ |
|
32 #include <sys/mount.h> |
|
33 #endif |
|
34 |
|
35 #ifdef STAT_STATFS2_FS_DATA /* Ultrix. */ |
|
36 #include <sys/param.h> |
|
37 #include <sys/mount.h> |
|
38 #endif |
|
39 |
|
40 #ifdef STAT_READ /* SVR2. */ |
|
41 #include <sys/param.h> |
|
42 #include <sys/filsys.h> |
|
43 #include <fcntl.h> |
|
44 #endif |
|
45 |
|
46 #if defined(STAT_STATFS4) || (defined(_AIX) && defined(_IBMR2)) /* SVR3, Dynix, Irix, AIX RS6000. */ |
|
47 #include <sys/statfs.h> |
|
48 #endif |
|
49 |
|
50 #if defined(_AIX) && defined(_I386) /* AIX PS/2. */ |
|
51 #include <sys/stat.h> |
|
52 #include <sys/dustat.h> |
|
53 #endif |
|
54 |
|
55 #ifdef STAT_STATVFS /* SVR4. */ |
|
56 #include <sys/statvfs.h> |
|
57 int statvfs (); |
|
58 #endif |
|
59 |
|
60 /* Return the number of TOSIZE-byte blocks used by |
97
|
61 BLOCKS FROMSIZE-byte blocks, rounding away from zero. */ |
5
|
62 |
40
|
63 static long |
|
64 adjust_blocks (blocks, fromsize, tosize) |
|
65 long blocks; |
|
66 int fromsize, tosize; |
|
67 { |
|
68 if (fromsize == tosize) /* E.g., from 512 to 512. */ |
|
69 return blocks; |
|
70 else if (fromsize > tosize) /* E.g., from 2048 to 512. */ |
|
71 return blocks * (fromsize / tosize); |
|
72 else /* E.g., from 256 to 512. */ |
104
|
73 return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize); |
40
|
74 } |
5
|
75 |
|
76 /* Fill in the fields of FSP with information about space usage for |
|
77 the filesystem on which PATH resides. |
|
78 DISK is the device on which PATH is mounted, for space-getting |
|
79 methods that need to know it. |
|
80 Return 0 if successful, -1 if not. */ |
|
81 |
|
82 int |
|
83 get_fs_usage (path, disk, fsp) |
|
84 char *path, *disk; |
|
85 struct fs_usage *fsp; |
|
86 { |
76
|
87 #if defined (STATFS_OSF1) |
|
88 struct statfs fsd; |
|
89 |
|
90 if (statfs (path, &fsd, sizeof (struct statfs)) != 0) |
|
91 return (-1); |
|
92 #define convert_blocks(b) adjust_blocks ((b),fsd.f_fsize, 512) |
|
93 #endif /* STATFS_OSF1 */ |
|
94 |
5
|
95 #ifdef STAT_STATFS2_FS_DATA /* Ultrix. */ |
|
96 struct fs_data fsd; |
|
97 |
|
98 if (statfs (path, &fsd) != 1) |
|
99 return -1; |
|
100 #define convert_blocks(b) adjust_blocks ((b), 1024, 512) |
|
101 fsp->fsu_blocks = convert_blocks (fsd.fd_req.btot); |
|
102 fsp->fsu_bfree = convert_blocks (fsd.fd_req.bfree); |
|
103 fsp->fsu_bavail = convert_blocks (fsd.fd_req.bfreen); |
|
104 fsp->fsu_files = fsd.fd_req.gtot; |
|
105 fsp->fsu_ffree = fsd.fd_req.gfree; |
|
106 #endif |
|
107 |
|
108 #ifdef STAT_READ /* SVR2. */ |
|
109 #ifndef SUPERBOFF |
|
110 #define SUPERBOFF (SUPERB * 512) |
|
111 #endif |
|
112 struct filsys fsd; |
|
113 int fd; |
|
114 |
|
115 fd = open (disk, O_RDONLY); |
|
116 if (fd < 0) |
|
117 return -1; |
|
118 lseek (fd, (long) SUPERBOFF, 0); |
|
119 if (read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd) |
|
120 { |
|
121 close (fd); |
|
122 return -1; |
|
123 } |
|
124 close (fd); |
|
125 #define convert_blocks(b) adjust_blocks ((b), (fsd.s_type == Fs2b ? 1024 : 512), 512) |
|
126 fsp->fsu_blocks = convert_blocks (fsd.s_fsize); |
|
127 fsp->fsu_bfree = convert_blocks (fsd.s_tfree); |
|
128 fsp->fsu_bavail = convert_blocks (fsd.s_tfree); |
|
129 fsp->fsu_files = (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1); |
|
130 fsp->fsu_ffree = fsd.s_tinode; |
|
131 #endif |
|
132 |
|
133 #ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX. */ |
|
134 struct statfs fsd; |
|
135 |
|
136 if (statfs (path, &fsd) < 0) |
|
137 return -1; |
|
138 #define convert_blocks(b) adjust_blocks ((b), fsd.f_bsize, 512) |
|
139 #endif |
|
140 |
|
141 #ifdef STAT_STATFS2_FSIZE /* 4.4BSD. */ |
|
142 struct statfs fsd; |
|
143 |
|
144 if (statfs (path, &fsd) < 0) |
|
145 return -1; |
|
146 #define convert_blocks(b) adjust_blocks ((b), fsd.f_fsize, 512) |
|
147 #endif |
|
148 |
|
149 #ifdef STAT_STATFS4 /* SVR3, Dynix, Irix. */ |
|
150 struct statfs fsd; |
|
151 |
|
152 if (statfs (path, &fsd, sizeof fsd, 0) < 0) |
|
153 return -1; |
|
154 /* Empirically, the block counts on most SVR3 and SVR3-derived |
|
155 systems seem to always be in terms of 512-byte blocks, |
|
156 no matter what value f_bsize has. */ |
|
157 #define convert_blocks(b) (b) |
|
158 #ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx. */ |
85
|
159 #ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */ |
5
|
160 #define f_bavail f_bfree |
|
161 #endif |
|
162 #endif |
85
|
163 #endif |
5
|
164 |
|
165 #ifdef STAT_STATVFS /* SVR4. */ |
|
166 struct statvfs fsd; |
|
167 |
|
168 if (statvfs (path, &fsd) < 0) |
|
169 return -1; |
|
170 /* f_frsize isn't guaranteed to be supported. */ |
|
171 #define convert_blocks(b) \ |
|
172 adjust_blocks ((b), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512) |
|
173 #endif |
|
174 |
|
175 #if !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ) /* !Ultrix && !SVR2. */ |
|
176 fsp->fsu_blocks = convert_blocks (fsd.f_blocks); |
|
177 fsp->fsu_bfree = convert_blocks (fsd.f_bfree); |
|
178 fsp->fsu_bavail = convert_blocks (fsd.f_bavail); |
|
179 fsp->fsu_files = fsd.f_files; |
|
180 fsp->fsu_ffree = fsd.f_ffree; |
|
181 #endif |
|
182 |
|
183 return 0; |
|
184 } |
|
185 |
|
186 #if defined(_AIX) && defined(_I386) |
|
187 /* AIX PS/2 does not supply statfs. */ |
|
188 |
|
189 int |
|
190 statfs (path, fsb) |
|
191 char *path; |
|
192 struct statfs *fsb; |
|
193 { |
|
194 struct stat stats; |
|
195 struct dustat fsd; |
|
196 |
|
197 if (stat (path, &stats)) |
|
198 return -1; |
|
199 if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd))) |
|
200 return -1; |
|
201 fsb->f_type = 0; |
|
202 fsb->f_bsize = fsd.du_bsize; |
|
203 fsb->f_blocks = fsd.du_fsize - fsd.du_isize; |
|
204 fsb->f_bfree = fsd.du_tfree; |
|
205 fsb->f_bavail = fsd.du_tfree; |
|
206 fsb->f_files = (fsd.du_isize - 2) * fsd.du_inopb; |
|
207 fsb->f_ffree = fsd.du_tinode; |
|
208 fsb->f_fsid.val[0] = fsd.du_site; |
|
209 fsb->f_fsid.val[1] = fsd.du_pckno; |
|
210 return 0; |
|
211 } |
|
212 #endif /* _AIX && _I386 */ |